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 bool rs6000_attribute_takes_identifier_p (const_tree);
901 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
902 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
903 static bool rs6000_ms_bitfield_layout_p (const_tree);
904 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
905 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
906 static const char *rs6000_mangle_type (const_tree);
907 static void rs6000_set_default_type_attributes (tree);
908 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
909 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
910 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
911 enum machine_mode, bool, bool, bool);
912 static bool rs6000_reg_live_or_pic_offset_p (int);
913 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
914 static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
915 static void rs6000_restore_saved_cr (rtx, int);
916 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
917 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
918 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
920 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
921 static bool rs6000_return_in_memory (const_tree, const_tree);
922 static rtx rs6000_function_value (const_tree, const_tree, bool);
923 static void rs6000_file_start (void);
925 static int rs6000_elf_reloc_rw_mask (void);
926 static void rs6000_elf_asm_out_constructor (rtx, int);
927 static void rs6000_elf_asm_out_destructor (rtx, int);
928 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
929 static void rs6000_elf_asm_init_sections (void);
930 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
931 unsigned HOST_WIDE_INT);
932 static void rs6000_elf_encode_section_info (tree, rtx, int)
935 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
936 static void rs6000_alloc_sdmode_stack_slot (void);
937 static void rs6000_instantiate_decls (void);
939 static void rs6000_xcoff_asm_output_anchor (rtx);
940 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
941 static void rs6000_xcoff_asm_init_sections (void);
942 static int rs6000_xcoff_reloc_rw_mask (void);
943 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
944 static section *rs6000_xcoff_select_section (tree, int,
945 unsigned HOST_WIDE_INT);
946 static void rs6000_xcoff_unique_section (tree, int);
947 static section *rs6000_xcoff_select_rtx_section
948 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
949 static const char * rs6000_xcoff_strip_name_encoding (const char *);
950 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
951 static void rs6000_xcoff_file_start (void);
952 static void rs6000_xcoff_file_end (void);
954 static int rs6000_variable_issue (FILE *, int, rtx, int);
955 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
956 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
957 static int rs6000_debug_address_cost (rtx, bool);
958 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
959 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
960 static void rs6000_sched_init (FILE *, int, int);
961 static bool is_microcoded_insn (rtx);
962 static bool is_nonpipeline_insn (rtx);
963 static bool is_cracked_insn (rtx);
964 static bool is_branch_slot_insn (rtx);
965 static bool is_load_insn (rtx);
966 static rtx get_store_dest (rtx pat);
967 static bool is_store_insn (rtx);
968 static bool set_to_load_agen (rtx,rtx);
969 static bool adjacent_mem_locations (rtx,rtx);
970 static int rs6000_adjust_priority (rtx, int);
971 static int rs6000_issue_rate (void);
972 static bool rs6000_is_costly_dependence (dep_t, int, int);
973 static rtx get_next_active_insn (rtx, rtx);
974 static bool insn_terminates_group_p (rtx , enum group_termination);
975 static bool insn_must_be_first_in_group (rtx);
976 static bool insn_must_be_last_in_group (rtx);
977 static bool is_costly_group (rtx *, rtx);
978 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
979 static int redefine_groups (FILE *, int, rtx, rtx);
980 static int pad_groups (FILE *, int, rtx, rtx);
981 static void rs6000_sched_finish (FILE *, int);
982 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
983 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
984 static int rs6000_use_sched_lookahead (void);
985 static int rs6000_use_sched_lookahead_guard (rtx);
986 static void * rs6000_alloc_sched_context (void);
987 static void rs6000_init_sched_context (void *, bool);
988 static void rs6000_set_sched_context (void *);
989 static void rs6000_free_sched_context (void *);
990 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
991 static tree rs6000_builtin_mask_for_load (void);
992 static tree rs6000_builtin_mul_widen_even (tree);
993 static tree rs6000_builtin_mul_widen_odd (tree);
994 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
995 static tree rs6000_builtin_vec_perm (tree, tree *);
996 static bool rs6000_builtin_support_vector_misalignment (enum
1001 static void def_builtin (int, const char *, tree, int);
1002 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1003 static void rs6000_init_builtins (void);
1004 static tree rs6000_builtin_decl (unsigned, bool);
1006 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1007 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1008 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1009 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1010 static void altivec_init_builtins (void);
1011 static unsigned builtin_hash_function (const void *);
1012 static int builtin_hash_eq (const void *, const void *);
1013 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1014 enum machine_mode, enum machine_mode,
1015 enum rs6000_builtins, const char *name);
1016 static void rs6000_common_init_builtins (void);
1017 static void rs6000_init_libfuncs (void);
1019 static void paired_init_builtins (void);
1020 static rtx paired_expand_builtin (tree, rtx, bool *);
1021 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1022 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1023 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1025 static void enable_mask_for_builtins (struct builtin_description *, int,
1026 enum rs6000_builtins,
1027 enum rs6000_builtins);
1028 static void spe_init_builtins (void);
1029 static rtx spe_expand_builtin (tree, rtx, bool *);
1030 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1031 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1032 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1033 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1034 static rs6000_stack_t *rs6000_stack_info (void);
1035 static void debug_stack_info (rs6000_stack_t *);
1037 static rtx altivec_expand_builtin (tree, rtx, bool *);
1038 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1039 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1040 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1041 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1042 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1043 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1044 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1045 static rtx altivec_expand_vec_set_builtin (tree);
1046 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1047 static int get_element_number (tree, tree);
1048 static bool rs6000_handle_option (size_t, const char *, int);
1049 static void rs6000_parse_tls_size_option (void);
1050 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1051 static int first_altivec_reg_to_save (void);
1052 static unsigned int compute_vrsave_mask (void);
1053 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1054 static void is_altivec_return_reg (rtx, void *);
1055 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1056 int easy_vector_constant (rtx, enum machine_mode);
1057 static rtx rs6000_dwarf_register_span (rtx);
1058 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1059 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1060 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1061 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1062 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1063 static rtx rs6000_delegitimize_address (rtx);
1064 static rtx rs6000_tls_get_addr (void);
1065 static rtx rs6000_got_sym (void);
1066 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1067 static const char *rs6000_get_some_local_dynamic_name (void);
1068 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1069 static rtx rs6000_complex_function_value (enum machine_mode);
1070 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
1071 enum machine_mode, tree);
1072 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1074 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1075 tree, HOST_WIDE_INT);
1076 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1079 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1080 const_tree, HOST_WIDE_INT,
1082 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
1083 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
1084 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1085 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1086 enum machine_mode, tree,
1088 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1090 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1092 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1094 static void macho_branch_islands (void);
1095 static int no_previous_def (tree function_name);
1096 static tree get_prev_label (tree function_name);
1097 static void rs6000_darwin_file_start (void);
1100 static tree rs6000_build_builtin_va_list (void);
1101 static void rs6000_va_start (tree, rtx);
1102 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1103 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1104 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1105 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1106 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1107 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1109 static tree rs6000_stack_protect_fail (void);
1111 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1114 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1117 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1119 = rs6000_legitimize_reload_address;
1121 static bool rs6000_mode_dependent_address (rtx);
1122 static bool rs6000_debug_mode_dependent_address (rtx);
1123 bool (*rs6000_mode_dependent_address_ptr) (rtx)
1124 = rs6000_mode_dependent_address;
1126 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1127 enum machine_mode, rtx);
1128 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1131 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1132 enum machine_mode, rtx)
1133 = rs6000_secondary_reload_class;
1135 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1136 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1138 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1139 = rs6000_preferred_reload_class;
1141 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1144 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1148 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1150 = rs6000_secondary_memory_needed;
1152 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1155 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1159 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1162 = rs6000_cannot_change_mode_class;
1164 static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class,
1166 struct secondary_reload_info *);
1168 static const enum reg_class *rs6000_ira_cover_classes (void);
1170 const int INSN_NOT_AVAILABLE = -1;
1171 static enum machine_mode rs6000_eh_return_filter_mode (void);
1172 static bool rs6000_can_eliminate (const int, const int);
1173 static void rs6000_trampoline_init (rtx, tree, rtx);
1175 /* Hash table stuff for keeping track of TOC entries. */
1177 struct GTY(()) toc_hash_struct
1179 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1180 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1182 enum machine_mode key_mode;
1186 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1188 /* Hash table to keep track of the argument types for builtin functions. */
1190 struct GTY(()) builtin_hash_struct
1193 enum machine_mode mode[4]; /* return value + 3 arguments. */
1194 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1197 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1199 /* Default register names. */
1200 char rs6000_reg_names[][8] =
1202 "0", "1", "2", "3", "4", "5", "6", "7",
1203 "8", "9", "10", "11", "12", "13", "14", "15",
1204 "16", "17", "18", "19", "20", "21", "22", "23",
1205 "24", "25", "26", "27", "28", "29", "30", "31",
1206 "0", "1", "2", "3", "4", "5", "6", "7",
1207 "8", "9", "10", "11", "12", "13", "14", "15",
1208 "16", "17", "18", "19", "20", "21", "22", "23",
1209 "24", "25", "26", "27", "28", "29", "30", "31",
1210 "mq", "lr", "ctr","ap",
1211 "0", "1", "2", "3", "4", "5", "6", "7",
1213 /* AltiVec registers. */
1214 "0", "1", "2", "3", "4", "5", "6", "7",
1215 "8", "9", "10", "11", "12", "13", "14", "15",
1216 "16", "17", "18", "19", "20", "21", "22", "23",
1217 "24", "25", "26", "27", "28", "29", "30", "31",
1219 /* SPE registers. */
1220 "spe_acc", "spefscr",
1221 /* Soft frame pointer. */
1225 #ifdef TARGET_REGNAMES
1226 static const char alt_reg_names[][8] =
1228 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1229 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1230 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1231 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1232 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1233 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1234 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1235 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1236 "mq", "lr", "ctr", "ap",
1237 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1239 /* AltiVec registers. */
1240 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1241 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1242 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1243 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1245 /* SPE registers. */
1246 "spe_acc", "spefscr",
1247 /* Soft frame pointer. */
1252 /* Table of valid machine attributes. */
1254 static const struct attribute_spec rs6000_attribute_table[] =
1256 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1257 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1258 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1259 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1260 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1261 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1262 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1263 SUBTARGET_ATTRIBUTE_TABLE,
1265 { NULL, 0, 0, false, false, false, NULL }
1268 #ifndef MASK_STRICT_ALIGN
1269 #define MASK_STRICT_ALIGN 0
1271 #ifndef TARGET_PROFILE_KERNEL
1272 #define TARGET_PROFILE_KERNEL 0
1275 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1276 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1278 /* Initialize the GCC target structure. */
1279 #undef TARGET_ATTRIBUTE_TABLE
1280 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1281 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1282 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1283 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1284 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1286 #undef TARGET_ASM_ALIGNED_DI_OP
1287 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1289 /* Default unaligned ops are only provided for ELF. Find the ops needed
1290 for non-ELF systems. */
1291 #ifndef OBJECT_FORMAT_ELF
1293 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1295 #undef TARGET_ASM_UNALIGNED_HI_OP
1296 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1297 #undef TARGET_ASM_UNALIGNED_SI_OP
1298 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1299 #undef TARGET_ASM_UNALIGNED_DI_OP
1300 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1303 #undef TARGET_ASM_UNALIGNED_HI_OP
1304 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1305 #undef TARGET_ASM_UNALIGNED_SI_OP
1306 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1307 #undef TARGET_ASM_UNALIGNED_DI_OP
1308 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1309 #undef TARGET_ASM_ALIGNED_DI_OP
1310 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1314 /* This hook deals with fixups for relocatable code and DI-mode objects
1316 #undef TARGET_ASM_INTEGER
1317 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1319 #ifdef HAVE_GAS_HIDDEN
1320 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1321 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1324 #undef TARGET_HAVE_TLS
1325 #define TARGET_HAVE_TLS HAVE_AS_TLS
1327 #undef TARGET_CANNOT_FORCE_CONST_MEM
1328 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1330 #undef TARGET_DELEGITIMIZE_ADDRESS
1331 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1333 #undef TARGET_ASM_FUNCTION_PROLOGUE
1334 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1335 #undef TARGET_ASM_FUNCTION_EPILOGUE
1336 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1338 #undef TARGET_LEGITIMIZE_ADDRESS
1339 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1341 #undef TARGET_SCHED_VARIABLE_ISSUE
1342 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1344 #undef TARGET_SCHED_ISSUE_RATE
1345 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1346 #undef TARGET_SCHED_ADJUST_COST
1347 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1348 #undef TARGET_SCHED_ADJUST_PRIORITY
1349 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1350 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1351 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1352 #undef TARGET_SCHED_INIT
1353 #define TARGET_SCHED_INIT rs6000_sched_init
1354 #undef TARGET_SCHED_FINISH
1355 #define TARGET_SCHED_FINISH rs6000_sched_finish
1356 #undef TARGET_SCHED_REORDER
1357 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1358 #undef TARGET_SCHED_REORDER2
1359 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1361 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1362 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1364 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1365 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1367 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1368 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1369 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1370 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1371 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1372 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1373 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1374 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1376 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1377 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1378 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1379 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1380 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1381 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1382 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1383 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1384 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1385 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1386 #undef TARGET_SUPPORT_VECTOR_MISALIGNMENT
1387 #define TARGET_SUPPORT_VECTOR_MISALIGNMENT \
1388 rs6000_builtin_support_vector_misalignment
1389 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1390 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1392 #undef TARGET_INIT_BUILTINS
1393 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1394 #undef TARGET_BUILTIN_DECL
1395 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1397 #undef TARGET_EXPAND_BUILTIN
1398 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1400 #undef TARGET_MANGLE_TYPE
1401 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1403 #undef TARGET_INIT_LIBFUNCS
1404 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1407 #undef TARGET_BINDS_LOCAL_P
1408 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1411 #undef TARGET_MS_BITFIELD_LAYOUT_P
1412 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1414 #undef TARGET_ASM_OUTPUT_MI_THUNK
1415 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1417 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1418 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1420 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1421 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1423 #undef TARGET_INVALID_WITHIN_DOLOOP
1424 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1426 #undef TARGET_RTX_COSTS
1427 #define TARGET_RTX_COSTS rs6000_rtx_costs
1428 #undef TARGET_ADDRESS_COST
1429 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1431 #undef TARGET_DWARF_REGISTER_SPAN
1432 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1434 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1435 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1437 /* On rs6000, function arguments are promoted, as are function return
1439 #undef TARGET_PROMOTE_FUNCTION_MODE
1440 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1442 #undef TARGET_RETURN_IN_MEMORY
1443 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1445 #undef TARGET_SETUP_INCOMING_VARARGS
1446 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1448 /* Always strict argument naming on rs6000. */
1449 #undef TARGET_STRICT_ARGUMENT_NAMING
1450 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1451 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1452 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1453 #undef TARGET_SPLIT_COMPLEX_ARG
1454 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1455 #undef TARGET_MUST_PASS_IN_STACK
1456 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1457 #undef TARGET_PASS_BY_REFERENCE
1458 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1459 #undef TARGET_ARG_PARTIAL_BYTES
1460 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1462 #undef TARGET_BUILD_BUILTIN_VA_LIST
1463 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1465 #undef TARGET_EXPAND_BUILTIN_VA_START
1466 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1468 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1469 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1471 #undef TARGET_EH_RETURN_FILTER_MODE
1472 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1474 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1475 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1477 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1478 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1480 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1481 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1483 #undef TARGET_HANDLE_OPTION
1484 #define TARGET_HANDLE_OPTION rs6000_handle_option
1486 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1487 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1488 rs6000_builtin_vectorized_function
1490 #undef TARGET_DEFAULT_TARGET_FLAGS
1491 #define TARGET_DEFAULT_TARGET_FLAGS \
1494 #undef TARGET_STACK_PROTECT_FAIL
1495 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1497 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1498 The PowerPC architecture requires only weak consistency among
1499 processors--that is, memory accesses between processors need not be
1500 sequentially consistent and memory accesses among processors can occur
1501 in any order. The ability to order memory accesses weakly provides
1502 opportunities for more efficient use of the system bus. Unless a
1503 dependency exists, the 604e allows read operations to precede store
1505 #undef TARGET_RELAXED_ORDERING
1506 #define TARGET_RELAXED_ORDERING true
1509 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1510 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1513 /* Use a 32-bit anchor range. This leads to sequences like:
1515 addis tmp,anchor,high
1518 where tmp itself acts as an anchor, and can be shared between
1519 accesses to the same 64k page. */
1520 #undef TARGET_MIN_ANCHOR_OFFSET
1521 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1522 #undef TARGET_MAX_ANCHOR_OFFSET
1523 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1524 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1525 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1527 #undef TARGET_BUILTIN_RECIPROCAL
1528 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1530 #undef TARGET_EXPAND_TO_RTL_HOOK
1531 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1533 #undef TARGET_INSTANTIATE_DECLS
1534 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1536 #undef TARGET_SECONDARY_RELOAD
1537 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1539 #undef TARGET_IRA_COVER_CLASSES
1540 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1542 #undef TARGET_LEGITIMATE_ADDRESS_P
1543 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1545 #undef TARGET_CAN_ELIMINATE
1546 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1548 #undef TARGET_TRAMPOLINE_INIT
1549 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1551 #undef TARGET_FUNCTION_VALUE
1552 #define TARGET_FUNCTION_VALUE rs6000_function_value
1554 struct gcc_target targetm = TARGET_INITIALIZER;
1556 /* Return number of consecutive hard regs needed starting at reg REGNO
1557 to hold something of mode MODE.
1558 This is ordinarily the length in words of a value of mode MODE
1559 but can be less for certain modes in special long registers.
1561 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1562 scalar instructions. The upper 32 bits are only available to the
1565 POWER and PowerPC GPRs hold 32 bits worth;
1566 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1569 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1571 unsigned HOST_WIDE_INT reg_size;
1573 if (FP_REGNO_P (regno))
1574 reg_size = (VECTOR_MEM_VSX_P (mode)
1575 ? UNITS_PER_VSX_WORD
1576 : UNITS_PER_FP_WORD);
1578 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1579 reg_size = UNITS_PER_SPE_WORD;
1581 else if (ALTIVEC_REGNO_P (regno))
1582 reg_size = UNITS_PER_ALTIVEC_WORD;
1584 /* The value returned for SCmode in the E500 double case is 2 for
1585 ABI compatibility; storing an SCmode value in a single register
1586 would require function_arg and rs6000_spe_function_arg to handle
1587 SCmode so as to pass the value correctly in a pair of
1589 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1590 && !DECIMAL_FLOAT_MODE_P (mode))
1591 reg_size = UNITS_PER_FP_WORD;
1594 reg_size = UNITS_PER_WORD;
1596 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1599 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1602 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1604 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1606 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1607 implementations. Don't allow an item to be split between a FP register
1608 and an Altivec register. */
1609 if (VECTOR_MEM_VSX_P (mode))
1611 if (FP_REGNO_P (regno))
1612 return FP_REGNO_P (last_regno);
1614 if (ALTIVEC_REGNO_P (regno))
1615 return ALTIVEC_REGNO_P (last_regno);
1618 /* The GPRs can hold any mode, but values bigger than one register
1619 cannot go past R31. */
1620 if (INT_REGNO_P (regno))
1621 return INT_REGNO_P (last_regno);
1623 /* The float registers (except for VSX vector modes) can only hold floating
1624 modes and DImode. This excludes the 32-bit decimal float mode for
1626 if (FP_REGNO_P (regno))
1628 if (SCALAR_FLOAT_MODE_P (mode)
1629 && (mode != TDmode || (regno % 2) == 0)
1630 && FP_REGNO_P (last_regno))
1633 if (GET_MODE_CLASS (mode) == MODE_INT
1634 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1637 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1638 && PAIRED_VECTOR_MODE (mode))
1644 /* The CR register can only hold CC modes. */
1645 if (CR_REGNO_P (regno))
1646 return GET_MODE_CLASS (mode) == MODE_CC;
1648 if (XER_REGNO_P (regno))
1649 return mode == PSImode;
1651 /* AltiVec only in AldyVec registers. */
1652 if (ALTIVEC_REGNO_P (regno))
1653 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1655 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1656 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1659 /* We cannot put TImode anywhere except general register and it must be able
1660 to fit within the register set. In the future, allow TImode in the
1661 Altivec or VSX registers. */
1663 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1666 /* Print interesting facts about registers. */
1668 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1672 for (r = first_regno; r <= last_regno; ++r)
1674 const char *comma = "";
1677 if (first_regno == last_regno)
1678 fprintf (stderr, "%s:\t", reg_name);
1680 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1683 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1684 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1688 fprintf (stderr, ",\n\t");
1693 if (rs6000_hard_regno_nregs[m][r] > 1)
1694 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1695 rs6000_hard_regno_nregs[m][r]);
1697 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1702 if (call_used_regs[r])
1706 fprintf (stderr, ",\n\t");
1711 len += fprintf (stderr, "%s%s", comma, "call-used");
1719 fprintf (stderr, ",\n\t");
1724 len += fprintf (stderr, "%s%s", comma, "fixed");
1730 fprintf (stderr, ",\n\t");
1734 fprintf (stderr, "%sregno = %d\n", comma, r);
1738 /* Print various interesting information with -mdebug=reg. */
1740 rs6000_debug_reg_global (void)
1742 const char *nl = (const char *)0;
1744 char costly_num[20];
1746 const char *costly_str;
1747 const char *nop_str;
1749 /* Map enum rs6000_vector to string. */
1750 static const char *rs6000_debug_vector_unit[] = {
1759 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1760 LAST_VIRTUAL_REGISTER);
1761 rs6000_debug_reg_print (0, 31, "gr");
1762 rs6000_debug_reg_print (32, 63, "fp");
1763 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1766 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1767 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1768 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1769 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1770 rs6000_debug_reg_print (XER_REGNO, XER_REGNO, "xer");
1771 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1772 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1773 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1774 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1778 "d reg_class = %s\n"
1779 "f reg_class = %s\n"
1780 "v reg_class = %s\n"
1781 "wa reg_class = %s\n"
1782 "wd reg_class = %s\n"
1783 "wf reg_class = %s\n"
1784 "ws reg_class = %s\n\n",
1785 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1786 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1787 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1788 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1789 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1790 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1791 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1793 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1794 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1797 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1799 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1800 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1806 switch (rs6000_sched_costly_dep)
1808 case max_dep_latency:
1809 costly_str = "max_dep_latency";
1813 costly_str = "no_dep_costly";
1816 case all_deps_costly:
1817 costly_str = "all_deps_costly";
1820 case true_store_to_load_dep_costly:
1821 costly_str = "true_store_to_load_dep_costly";
1824 case store_to_load_dep_costly:
1825 costly_str = "store_to_load_dep_costly";
1829 costly_str = costly_num;
1830 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1834 switch (rs6000_sched_insert_nops)
1836 case sched_finish_regroup_exact:
1837 nop_str = "sched_finish_regroup_exact";
1840 case sched_finish_pad_groups:
1841 nop_str = "sched_finish_pad_groups";
1844 case sched_finish_none:
1845 nop_str = "sched_finish_none";
1850 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1855 "always_hint = %s\n"
1856 "align_branch_targets = %s\n"
1857 "sched_restricted_insns_priority = %d\n"
1858 "sched_costly_dep = %s\n"
1859 "sched_insert_nops = %s\n\n",
1860 rs6000_always_hint ? "true" : "false",
1861 rs6000_align_branch_targets ? "true" : "false",
1862 (int)rs6000_sched_restricted_insns_priority,
1863 costly_str, nop_str);
1866 /* Initialize the various global tables that are based on register size. */
1868 rs6000_init_hard_regno_mode_ok (void)
1874 /* Precalculate REGNO_REG_CLASS. */
1875 rs6000_regno_regclass[0] = GENERAL_REGS;
1876 for (r = 1; r < 32; ++r)
1877 rs6000_regno_regclass[r] = BASE_REGS;
1879 for (r = 32; r < 64; ++r)
1880 rs6000_regno_regclass[r] = FLOAT_REGS;
1882 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1883 rs6000_regno_regclass[r] = NO_REGS;
1885 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
1886 rs6000_regno_regclass[r] = ALTIVEC_REGS;
1888 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
1889 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
1890 rs6000_regno_regclass[r] = CR_REGS;
1892 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
1893 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
1894 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
1895 rs6000_regno_regclass[XER_REGNO] = XER_REGS;
1896 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
1897 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
1898 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
1899 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
1900 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
1901 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
1903 /* Precalculate vector information, this must be set up before the
1904 rs6000_hard_regno_nregs_internal below. */
1905 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1907 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
1908 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
1909 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
1912 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
1913 rs6000_constraints[c] = NO_REGS;
1915 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
1916 believes it can use native alignment or still uses 128-bit alignment. */
1917 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
1928 /* V2DF mode, VSX only. */
1931 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
1932 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
1933 rs6000_vector_align[V2DFmode] = align64;
1936 /* V4SF mode, either VSX or Altivec. */
1939 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
1940 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
1941 rs6000_vector_align[V4SFmode] = align32;
1943 else if (TARGET_ALTIVEC)
1945 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
1946 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
1947 rs6000_vector_align[V4SFmode] = align32;
1950 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
1954 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
1955 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
1956 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
1957 rs6000_vector_align[V4SImode] = align32;
1958 rs6000_vector_align[V8HImode] = align32;
1959 rs6000_vector_align[V16QImode] = align32;
1963 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
1964 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
1965 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
1969 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
1970 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
1971 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
1975 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
1976 Altivec doesn't have 64-bit support. */
1979 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
1980 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
1981 rs6000_vector_align[V2DImode] = align64;
1984 /* DFmode, see if we want to use the VSX unit. */
1985 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
1987 rs6000_vector_unit[DFmode] = VECTOR_VSX;
1988 rs6000_vector_mem[DFmode]
1989 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
1990 rs6000_vector_align[DFmode] = align64;
1993 /* TODO add SPE and paired floating point vector support. */
1995 /* Register class constaints for the constraints that depend on compile
1997 if (TARGET_HARD_FLOAT && TARGET_FPRS)
1998 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2000 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2001 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2005 /* At present, we just use VSX_REGS, but we have different constraints
2006 based on the use, in case we want to fine tune the default register
2007 class used. wa = any VSX register, wf = register class to use for
2008 V4SF, wd = register class to use for V2DF, and ws = register classs to
2009 use for DF scalars. */
2010 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2011 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2012 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2013 if (TARGET_VSX_SCALAR_DOUBLE)
2014 rs6000_constraints[RS6000_CONSTRAINT_ws] = VSX_REGS;
2018 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2020 /* Set up the reload helper functions. */
2021 if (TARGET_VSX || TARGET_ALTIVEC)
2025 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2026 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2027 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2028 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2029 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2030 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2031 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2032 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2033 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2034 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2035 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2036 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2040 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2041 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2042 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2043 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2044 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2045 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2046 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2047 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2048 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2049 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2050 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2051 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2055 /* Precalculate HARD_REGNO_NREGS. */
2056 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2057 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2058 rs6000_hard_regno_nregs[m][r]
2059 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2061 /* Precalculate HARD_REGNO_MODE_OK. */
2062 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2063 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2064 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2065 rs6000_hard_regno_mode_ok_p[m][r] = true;
2067 /* Precalculate CLASS_MAX_NREGS sizes. */
2068 for (c = 0; c < LIM_REG_CLASSES; ++c)
2072 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2073 reg_size = UNITS_PER_VSX_WORD;
2075 else if (c == ALTIVEC_REGS)
2076 reg_size = UNITS_PER_ALTIVEC_WORD;
2078 else if (c == FLOAT_REGS)
2079 reg_size = UNITS_PER_FP_WORD;
2082 reg_size = UNITS_PER_WORD;
2084 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2085 rs6000_class_max_nregs[m][c]
2086 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2089 if (TARGET_E500_DOUBLE)
2090 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2092 if (TARGET_DEBUG_REG)
2093 rs6000_debug_reg_global ();
2097 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2100 darwin_rs6000_override_options (void)
2102 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2104 rs6000_altivec_abi = 1;
2105 TARGET_ALTIVEC_VRSAVE = 1;
2106 if (DEFAULT_ABI == ABI_DARWIN)
2108 if (MACHO_DYNAMIC_NO_PIC_P)
2111 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2114 else if (flag_pic == 1)
2119 if (TARGET_64BIT && ! TARGET_POWERPC64)
2121 target_flags |= MASK_POWERPC64;
2122 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2126 rs6000_default_long_calls = 1;
2127 target_flags |= MASK_SOFT_FLOAT;
2130 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2132 if (!flag_mkernel && !flag_apple_kext
2134 && ! (target_flags_explicit & MASK_ALTIVEC))
2135 target_flags |= MASK_ALTIVEC;
2137 /* Unless the user (not the configurer) has explicitly overridden
2138 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2139 G4 unless targetting the kernel. */
2142 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2143 && ! (target_flags_explicit & MASK_ALTIVEC)
2144 && ! rs6000_select[1].string)
2146 target_flags |= MASK_ALTIVEC;
2151 /* If not otherwise specified by a target, make 'long double' equivalent to
2154 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2155 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2158 /* Override command line options. Mostly we process the processor
2159 type and sometimes adjust other TARGET_ options. */
2162 rs6000_override_options (const char *default_cpu)
2165 struct rs6000_cpu_select *ptr;
2168 /* Simplifications for entries below. */
2171 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2172 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2175 /* This table occasionally claims that a processor does not support
2176 a particular feature even though it does, but the feature is slower
2177 than the alternative. Thus, it shouldn't be relied on as a
2178 complete description of the processor's support.
2180 Please keep this list in order, and don't forget to update the
2181 documentation in invoke.texi when adding a new processor or
2185 const char *const name; /* Canonical processor name. */
2186 const enum processor_type processor; /* Processor type enum value. */
2187 const int target_enable; /* Target flags to enable. */
2188 } const processor_target_table[]
2189 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2190 {"403", PROCESSOR_PPC403,
2191 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2192 {"405", PROCESSOR_PPC405,
2193 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2194 {"405fp", PROCESSOR_PPC405,
2195 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2196 {"440", PROCESSOR_PPC440,
2197 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2198 {"440fp", PROCESSOR_PPC440,
2199 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2200 {"464", PROCESSOR_PPC440,
2201 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2202 {"464fp", PROCESSOR_PPC440,
2203 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2204 {"476", PROCESSOR_PPC476,
2205 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2206 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2207 {"476fp", PROCESSOR_PPC476,
2208 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2209 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2210 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2211 {"601", PROCESSOR_PPC601,
2212 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2213 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2214 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2215 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2216 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2217 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2218 {"620", PROCESSOR_PPC620,
2219 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2220 {"630", PROCESSOR_PPC630,
2221 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2222 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2223 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2224 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2225 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2226 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2227 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2228 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2229 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2231 /* 8548 has a dummy entry for now. */
2232 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2234 {"a2", PROCESSOR_PPCA2,
2235 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2236 | MASK_CMPB | MASK_NO_UPDATE },
2237 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2238 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2239 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2241 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2242 | MASK_PPC_GFXOPT | MASK_ISEL},
2243 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2244 {"970", PROCESSOR_POWER4,
2245 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2246 {"cell", PROCESSOR_CELL,
2247 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2248 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2249 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2250 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2251 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2252 {"G5", PROCESSOR_POWER4,
2253 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2254 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2255 {"power2", PROCESSOR_POWER,
2256 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2257 {"power3", PROCESSOR_PPC630,
2258 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2259 {"power4", PROCESSOR_POWER4,
2260 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2262 {"power5", PROCESSOR_POWER5,
2263 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2264 | MASK_MFCRF | MASK_POPCNTB},
2265 {"power5+", PROCESSOR_POWER5,
2266 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2267 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2268 {"power6", PROCESSOR_POWER6,
2269 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2270 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP},
2271 {"power6x", PROCESSOR_POWER6,
2272 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2273 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2275 {"power7", PROCESSOR_POWER7,
2276 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2277 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2278 | MASK_VSX}, /* Don't add MASK_ISEL by default */
2279 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2280 {"powerpc64", PROCESSOR_POWERPC64,
2281 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2282 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2283 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2284 {"rios2", PROCESSOR_RIOS2,
2285 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2286 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2287 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2288 {"rs64", PROCESSOR_RS64A,
2289 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2292 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2294 /* Some OSs don't support saving the high part of 64-bit registers on
2295 context switch. Other OSs don't support saving Altivec registers.
2296 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2297 settings; if the user wants either, the user must explicitly specify
2298 them and we won't interfere with the user's specification. */
2301 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2302 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2303 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2304 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2305 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2306 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE)
2309 /* Numerous experiment shows that IRA based loop pressure
2310 calculation works better for RTL loop invariant motion on targets
2311 with enough (>= 32) registers. It is an expensive optimization.
2312 So it is on only for peak performance. */
2314 flag_ira_loop_pressure = 1;
2316 /* Set the pointer size. */
2319 rs6000_pmode = (int)DImode;
2320 rs6000_pointer_size = 64;
2324 rs6000_pmode = (int)SImode;
2325 rs6000_pointer_size = 32;
2328 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2329 #ifdef OS_MISSING_POWERPC64
2330 if (OS_MISSING_POWERPC64)
2331 set_masks &= ~MASK_POWERPC64;
2333 #ifdef OS_MISSING_ALTIVEC
2334 if (OS_MISSING_ALTIVEC)
2335 set_masks &= ~MASK_ALTIVEC;
2338 /* Don't override by the processor default if given explicitly. */
2339 set_masks &= ~target_flags_explicit;
2341 /* Identify the processor type. */
2342 rs6000_select[0].string = default_cpu;
2343 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2345 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2347 ptr = &rs6000_select[i];
2348 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2350 for (j = 0; j < ptt_size; j++)
2351 if (! strcmp (ptr->string, processor_target_table[j].name))
2353 if (ptr->set_tune_p)
2354 rs6000_cpu = processor_target_table[j].processor;
2356 if (ptr->set_arch_p)
2358 target_flags &= ~set_masks;
2359 target_flags |= (processor_target_table[j].target_enable
2366 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2370 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2371 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2374 error ("AltiVec not supported in this target");
2376 error ("Spe not supported in this target");
2379 /* Disable Cell microcode if we are optimizing for the Cell
2380 and not optimizing for size. */
2381 if (rs6000_gen_cell_microcode == -1)
2382 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2385 /* If we are optimizing big endian systems for space and it's OK to
2386 use instructions that would be microcoded on the Cell, use the
2387 load/store multiple and string instructions. */
2388 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2389 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2391 /* Don't allow -mmultiple or -mstring on little endian systems
2392 unless the cpu is a 750, because the hardware doesn't support the
2393 instructions used in little endian mode, and causes an alignment
2394 trap. The 750 does not cause an alignment trap (except when the
2395 target is unaligned). */
2397 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2399 if (TARGET_MULTIPLE)
2401 target_flags &= ~MASK_MULTIPLE;
2402 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2403 warning (0, "-mmultiple is not supported on little endian systems");
2408 target_flags &= ~MASK_STRING;
2409 if ((target_flags_explicit & MASK_STRING) != 0)
2410 warning (0, "-mstring is not supported on little endian systems");
2414 /* Add some warnings for VSX. */
2417 const char *msg = NULL;
2418 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2419 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2421 if (target_flags_explicit & MASK_VSX)
2422 msg = N_("-mvsx requires hardware floating point");
2424 target_flags &= ~ MASK_VSX;
2426 else if (TARGET_PAIRED_FLOAT)
2427 msg = N_("-mvsx and -mpaired are incompatible");
2428 /* The hardware will allow VSX and little endian, but until we make sure
2429 things like vector select, etc. work don't allow VSX on little endian
2430 systems at this point. */
2431 else if (!BYTES_BIG_ENDIAN)
2432 msg = N_("-mvsx used with little endian code");
2433 else if (TARGET_AVOID_XFORM > 0)
2434 msg = N_("-mvsx needs indexed addressing");
2435 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2437 if (target_flags_explicit & MASK_VSX)
2438 msg = N_("-mvsx and -mno-altivec are incompatible");
2440 msg = N_("-mno-altivec disables vsx");
2446 target_flags &= ~ MASK_VSX;
2448 else if (TARGET_VSX && !TARGET_ALTIVEC)
2449 target_flags |= MASK_ALTIVEC;
2452 /* Set debug flags */
2453 if (rs6000_debug_name)
2455 if (! strcmp (rs6000_debug_name, "all"))
2456 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2457 = rs6000_debug_addr = rs6000_debug_cost = 1;
2458 else if (! strcmp (rs6000_debug_name, "stack"))
2459 rs6000_debug_stack = 1;
2460 else if (! strcmp (rs6000_debug_name, "arg"))
2461 rs6000_debug_arg = 1;
2462 else if (! strcmp (rs6000_debug_name, "reg"))
2463 rs6000_debug_reg = 1;
2464 else if (! strcmp (rs6000_debug_name, "addr"))
2465 rs6000_debug_addr = 1;
2466 else if (! strcmp (rs6000_debug_name, "cost"))
2467 rs6000_debug_cost = 1;
2469 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2471 /* If the appropriate debug option is enabled, replace the target hooks
2472 with debug versions that call the real version and then prints
2473 debugging information. */
2474 if (TARGET_DEBUG_COST)
2476 targetm.rtx_costs = rs6000_debug_rtx_costs;
2477 targetm.address_cost = rs6000_debug_address_cost;
2478 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2481 if (TARGET_DEBUG_ADDR)
2483 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2484 targetm.legitimize_address = rs6000_debug_legitimize_address;
2485 rs6000_secondary_reload_class_ptr
2486 = rs6000_debug_secondary_reload_class;
2487 rs6000_secondary_memory_needed_ptr
2488 = rs6000_debug_secondary_memory_needed;
2489 rs6000_cannot_change_mode_class_ptr
2490 = rs6000_debug_cannot_change_mode_class;
2491 rs6000_preferred_reload_class_ptr
2492 = rs6000_debug_preferred_reload_class;
2493 rs6000_legitimize_reload_address_ptr
2494 = rs6000_debug_legitimize_reload_address;
2495 rs6000_mode_dependent_address_ptr
2496 = rs6000_debug_mode_dependent_address;
2500 if (rs6000_traceback_name)
2502 if (! strncmp (rs6000_traceback_name, "full", 4))
2503 rs6000_traceback = traceback_full;
2504 else if (! strncmp (rs6000_traceback_name, "part", 4))
2505 rs6000_traceback = traceback_part;
2506 else if (! strncmp (rs6000_traceback_name, "no", 2))
2507 rs6000_traceback = traceback_none;
2509 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2510 rs6000_traceback_name);
2513 if (!rs6000_explicit_options.long_double)
2514 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2516 #ifndef POWERPC_LINUX
2517 if (!rs6000_explicit_options.ieee)
2518 rs6000_ieeequad = 1;
2521 /* Enable Altivec ABI for AIX -maltivec. */
2522 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2523 rs6000_altivec_abi = 1;
2525 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2526 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2527 be explicitly overridden in either case. */
2530 if (!rs6000_explicit_options.altivec_abi
2531 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2532 rs6000_altivec_abi = 1;
2534 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2535 if (!rs6000_explicit_options.vrsave)
2536 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2539 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2540 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2542 rs6000_darwin64_abi = 1;
2544 darwin_one_byte_bool = 1;
2546 /* Default to natural alignment, for better performance. */
2547 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2550 /* Place FP constants in the constant pool instead of TOC
2551 if section anchors enabled. */
2552 if (flag_section_anchors)
2553 TARGET_NO_FP_IN_TOC = 1;
2555 /* Handle -mtls-size option. */
2556 rs6000_parse_tls_size_option ();
2558 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2559 SUBTARGET_OVERRIDE_OPTIONS;
2561 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2562 SUBSUBTARGET_OVERRIDE_OPTIONS;
2564 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2565 SUB3TARGET_OVERRIDE_OPTIONS;
2568 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2569 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2571 /* The e500 and e500mc do not have string instructions, and we set
2572 MASK_STRING above when optimizing for size. */
2573 if ((target_flags & MASK_STRING) != 0)
2574 target_flags = target_flags & ~MASK_STRING;
2576 else if (rs6000_select[1].string != NULL)
2578 /* For the powerpc-eabispe configuration, we set all these by
2579 default, so let's unset them if we manually set another
2580 CPU that is not the E500. */
2581 if (!rs6000_explicit_options.spe_abi)
2583 if (!rs6000_explicit_options.spe)
2585 if (!rs6000_explicit_options.float_gprs)
2586 rs6000_float_gprs = 0;
2587 if (!(target_flags_explicit & MASK_ISEL))
2588 target_flags &= ~MASK_ISEL;
2591 /* Detect invalid option combinations with E500. */
2594 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2595 && rs6000_cpu != PROCESSOR_POWER5
2596 && rs6000_cpu != PROCESSOR_POWER6
2597 && rs6000_cpu != PROCESSOR_POWER7
2598 && rs6000_cpu != PROCESSOR_PPCA2
2599 && rs6000_cpu != PROCESSOR_CELL);
2600 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2601 || rs6000_cpu == PROCESSOR_POWER5
2602 || rs6000_cpu == PROCESSOR_POWER7);
2603 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2604 || rs6000_cpu == PROCESSOR_POWER5
2605 || rs6000_cpu == PROCESSOR_POWER6
2606 || rs6000_cpu == PROCESSOR_POWER7
2607 || rs6000_cpu == PROCESSOR_PPCE500MC
2608 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2610 /* Allow debug switches to override the above settings. */
2611 if (TARGET_ALWAYS_HINT > 0)
2612 rs6000_always_hint = TARGET_ALWAYS_HINT;
2614 if (TARGET_SCHED_GROUPS > 0)
2615 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2617 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2618 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2620 rs6000_sched_restricted_insns_priority
2621 = (rs6000_sched_groups ? 1 : 0);
2623 /* Handle -msched-costly-dep option. */
2624 rs6000_sched_costly_dep
2625 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2627 if (rs6000_sched_costly_dep_str)
2629 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2630 rs6000_sched_costly_dep = no_dep_costly;
2631 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2632 rs6000_sched_costly_dep = all_deps_costly;
2633 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2634 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2635 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2636 rs6000_sched_costly_dep = store_to_load_dep_costly;
2638 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2639 atoi (rs6000_sched_costly_dep_str));
2642 /* Handle -minsert-sched-nops option. */
2643 rs6000_sched_insert_nops
2644 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2646 if (rs6000_sched_insert_nops_str)
2648 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2649 rs6000_sched_insert_nops = sched_finish_none;
2650 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2651 rs6000_sched_insert_nops = sched_finish_pad_groups;
2652 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2653 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2655 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2656 atoi (rs6000_sched_insert_nops_str));
2659 #ifdef TARGET_REGNAMES
2660 /* If the user desires alternate register names, copy in the
2661 alternate names now. */
2662 if (TARGET_REGNAMES)
2663 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2666 /* Set aix_struct_return last, after the ABI is determined.
2667 If -maix-struct-return or -msvr4-struct-return was explicitly
2668 used, don't override with the ABI default. */
2669 if (!rs6000_explicit_options.aix_struct_ret)
2670 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2672 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2673 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2676 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2678 /* We can only guarantee the availability of DI pseudo-ops when
2679 assembling for 64-bit targets. */
2682 targetm.asm_out.aligned_op.di = NULL;
2683 targetm.asm_out.unaligned_op.di = NULL;
2686 /* Set branch target alignment, if not optimizing for size. */
2689 /* Cell wants to be aligned 8byte for dual issue. */
2690 if (rs6000_cpu == PROCESSOR_CELL)
2692 if (align_functions <= 0)
2693 align_functions = 8;
2694 if (align_jumps <= 0)
2696 if (align_loops <= 0)
2699 if (rs6000_align_branch_targets)
2701 if (align_functions <= 0)
2702 align_functions = 16;
2703 if (align_jumps <= 0)
2705 if (align_loops <= 0)
2708 if (align_jumps_max_skip <= 0)
2709 align_jumps_max_skip = 15;
2710 if (align_loops_max_skip <= 0)
2711 align_loops_max_skip = 15;
2714 /* Arrange to save and restore machine status around nested functions. */
2715 init_machine_status = rs6000_init_machine_status;
2717 /* We should always be splitting complex arguments, but we can't break
2718 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2719 if (DEFAULT_ABI != ABI_AIX)
2720 targetm.calls.split_complex_arg = NULL;
2722 /* Initialize rs6000_cost with the appropriate target costs. */
2724 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2728 case PROCESSOR_RIOS1:
2729 rs6000_cost = &rios1_cost;
2732 case PROCESSOR_RIOS2:
2733 rs6000_cost = &rios2_cost;
2736 case PROCESSOR_RS64A:
2737 rs6000_cost = &rs64a_cost;
2740 case PROCESSOR_MPCCORE:
2741 rs6000_cost = &mpccore_cost;
2744 case PROCESSOR_PPC403:
2745 rs6000_cost = &ppc403_cost;
2748 case PROCESSOR_PPC405:
2749 rs6000_cost = &ppc405_cost;
2752 case PROCESSOR_PPC440:
2753 rs6000_cost = &ppc440_cost;
2756 case PROCESSOR_PPC476:
2757 rs6000_cost = &ppc476_cost;
2760 case PROCESSOR_PPC601:
2761 rs6000_cost = &ppc601_cost;
2764 case PROCESSOR_PPC603:
2765 rs6000_cost = &ppc603_cost;
2768 case PROCESSOR_PPC604:
2769 rs6000_cost = &ppc604_cost;
2772 case PROCESSOR_PPC604e:
2773 rs6000_cost = &ppc604e_cost;
2776 case PROCESSOR_PPC620:
2777 rs6000_cost = &ppc620_cost;
2780 case PROCESSOR_PPC630:
2781 rs6000_cost = &ppc630_cost;
2784 case PROCESSOR_CELL:
2785 rs6000_cost = &ppccell_cost;
2788 case PROCESSOR_PPC750:
2789 case PROCESSOR_PPC7400:
2790 rs6000_cost = &ppc750_cost;
2793 case PROCESSOR_PPC7450:
2794 rs6000_cost = &ppc7450_cost;
2797 case PROCESSOR_PPC8540:
2798 rs6000_cost = &ppc8540_cost;
2801 case PROCESSOR_PPCE300C2:
2802 case PROCESSOR_PPCE300C3:
2803 rs6000_cost = &ppce300c2c3_cost;
2806 case PROCESSOR_PPCE500MC:
2807 rs6000_cost = &ppce500mc_cost;
2810 case PROCESSOR_PPCE500MC64:
2811 rs6000_cost = &ppce500mc64_cost;
2814 case PROCESSOR_POWER4:
2815 case PROCESSOR_POWER5:
2816 rs6000_cost = &power4_cost;
2819 case PROCESSOR_POWER6:
2820 rs6000_cost = &power6_cost;
2823 case PROCESSOR_POWER7:
2824 rs6000_cost = &power7_cost;
2827 case PROCESSOR_PPCA2:
2828 rs6000_cost = &ppca2_cost;
2835 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
2836 set_param_value ("simultaneous-prefetches",
2837 rs6000_cost->simultaneous_prefetches);
2838 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
2839 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
2840 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
2841 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
2842 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
2843 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
2845 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
2846 can be optimized to ap = __builtin_next_arg (0). */
2847 if (DEFAULT_ABI != ABI_V4)
2848 targetm.expand_builtin_va_start = NULL;
2850 /* Set up single/double float flags.
2851 If TARGET_HARD_FLOAT is set, but neither single or double is set,
2852 then set both flags. */
2853 if (TARGET_HARD_FLOAT && TARGET_FPRS
2854 && rs6000_single_float == 0 && rs6000_double_float == 0)
2855 rs6000_single_float = rs6000_double_float = 1;
2857 /* Reset single and double FP flags if target is E500. */
2860 rs6000_single_float = rs6000_double_float = 0;
2861 if (TARGET_E500_SINGLE)
2862 rs6000_single_float = 1;
2863 if (TARGET_E500_DOUBLE)
2864 rs6000_single_float = rs6000_double_float = 1;
2867 /* If not explicitly specified via option, decide whether to generate indexed
2868 load/store instructions. */
2869 if (TARGET_AVOID_XFORM == -1)
2870 /* Avoid indexed addressing when targeting Power6 in order to avoid
2871 the DERAT mispredict penalty. */
2872 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
2874 rs6000_init_hard_regno_mode_ok ();
2877 /* Implement targetm.vectorize.builtin_mask_for_load. */
2879 rs6000_builtin_mask_for_load (void)
2881 if (TARGET_ALTIVEC || TARGET_VSX)
2882 return altivec_builtin_mask_for_load;
2887 /* Implement targetm.vectorize.builtin_conversion.
2888 Returns a decl of a function that implements conversion of an integer vector
2889 into a floating-point vector, or vice-versa. DEST_TYPE is the
2890 destination type and SRC_TYPE the source type of the conversion.
2891 Return NULL_TREE if it is not available. */
2893 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
2895 enum tree_code code = (enum tree_code) tcode;
2899 case FIX_TRUNC_EXPR:
2900 switch (TYPE_MODE (dest_type))
2903 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2906 return TYPE_UNSIGNED (dest_type)
2907 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
2908 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
2911 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2914 return TYPE_UNSIGNED (dest_type)
2915 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
2916 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
2923 switch (TYPE_MODE (src_type))
2926 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2929 return TYPE_UNSIGNED (src_type)
2930 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
2931 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
2934 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2937 return TYPE_UNSIGNED (src_type)
2938 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
2939 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
2950 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2952 rs6000_builtin_mul_widen_even (tree type)
2954 if (!TARGET_ALTIVEC)
2957 switch (TYPE_MODE (type))
2960 return TYPE_UNSIGNED (type)
2961 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
2962 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
2965 return TYPE_UNSIGNED (type)
2966 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
2967 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
2973 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2975 rs6000_builtin_mul_widen_odd (tree type)
2977 if (!TARGET_ALTIVEC)
2980 switch (TYPE_MODE (type))
2983 return TYPE_UNSIGNED (type)
2984 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
2985 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
2988 return TYPE_UNSIGNED (type)
2989 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
2990 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
2997 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2998 after applying N number of iterations. This routine does not determine
2999 how may iterations are required to reach desired alignment. */
3002 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3009 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3012 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3022 /* Assuming that all other types are naturally aligned. CHECKME! */
3027 /* Return true if the vector misalignment factor is supported by the
3030 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3037 /* Return if movmisalign pattern is not supported for this mode. */
3038 if (optab_handler (movmisalign_optab, mode)->insn_code ==
3042 if (misalignment == -1)
3044 /* misalignment factor is unknown at compile time but we know
3045 it's word aligned. */
3046 if (rs6000_vector_alignment_reachable (type, is_packed))
3050 /* VSX supports word-aligned vector. */
3051 if (misalignment % 4 == 0)
3057 /* Implement targetm.vectorize.builtin_vec_perm. */
3059 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3061 tree inner_type = TREE_TYPE (type);
3062 bool uns_p = TYPE_UNSIGNED (inner_type);
3065 *mask_element_type = unsigned_char_type_node;
3067 switch (TYPE_MODE (type))
3071 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3072 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3077 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3078 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3083 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3084 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3088 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3092 if (!TARGET_ALLOW_DF_PERMUTE)
3095 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3099 if (!TARGET_ALLOW_DF_PERMUTE)
3103 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3104 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3115 /* Handle generic options of the form -mfoo=yes/no.
3116 NAME is the option name.
3117 VALUE is the option value.
3118 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3119 whether the option value is 'yes' or 'no' respectively. */
3121 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3125 else if (!strcmp (value, "yes"))
3127 else if (!strcmp (value, "no"))
3130 error ("unknown -m%s= option specified: '%s'", name, value);
3133 /* Validate and record the size specified with the -mtls-size option. */
3136 rs6000_parse_tls_size_option (void)
3138 if (rs6000_tls_size_string == 0)
3140 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3141 rs6000_tls_size = 16;
3142 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3143 rs6000_tls_size = 32;
3144 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3145 rs6000_tls_size = 64;
3147 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3151 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3153 if (DEFAULT_ABI == ABI_DARWIN)
3154 /* The Darwin libraries never set errno, so we might as well
3155 avoid calling them when that's the only reason we would. */
3156 flag_errno_math = 0;
3158 /* Double growth factor to counter reduced min jump length. */
3159 set_param_value ("max-grow-copy-bb-insns", 16);
3161 /* Enable section anchors by default.
3162 Skip section anchors for Objective C and Objective C++
3163 until front-ends fixed. */
3164 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3165 flag_section_anchors = 2;
3168 static enum fpu_type_t
3169 rs6000_parse_fpu_option (const char *option)
3171 if (!strcmp("none", option)) return FPU_NONE;
3172 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3173 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3174 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3175 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3176 error("unknown value %s for -mfpu", option);
3180 /* Returns a function decl for a vectorized version of the builtin function
3181 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3182 if it is not available. */
3185 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3188 enum machine_mode in_mode, out_mode;
3190 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3192 if (TREE_CODE (type_out) != VECTOR_TYPE
3193 || TREE_CODE (type_in) != VECTOR_TYPE
3194 || !TARGET_VECTORIZE_BUILTINS
3195 || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
3198 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3199 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3200 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3201 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3205 case BUILT_IN_COPYSIGN:
3206 if (VECTOR_UNIT_VSX_P (V2DFmode)
3207 && out_mode == DFmode && out_n == 2
3208 && in_mode == DFmode && in_n == 2)
3209 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3211 case BUILT_IN_COPYSIGNF:
3212 if (out_mode != SFmode || out_n != 4
3213 || in_mode != SFmode || in_n != 4)
3215 if (VECTOR_UNIT_VSX_P (V4SFmode))
3216 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3217 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3218 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3221 if (VECTOR_UNIT_VSX_P (V2DFmode)
3222 && out_mode == DFmode && out_n == 2
3223 && in_mode == DFmode && in_n == 2)
3224 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3226 case BUILT_IN_SQRTF:
3227 if (VECTOR_UNIT_VSX_P (V4SFmode)
3228 && out_mode == SFmode && out_n == 4
3229 && in_mode == SFmode && in_n == 4)
3230 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3233 if (VECTOR_UNIT_VSX_P (V2DFmode)
3234 && out_mode == DFmode && out_n == 2
3235 && in_mode == DFmode && in_n == 2)
3236 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3238 case BUILT_IN_CEILF:
3239 if (out_mode != SFmode || out_n != 4
3240 || in_mode != SFmode || in_n != 4)
3242 if (VECTOR_UNIT_VSX_P (V4SFmode))
3243 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3244 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3245 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3247 case BUILT_IN_FLOOR:
3248 if (VECTOR_UNIT_VSX_P (V2DFmode)
3249 && out_mode == DFmode && out_n == 2
3250 && in_mode == DFmode && in_n == 2)
3251 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3253 case BUILT_IN_FLOORF:
3254 if (out_mode != SFmode || out_n != 4
3255 || in_mode != SFmode || in_n != 4)
3257 if (VECTOR_UNIT_VSX_P (V4SFmode))
3258 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3259 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3260 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3262 case BUILT_IN_TRUNC:
3263 if (VECTOR_UNIT_VSX_P (V2DFmode)
3264 && out_mode == DFmode && out_n == 2
3265 && in_mode == DFmode && in_n == 2)
3266 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3268 case BUILT_IN_TRUNCF:
3269 if (out_mode != SFmode || out_n != 4
3270 || in_mode != SFmode || in_n != 4)
3272 if (VECTOR_UNIT_VSX_P (V4SFmode))
3273 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3274 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3275 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3277 case BUILT_IN_NEARBYINT:
3278 if (VECTOR_UNIT_VSX_P (V2DFmode)
3279 && flag_unsafe_math_optimizations
3280 && out_mode == DFmode && out_n == 2
3281 && in_mode == DFmode && in_n == 2)
3282 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3284 case BUILT_IN_NEARBYINTF:
3285 if (VECTOR_UNIT_VSX_P (V4SFmode)
3286 && flag_unsafe_math_optimizations
3287 && out_mode == SFmode && out_n == 4
3288 && in_mode == SFmode && in_n == 4)
3289 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3292 if (VECTOR_UNIT_VSX_P (V2DFmode)
3293 && !flag_trapping_math
3294 && out_mode == DFmode && out_n == 2
3295 && in_mode == DFmode && in_n == 2)
3296 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3298 case BUILT_IN_RINTF:
3299 if (VECTOR_UNIT_VSX_P (V4SFmode)
3300 && !flag_trapping_math
3301 && out_mode == SFmode && out_n == 4
3302 && in_mode == SFmode && in_n == 4)
3303 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3312 /* Implement TARGET_HANDLE_OPTION. */
3315 rs6000_handle_option (size_t code, const char *arg, int value)
3317 enum fpu_type_t fpu_type = FPU_NONE;
3323 target_flags &= ~(MASK_POWER | MASK_POWER2
3324 | MASK_MULTIPLE | MASK_STRING);
3325 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3326 | MASK_MULTIPLE | MASK_STRING);
3328 case OPT_mno_powerpc:
3329 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3330 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3331 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3332 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3335 target_flags &= ~MASK_MINIMAL_TOC;
3336 TARGET_NO_FP_IN_TOC = 0;
3337 TARGET_NO_SUM_IN_TOC = 0;
3338 target_flags_explicit |= MASK_MINIMAL_TOC;
3339 #ifdef TARGET_USES_SYSV4_OPT
3340 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3341 just the same as -mminimal-toc. */
3342 target_flags |= MASK_MINIMAL_TOC;
3343 target_flags_explicit |= MASK_MINIMAL_TOC;
3347 #ifdef TARGET_USES_SYSV4_OPT
3349 /* Make -mtoc behave like -mminimal-toc. */
3350 target_flags |= MASK_MINIMAL_TOC;
3351 target_flags_explicit |= MASK_MINIMAL_TOC;
3355 #ifdef TARGET_USES_AIX64_OPT
3360 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3361 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3362 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3365 #ifdef TARGET_USES_AIX64_OPT
3370 target_flags &= ~MASK_POWERPC64;
3371 target_flags_explicit |= MASK_POWERPC64;
3374 case OPT_minsert_sched_nops_:
3375 rs6000_sched_insert_nops_str = arg;
3378 case OPT_mminimal_toc:
3381 TARGET_NO_FP_IN_TOC = 0;
3382 TARGET_NO_SUM_IN_TOC = 0;
3389 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3390 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3397 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3398 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3402 case OPT_mpowerpc_gpopt:
3403 case OPT_mpowerpc_gfxopt:
3406 target_flags |= MASK_POWERPC;
3407 target_flags_explicit |= MASK_POWERPC;
3411 case OPT_maix_struct_return:
3412 case OPT_msvr4_struct_return:
3413 rs6000_explicit_options.aix_struct_ret = true;
3417 rs6000_explicit_options.vrsave = true;
3418 TARGET_ALTIVEC_VRSAVE = value;
3422 rs6000_explicit_options.vrsave = true;
3423 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3427 target_flags_explicit |= MASK_ISEL;
3429 rs6000_parse_yes_no_option ("isel", arg, &isel);
3431 target_flags |= MASK_ISEL;
3433 target_flags &= ~MASK_ISEL;
3437 rs6000_explicit_options.spe = true;
3442 rs6000_explicit_options.spe = true;
3443 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3447 rs6000_debug_name = arg;
3450 #ifdef TARGET_USES_SYSV4_OPT
3452 rs6000_abi_name = arg;
3456 rs6000_sdata_name = arg;
3459 case OPT_mtls_size_:
3460 rs6000_tls_size_string = arg;
3463 case OPT_mrelocatable:
3466 target_flags |= MASK_MINIMAL_TOC;
3467 target_flags_explicit |= MASK_MINIMAL_TOC;
3468 TARGET_NO_FP_IN_TOC = 1;
3472 case OPT_mrelocatable_lib:
3475 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3476 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3477 TARGET_NO_FP_IN_TOC = 1;
3481 target_flags &= ~MASK_RELOCATABLE;
3482 target_flags_explicit |= MASK_RELOCATABLE;
3488 if (!strcmp (arg, "altivec"))
3490 rs6000_explicit_options.altivec_abi = true;
3491 rs6000_altivec_abi = 1;
3493 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3496 else if (! strcmp (arg, "no-altivec"))
3498 rs6000_explicit_options.altivec_abi = true;
3499 rs6000_altivec_abi = 0;
3501 else if (! strcmp (arg, "spe"))
3503 rs6000_explicit_options.spe_abi = true;
3505 rs6000_altivec_abi = 0;
3506 if (!TARGET_SPE_ABI)
3507 error ("not configured for ABI: '%s'", arg);
3509 else if (! strcmp (arg, "no-spe"))
3511 rs6000_explicit_options.spe_abi = true;
3515 /* These are here for testing during development only, do not
3516 document in the manual please. */
3517 else if (! strcmp (arg, "d64"))
3519 rs6000_darwin64_abi = 1;
3520 warning (0, "Using darwin64 ABI");
3522 else if (! strcmp (arg, "d32"))
3524 rs6000_darwin64_abi = 0;
3525 warning (0, "Using old darwin ABI");
3528 else if (! strcmp (arg, "ibmlongdouble"))
3530 rs6000_explicit_options.ieee = true;
3531 rs6000_ieeequad = 0;
3532 warning (0, "Using IBM extended precision long double");
3534 else if (! strcmp (arg, "ieeelongdouble"))
3536 rs6000_explicit_options.ieee = true;
3537 rs6000_ieeequad = 1;
3538 warning (0, "Using IEEE extended precision long double");
3543 error ("unknown ABI specified: '%s'", arg);
3549 rs6000_select[1].string = arg;
3553 rs6000_select[2].string = arg;
3556 case OPT_mtraceback_:
3557 rs6000_traceback_name = arg;
3560 case OPT_mfloat_gprs_:
3561 rs6000_explicit_options.float_gprs = true;
3562 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3563 rs6000_float_gprs = 1;
3564 else if (! strcmp (arg, "double"))
3565 rs6000_float_gprs = 2;
3566 else if (! strcmp (arg, "no"))
3567 rs6000_float_gprs = 0;
3570 error ("invalid option for -mfloat-gprs: '%s'", arg);
3575 case OPT_mlong_double_:
3576 rs6000_explicit_options.long_double = true;
3577 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3578 if (value != 64 && value != 128)
3580 error ("Unknown switch -mlong-double-%s", arg);
3581 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3585 rs6000_long_double_type_size = value;
3588 case OPT_msched_costly_dep_:
3589 rs6000_sched_costly_dep_str = arg;
3593 rs6000_explicit_options.alignment = true;
3594 if (! strcmp (arg, "power"))
3596 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3597 some C library functions, so warn about it. The flag may be
3598 useful for performance studies from time to time though, so
3599 don't disable it entirely. */
3600 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3601 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3602 " it is incompatible with the installed C and C++ libraries");
3603 rs6000_alignment_flags = MASK_ALIGN_POWER;
3605 else if (! strcmp (arg, "natural"))
3606 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3609 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3614 case OPT_msingle_float:
3615 if (!TARGET_SINGLE_FPU)
3616 warning (0, "-msingle-float option equivalent to -mhard-float");
3617 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3618 rs6000_double_float = 0;
3619 target_flags &= ~MASK_SOFT_FLOAT;
3620 target_flags_explicit |= MASK_SOFT_FLOAT;
3623 case OPT_mdouble_float:
3624 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3625 rs6000_single_float = 1;
3626 target_flags &= ~MASK_SOFT_FLOAT;
3627 target_flags_explicit |= MASK_SOFT_FLOAT;
3630 case OPT_msimple_fpu:
3631 if (!TARGET_SINGLE_FPU)
3632 warning (0, "-msimple-fpu option ignored");
3635 case OPT_mhard_float:
3636 /* -mhard_float implies -msingle-float and -mdouble-float. */
3637 rs6000_single_float = rs6000_double_float = 1;
3640 case OPT_msoft_float:
3641 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3642 rs6000_single_float = rs6000_double_float = 0;
3646 fpu_type = rs6000_parse_fpu_option(arg);
3647 if (fpu_type != FPU_NONE)
3648 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3650 target_flags &= ~MASK_SOFT_FLOAT;
3651 target_flags_explicit |= MASK_SOFT_FLOAT;
3652 rs6000_xilinx_fpu = 1;
3653 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3654 rs6000_single_float = 1;
3655 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3656 rs6000_single_float = rs6000_double_float = 1;
3657 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3658 rs6000_simple_fpu = 1;
3662 /* -mfpu=none is equivalent to -msoft-float */
3663 target_flags |= MASK_SOFT_FLOAT;
3664 target_flags_explicit |= MASK_SOFT_FLOAT;
3665 rs6000_single_float = rs6000_double_float = 0;
3672 /* Do anything needed at the start of the asm file. */
3675 rs6000_file_start (void)
3679 const char *start = buffer;
3680 struct rs6000_cpu_select *ptr;
3681 const char *default_cpu = TARGET_CPU_DEFAULT;
3682 FILE *file = asm_out_file;
3684 default_file_start ();
3686 #ifdef TARGET_BI_ARCH
3687 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3691 if (flag_verbose_asm)
3693 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3694 rs6000_select[0].string = default_cpu;
3696 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3698 ptr = &rs6000_select[i];
3699 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
3701 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
3706 if (PPC405_ERRATUM77)
3708 fprintf (file, "%s PPC405CR_ERRATUM77", start);
3712 #ifdef USING_ELFOS_H
3713 switch (rs6000_sdata)
3715 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
3716 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
3717 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
3718 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
3721 if (rs6000_sdata && g_switch_value)
3723 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
3733 #ifdef HAVE_AS_GNU_ATTRIBUTE
3734 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
3736 fprintf (file, "\t.gnu_attribute 4, %d\n",
3737 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
3738 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
3740 fprintf (file, "\t.gnu_attribute 8, %d\n",
3741 (TARGET_ALTIVEC_ABI ? 2
3742 : TARGET_SPE_ABI ? 3
3744 fprintf (file, "\t.gnu_attribute 12, %d\n",
3745 aix_struct_return ? 2 : 1);
3750 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
3752 switch_to_section (toc_section);
3753 switch_to_section (text_section);
3758 /* Return nonzero if this function is known to have a null epilogue. */
3761 direct_return (void)
3763 if (reload_completed)
3765 rs6000_stack_t *info = rs6000_stack_info ();
3767 if (info->first_gp_reg_save == 32
3768 && info->first_fp_reg_save == 64
3769 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
3770 && ! info->lr_save_p
3771 && ! info->cr_save_p
3772 && info->vrsave_mask == 0
3780 /* Return the number of instructions it takes to form a constant in an
3781 integer register. */
3784 num_insns_constant_wide (HOST_WIDE_INT value)
3786 /* signed constant loadable with {cal|addi} */
3787 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
3790 /* constant loadable with {cau|addis} */
3791 else if ((value & 0xffff) == 0
3792 && (value >> 31 == -1 || value >> 31 == 0))
3795 #if HOST_BITS_PER_WIDE_INT == 64
3796 else if (TARGET_POWERPC64)
3798 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
3799 HOST_WIDE_INT high = value >> 31;
3801 if (high == 0 || high == -1)
3807 return num_insns_constant_wide (high) + 1;
3809 return num_insns_constant_wide (low) + 1;
3811 return (num_insns_constant_wide (high)
3812 + num_insns_constant_wide (low) + 1);
3821 num_insns_constant (rtx op, enum machine_mode mode)
3823 HOST_WIDE_INT low, high;
3825 switch (GET_CODE (op))
3828 #if HOST_BITS_PER_WIDE_INT == 64
3829 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
3830 && mask64_operand (op, mode))
3834 return num_insns_constant_wide (INTVAL (op));
3837 if (mode == SFmode || mode == SDmode)
3842 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3843 if (DECIMAL_FLOAT_MODE_P (mode))
3844 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
3846 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
3847 return num_insns_constant_wide ((HOST_WIDE_INT) l);
3850 if (mode == VOIDmode || mode == DImode)
3852 high = CONST_DOUBLE_HIGH (op);
3853 low = CONST_DOUBLE_LOW (op);
3860 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3861 if (DECIMAL_FLOAT_MODE_P (mode))
3862 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
3864 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
3865 high = l[WORDS_BIG_ENDIAN == 0];
3866 low = l[WORDS_BIG_ENDIAN != 0];
3870 return (num_insns_constant_wide (low)
3871 + num_insns_constant_wide (high));
3874 if ((high == 0 && low >= 0)
3875 || (high == -1 && low < 0))
3876 return num_insns_constant_wide (low);
3878 else if (mask64_operand (op, mode))
3882 return num_insns_constant_wide (high) + 1;
3885 return (num_insns_constant_wide (high)
3886 + num_insns_constant_wide (low) + 1);
3894 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
3895 If the mode of OP is MODE_VECTOR_INT, this simply returns the
3896 corresponding element of the vector, but for V4SFmode and V2SFmode,
3897 the corresponding "float" is interpreted as an SImode integer. */
3900 const_vector_elt_as_int (rtx op, unsigned int elt)
3902 rtx tmp = CONST_VECTOR_ELT (op, elt);
3903 if (GET_MODE (op) == V4SFmode
3904 || GET_MODE (op) == V2SFmode)
3905 tmp = gen_lowpart (SImode, tmp);
3906 return INTVAL (tmp);
3909 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
3910 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
3911 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
3912 all items are set to the same value and contain COPIES replicas of the
3913 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
3914 operand and the others are set to the value of the operand's msb. */
3917 vspltis_constant (rtx op, unsigned step, unsigned copies)
3919 enum machine_mode mode = GET_MODE (op);
3920 enum machine_mode inner = GET_MODE_INNER (mode);
3923 unsigned nunits = GET_MODE_NUNITS (mode);
3924 unsigned bitsize = GET_MODE_BITSIZE (inner);
3925 unsigned mask = GET_MODE_MASK (inner);
3927 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
3928 HOST_WIDE_INT splat_val = val;
3929 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
3931 /* Construct the value to be splatted, if possible. If not, return 0. */
3932 for (i = 2; i <= copies; i *= 2)
3934 HOST_WIDE_INT small_val;
3936 small_val = splat_val >> bitsize;
3938 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
3940 splat_val = small_val;
3943 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
3944 if (EASY_VECTOR_15 (splat_val))
3947 /* Also check if we can splat, and then add the result to itself. Do so if
3948 the value is positive, of if the splat instruction is using OP's mode;
3949 for splat_val < 0, the splat and the add should use the same mode. */
3950 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
3951 && (splat_val >= 0 || (step == 1 && copies == 1)))
3954 /* Also check if are loading up the most significant bit which can be done by
3955 loading up -1 and shifting the value left by -1. */
3956 else if (EASY_VECTOR_MSB (splat_val, inner))
3962 /* Check if VAL is present in every STEP-th element, and the
3963 other elements are filled with its most significant bit. */
3964 for (i = 0; i < nunits - 1; ++i)
3966 HOST_WIDE_INT desired_val;
3967 if (((i + 1) & (step - 1)) == 0)
3970 desired_val = msb_val;
3972 if (desired_val != const_vector_elt_as_int (op, i))
3980 /* Return true if OP is of the given MODE and can be synthesized
3981 with a vspltisb, vspltish or vspltisw. */
3984 easy_altivec_constant (rtx op, enum machine_mode mode)
3986 unsigned step, copies;
3988 if (mode == VOIDmode)
3989 mode = GET_MODE (op);
3990 else if (mode != GET_MODE (op))
3993 /* Start with a vspltisw. */
3994 step = GET_MODE_NUNITS (mode) / 4;
3997 if (vspltis_constant (op, step, copies))
4000 /* Then try with a vspltish. */
4006 if (vspltis_constant (op, step, copies))
4009 /* And finally a vspltisb. */
4015 if (vspltis_constant (op, step, copies))
4021 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4022 result is OP. Abort if it is not possible. */
4025 gen_easy_altivec_constant (rtx op)
4027 enum machine_mode mode = GET_MODE (op);
4028 int nunits = GET_MODE_NUNITS (mode);
4029 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4030 unsigned step = nunits / 4;
4031 unsigned copies = 1;
4033 /* Start with a vspltisw. */
4034 if (vspltis_constant (op, step, copies))
4035 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4037 /* Then try with a vspltish. */
4043 if (vspltis_constant (op, step, copies))
4044 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4046 /* And finally a vspltisb. */
4052 if (vspltis_constant (op, step, copies))
4053 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4059 output_vec_const_move (rtx *operands)
4062 enum machine_mode mode;
4067 mode = GET_MODE (dest);
4069 if (TARGET_VSX && zero_constant (vec, mode))
4070 return "xxlxor %x0,%x0,%x0";
4075 if (zero_constant (vec, mode))
4076 return "vxor %0,%0,%0";
4078 splat_vec = gen_easy_altivec_constant (vec);
4079 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4080 operands[1] = XEXP (splat_vec, 0);
4081 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4084 switch (GET_MODE (splat_vec))
4087 return "vspltisw %0,%1";
4090 return "vspltish %0,%1";
4093 return "vspltisb %0,%1";
4100 gcc_assert (TARGET_SPE);
4102 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4103 pattern of V1DI, V4HI, and V2SF.
4105 FIXME: We should probably return # and add post reload
4106 splitters for these, but this way is so easy ;-). */
4107 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4108 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4109 operands[1] = CONST_VECTOR_ELT (vec, 0);
4110 operands[2] = CONST_VECTOR_ELT (vec, 1);
4112 return "li %0,%1\n\tevmergelo %0,%0,%0";
4114 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4117 /* Initialize TARGET of vector PAIRED to VALS. */
4120 paired_expand_vector_init (rtx target, rtx vals)
4122 enum machine_mode mode = GET_MODE (target);
4123 int n_elts = GET_MODE_NUNITS (mode);
4125 rtx x, new_rtx, tmp, constant_op, op1, op2;
4128 for (i = 0; i < n_elts; ++i)
4130 x = XVECEXP (vals, 0, i);
4131 if (!CONSTANT_P (x))
4136 /* Load from constant pool. */
4137 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4143 /* The vector is initialized only with non-constants. */
4144 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4145 XVECEXP (vals, 0, 1));
4147 emit_move_insn (target, new_rtx);
4151 /* One field is non-constant and the other one is a constant. Load the
4152 constant from the constant pool and use ps_merge instruction to
4153 construct the whole vector. */
4154 op1 = XVECEXP (vals, 0, 0);
4155 op2 = XVECEXP (vals, 0, 1);
4157 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4159 tmp = gen_reg_rtx (GET_MODE (constant_op));
4160 emit_move_insn (tmp, constant_op);
4162 if (CONSTANT_P (op1))
4163 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4165 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4167 emit_move_insn (target, new_rtx);
4171 paired_expand_vector_move (rtx operands[])
4173 rtx op0 = operands[0], op1 = operands[1];
4175 emit_move_insn (op0, op1);
4178 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4179 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4180 operands for the relation operation COND. This is a recursive
4184 paired_emit_vector_compare (enum rtx_code rcode,
4185 rtx dest, rtx op0, rtx op1,
4186 rtx cc_op0, rtx cc_op1)
4188 rtx tmp = gen_reg_rtx (V2SFmode);
4191 gcc_assert (TARGET_PAIRED_FLOAT);
4192 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4198 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4202 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4203 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4207 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4210 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4213 tmp1 = gen_reg_rtx (V2SFmode);
4214 max = gen_reg_rtx (V2SFmode);
4215 min = gen_reg_rtx (V2SFmode);
4216 gen_reg_rtx (V2SFmode);
4218 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4219 emit_insn (gen_selv2sf4
4220 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4221 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4222 emit_insn (gen_selv2sf4
4223 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4224 emit_insn (gen_subv2sf3 (tmp1, min, max));
4225 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4228 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4231 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4234 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4237 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4240 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4249 /* Emit vector conditional expression.
4250 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4251 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4254 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4255 rtx cond, rtx cc_op0, rtx cc_op1)
4257 enum rtx_code rcode = GET_CODE (cond);
4259 if (!TARGET_PAIRED_FLOAT)
4262 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4267 /* Initialize vector TARGET to VALS. */
4270 rs6000_expand_vector_init (rtx target, rtx vals)
4272 enum machine_mode mode = GET_MODE (target);
4273 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4274 int n_elts = GET_MODE_NUNITS (mode);
4275 int n_var = 0, one_var = -1;
4276 bool all_same = true, all_const_zero = true;
4280 for (i = 0; i < n_elts; ++i)
4282 x = XVECEXP (vals, 0, i);
4283 if (!CONSTANT_P (x))
4284 ++n_var, one_var = i;
4285 else if (x != CONST0_RTX (inner_mode))
4286 all_const_zero = false;
4288 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4294 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4295 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4296 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4298 /* Zero register. */
4299 emit_insn (gen_rtx_SET (VOIDmode, target,
4300 gen_rtx_XOR (mode, target, target)));
4303 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4305 /* Splat immediate. */
4306 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4311 /* Load from constant pool. */
4312 emit_move_insn (target, const_vec);
4317 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4318 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4322 rtx element = XVECEXP (vals, 0, 0);
4323 if (mode == V2DFmode)
4324 emit_insn (gen_vsx_splat_v2df (target, element));
4326 emit_insn (gen_vsx_splat_v2di (target, element));
4330 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4331 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4332 if (mode == V2DFmode)
4333 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4335 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4340 /* With single precision floating point on VSX, know that internally single
4341 precision is actually represented as a double, and either make 2 V2DF
4342 vectors, and convert these vectors to single precision, or do one
4343 conversion, and splat the result to the other elements. */
4344 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4348 rtx freg = gen_reg_rtx (V4SFmode);
4349 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4351 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4352 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4356 rtx dbl_even = gen_reg_rtx (V2DFmode);
4357 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4358 rtx flt_even = gen_reg_rtx (V4SFmode);
4359 rtx flt_odd = gen_reg_rtx (V4SFmode);
4361 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4362 copy_to_reg (XVECEXP (vals, 0, 0)),
4363 copy_to_reg (XVECEXP (vals, 0, 1))));
4364 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4365 copy_to_reg (XVECEXP (vals, 0, 2)),
4366 copy_to_reg (XVECEXP (vals, 0, 3))));
4367 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4368 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4369 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4374 /* Store value to stack temp. Load vector element. Splat. However, splat
4375 of 64-bit items is not supported on Altivec. */
4376 if (all_same && GET_MODE_SIZE (mode) <= 4)
4378 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4379 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4380 XVECEXP (vals, 0, 0));
4381 x = gen_rtx_UNSPEC (VOIDmode,
4382 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4383 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4385 gen_rtx_SET (VOIDmode,
4388 x = gen_rtx_VEC_SELECT (inner_mode, target,
4389 gen_rtx_PARALLEL (VOIDmode,
4390 gen_rtvec (1, const0_rtx)));
4391 emit_insn (gen_rtx_SET (VOIDmode, target,
4392 gen_rtx_VEC_DUPLICATE (mode, x)));
4396 /* One field is non-constant. Load constant then overwrite
4400 rtx copy = copy_rtx (vals);
4402 /* Load constant part of vector, substitute neighboring value for
4404 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4405 rs6000_expand_vector_init (target, copy);
4407 /* Insert variable. */
4408 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4412 /* Construct the vector in memory one field at a time
4413 and load the whole vector. */
4414 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4415 for (i = 0; i < n_elts; i++)
4416 emit_move_insn (adjust_address_nv (mem, inner_mode,
4417 i * GET_MODE_SIZE (inner_mode)),
4418 XVECEXP (vals, 0, i));
4419 emit_move_insn (target, mem);
4422 /* Set field ELT of TARGET to VAL. */
4425 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4427 enum machine_mode mode = GET_MODE (target);
4428 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4429 rtx reg = gen_reg_rtx (mode);
4431 int width = GET_MODE_SIZE (inner_mode);
4434 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4436 rtx (*set_func) (rtx, rtx, rtx, rtx)
4437 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4438 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4442 /* Load single variable value. */
4443 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4444 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4445 x = gen_rtx_UNSPEC (VOIDmode,
4446 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4447 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4449 gen_rtx_SET (VOIDmode,
4453 /* Linear sequence. */
4454 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4455 for (i = 0; i < 16; ++i)
4456 XVECEXP (mask, 0, i) = GEN_INT (i);
4458 /* Set permute mask to insert element into target. */
4459 for (i = 0; i < width; ++i)
4460 XVECEXP (mask, 0, elt*width + i)
4461 = GEN_INT (i + 0x10);
4462 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4463 x = gen_rtx_UNSPEC (mode,
4464 gen_rtvec (3, target, reg,
4465 force_reg (V16QImode, x)),
4467 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4470 /* Extract field ELT from VEC into TARGET. */
4473 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4475 enum machine_mode mode = GET_MODE (vec);
4476 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4479 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4481 rtx (*extract_func) (rtx, rtx, rtx)
4482 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4483 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4487 /* Allocate mode-sized buffer. */
4488 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4490 /* Add offset to field within buffer matching vector element. */
4491 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4493 /* Store single field into mode-sized buffer. */
4494 x = gen_rtx_UNSPEC (VOIDmode,
4495 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4496 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4498 gen_rtx_SET (VOIDmode,
4501 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4504 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4505 implement ANDing by the mask IN. */
4507 build_mask64_2_operands (rtx in, rtx *out)
4509 #if HOST_BITS_PER_WIDE_INT >= 64
4510 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4513 gcc_assert (GET_CODE (in) == CONST_INT);
4518 /* Assume c initially something like 0x00fff000000fffff. The idea
4519 is to rotate the word so that the middle ^^^^^^ group of zeros
4520 is at the MS end and can be cleared with an rldicl mask. We then
4521 rotate back and clear off the MS ^^ group of zeros with a
4523 c = ~c; /* c == 0xff000ffffff00000 */
4524 lsb = c & -c; /* lsb == 0x0000000000100000 */
4525 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4526 c = ~c; /* c == 0x00fff000000fffff */
4527 c &= -lsb; /* c == 0x00fff00000000000 */
4528 lsb = c & -c; /* lsb == 0x0000100000000000 */
4529 c = ~c; /* c == 0xff000fffffffffff */
4530 c &= -lsb; /* c == 0xff00000000000000 */
4532 while ((lsb >>= 1) != 0)
4533 shift++; /* shift == 44 on exit from loop */
4534 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4535 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4536 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4540 /* Assume c initially something like 0xff000f0000000000. The idea
4541 is to rotate the word so that the ^^^ middle group of zeros
4542 is at the LS end and can be cleared with an rldicr mask. We then
4543 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4545 lsb = c & -c; /* lsb == 0x0000010000000000 */
4546 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4547 c = ~c; /* c == 0x00fff0ffffffffff */
4548 c &= -lsb; /* c == 0x00fff00000000000 */
4549 lsb = c & -c; /* lsb == 0x0000100000000000 */
4550 c = ~c; /* c == 0xff000fffffffffff */
4551 c &= -lsb; /* c == 0xff00000000000000 */
4553 while ((lsb >>= 1) != 0)
4554 shift++; /* shift == 44 on exit from loop */
4555 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4556 m1 >>= shift; /* m1 == 0x0000000000000fff */
4557 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4560 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4561 masks will be all 1's. We are guaranteed more than one transition. */
4562 out[0] = GEN_INT (64 - shift);
4563 out[1] = GEN_INT (m1);
4564 out[2] = GEN_INT (shift);
4565 out[3] = GEN_INT (m2);
4573 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4576 invalid_e500_subreg (rtx op, enum machine_mode mode)
4578 if (TARGET_E500_DOUBLE)
4580 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4581 subreg:TI and reg:TF. Decimal float modes are like integer
4582 modes (only low part of each register used) for this
4584 if (GET_CODE (op) == SUBREG
4585 && (mode == SImode || mode == DImode || mode == TImode
4586 || mode == DDmode || mode == TDmode)
4587 && REG_P (SUBREG_REG (op))
4588 && (GET_MODE (SUBREG_REG (op)) == DFmode
4589 || GET_MODE (SUBREG_REG (op)) == TFmode))
4592 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4594 if (GET_CODE (op) == SUBREG
4595 && (mode == DFmode || mode == TFmode)
4596 && REG_P (SUBREG_REG (op))
4597 && (GET_MODE (SUBREG_REG (op)) == DImode
4598 || GET_MODE (SUBREG_REG (op)) == TImode
4599 || GET_MODE (SUBREG_REG (op)) == DDmode
4600 || GET_MODE (SUBREG_REG (op)) == TDmode))
4605 && GET_CODE (op) == SUBREG
4607 && REG_P (SUBREG_REG (op))
4608 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4614 /* AIX increases natural record alignment to doubleword if the first
4615 field is an FP double while the FP fields remain word aligned. */
4618 rs6000_special_round_type_align (tree type, unsigned int computed,
4619 unsigned int specified)
4621 unsigned int align = MAX (computed, specified);
4622 tree field = TYPE_FIELDS (type);
4624 /* Skip all non field decls */
4625 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4626 field = TREE_CHAIN (field);
4628 if (field != NULL && field != type)
4630 type = TREE_TYPE (field);
4631 while (TREE_CODE (type) == ARRAY_TYPE)
4632 type = TREE_TYPE (type);
4634 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4635 align = MAX (align, 64);
4641 /* Darwin increases record alignment to the natural alignment of
4645 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4646 unsigned int specified)
4648 unsigned int align = MAX (computed, specified);
4650 if (TYPE_PACKED (type))
4653 /* Find the first field, looking down into aggregates. */
4655 tree field = TYPE_FIELDS (type);
4656 /* Skip all non field decls */
4657 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4658 field = TREE_CHAIN (field);
4661 /* A packed field does not contribute any extra alignment. */
4662 if (DECL_PACKED (field))
4664 type = TREE_TYPE (field);
4665 while (TREE_CODE (type) == ARRAY_TYPE)
4666 type = TREE_TYPE (type);
4667 } while (AGGREGATE_TYPE_P (type));
4669 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
4670 align = MAX (align, TYPE_ALIGN (type));
4675 /* Return 1 for an operand in small memory on V.4/eabi. */
4678 small_data_operand (rtx op ATTRIBUTE_UNUSED,
4679 enum machine_mode mode ATTRIBUTE_UNUSED)
4684 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
4687 if (DEFAULT_ABI != ABI_V4)
4690 /* Vector and float memory instructions have a limited offset on the
4691 SPE, so using a vector or float variable directly as an operand is
4694 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
4697 if (GET_CODE (op) == SYMBOL_REF)
4700 else if (GET_CODE (op) != CONST
4701 || GET_CODE (XEXP (op, 0)) != PLUS
4702 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
4703 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
4708 rtx sum = XEXP (op, 0);
4709 HOST_WIDE_INT summand;
4711 /* We have to be careful here, because it is the referenced address
4712 that must be 32k from _SDA_BASE_, not just the symbol. */
4713 summand = INTVAL (XEXP (sum, 1));
4714 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
4717 sym_ref = XEXP (sum, 0);
4720 return SYMBOL_REF_SMALL_P (sym_ref);
4726 /* Return true if either operand is a general purpose register. */
4729 gpr_or_gpr_p (rtx op0, rtx op1)
4731 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
4732 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
4736 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
4739 reg_offset_addressing_ok_p (enum machine_mode mode)
4749 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
4750 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
4758 /* Paired vector modes. Only reg+reg addressing is valid. */
4759 if (TARGET_PAIRED_FLOAT)
4771 virtual_stack_registers_memory_p (rtx op)
4775 if (GET_CODE (op) == REG)
4776 regnum = REGNO (op);
4778 else if (GET_CODE (op) == PLUS
4779 && GET_CODE (XEXP (op, 0)) == REG
4780 && GET_CODE (XEXP (op, 1)) == CONST_INT)
4781 regnum = REGNO (XEXP (op, 0));
4786 return (regnum >= FIRST_VIRTUAL_REGISTER
4787 && regnum <= LAST_VIRTUAL_REGISTER);
4791 constant_pool_expr_p (rtx op)
4795 split_const (op, &base, &offset);
4796 return (GET_CODE (base) == SYMBOL_REF
4797 && CONSTANT_POOL_ADDRESS_P (base)
4798 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
4802 toc_relative_expr_p (rtx op)
4806 if (GET_CODE (op) != CONST)
4809 split_const (op, &base, &offset);
4810 return (GET_CODE (base) == UNSPEC
4811 && XINT (base, 1) == UNSPEC_TOCREL);
4815 legitimate_constant_pool_address_p (rtx x)
4818 && GET_CODE (x) == PLUS
4819 && GET_CODE (XEXP (x, 0)) == REG
4820 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
4821 && toc_relative_expr_p (XEXP (x, 1)));
4825 legitimate_small_data_p (enum machine_mode mode, rtx x)
4827 return (DEFAULT_ABI == ABI_V4
4828 && !flag_pic && !TARGET_TOC
4829 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
4830 && small_data_operand (x, mode));
4833 /* SPE offset addressing is limited to 5-bits worth of double words. */
4834 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
4837 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
4839 unsigned HOST_WIDE_INT offset, extra;
4841 if (GET_CODE (x) != PLUS)
4843 if (GET_CODE (XEXP (x, 0)) != REG)
4845 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4847 if (!reg_offset_addressing_ok_p (mode))
4848 return virtual_stack_registers_memory_p (x);
4849 if (legitimate_constant_pool_address_p (x))
4851 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4854 offset = INTVAL (XEXP (x, 1));
4862 /* SPE vector modes. */
4863 return SPE_CONST_OFFSET_OK (offset);
4866 if (TARGET_E500_DOUBLE)
4867 return SPE_CONST_OFFSET_OK (offset);
4869 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
4871 if (VECTOR_MEM_VSX_P (DFmode))
4876 /* On e500v2, we may have:
4878 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
4880 Which gets addressed with evldd instructions. */
4881 if (TARGET_E500_DOUBLE)
4882 return SPE_CONST_OFFSET_OK (offset);
4884 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
4886 else if (offset & 3)
4891 if (TARGET_E500_DOUBLE)
4892 return (SPE_CONST_OFFSET_OK (offset)
4893 && SPE_CONST_OFFSET_OK (offset + 8));
4897 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
4899 else if (offset & 3)
4910 return (offset < 0x10000) && (offset + extra < 0x10000);
4914 legitimate_indexed_address_p (rtx x, int strict)
4918 if (GET_CODE (x) != PLUS)
4924 /* Recognize the rtl generated by reload which we know will later be
4925 replaced with proper base and index regs. */
4927 && reload_in_progress
4928 && (REG_P (op0) || GET_CODE (op0) == PLUS)
4932 return (REG_P (op0) && REG_P (op1)
4933 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
4934 && INT_REG_OK_FOR_INDEX_P (op1, strict))
4935 || (INT_REG_OK_FOR_BASE_P (op1, strict)
4936 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
4940 avoiding_indexed_address_p (enum machine_mode mode)
4942 /* Avoid indexed addressing for modes that have non-indexed
4943 load/store instruction forms. */
4944 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
4948 legitimate_indirect_address_p (rtx x, int strict)
4950 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
4954 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
4956 if (!TARGET_MACHO || !flag_pic
4957 || mode != SImode || GET_CODE (x) != MEM)
4961 if (GET_CODE (x) != LO_SUM)
4963 if (GET_CODE (XEXP (x, 0)) != REG)
4965 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
4969 return CONSTANT_P (x);
4973 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
4975 if (GET_CODE (x) != LO_SUM)
4977 if (GET_CODE (XEXP (x, 0)) != REG)
4979 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4981 /* Restrict addressing for DI because of our SUBREG hackery. */
4982 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4983 || mode == DDmode || mode == TDmode
4988 if (TARGET_ELF || TARGET_MACHO)
4990 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
4994 if (GET_MODE_NUNITS (mode) != 1)
4996 if (GET_MODE_BITSIZE (mode) > 64
4997 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
4998 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4999 && (mode == DFmode || mode == DDmode))))
5002 return CONSTANT_P (x);
5009 /* Try machine-dependent ways of modifying an illegitimate address
5010 to be legitimate. If we find one, return the new, valid address.
5011 This is used from only one place: `memory_address' in explow.c.
5013 OLDX is the address as it was before break_out_memory_refs was
5014 called. In some cases it is useful to look at this to decide what
5017 It is always safe for this function to do nothing. It exists to
5018 recognize opportunities to optimize the output.
5020 On RS/6000, first check for the sum of a register with a constant
5021 integer that is out of range. If so, generate code to add the
5022 constant with the low-order 16 bits masked to the register and force
5023 this result into another register (this can be done with `cau').
5024 Then generate an address of REG+(CONST&0xffff), allowing for the
5025 possibility of bit 16 being a one.
5027 Then check for the sum of a register and something not constant, try to
5028 load the other things into a register and return the sum. */
5031 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5032 enum machine_mode mode)
5034 unsigned int extra = 0;
5036 if (!reg_offset_addressing_ok_p (mode))
5038 if (virtual_stack_registers_memory_p (x))
5041 /* In theory we should not be seeing addresses of the form reg+0,
5042 but just in case it is generated, optimize it away. */
5043 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5044 return force_reg (Pmode, XEXP (x, 0));
5046 /* Make sure both operands are registers. */
5047 else if (GET_CODE (x) == PLUS)
5048 return gen_rtx_PLUS (Pmode,
5049 force_reg (Pmode, XEXP (x, 0)),
5050 force_reg (Pmode, XEXP (x, 1)));
5052 return force_reg (Pmode, x);
5054 if (GET_CODE (x) == SYMBOL_REF)
5056 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5058 return rs6000_legitimize_tls_address (x, model);
5068 if (!TARGET_POWERPC64)
5076 extra = TARGET_POWERPC64 ? 8 : 12;
5082 if (GET_CODE (x) == PLUS
5083 && GET_CODE (XEXP (x, 0)) == REG
5084 && GET_CODE (XEXP (x, 1)) == CONST_INT
5085 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5087 && !((TARGET_POWERPC64
5088 && (mode == DImode || mode == TImode)
5089 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5090 || SPE_VECTOR_MODE (mode)
5091 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5092 || mode == DImode || mode == DDmode
5093 || mode == TDmode))))
5095 HOST_WIDE_INT high_int, low_int;
5097 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5098 if (low_int >= 0x8000 - extra)
5100 high_int = INTVAL (XEXP (x, 1)) - low_int;
5101 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5102 GEN_INT (high_int)), 0);
5103 return plus_constant (sum, low_int);
5105 else if (GET_CODE (x) == PLUS
5106 && GET_CODE (XEXP (x, 0)) == REG
5107 && GET_CODE (XEXP (x, 1)) != CONST_INT
5108 && GET_MODE_NUNITS (mode) == 1
5109 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5111 || ((mode != DImode && mode != DFmode && mode != DDmode)
5112 || (TARGET_E500_DOUBLE && mode != DDmode)))
5113 && (TARGET_POWERPC64 || mode != DImode)
5114 && !avoiding_indexed_address_p (mode)
5119 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5120 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5122 else if (SPE_VECTOR_MODE (mode)
5123 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5124 || mode == DDmode || mode == TDmode
5125 || mode == DImode)))
5129 /* We accept [reg + reg] and [reg + OFFSET]. */
5131 if (GET_CODE (x) == PLUS)
5133 rtx op1 = XEXP (x, 0);
5134 rtx op2 = XEXP (x, 1);
5137 op1 = force_reg (Pmode, op1);
5139 if (GET_CODE (op2) != REG
5140 && (GET_CODE (op2) != CONST_INT
5141 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5142 || (GET_MODE_SIZE (mode) > 8
5143 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5144 op2 = force_reg (Pmode, op2);
5146 /* We can't always do [reg + reg] for these, because [reg +
5147 reg + offset] is not a legitimate addressing mode. */
5148 y = gen_rtx_PLUS (Pmode, op1, op2);
5150 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5151 return force_reg (Pmode, y);
5156 return force_reg (Pmode, x);
5162 && GET_CODE (x) != CONST_INT
5163 && GET_CODE (x) != CONST_DOUBLE
5165 && GET_MODE_NUNITS (mode) == 1
5166 && (GET_MODE_BITSIZE (mode) <= 32
5167 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5168 && (mode == DFmode || mode == DDmode))))
5170 rtx reg = gen_reg_rtx (Pmode);
5171 emit_insn (gen_elf_high (reg, x));
5172 return gen_rtx_LO_SUM (Pmode, reg, x);
5174 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5177 && ! MACHO_DYNAMIC_NO_PIC_P
5179 && GET_CODE (x) != CONST_INT
5180 && GET_CODE (x) != CONST_DOUBLE
5182 && GET_MODE_NUNITS (mode) == 1
5183 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5184 || (mode != DFmode && mode != DDmode))
5188 rtx reg = gen_reg_rtx (Pmode);
5189 emit_insn (gen_macho_high (reg, x));
5190 return gen_rtx_LO_SUM (Pmode, reg, x);
5193 && GET_CODE (x) == SYMBOL_REF
5194 && constant_pool_expr_p (x)
5195 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5197 return create_TOC_reference (x);
5203 /* Debug version of rs6000_legitimize_address. */
5205 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5211 ret = rs6000_legitimize_address (x, oldx, mode);
5212 insns = get_insns ();
5218 "\nrs6000_legitimize_address: mode %s, old code %s, "
5219 "new code %s, modified\n",
5220 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5221 GET_RTX_NAME (GET_CODE (ret)));
5223 fprintf (stderr, "Original address:\n");
5226 fprintf (stderr, "oldx:\n");
5229 fprintf (stderr, "New address:\n");
5234 fprintf (stderr, "Insns added:\n");
5235 debug_rtx_list (insns, 20);
5241 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5242 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5253 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5254 We need to emit DTP-relative relocations. */
5257 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5262 fputs ("\t.long\t", file);
5265 fputs (DOUBLE_INT_ASM_OP, file);
5270 output_addr_const (file, x);
5271 fputs ("@dtprel+0x8000", file);
5274 /* In the name of slightly smaller debug output, and to cater to
5275 general assembler lossage, recognize various UNSPEC sequences
5276 and turn them back into a direct symbol reference. */
5279 rs6000_delegitimize_address (rtx orig_x)
5283 orig_x = delegitimize_mem_from_attrs (orig_x);
5288 if (GET_CODE (x) == PLUS
5289 && GET_CODE (XEXP (x, 1)) == CONST
5290 && GET_CODE (XEXP (x, 0)) == REG
5291 && REGNO (XEXP (x, 0)) == TOC_REGISTER)
5293 y = XEXP (XEXP (x, 1), 0);
5294 if (GET_CODE (y) == UNSPEC
5295 && XINT (y, 1) == UNSPEC_TOCREL)
5297 y = XVECEXP (y, 0, 0);
5298 if (!MEM_P (orig_x))
5301 return replace_equiv_address_nv (orig_x, y);
5307 && GET_CODE (orig_x) == LO_SUM
5308 && GET_CODE (XEXP (x, 1)) == CONST)
5310 y = XEXP (XEXP (x, 1), 0);
5311 if (GET_CODE (y) == UNSPEC
5312 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5313 return XVECEXP (y, 0, 0);
5319 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5321 static GTY(()) rtx rs6000_tls_symbol;
5323 rs6000_tls_get_addr (void)
5325 if (!rs6000_tls_symbol)
5326 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5328 return rs6000_tls_symbol;
5331 /* Construct the SYMBOL_REF for TLS GOT references. */
5333 static GTY(()) rtx rs6000_got_symbol;
5335 rs6000_got_sym (void)
5337 if (!rs6000_got_symbol)
5339 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5340 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5341 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5344 return rs6000_got_symbol;
5347 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5348 this (thread-local) address. */
5351 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5355 dest = gen_reg_rtx (Pmode);
5356 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5362 tlsreg = gen_rtx_REG (Pmode, 13);
5363 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5367 tlsreg = gen_rtx_REG (Pmode, 2);
5368 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5372 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5376 tmp = gen_reg_rtx (Pmode);
5379 tlsreg = gen_rtx_REG (Pmode, 13);
5380 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5384 tlsreg = gen_rtx_REG (Pmode, 2);
5385 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5389 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5391 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5396 rtx r3, got, tga, tmp1, tmp2, eqv;
5398 /* We currently use relocations like @got@tlsgd for tls, which
5399 means the linker will handle allocation of tls entries, placing
5400 them in the .got section. So use a pointer to the .got section,
5401 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5402 or to secondary GOT sections used by 32-bit -fPIC. */
5404 got = gen_rtx_REG (Pmode, 2);
5408 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5411 rtx gsym = rs6000_got_sym ();
5412 got = gen_reg_rtx (Pmode);
5414 rs6000_emit_move (got, gsym, Pmode);
5420 tmp1 = gen_reg_rtx (Pmode);
5421 tmp2 = gen_reg_rtx (Pmode);
5422 tmp3 = gen_reg_rtx (Pmode);
5423 mem = gen_const_mem (Pmode, tmp1);
5425 emit_insn (gen_load_toc_v4_PIC_1b (gsym));
5426 emit_move_insn (tmp1,
5427 gen_rtx_REG (Pmode, LR_REGNO));
5428 emit_move_insn (tmp2, mem);
5429 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
5430 last = emit_move_insn (got, tmp3);
5431 set_unique_reg_note (last, REG_EQUAL, gsym);
5436 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5438 r3 = gen_rtx_REG (Pmode, 3);
5439 tga = rs6000_tls_get_addr ();
5441 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5442 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5443 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5444 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5445 else if (DEFAULT_ABI == ABI_V4)
5446 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5451 insn = emit_call_insn (insn);
5452 RTL_CONST_CALL_P (insn) = 1;
5453 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5454 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5455 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5456 insn = get_insns ();
5458 emit_libcall_block (insn, dest, r3, addr);
5460 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5462 r3 = gen_rtx_REG (Pmode, 3);
5463 tga = rs6000_tls_get_addr ();
5465 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5466 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5467 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5468 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5469 else if (DEFAULT_ABI == ABI_V4)
5470 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5475 insn = emit_call_insn (insn);
5476 RTL_CONST_CALL_P (insn) = 1;
5477 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5478 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5479 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5480 insn = get_insns ();
5482 tmp1 = gen_reg_rtx (Pmode);
5483 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
5485 emit_libcall_block (insn, tmp1, r3, eqv);
5486 if (rs6000_tls_size == 16)
5489 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5491 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5493 else if (rs6000_tls_size == 32)
5495 tmp2 = gen_reg_rtx (Pmode);
5497 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5499 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5502 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5504 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5508 tmp2 = gen_reg_rtx (Pmode);
5510 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5512 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5514 insn = gen_rtx_SET (Pmode, dest,
5515 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5521 /* IE, or 64-bit offset LE. */
5522 tmp2 = gen_reg_rtx (Pmode);
5524 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5526 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5529 insn = gen_tls_tls_64 (dest, tmp2, addr);
5531 insn = gen_tls_tls_32 (dest, tmp2, addr);
5539 /* Return 1 if X contains a thread-local symbol. */
5542 rs6000_tls_referenced_p (rtx x)
5544 if (! TARGET_HAVE_TLS)
5547 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5550 /* Return 1 if *X is a thread-local symbol. This is the same as
5551 rs6000_tls_symbol_ref except for the type of the unused argument. */
5554 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5556 return RS6000_SYMBOL_REF_TLS_P (*x);
5559 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5560 replace the input X, or the original X if no replacement is called for.
5561 The output parameter *WIN is 1 if the calling macro should goto WIN,
5564 For RS/6000, we wish to handle large displacements off a base
5565 register by splitting the addend across an addiu/addis and the mem insn.
5566 This cuts number of extra insns needed from 3 to 1.
5568 On Darwin, we use this to generate code for floating point constants.
5569 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5570 The Darwin code is inside #if TARGET_MACHO because only then are the
5571 machopic_* functions defined. */
5573 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5574 int opnum, int type,
5575 int ind_levels ATTRIBUTE_UNUSED, int *win)
5577 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5579 /* We must recognize output that we have already generated ourselves. */
5580 if (GET_CODE (x) == PLUS
5581 && GET_CODE (XEXP (x, 0)) == PLUS
5582 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5583 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5584 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5586 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5587 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5588 opnum, (enum reload_type)type);
5594 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5595 && GET_CODE (x) == LO_SUM
5596 && GET_CODE (XEXP (x, 0)) == PLUS
5597 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5598 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5599 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5600 && machopic_operand_p (XEXP (x, 1)))
5602 /* Result of previous invocation of this function on Darwin
5603 floating point constant. */
5604 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5605 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5606 opnum, (enum reload_type)type);
5612 /* Force ld/std non-word aligned offset into base register by wrapping
5614 if (GET_CODE (x) == PLUS
5615 && GET_CODE (XEXP (x, 0)) == REG
5616 && REGNO (XEXP (x, 0)) < 32
5617 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5618 && GET_CODE (XEXP (x, 1)) == CONST_INT
5620 && (INTVAL (XEXP (x, 1)) & 3) != 0
5621 && VECTOR_MEM_NONE_P (mode)
5622 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5623 && TARGET_POWERPC64)
5625 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5626 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5627 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5628 opnum, (enum reload_type) type);
5633 if (GET_CODE (x) == PLUS
5634 && GET_CODE (XEXP (x, 0)) == REG
5635 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5636 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5637 && GET_CODE (XEXP (x, 1)) == CONST_INT
5639 && !SPE_VECTOR_MODE (mode)
5640 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5641 || mode == DDmode || mode == TDmode
5643 && VECTOR_MEM_NONE_P (mode))
5645 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5646 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5648 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5650 /* Check for 32-bit overflow. */
5651 if (high + low != val)
5657 /* Reload the high part into a base reg; leave the low part
5658 in the mem directly. */
5660 x = gen_rtx_PLUS (GET_MODE (x),
5661 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5665 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5666 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5667 opnum, (enum reload_type)type);
5672 if (GET_CODE (x) == SYMBOL_REF
5674 && VECTOR_MEM_NONE_P (mode)
5675 && !SPE_VECTOR_MODE (mode)
5677 && DEFAULT_ABI == ABI_DARWIN
5678 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
5680 && DEFAULT_ABI == ABI_V4
5683 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
5684 The same goes for DImode without 64-bit gprs and DFmode and DDmode
5688 && (mode != DImode || TARGET_POWERPC64)
5689 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
5690 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
5695 rtx offset = machopic_gen_offset (x);
5696 x = gen_rtx_LO_SUM (GET_MODE (x),
5697 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
5698 gen_rtx_HIGH (Pmode, offset)), offset);
5702 x = gen_rtx_LO_SUM (GET_MODE (x),
5703 gen_rtx_HIGH (Pmode, x), x);
5705 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5706 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5707 opnum, (enum reload_type)type);
5712 /* Reload an offset address wrapped by an AND that represents the
5713 masking of the lower bits. Strip the outer AND and let reload
5714 convert the offset address into an indirect address. For VSX,
5715 force reload to create the address with an AND in a separate
5716 register, because we can't guarantee an altivec register will
5718 if (VECTOR_MEM_ALTIVEC_P (mode)
5719 && GET_CODE (x) == AND
5720 && GET_CODE (XEXP (x, 0)) == PLUS
5721 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5722 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5723 && GET_CODE (XEXP (x, 1)) == CONST_INT
5724 && INTVAL (XEXP (x, 1)) == -16)
5733 && GET_CODE (x) == SYMBOL_REF
5734 && constant_pool_expr_p (x)
5735 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
5737 x = create_TOC_reference (x);
5745 /* Debug version of rs6000_legitimize_reload_address. */
5747 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
5748 int opnum, int type,
5749 int ind_levels, int *win)
5751 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
5754 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
5755 "type = %d, ind_levels = %d, win = %d, original addr:\n",
5756 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
5760 fprintf (stderr, "Same address returned\n");
5762 fprintf (stderr, "NULL returned\n");
5765 fprintf (stderr, "New address:\n");
5772 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
5773 that is a valid memory address for an instruction.
5774 The MODE argument is the machine mode for the MEM expression
5775 that wants to use this address.
5777 On the RS/6000, there are four valid address: a SYMBOL_REF that
5778 refers to a constant pool entry of an address (or the sum of it
5779 plus a constant), a short (16-bit signed) constant plus a register,
5780 the sum of two registers, or a register indirect, possibly with an
5781 auto-increment. For DFmode, DDmode and DImode with a constant plus
5782 register, we must ensure that both words are addressable or PowerPC64
5783 with offset word aligned.
5785 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
5786 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
5787 because adjacent memory cells are accessed by adding word-sized offsets
5788 during assembly output. */
5790 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
5792 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5794 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
5795 if (VECTOR_MEM_ALTIVEC_P (mode)
5796 && GET_CODE (x) == AND
5797 && GET_CODE (XEXP (x, 1)) == CONST_INT
5798 && INTVAL (XEXP (x, 1)) == -16)
5801 if (RS6000_SYMBOL_REF_TLS_P (x))
5803 if (legitimate_indirect_address_p (x, reg_ok_strict))
5805 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
5806 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5807 && !SPE_VECTOR_MODE (mode)
5810 /* Restrict addressing for DI because of our SUBREG hackery. */
5811 && !(TARGET_E500_DOUBLE
5812 && (mode == DFmode || mode == DDmode || mode == DImode))
5814 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
5816 if (virtual_stack_registers_memory_p (x))
5818 if (reg_offset_p && legitimate_small_data_p (mode, x))
5820 if (reg_offset_p && legitimate_constant_pool_address_p (x))
5822 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
5825 && GET_CODE (x) == PLUS
5826 && GET_CODE (XEXP (x, 0)) == REG
5827 && (XEXP (x, 0) == virtual_stack_vars_rtx
5828 || XEXP (x, 0) == arg_pointer_rtx)
5829 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5831 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
5836 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5838 || (mode != DFmode && mode != DDmode)
5839 || (TARGET_E500_DOUBLE && mode != DDmode))
5840 && (TARGET_POWERPC64 || mode != DImode)
5841 && !avoiding_indexed_address_p (mode)
5842 && legitimate_indexed_address_p (x, reg_ok_strict))
5844 if (GET_CODE (x) == PRE_MODIFY
5848 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5850 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
5851 && (TARGET_POWERPC64 || mode != DImode)
5852 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5853 && !SPE_VECTOR_MODE (mode)
5854 /* Restrict addressing for DI because of our SUBREG hackery. */
5855 && !(TARGET_E500_DOUBLE
5856 && (mode == DFmode || mode == DDmode || mode == DImode))
5858 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
5859 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
5860 || (!avoiding_indexed_address_p (mode)
5861 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
5862 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5864 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
5869 /* Debug version of rs6000_legitimate_address_p. */
5871 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
5874 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
5876 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
5877 "strict = %d, code = %s\n",
5878 ret ? "true" : "false",
5879 GET_MODE_NAME (mode),
5881 GET_RTX_NAME (GET_CODE (x)));
5887 /* Go to LABEL if ADDR (a legitimate address expression)
5888 has an effect that depends on the machine mode it is used for.
5890 On the RS/6000 this is true of all integral offsets (since AltiVec
5891 and VSX modes don't allow them) or is a pre-increment or decrement.
5893 ??? Except that due to conceptual problems in offsettable_address_p
5894 we can't really report the problems of integral offsets. So leave
5895 this assuming that the adjustable offset must be valid for the
5896 sub-words of a TFmode operand, which is what we had before. */
5899 rs6000_mode_dependent_address (rtx addr)
5901 switch (GET_CODE (addr))
5904 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
5905 is considered a legitimate address before reload, so there
5906 are no offset restrictions in that case. Note that this
5907 condition is safe in strict mode because any address involving
5908 virtual_stack_vars_rtx or arg_pointer_rtx would already have
5909 been rejected as illegitimate. */
5910 if (XEXP (addr, 0) != virtual_stack_vars_rtx
5911 && XEXP (addr, 0) != arg_pointer_rtx
5912 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5914 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
5915 return val + 12 + 0x8000 >= 0x10000;
5922 /* Auto-increment cases are now treated generically in recog.c. */
5924 return TARGET_UPDATE;
5926 /* AND is only allowed in Altivec loads. */
5937 /* Debug version of rs6000_mode_dependent_address. */
5939 rs6000_debug_mode_dependent_address (rtx addr)
5941 bool ret = rs6000_mode_dependent_address (addr);
5943 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
5944 ret ? "true" : "false");
5950 /* Implement FIND_BASE_TERM. */
5953 rs6000_find_base_term (rtx op)
5957 split_const (op, &base, &offset);
5958 if (GET_CODE (base) == UNSPEC)
5959 switch (XINT (base, 1))
5962 case UNSPEC_MACHOPIC_OFFSET:
5963 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
5964 for aliasing purposes. */
5965 return XVECEXP (base, 0, 0);
5971 /* More elaborate version of recog's offsettable_memref_p predicate
5972 that works around the ??? note of rs6000_mode_dependent_address.
5973 In particular it accepts
5975 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
5977 in 32-bit mode, that the recog predicate rejects. */
5980 rs6000_offsettable_memref_p (rtx op)
5985 /* First mimic offsettable_memref_p. */
5986 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
5989 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
5990 the latter predicate knows nothing about the mode of the memory
5991 reference and, therefore, assumes that it is the largest supported
5992 mode (TFmode). As a consequence, legitimate offsettable memory
5993 references are rejected. rs6000_legitimate_offset_address_p contains
5994 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
5995 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
5998 /* Change register usage conditional on target flags. */
6000 rs6000_conditional_register_usage (void)
6004 /* Set MQ register fixed (already call_used) if not POWER
6005 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6010 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6012 fixed_regs[13] = call_used_regs[13]
6013 = call_really_used_regs[13] = 1;
6015 /* Conditionally disable FPRs. */
6016 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6017 for (i = 32; i < 64; i++)
6018 fixed_regs[i] = call_used_regs[i]
6019 = call_really_used_regs[i] = 1;
6021 /* The TOC register is not killed across calls in a way that is
6022 visible to the compiler. */
6023 if (DEFAULT_ABI == ABI_AIX)
6024 call_really_used_regs[2] = 0;
6026 if (DEFAULT_ABI == ABI_V4
6027 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6029 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6031 if (DEFAULT_ABI == ABI_V4
6032 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6034 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6035 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6036 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6038 if (DEFAULT_ABI == ABI_DARWIN
6039 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6040 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6041 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6042 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6044 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6045 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6046 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6050 global_regs[SPEFSCR_REGNO] = 1;
6051 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6052 registers in prologues and epilogues. We no longer use r14
6053 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6054 pool for link-compatibility with older versions of GCC. Once
6055 "old" code has died out, we can return r14 to the allocation
6058 = call_used_regs[14]
6059 = call_really_used_regs[14] = 1;
6062 if (!TARGET_ALTIVEC && !TARGET_VSX)
6064 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6065 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6066 call_really_used_regs[VRSAVE_REGNO] = 1;
6069 if (TARGET_ALTIVEC || TARGET_VSX)
6070 global_regs[VSCR_REGNO] = 1;
6072 if (TARGET_ALTIVEC_ABI)
6074 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6075 call_used_regs[i] = call_really_used_regs[i] = 1;
6077 /* AIX reserves VR20:31 in non-extended ABI mode. */
6079 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6080 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6084 /* Try to output insns to set TARGET equal to the constant C if it can
6085 be done in less than N insns. Do all computations in MODE.
6086 Returns the place where the output has been placed if it can be
6087 done and the insns have been emitted. If it would take more than N
6088 insns, zero is returned and no insns and emitted. */
6091 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6092 rtx source, int n ATTRIBUTE_UNUSED)
6094 rtx result, insn, set;
6095 HOST_WIDE_INT c0, c1;
6102 dest = gen_reg_rtx (mode);
6103 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6107 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6109 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6110 GEN_INT (INTVAL (source)
6111 & (~ (HOST_WIDE_INT) 0xffff))));
6112 emit_insn (gen_rtx_SET (VOIDmode, dest,
6113 gen_rtx_IOR (SImode, copy_rtx (result),
6114 GEN_INT (INTVAL (source) & 0xffff))));
6119 switch (GET_CODE (source))
6122 c0 = INTVAL (source);
6127 #if HOST_BITS_PER_WIDE_INT >= 64
6128 c0 = CONST_DOUBLE_LOW (source);
6131 c0 = CONST_DOUBLE_LOW (source);
6132 c1 = CONST_DOUBLE_HIGH (source);
6140 result = rs6000_emit_set_long_const (dest, c0, c1);
6147 insn = get_last_insn ();
6148 set = single_set (insn);
6149 if (! CONSTANT_P (SET_SRC (set)))
6150 set_unique_reg_note (insn, REG_EQUAL, source);
6155 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6156 fall back to a straight forward decomposition. We do this to avoid
6157 exponential run times encountered when looking for longer sequences
6158 with rs6000_emit_set_const. */
6160 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6162 if (!TARGET_POWERPC64)
6164 rtx operand1, operand2;
6166 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6168 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6170 emit_move_insn (operand1, GEN_INT (c1));
6171 emit_move_insn (operand2, GEN_INT (c2));
6175 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6178 ud2 = (c1 & 0xffff0000) >> 16;
6179 #if HOST_BITS_PER_WIDE_INT >= 64
6183 ud4 = (c2 & 0xffff0000) >> 16;
6185 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6186 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6189 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6191 emit_move_insn (dest, GEN_INT (ud1));
6194 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6195 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6198 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6201 emit_move_insn (dest, GEN_INT (ud2 << 16));
6203 emit_move_insn (copy_rtx (dest),
6204 gen_rtx_IOR (DImode, copy_rtx (dest),
6207 else if (ud3 == 0 && ud4 == 0)
6209 gcc_assert (ud2 & 0x8000);
6210 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6213 emit_move_insn (copy_rtx (dest),
6214 gen_rtx_IOR (DImode, copy_rtx (dest),
6216 emit_move_insn (copy_rtx (dest),
6217 gen_rtx_ZERO_EXTEND (DImode,
6218 gen_lowpart (SImode,
6221 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6222 || (ud4 == 0 && ! (ud3 & 0x8000)))
6225 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6228 emit_move_insn (dest, GEN_INT (ud3 << 16));
6231 emit_move_insn (copy_rtx (dest),
6232 gen_rtx_IOR (DImode, copy_rtx (dest),
6234 emit_move_insn (copy_rtx (dest),
6235 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6238 emit_move_insn (copy_rtx (dest),
6239 gen_rtx_IOR (DImode, copy_rtx (dest),
6245 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6248 emit_move_insn (dest, GEN_INT (ud4 << 16));
6251 emit_move_insn (copy_rtx (dest),
6252 gen_rtx_IOR (DImode, copy_rtx (dest),
6255 emit_move_insn (copy_rtx (dest),
6256 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6259 emit_move_insn (copy_rtx (dest),
6260 gen_rtx_IOR (DImode, copy_rtx (dest),
6261 GEN_INT (ud2 << 16)));
6263 emit_move_insn (copy_rtx (dest),
6264 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6270 /* Helper for the following. Get rid of [r+r] memory refs
6271 in cases where it won't work (TImode, TFmode, TDmode). */
6274 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6276 if (GET_CODE (operands[0]) == MEM
6277 && GET_CODE (XEXP (operands[0], 0)) != REG
6278 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
6279 && ! reload_in_progress)
6281 = replace_equiv_address (operands[0],
6282 copy_addr_to_reg (XEXP (operands[0], 0)));
6284 if (GET_CODE (operands[1]) == MEM
6285 && GET_CODE (XEXP (operands[1], 0)) != REG
6286 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
6287 && ! reload_in_progress)
6289 = replace_equiv_address (operands[1],
6290 copy_addr_to_reg (XEXP (operands[1], 0)));
6293 /* Emit a move from SOURCE to DEST in mode MODE. */
6295 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6299 operands[1] = source;
6301 if (TARGET_DEBUG_ADDR)
6304 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6305 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6306 GET_MODE_NAME (mode),
6309 can_create_pseudo_p ());
6311 fprintf (stderr, "source:\n");
6315 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6316 if (GET_CODE (operands[1]) == CONST_DOUBLE
6317 && ! FLOAT_MODE_P (mode)
6318 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6320 /* FIXME. This should never happen. */
6321 /* Since it seems that it does, do the safe thing and convert
6323 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6325 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6326 || FLOAT_MODE_P (mode)
6327 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6328 || CONST_DOUBLE_LOW (operands[1]) < 0)
6329 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6330 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6332 /* Check if GCC is setting up a block move that will end up using FP
6333 registers as temporaries. We must make sure this is acceptable. */
6334 if (GET_CODE (operands[0]) == MEM
6335 && GET_CODE (operands[1]) == MEM
6337 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6338 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6339 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6340 ? 32 : MEM_ALIGN (operands[0])))
6341 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6343 : MEM_ALIGN (operands[1]))))
6344 && ! MEM_VOLATILE_P (operands [0])
6345 && ! MEM_VOLATILE_P (operands [1]))
6347 emit_move_insn (adjust_address (operands[0], SImode, 0),
6348 adjust_address (operands[1], SImode, 0));
6349 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6350 adjust_address (copy_rtx (operands[1]), SImode, 4));
6354 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6355 && !gpc_reg_operand (operands[1], mode))
6356 operands[1] = force_reg (mode, operands[1]);
6358 if (mode == SFmode && ! TARGET_POWERPC
6359 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6360 && GET_CODE (operands[0]) == MEM)
6364 if (reload_in_progress || reload_completed)
6365 regnum = true_regnum (operands[1]);
6366 else if (GET_CODE (operands[1]) == REG)
6367 regnum = REGNO (operands[1]);
6371 /* If operands[1] is a register, on POWER it may have
6372 double-precision data in it, so truncate it to single
6374 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6377 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6378 : gen_reg_rtx (mode));
6379 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6380 operands[1] = newreg;
6384 /* Recognize the case where operand[1] is a reference to thread-local
6385 data and load its address to a register. */
6386 if (rs6000_tls_referenced_p (operands[1]))
6388 enum tls_model model;
6389 rtx tmp = operands[1];
6392 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6394 addend = XEXP (XEXP (tmp, 0), 1);
6395 tmp = XEXP (XEXP (tmp, 0), 0);
6398 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6399 model = SYMBOL_REF_TLS_MODEL (tmp);
6400 gcc_assert (model != 0);
6402 tmp = rs6000_legitimize_tls_address (tmp, model);
6405 tmp = gen_rtx_PLUS (mode, tmp, addend);
6406 tmp = force_operand (tmp, operands[0]);
6411 /* Handle the case where reload calls us with an invalid address. */
6412 if (reload_in_progress && mode == Pmode
6413 && (! general_operand (operands[1], mode)
6414 || ! nonimmediate_operand (operands[0], mode)))
6417 /* 128-bit constant floating-point values on Darwin should really be
6418 loaded as two parts. */
6419 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6420 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6422 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6423 know how to get a DFmode SUBREG of a TFmode. */
6424 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6425 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6426 simplify_gen_subreg (imode, operands[1], mode, 0),
6428 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6429 GET_MODE_SIZE (imode)),
6430 simplify_gen_subreg (imode, operands[1], mode,
6431 GET_MODE_SIZE (imode)),
6436 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6437 cfun->machine->sdmode_stack_slot =
6438 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6440 if (reload_in_progress
6442 && MEM_P (operands[0])
6443 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6444 && REG_P (operands[1]))
6446 if (FP_REGNO_P (REGNO (operands[1])))
6448 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6449 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6450 emit_insn (gen_movsd_store (mem, operands[1]));
6452 else if (INT_REGNO_P (REGNO (operands[1])))
6454 rtx mem = adjust_address_nv (operands[0], mode, 4);
6455 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6456 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6462 if (reload_in_progress
6464 && REG_P (operands[0])
6465 && MEM_P (operands[1])
6466 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6468 if (FP_REGNO_P (REGNO (operands[0])))
6470 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6471 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6472 emit_insn (gen_movsd_load (operands[0], mem));
6474 else if (INT_REGNO_P (REGNO (operands[0])))
6476 rtx mem = adjust_address_nv (operands[1], mode, 4);
6477 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6478 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6485 /* FIXME: In the long term, this switch statement should go away
6486 and be replaced by a sequence of tests based on things like
6492 if (CONSTANT_P (operands[1])
6493 && GET_CODE (operands[1]) != CONST_INT)
6494 operands[1] = force_const_mem (mode, operands[1]);
6499 rs6000_eliminate_indexed_memrefs (operands);
6506 if (CONSTANT_P (operands[1])
6507 && ! easy_fp_constant (operands[1], mode))
6508 operands[1] = force_const_mem (mode, operands[1]);
6521 if (CONSTANT_P (operands[1])
6522 && !easy_vector_constant (operands[1], mode))
6523 operands[1] = force_const_mem (mode, operands[1]);
6528 /* Use default pattern for address of ELF small data */
6531 && DEFAULT_ABI == ABI_V4
6532 && (GET_CODE (operands[1]) == SYMBOL_REF
6533 || GET_CODE (operands[1]) == CONST)
6534 && small_data_operand (operands[1], mode))
6536 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6540 if (DEFAULT_ABI == ABI_V4
6541 && mode == Pmode && mode == SImode
6542 && flag_pic == 1 && got_operand (operands[1], mode))
6544 emit_insn (gen_movsi_got (operands[0], operands[1]));
6548 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6552 && CONSTANT_P (operands[1])
6553 && GET_CODE (operands[1]) != HIGH
6554 && GET_CODE (operands[1]) != CONST_INT)
6556 rtx target = (!can_create_pseudo_p ()
6558 : gen_reg_rtx (mode));
6560 /* If this is a function address on -mcall-aixdesc,
6561 convert it to the address of the descriptor. */
6562 if (DEFAULT_ABI == ABI_AIX
6563 && GET_CODE (operands[1]) == SYMBOL_REF
6564 && XSTR (operands[1], 0)[0] == '.')
6566 const char *name = XSTR (operands[1], 0);
6568 while (*name == '.')
6570 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6571 CONSTANT_POOL_ADDRESS_P (new_ref)
6572 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6573 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6574 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6575 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6576 operands[1] = new_ref;
6579 if (DEFAULT_ABI == ABI_DARWIN)
6582 if (MACHO_DYNAMIC_NO_PIC_P)
6584 /* Take care of any required data indirection. */
6585 operands[1] = rs6000_machopic_legitimize_pic_address (
6586 operands[1], mode, operands[0]);
6587 if (operands[0] != operands[1])
6588 emit_insn (gen_rtx_SET (VOIDmode,
6589 operands[0], operands[1]));
6593 emit_insn (gen_macho_high (target, operands[1]));
6594 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6598 emit_insn (gen_elf_high (target, operands[1]));
6599 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6603 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6604 and we have put it in the TOC, we just need to make a TOC-relative
6607 && GET_CODE (operands[1]) == SYMBOL_REF
6608 && constant_pool_expr_p (operands[1])
6609 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6610 get_pool_mode (operands[1])))
6612 operands[1] = create_TOC_reference (operands[1]);
6614 else if (mode == Pmode
6615 && CONSTANT_P (operands[1])
6616 && ((GET_CODE (operands[1]) != CONST_INT
6617 && ! easy_fp_constant (operands[1], mode))
6618 || (GET_CODE (operands[1]) == CONST_INT
6619 && num_insns_constant (operands[1], mode) > 2)
6620 || (GET_CODE (operands[0]) == REG
6621 && FP_REGNO_P (REGNO (operands[0]))))
6622 && GET_CODE (operands[1]) != HIGH
6623 && ! legitimate_constant_pool_address_p (operands[1])
6624 && ! toc_relative_expr_p (operands[1]))
6628 /* Darwin uses a special PIC legitimizer. */
6629 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
6632 rs6000_machopic_legitimize_pic_address (operands[1], mode,
6634 if (operands[0] != operands[1])
6635 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6640 /* If we are to limit the number of things we put in the TOC and
6641 this is a symbol plus a constant we can add in one insn,
6642 just put the symbol in the TOC and add the constant. Don't do
6643 this if reload is in progress. */
6644 if (GET_CODE (operands[1]) == CONST
6645 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
6646 && GET_CODE (XEXP (operands[1], 0)) == PLUS
6647 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
6648 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
6649 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
6650 && ! side_effects_p (operands[0]))
6653 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
6654 rtx other = XEXP (XEXP (operands[1], 0), 1);
6656 sym = force_reg (mode, sym);
6657 emit_insn (gen_add3_insn (operands[0], sym, other));
6661 operands[1] = force_const_mem (mode, operands[1]);
6664 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6665 && constant_pool_expr_p (XEXP (operands[1], 0))
6666 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
6667 get_pool_constant (XEXP (operands[1], 0)),
6668 get_pool_mode (XEXP (operands[1], 0))))
6671 = gen_const_mem (mode,
6672 create_TOC_reference (XEXP (operands[1], 0)));
6673 set_mem_alias_set (operands[1], get_TOC_alias_set ());
6679 rs6000_eliminate_indexed_memrefs (operands);
6683 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6685 gen_rtx_SET (VOIDmode,
6686 operands[0], operands[1]),
6687 gen_rtx_CLOBBER (VOIDmode,
6688 gen_rtx_SCRATCH (SImode)))));
6694 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
6697 /* Above, we may have called force_const_mem which may have returned
6698 an invalid address. If we can, fix this up; otherwise, reload will
6699 have to deal with it. */
6700 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
6701 operands[1] = validize_mem (operands[1]);
6704 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6707 /* Nonzero if we can use a floating-point register to pass this arg. */
6708 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
6709 (SCALAR_FLOAT_MODE_P (MODE) \
6710 && (CUM)->fregno <= FP_ARG_MAX_REG \
6711 && TARGET_HARD_FLOAT && TARGET_FPRS)
6713 /* Nonzero if we can use an AltiVec register to pass this arg. */
6714 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
6715 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
6716 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
6717 && TARGET_ALTIVEC_ABI \
6720 /* Return a nonzero value to say to return the function value in
6721 memory, just as large structures are always returned. TYPE will be
6722 the data type of the value, and FNTYPE will be the type of the
6723 function doing the returning, or @code{NULL} for libcalls.
6725 The AIX ABI for the RS/6000 specifies that all structures are
6726 returned in memory. The Darwin ABI does the same. The SVR4 ABI
6727 specifies that structures <= 8 bytes are returned in r3/r4, but a
6728 draft put them in memory, and GCC used to implement the draft
6729 instead of the final standard. Therefore, aix_struct_return
6730 controls this instead of DEFAULT_ABI; V.4 targets needing backward
6731 compatibility can change DRAFT_V4_STRUCT_RET to override the
6732 default, and -m switches get the final word. See
6733 rs6000_override_options for more details.
6735 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
6736 long double support is enabled. These values are returned in memory.
6738 int_size_in_bytes returns -1 for variable size objects, which go in
6739 memory always. The cast to unsigned makes -1 > 8. */
6742 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6744 /* In the darwin64 abi, try to use registers for larger structs
6746 if (rs6000_darwin64_abi
6747 && TREE_CODE (type) == RECORD_TYPE
6748 && int_size_in_bytes (type) > 0)
6750 CUMULATIVE_ARGS valcum;
6754 valcum.fregno = FP_ARG_MIN_REG;
6755 valcum.vregno = ALTIVEC_ARG_MIN_REG;
6756 /* Do a trial code generation as if this were going to be passed
6757 as an argument; if any part goes in memory, we return NULL. */
6758 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
6761 /* Otherwise fall through to more conventional ABI rules. */
6764 if (AGGREGATE_TYPE_P (type)
6765 && (aix_struct_return
6766 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
6769 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6770 modes only exist for GCC vector types if -maltivec. */
6771 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
6772 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6775 /* Return synthetic vectors in memory. */
6776 if (TREE_CODE (type) == VECTOR_TYPE
6777 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
6779 static bool warned_for_return_big_vectors = false;
6780 if (!warned_for_return_big_vectors)
6782 warning (0, "GCC vector returned by reference: "
6783 "non-standard ABI extension with no compatibility guarantee");
6784 warned_for_return_big_vectors = true;
6789 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
6795 /* Initialize a variable CUM of type CUMULATIVE_ARGS
6796 for a call to a function whose data type is FNTYPE.
6797 For a library call, FNTYPE is 0.
6799 For incoming args we set the number of arguments in the prototype large
6800 so we never return a PARALLEL. */
6803 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
6804 rtx libname ATTRIBUTE_UNUSED, int incoming,
6805 int libcall, int n_named_args)
6807 static CUMULATIVE_ARGS zero_cumulative;
6809 *cum = zero_cumulative;
6811 cum->fregno = FP_ARG_MIN_REG;
6812 cum->vregno = ALTIVEC_ARG_MIN_REG;
6813 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
6814 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
6815 ? CALL_LIBCALL : CALL_NORMAL);
6816 cum->sysv_gregno = GP_ARG_MIN_REG;
6817 cum->stdarg = fntype
6818 && (TYPE_ARG_TYPES (fntype) != 0
6819 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
6820 != void_type_node));
6822 cum->nargs_prototype = 0;
6823 if (incoming || cum->prototype)
6824 cum->nargs_prototype = n_named_args;
6826 /* Check for a longcall attribute. */
6827 if ((!fntype && rs6000_default_long_calls)
6829 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
6830 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
6831 cum->call_cookie |= CALL_LONG;
6833 if (TARGET_DEBUG_ARG)
6835 fprintf (stderr, "\ninit_cumulative_args:");
6838 tree ret_type = TREE_TYPE (fntype);
6839 fprintf (stderr, " ret code = %s,",
6840 tree_code_name[ (int)TREE_CODE (ret_type) ]);
6843 if (cum->call_cookie & CALL_LONG)
6844 fprintf (stderr, " longcall,");
6846 fprintf (stderr, " proto = %d, nargs = %d\n",
6847 cum->prototype, cum->nargs_prototype);
6852 && TARGET_ALTIVEC_ABI
6853 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
6855 error ("cannot return value in vector register because"
6856 " altivec instructions are disabled, use -maltivec"
6861 /* Return true if TYPE must be passed on the stack and not in registers. */
6864 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
6866 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
6867 return must_pass_in_stack_var_size (mode, type);
6869 return must_pass_in_stack_var_size_or_pad (mode, type);
6872 /* If defined, a C expression which determines whether, and in which
6873 direction, to pad out an argument with extra space. The value
6874 should be of type `enum direction': either `upward' to pad above
6875 the argument, `downward' to pad below, or `none' to inhibit
6878 For the AIX ABI structs are always stored left shifted in their
6882 function_arg_padding (enum machine_mode mode, const_tree type)
6884 #ifndef AGGREGATE_PADDING_FIXED
6885 #define AGGREGATE_PADDING_FIXED 0
6887 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
6888 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
6891 if (!AGGREGATE_PADDING_FIXED)
6893 /* GCC used to pass structures of the same size as integer types as
6894 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
6895 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6896 passed padded downward, except that -mstrict-align further
6897 muddied the water in that multi-component structures of 2 and 4
6898 bytes in size were passed padded upward.
6900 The following arranges for best compatibility with previous
6901 versions of gcc, but removes the -mstrict-align dependency. */
6902 if (BYTES_BIG_ENDIAN)
6904 HOST_WIDE_INT size = 0;
6906 if (mode == BLKmode)
6908 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
6909 size = int_size_in_bytes (type);
6912 size = GET_MODE_SIZE (mode);
6914 if (size == 1 || size == 2 || size == 4)
6920 if (AGGREGATES_PAD_UPWARD_ALWAYS)
6922 if (type != 0 && AGGREGATE_TYPE_P (type))
6926 /* Fall back to the default. */
6927 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
6930 /* If defined, a C expression that gives the alignment boundary, in bits,
6931 of an argument with the specified mode and type. If it is not defined,
6932 PARM_BOUNDARY is used for all arguments.
6934 V.4 wants long longs and doubles to be double word aligned. Just
6935 testing the mode size is a boneheaded way to do this as it means
6936 that other types such as complex int are also double word aligned.
6937 However, we're stuck with this because changing the ABI might break
6938 existing library interfaces.
6940 Doubleword align SPE vectors.
6941 Quadword align Altivec vectors.
6942 Quadword align large synthetic vector types. */
6945 function_arg_boundary (enum machine_mode mode, tree type)
6947 if (DEFAULT_ABI == ABI_V4
6948 && (GET_MODE_SIZE (mode) == 8
6949 || (TARGET_HARD_FLOAT
6951 && (mode == TFmode || mode == TDmode))))
6953 else if (SPE_VECTOR_MODE (mode)
6954 || (type && TREE_CODE (type) == VECTOR_TYPE
6955 && int_size_in_bytes (type) >= 8
6956 && int_size_in_bytes (type) < 16))
6958 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
6959 || (type && TREE_CODE (type) == VECTOR_TYPE
6960 && int_size_in_bytes (type) >= 16))
6962 else if (rs6000_darwin64_abi && mode == BLKmode
6963 && type && TYPE_ALIGN (type) > 64)
6966 return PARM_BOUNDARY;
6969 /* For a function parm of MODE and TYPE, return the starting word in
6970 the parameter area. NWORDS of the parameter area are already used. */
6973 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
6976 unsigned int parm_offset;
6978 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
6979 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
6980 return nwords + (-(parm_offset + nwords) & align);
6983 /* Compute the size (in words) of a function argument. */
6985 static unsigned long
6986 rs6000_arg_size (enum machine_mode mode, tree type)
6990 if (mode != BLKmode)
6991 size = GET_MODE_SIZE (mode);
6993 size = int_size_in_bytes (type);
6996 return (size + 3) >> 2;
6998 return (size + 7) >> 3;
7001 /* Use this to flush pending int fields. */
7004 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7005 HOST_WIDE_INT bitpos)
7007 unsigned int startbit, endbit;
7008 int intregs, intoffset;
7009 enum machine_mode mode;
7011 if (cum->intoffset == -1)
7014 intoffset = cum->intoffset;
7015 cum->intoffset = -1;
7017 if (intoffset % BITS_PER_WORD != 0)
7019 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7021 if (mode == BLKmode)
7023 /* We couldn't find an appropriate mode, which happens,
7024 e.g., in packed structs when there are 3 bytes to load.
7025 Back intoffset back to the beginning of the word in this
7027 intoffset = intoffset & -BITS_PER_WORD;
7031 startbit = intoffset & -BITS_PER_WORD;
7032 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7033 intregs = (endbit - startbit) / BITS_PER_WORD;
7034 cum->words += intregs;
7037 /* The darwin64 ABI calls for us to recurse down through structs,
7038 looking for elements passed in registers. Unfortunately, we have
7039 to track int register count here also because of misalignments
7040 in powerpc alignment mode. */
7043 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7045 HOST_WIDE_INT startbitpos)
7049 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7050 if (TREE_CODE (f) == FIELD_DECL)
7052 HOST_WIDE_INT bitpos = startbitpos;
7053 tree ftype = TREE_TYPE (f);
7054 enum machine_mode mode;
7055 if (ftype == error_mark_node)
7057 mode = TYPE_MODE (ftype);
7059 if (DECL_SIZE (f) != 0
7060 && host_integerp (bit_position (f), 1))
7061 bitpos += int_bit_position (f);
7063 /* ??? FIXME: else assume zero offset. */
7065 if (TREE_CODE (ftype) == RECORD_TYPE)
7066 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7067 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7069 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7070 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7071 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7073 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7075 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7079 else if (cum->intoffset == -1)
7080 cum->intoffset = bitpos;
7084 /* Update the data in CUM to advance over an argument
7085 of mode MODE and data type TYPE.
7086 (TYPE is null for libcalls where that information may not be available.)
7088 Note that for args passed by reference, function_arg will be called
7089 with MODE and TYPE set to that of the pointer to the arg, not the arg
7093 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7094 tree type, int named, int depth)
7098 /* Only tick off an argument if we're not recursing. */
7100 cum->nargs_prototype--;
7102 if (TARGET_ALTIVEC_ABI
7103 && (ALTIVEC_VECTOR_MODE (mode)
7104 || VSX_VECTOR_MODE (mode)
7105 || (type && TREE_CODE (type) == VECTOR_TYPE
7106 && int_size_in_bytes (type) == 16)))
7110 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7113 if (!TARGET_ALTIVEC)
7114 error ("cannot pass argument in vector register because"
7115 " altivec instructions are disabled, use -maltivec"
7118 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7119 even if it is going to be passed in a vector register.
7120 Darwin does the same for variable-argument functions. */
7121 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7122 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7132 /* Vector parameters must be 16-byte aligned. This places
7133 them at 2 mod 4 in terms of words in 32-bit mode, since
7134 the parameter save area starts at offset 24 from the
7135 stack. In 64-bit mode, they just have to start on an
7136 even word, since the parameter save area is 16-byte
7137 aligned. Space for GPRs is reserved even if the argument
7138 will be passed in memory. */
7140 align = (2 - cum->words) & 3;
7142 align = cum->words & 1;
7143 cum->words += align + rs6000_arg_size (mode, type);
7145 if (TARGET_DEBUG_ARG)
7147 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7149 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7150 cum->nargs_prototype, cum->prototype,
7151 GET_MODE_NAME (mode));
7155 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7157 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7160 else if (rs6000_darwin64_abi
7162 && TREE_CODE (type) == RECORD_TYPE
7163 && (size = int_size_in_bytes (type)) > 0)
7165 /* Variable sized types have size == -1 and are
7166 treated as if consisting entirely of ints.
7167 Pad to 16 byte boundary if needed. */
7168 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7169 && (cum->words % 2) != 0)
7171 /* For varargs, we can just go up by the size of the struct. */
7173 cum->words += (size + 7) / 8;
7176 /* It is tempting to say int register count just goes up by
7177 sizeof(type)/8, but this is wrong in a case such as
7178 { int; double; int; } [powerpc alignment]. We have to
7179 grovel through the fields for these too. */
7181 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7182 rs6000_darwin64_record_arg_advance_flush (cum,
7183 size * BITS_PER_UNIT);
7186 else if (DEFAULT_ABI == ABI_V4)
7188 if (TARGET_HARD_FLOAT && TARGET_FPRS
7189 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7190 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7191 || (mode == TFmode && !TARGET_IEEEQUAD)
7192 || mode == SDmode || mode == DDmode || mode == TDmode))
7194 /* _Decimal128 must use an even/odd register pair. This assumes
7195 that the register number is odd when fregno is odd. */
7196 if (mode == TDmode && (cum->fregno % 2) == 1)
7199 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7200 <= FP_ARG_V4_MAX_REG)
7201 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7204 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7205 if (mode == DFmode || mode == TFmode
7206 || mode == DDmode || mode == TDmode)
7207 cum->words += cum->words & 1;
7208 cum->words += rs6000_arg_size (mode, type);
7213 int n_words = rs6000_arg_size (mode, type);
7214 int gregno = cum->sysv_gregno;
7216 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7217 (r7,r8) or (r9,r10). As does any other 2 word item such
7218 as complex int due to a historical mistake. */
7220 gregno += (1 - gregno) & 1;
7222 /* Multi-reg args are not split between registers and stack. */
7223 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7225 /* Long long and SPE vectors are aligned on the stack.
7226 So are other 2 word items such as complex int due to
7227 a historical mistake. */
7229 cum->words += cum->words & 1;
7230 cum->words += n_words;
7233 /* Note: continuing to accumulate gregno past when we've started
7234 spilling to the stack indicates the fact that we've started
7235 spilling to the stack to expand_builtin_saveregs. */
7236 cum->sysv_gregno = gregno + n_words;
7239 if (TARGET_DEBUG_ARG)
7241 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7242 cum->words, cum->fregno);
7243 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7244 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7245 fprintf (stderr, "mode = %4s, named = %d\n",
7246 GET_MODE_NAME (mode), named);
7251 int n_words = rs6000_arg_size (mode, type);
7252 int start_words = cum->words;
7253 int align_words = rs6000_parm_start (mode, type, start_words);
7255 cum->words = align_words + n_words;
7257 if (SCALAR_FLOAT_MODE_P (mode)
7258 && TARGET_HARD_FLOAT && TARGET_FPRS)
7260 /* _Decimal128 must be passed in an even/odd float register pair.
7261 This assumes that the register number is odd when fregno is
7263 if (mode == TDmode && (cum->fregno % 2) == 1)
7265 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7268 if (TARGET_DEBUG_ARG)
7270 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7271 cum->words, cum->fregno);
7272 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7273 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7274 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7275 named, align_words - start_words, depth);
7281 spe_build_register_parallel (enum machine_mode mode, int gregno)
7288 r1 = gen_rtx_REG (DImode, gregno);
7289 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7290 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7294 r1 = gen_rtx_REG (DImode, gregno);
7295 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7296 r3 = gen_rtx_REG (DImode, gregno + 2);
7297 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7298 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7301 r1 = gen_rtx_REG (DImode, gregno);
7302 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7303 r3 = gen_rtx_REG (DImode, gregno + 2);
7304 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7305 r5 = gen_rtx_REG (DImode, gregno + 4);
7306 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7307 r7 = gen_rtx_REG (DImode, gregno + 6);
7308 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7309 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7316 /* Determine where to put a SIMD argument on the SPE. */
7318 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7321 int gregno = cum->sysv_gregno;
7323 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7324 are passed and returned in a pair of GPRs for ABI compatibility. */
7325 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7326 || mode == DCmode || mode == TCmode))
7328 int n_words = rs6000_arg_size (mode, type);
7330 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7332 gregno += (1 - gregno) & 1;
7334 /* Multi-reg args are not split between registers and stack. */
7335 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7338 return spe_build_register_parallel (mode, gregno);
7342 int n_words = rs6000_arg_size (mode, type);
7344 /* SPE vectors are put in odd registers. */
7345 if (n_words == 2 && (gregno & 1) == 0)
7348 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7351 enum machine_mode m = SImode;
7353 r1 = gen_rtx_REG (m, gregno);
7354 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7355 r2 = gen_rtx_REG (m, gregno + 1);
7356 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7357 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7364 if (gregno <= GP_ARG_MAX_REG)
7365 return gen_rtx_REG (mode, gregno);
7371 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7372 structure between cum->intoffset and bitpos to integer registers. */
7375 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7376 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7378 enum machine_mode mode;
7380 unsigned int startbit, endbit;
7381 int this_regno, intregs, intoffset;
7384 if (cum->intoffset == -1)
7387 intoffset = cum->intoffset;
7388 cum->intoffset = -1;
7390 /* If this is the trailing part of a word, try to only load that
7391 much into the register. Otherwise load the whole register. Note
7392 that in the latter case we may pick up unwanted bits. It's not a
7393 problem at the moment but may wish to revisit. */
7395 if (intoffset % BITS_PER_WORD != 0)
7397 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7399 if (mode == BLKmode)
7401 /* We couldn't find an appropriate mode, which happens,
7402 e.g., in packed structs when there are 3 bytes to load.
7403 Back intoffset back to the beginning of the word in this
7405 intoffset = intoffset & -BITS_PER_WORD;
7412 startbit = intoffset & -BITS_PER_WORD;
7413 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7414 intregs = (endbit - startbit) / BITS_PER_WORD;
7415 this_regno = cum->words + intoffset / BITS_PER_WORD;
7417 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7420 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7424 intoffset /= BITS_PER_UNIT;
7427 regno = GP_ARG_MIN_REG + this_regno;
7428 reg = gen_rtx_REG (mode, regno);
7430 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7433 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7437 while (intregs > 0);
7440 /* Recursive workhorse for the following. */
7443 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7444 HOST_WIDE_INT startbitpos, rtx rvec[],
7449 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7450 if (TREE_CODE (f) == FIELD_DECL)
7452 HOST_WIDE_INT bitpos = startbitpos;
7453 tree ftype = TREE_TYPE (f);
7454 enum machine_mode mode;
7455 if (ftype == error_mark_node)
7457 mode = TYPE_MODE (ftype);
7459 if (DECL_SIZE (f) != 0
7460 && host_integerp (bit_position (f), 1))
7461 bitpos += int_bit_position (f);
7463 /* ??? FIXME: else assume zero offset. */
7465 if (TREE_CODE (ftype) == RECORD_TYPE)
7466 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7467 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7472 case SCmode: mode = SFmode; break;
7473 case DCmode: mode = DFmode; break;
7474 case TCmode: mode = TFmode; break;
7478 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7480 = gen_rtx_EXPR_LIST (VOIDmode,
7481 gen_rtx_REG (mode, cum->fregno++),
7482 GEN_INT (bitpos / BITS_PER_UNIT));
7483 if (mode == TFmode || mode == TDmode)
7486 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7488 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7490 = gen_rtx_EXPR_LIST (VOIDmode,
7491 gen_rtx_REG (mode, cum->vregno++),
7492 GEN_INT (bitpos / BITS_PER_UNIT));
7494 else if (cum->intoffset == -1)
7495 cum->intoffset = bitpos;
7499 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7500 the register(s) to be used for each field and subfield of a struct
7501 being passed by value, along with the offset of where the
7502 register's value may be found in the block. FP fields go in FP
7503 register, vector fields go in vector registers, and everything
7504 else goes in int registers, packed as in memory.
7506 This code is also used for function return values. RETVAL indicates
7507 whether this is the case.
7509 Much of this is taken from the SPARC V9 port, which has a similar
7510 calling convention. */
7513 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7514 int named, bool retval)
7516 rtx rvec[FIRST_PSEUDO_REGISTER];
7517 int k = 1, kbase = 1;
7518 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7519 /* This is a copy; modifications are not visible to our caller. */
7520 CUMULATIVE_ARGS copy_cum = *orig_cum;
7521 CUMULATIVE_ARGS *cum = ©_cum;
7523 /* Pad to 16 byte boundary if needed. */
7524 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7525 && (cum->words % 2) != 0)
7532 /* Put entries into rvec[] for individual FP and vector fields, and
7533 for the chunks of memory that go in int regs. Note we start at
7534 element 1; 0 is reserved for an indication of using memory, and
7535 may or may not be filled in below. */
7536 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7537 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7539 /* If any part of the struct went on the stack put all of it there.
7540 This hack is because the generic code for
7541 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7542 parts of the struct are not at the beginning. */
7546 return NULL_RTX; /* doesn't go in registers at all */
7548 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7550 if (k > 1 || cum->use_stack)
7551 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7556 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7559 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7563 rtx rvec[GP_ARG_NUM_REG + 1];
7565 if (align_words >= GP_ARG_NUM_REG)
7568 n_units = rs6000_arg_size (mode, type);
7570 /* Optimize the simple case where the arg fits in one gpr, except in
7571 the case of BLKmode due to assign_parms assuming that registers are
7572 BITS_PER_WORD wide. */
7574 || (n_units == 1 && mode != BLKmode))
7575 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7578 if (align_words + n_units > GP_ARG_NUM_REG)
7579 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7580 using a magic NULL_RTX component.
7581 This is not strictly correct. Only some of the arg belongs in
7582 memory, not all of it. However, the normal scheme using
7583 function_arg_partial_nregs can result in unusual subregs, eg.
7584 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7585 store the whole arg to memory is often more efficient than code
7586 to store pieces, and we know that space is available in the right
7587 place for the whole arg. */
7588 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7593 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7594 rtx off = GEN_INT (i++ * 4);
7595 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7597 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7599 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7602 /* Determine where to put an argument to a function.
7603 Value is zero to push the argument on the stack,
7604 or a hard register in which to store the argument.
7606 MODE is the argument's machine mode.
7607 TYPE is the data type of the argument (as a tree).
7608 This is null for libcalls where that information may
7610 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7611 the preceding args and about the function being called. It is
7612 not modified in this routine.
7613 NAMED is nonzero if this argument is a named parameter
7614 (otherwise it is an extra parameter matching an ellipsis).
7616 On RS/6000 the first eight words of non-FP are normally in registers
7617 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7618 Under V.4, the first 8 FP args are in registers.
7620 If this is floating-point and no prototype is specified, we use
7621 both an FP and integer register (or possibly FP reg and stack). Library
7622 functions (when CALL_LIBCALL is set) always have the proper types for args,
7623 so we can pass the FP value just in one register. emit_library_function
7624 doesn't support PARALLEL anyway.
7626 Note that for args passed by reference, function_arg will be called
7627 with MODE and TYPE set to that of the pointer to the arg, not the arg
7631 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7632 tree type, int named)
7634 enum rs6000_abi abi = DEFAULT_ABI;
7636 /* Return a marker to indicate whether CR1 needs to set or clear the
7637 bit that V.4 uses to say fp args were passed in registers.
7638 Assume that we don't need the marker for software floating point,
7639 or compiler generated library calls. */
7640 if (mode == VOIDmode)
7643 && (cum->call_cookie & CALL_LIBCALL) == 0
7645 || (cum->nargs_prototype < 0
7646 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7648 /* For the SPE, we need to crxor CR6 always. */
7650 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
7651 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
7652 return GEN_INT (cum->call_cookie
7653 | ((cum->fregno == FP_ARG_MIN_REG)
7654 ? CALL_V4_SET_FP_ARGS
7655 : CALL_V4_CLEAR_FP_ARGS));
7658 return GEN_INT (cum->call_cookie);
7661 if (rs6000_darwin64_abi && mode == BLKmode
7662 && TREE_CODE (type) == RECORD_TYPE)
7664 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
7665 if (rslt != NULL_RTX)
7667 /* Else fall through to usual handling. */
7670 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7671 if (TARGET_64BIT && ! cum->prototype)
7673 /* Vector parameters get passed in vector register
7674 and also in GPRs or memory, in absence of prototype. */
7677 align_words = (cum->words + 1) & ~1;
7679 if (align_words >= GP_ARG_NUM_REG)
7685 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7687 return gen_rtx_PARALLEL (mode,
7689 gen_rtx_EXPR_LIST (VOIDmode,
7691 gen_rtx_EXPR_LIST (VOIDmode,
7692 gen_rtx_REG (mode, cum->vregno),
7696 return gen_rtx_REG (mode, cum->vregno);
7697 else if (TARGET_ALTIVEC_ABI
7698 && (ALTIVEC_VECTOR_MODE (mode)
7699 || VSX_VECTOR_MODE (mode)
7700 || (type && TREE_CODE (type) == VECTOR_TYPE
7701 && int_size_in_bytes (type) == 16)))
7703 if (named || abi == ABI_V4)
7707 /* Vector parameters to varargs functions under AIX or Darwin
7708 get passed in memory and possibly also in GPRs. */
7709 int align, align_words, n_words;
7710 enum machine_mode part_mode;
7712 /* Vector parameters must be 16-byte aligned. This places them at
7713 2 mod 4 in terms of words in 32-bit mode, since the parameter
7714 save area starts at offset 24 from the stack. In 64-bit mode,
7715 they just have to start on an even word, since the parameter
7716 save area is 16-byte aligned. */
7718 align = (2 - cum->words) & 3;
7720 align = cum->words & 1;
7721 align_words = cum->words + align;
7723 /* Out of registers? Memory, then. */
7724 if (align_words >= GP_ARG_NUM_REG)
7727 if (TARGET_32BIT && TARGET_POWERPC64)
7728 return rs6000_mixed_function_arg (mode, type, align_words);
7730 /* The vector value goes in GPRs. Only the part of the
7731 value in GPRs is reported here. */
7733 n_words = rs6000_arg_size (mode, type);
7734 if (align_words + n_words > GP_ARG_NUM_REG)
7735 /* Fortunately, there are only two possibilities, the value
7736 is either wholly in GPRs or half in GPRs and half not. */
7739 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
7742 else if (TARGET_SPE_ABI && TARGET_SPE
7743 && (SPE_VECTOR_MODE (mode)
7744 || (TARGET_E500_DOUBLE && (mode == DFmode
7747 || mode == TCmode))))
7748 return rs6000_spe_function_arg (cum, mode, type);
7750 else if (abi == ABI_V4)
7752 if (TARGET_HARD_FLOAT && TARGET_FPRS
7753 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7754 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7755 || (mode == TFmode && !TARGET_IEEEQUAD)
7756 || mode == SDmode || mode == DDmode || mode == TDmode))
7758 /* _Decimal128 must use an even/odd register pair. This assumes
7759 that the register number is odd when fregno is odd. */
7760 if (mode == TDmode && (cum->fregno % 2) == 1)
7763 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7764 <= FP_ARG_V4_MAX_REG)
7765 return gen_rtx_REG (mode, cum->fregno);
7771 int n_words = rs6000_arg_size (mode, type);
7772 int gregno = cum->sysv_gregno;
7774 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7775 (r7,r8) or (r9,r10). As does any other 2 word item such
7776 as complex int due to a historical mistake. */
7778 gregno += (1 - gregno) & 1;
7780 /* Multi-reg args are not split between registers and stack. */
7781 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7784 if (TARGET_32BIT && TARGET_POWERPC64)
7785 return rs6000_mixed_function_arg (mode, type,
7786 gregno - GP_ARG_MIN_REG);
7787 return gen_rtx_REG (mode, gregno);
7792 int align_words = rs6000_parm_start (mode, type, cum->words);
7794 /* _Decimal128 must be passed in an even/odd float register pair.
7795 This assumes that the register number is odd when fregno is odd. */
7796 if (mode == TDmode && (cum->fregno % 2) == 1)
7799 if (USE_FP_FOR_ARG_P (cum, mode, type))
7801 rtx rvec[GP_ARG_NUM_REG + 1];
7805 enum machine_mode fmode = mode;
7806 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
7808 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
7810 /* Currently, we only ever need one reg here because complex
7811 doubles are split. */
7812 gcc_assert (cum->fregno == FP_ARG_MAX_REG
7813 && (fmode == TFmode || fmode == TDmode));
7815 /* Long double or _Decimal128 split over regs and memory. */
7816 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
7819 /* Do we also need to pass this arg in the parameter save
7822 && (cum->nargs_prototype <= 0
7823 || (DEFAULT_ABI == ABI_AIX
7825 && align_words >= GP_ARG_NUM_REG)));
7827 if (!needs_psave && mode == fmode)
7828 return gen_rtx_REG (fmode, cum->fregno);
7833 /* Describe the part that goes in gprs or the stack.
7834 This piece must come first, before the fprs. */
7835 if (align_words < GP_ARG_NUM_REG)
7837 unsigned long n_words = rs6000_arg_size (mode, type);
7839 if (align_words + n_words > GP_ARG_NUM_REG
7840 || (TARGET_32BIT && TARGET_POWERPC64))
7842 /* If this is partially on the stack, then we only
7843 include the portion actually in registers here. */
7844 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
7847 if (align_words + n_words > GP_ARG_NUM_REG)
7848 /* Not all of the arg fits in gprs. Say that it
7849 goes in memory too, using a magic NULL_RTX
7850 component. Also see comment in
7851 rs6000_mixed_function_arg for why the normal
7852 function_arg_partial_nregs scheme doesn't work
7854 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
7858 r = gen_rtx_REG (rmode,
7859 GP_ARG_MIN_REG + align_words);
7860 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
7861 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7863 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
7867 /* The whole arg fits in gprs. */
7868 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7869 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7873 /* It's entirely in memory. */
7874 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7877 /* Describe where this piece goes in the fprs. */
7878 r = gen_rtx_REG (fmode, cum->fregno);
7879 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7881 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7883 else if (align_words < GP_ARG_NUM_REG)
7885 if (TARGET_32BIT && TARGET_POWERPC64)
7886 return rs6000_mixed_function_arg (mode, type, align_words);
7888 if (mode == BLKmode)
7891 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7898 /* For an arg passed partly in registers and partly in memory, this is
7899 the number of bytes passed in registers. For args passed entirely in
7900 registers or entirely in memory, zero. When an arg is described by a
7901 PARALLEL, perhaps using more than one register type, this function
7902 returns the number of bytes used by the first element of the PARALLEL. */
7905 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7906 tree type, bool named)
7911 if (DEFAULT_ABI == ABI_V4)
7914 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
7915 && cum->nargs_prototype >= 0)
7918 /* In this complicated case we just disable the partial_nregs code. */
7919 if (rs6000_darwin64_abi && mode == BLKmode
7920 && TREE_CODE (type) == RECORD_TYPE
7921 && int_size_in_bytes (type) > 0)
7924 align_words = rs6000_parm_start (mode, type, cum->words);
7926 if (USE_FP_FOR_ARG_P (cum, mode, type))
7928 /* If we are passing this arg in the fixed parameter save area
7929 (gprs or memory) as well as fprs, then this function should
7930 return the number of partial bytes passed in the parameter
7931 save area rather than partial bytes passed in fprs. */
7933 && (cum->nargs_prototype <= 0
7934 || (DEFAULT_ABI == ABI_AIX
7936 && align_words >= GP_ARG_NUM_REG)))
7938 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
7939 > FP_ARG_MAX_REG + 1)
7940 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
7941 else if (cum->nargs_prototype >= 0)
7945 if (align_words < GP_ARG_NUM_REG
7946 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
7947 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
7949 if (ret != 0 && TARGET_DEBUG_ARG)
7950 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
7955 /* A C expression that indicates when an argument must be passed by
7956 reference. If nonzero for an argument, a copy of that argument is
7957 made in memory and a pointer to the argument is passed instead of
7958 the argument itself. The pointer is passed in whatever way is
7959 appropriate for passing a pointer to that type.
7961 Under V.4, aggregates and long double are passed by reference.
7963 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
7964 reference unless the AltiVec vector extension ABI is in force.
7966 As an extension to all ABIs, variable sized types are passed by
7970 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
7971 enum machine_mode mode, const_tree type,
7972 bool named ATTRIBUTE_UNUSED)
7974 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
7976 if (TARGET_DEBUG_ARG)
7977 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
7984 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
7986 if (TARGET_DEBUG_ARG)
7987 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
7991 if (int_size_in_bytes (type) < 0)
7993 if (TARGET_DEBUG_ARG)
7994 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
7998 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7999 modes only exist for GCC vector types if -maltivec. */
8000 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8002 if (TARGET_DEBUG_ARG)
8003 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8007 /* Pass synthetic vectors in memory. */
8008 if (TREE_CODE (type) == VECTOR_TYPE
8009 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8011 static bool warned_for_pass_big_vectors = false;
8012 if (TARGET_DEBUG_ARG)
8013 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8014 if (!warned_for_pass_big_vectors)
8016 warning (0, "GCC vector passed by reference: "
8017 "non-standard ABI extension with no compatibility guarantee");
8018 warned_for_pass_big_vectors = true;
8027 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8030 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8035 for (i = 0; i < nregs; i++)
8037 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8038 if (reload_completed)
8040 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8043 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8044 i * GET_MODE_SIZE (reg_mode));
8047 tem = replace_equiv_address (tem, XEXP (tem, 0));
8051 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8055 /* Perform any needed actions needed for a function that is receiving a
8056 variable number of arguments.
8060 MODE and TYPE are the mode and type of the current parameter.
8062 PRETEND_SIZE is a variable that should be set to the amount of stack
8063 that must be pushed by the prolog to pretend that our caller pushed
8066 Normally, this macro will push all remaining incoming registers on the
8067 stack and set PRETEND_SIZE to the length of the registers pushed. */
8070 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8071 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8074 CUMULATIVE_ARGS next_cum;
8075 int reg_size = TARGET_32BIT ? 4 : 8;
8076 rtx save_area = NULL_RTX, mem;
8077 int first_reg_offset;
8080 /* Skip the last named argument. */
8082 function_arg_advance (&next_cum, mode, type, 1, 0);
8084 if (DEFAULT_ABI == ABI_V4)
8086 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8090 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8091 HOST_WIDE_INT offset = 0;
8093 /* Try to optimize the size of the varargs save area.
8094 The ABI requires that ap.reg_save_area is doubleword
8095 aligned, but we don't need to allocate space for all
8096 the bytes, only those to which we actually will save
8098 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8099 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8100 if (TARGET_HARD_FLOAT && TARGET_FPRS
8101 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8102 && cfun->va_list_fpr_size)
8105 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8106 * UNITS_PER_FP_WORD;
8107 if (cfun->va_list_fpr_size
8108 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8109 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8111 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8112 * UNITS_PER_FP_WORD;
8116 offset = -((first_reg_offset * reg_size) & ~7);
8117 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8119 gpr_reg_num = cfun->va_list_gpr_size;
8120 if (reg_size == 4 && (first_reg_offset & 1))
8123 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8126 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8128 - (int) (GP_ARG_NUM_REG * reg_size);
8130 if (gpr_size + fpr_size)
8133 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8134 gcc_assert (GET_CODE (reg_save_area) == MEM);
8135 reg_save_area = XEXP (reg_save_area, 0);
8136 if (GET_CODE (reg_save_area) == PLUS)
8138 gcc_assert (XEXP (reg_save_area, 0)
8139 == virtual_stack_vars_rtx);
8140 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8141 offset += INTVAL (XEXP (reg_save_area, 1));
8144 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8147 cfun->machine->varargs_save_offset = offset;
8148 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8153 first_reg_offset = next_cum.words;
8154 save_area = virtual_incoming_args_rtx;
8156 if (targetm.calls.must_pass_in_stack (mode, type))
8157 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8160 set = get_varargs_alias_set ();
8161 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8162 && cfun->va_list_gpr_size)
8164 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8166 if (va_list_gpr_counter_field)
8168 /* V4 va_list_gpr_size counts number of registers needed. */
8169 if (nregs > cfun->va_list_gpr_size)
8170 nregs = cfun->va_list_gpr_size;
8174 /* char * va_list instead counts number of bytes needed. */
8175 if (nregs > cfun->va_list_gpr_size / reg_size)
8176 nregs = cfun->va_list_gpr_size / reg_size;
8179 mem = gen_rtx_MEM (BLKmode,
8180 plus_constant (save_area,
8181 first_reg_offset * reg_size));
8182 MEM_NOTRAP_P (mem) = 1;
8183 set_mem_alias_set (mem, set);
8184 set_mem_align (mem, BITS_PER_WORD);
8186 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8190 /* Save FP registers if needed. */
8191 if (DEFAULT_ABI == ABI_V4
8192 && TARGET_HARD_FLOAT && TARGET_FPRS
8194 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8195 && cfun->va_list_fpr_size)
8197 int fregno = next_cum.fregno, nregs;
8198 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8199 rtx lab = gen_label_rtx ();
8200 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8201 * UNITS_PER_FP_WORD);
8204 (gen_rtx_SET (VOIDmode,
8206 gen_rtx_IF_THEN_ELSE (VOIDmode,
8207 gen_rtx_NE (VOIDmode, cr1,
8209 gen_rtx_LABEL_REF (VOIDmode, lab),
8213 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8214 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8216 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8218 plus_constant (save_area, off));
8219 MEM_NOTRAP_P (mem) = 1;
8220 set_mem_alias_set (mem, set);
8221 set_mem_align (mem, GET_MODE_ALIGNMENT (
8222 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8223 ? DFmode : SFmode));
8224 emit_move_insn (mem, gen_rtx_REG (
8225 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8226 ? DFmode : SFmode, fregno));
8233 /* Create the va_list data type. */
8236 rs6000_build_builtin_va_list (void)
8238 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8240 /* For AIX, prefer 'char *' because that's what the system
8241 header files like. */
8242 if (DEFAULT_ABI != ABI_V4)
8243 return build_pointer_type (char_type_node);
8245 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8246 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8247 get_identifier ("__va_list_tag"), record);
8249 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8250 unsigned_char_type_node);
8251 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8252 unsigned_char_type_node);
8253 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8255 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8256 get_identifier ("reserved"), short_unsigned_type_node);
8257 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8258 get_identifier ("overflow_arg_area"),
8260 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8261 get_identifier ("reg_save_area"),
8264 va_list_gpr_counter_field = f_gpr;
8265 va_list_fpr_counter_field = f_fpr;
8267 DECL_FIELD_CONTEXT (f_gpr) = record;
8268 DECL_FIELD_CONTEXT (f_fpr) = record;
8269 DECL_FIELD_CONTEXT (f_res) = record;
8270 DECL_FIELD_CONTEXT (f_ovf) = record;
8271 DECL_FIELD_CONTEXT (f_sav) = record;
8273 TREE_CHAIN (record) = type_decl;
8274 TYPE_NAME (record) = type_decl;
8275 TYPE_FIELDS (record) = f_gpr;
8276 TREE_CHAIN (f_gpr) = f_fpr;
8277 TREE_CHAIN (f_fpr) = f_res;
8278 TREE_CHAIN (f_res) = f_ovf;
8279 TREE_CHAIN (f_ovf) = f_sav;
8281 layout_type (record);
8283 /* The correct type is an array type of one element. */
8284 return build_array_type (record, build_index_type (size_zero_node));
8287 /* Implement va_start. */
8290 rs6000_va_start (tree valist, rtx nextarg)
8292 HOST_WIDE_INT words, n_gpr, n_fpr;
8293 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8294 tree gpr, fpr, ovf, sav, t;
8296 /* Only SVR4 needs something special. */
8297 if (DEFAULT_ABI != ABI_V4)
8299 std_expand_builtin_va_start (valist, nextarg);
8303 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8304 f_fpr = TREE_CHAIN (f_gpr);
8305 f_res = TREE_CHAIN (f_fpr);
8306 f_ovf = TREE_CHAIN (f_res);
8307 f_sav = TREE_CHAIN (f_ovf);
8309 valist = build_va_arg_indirect_ref (valist);
8310 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8311 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8313 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8315 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8318 /* Count number of gp and fp argument registers used. */
8319 words = crtl->args.info.words;
8320 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8322 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8325 if (TARGET_DEBUG_ARG)
8326 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8327 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8328 words, n_gpr, n_fpr);
8330 if (cfun->va_list_gpr_size)
8332 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8333 build_int_cst (NULL_TREE, n_gpr));
8334 TREE_SIDE_EFFECTS (t) = 1;
8335 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8338 if (cfun->va_list_fpr_size)
8340 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8341 build_int_cst (NULL_TREE, n_fpr));
8342 TREE_SIDE_EFFECTS (t) = 1;
8343 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8346 /* Find the overflow area. */
8347 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8349 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8350 size_int (words * UNITS_PER_WORD));
8351 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8352 TREE_SIDE_EFFECTS (t) = 1;
8353 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8355 /* If there were no va_arg invocations, don't set up the register
8357 if (!cfun->va_list_gpr_size
8358 && !cfun->va_list_fpr_size
8359 && n_gpr < GP_ARG_NUM_REG
8360 && n_fpr < FP_ARG_V4_MAX_REG)
8363 /* Find the register save area. */
8364 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8365 if (cfun->machine->varargs_save_offset)
8366 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8367 size_int (cfun->machine->varargs_save_offset));
8368 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8369 TREE_SIDE_EFFECTS (t) = 1;
8370 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8373 /* Implement va_arg. */
8376 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8379 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8380 tree gpr, fpr, ovf, sav, reg, t, u;
8381 int size, rsize, n_reg, sav_ofs, sav_scale;
8382 tree lab_false, lab_over, addr;
8384 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8388 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8390 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8391 return build_va_arg_indirect_ref (t);
8394 if (DEFAULT_ABI != ABI_V4)
8396 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8398 tree elem_type = TREE_TYPE (type);
8399 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8400 int elem_size = GET_MODE_SIZE (elem_mode);
8402 if (elem_size < UNITS_PER_WORD)
8404 tree real_part, imag_part;
8405 gimple_seq post = NULL;
8407 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8409 /* Copy the value into a temporary, lest the formal temporary
8410 be reused out from under us. */
8411 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8412 gimple_seq_add_seq (pre_p, post);
8414 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8417 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8421 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8424 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8425 f_fpr = TREE_CHAIN (f_gpr);
8426 f_res = TREE_CHAIN (f_fpr);
8427 f_ovf = TREE_CHAIN (f_res);
8428 f_sav = TREE_CHAIN (f_ovf);
8430 valist = build_va_arg_indirect_ref (valist);
8431 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8432 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8434 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8436 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8439 size = int_size_in_bytes (type);
8440 rsize = (size + 3) / 4;
8443 if (TARGET_HARD_FLOAT && TARGET_FPRS
8444 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8445 || (TARGET_DOUBLE_FLOAT
8446 && (TYPE_MODE (type) == DFmode
8447 || TYPE_MODE (type) == TFmode
8448 || TYPE_MODE (type) == SDmode
8449 || TYPE_MODE (type) == DDmode
8450 || TYPE_MODE (type) == TDmode))))
8452 /* FP args go in FP registers, if present. */
8454 n_reg = (size + 7) / 8;
8455 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8456 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8457 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8462 /* Otherwise into GP registers. */
8471 /* Pull the value out of the saved registers.... */
8474 addr = create_tmp_var (ptr_type_node, "addr");
8476 /* AltiVec vectors never go in registers when -mabi=altivec. */
8477 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8481 lab_false = create_artificial_label (input_location);
8482 lab_over = create_artificial_label (input_location);
8484 /* Long long and SPE vectors are aligned in the registers.
8485 As are any other 2 gpr item such as complex int due to a
8486 historical mistake. */
8488 if (n_reg == 2 && reg == gpr)
8491 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8492 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8493 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8494 unshare_expr (reg), u);
8496 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8497 reg number is 0 for f1, so we want to make it odd. */
8498 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8500 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8501 build_int_cst (TREE_TYPE (reg), 1));
8502 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8505 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8506 t = build2 (GE_EXPR, boolean_type_node, u, t);
8507 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8508 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8509 gimplify_and_add (t, pre_p);
8513 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8515 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8516 build_int_cst (TREE_TYPE (reg), n_reg));
8517 u = fold_convert (sizetype, u);
8518 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8519 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8521 /* _Decimal32 varargs are located in the second word of the 64-bit
8522 FP register for 32-bit binaries. */
8523 if (!TARGET_POWERPC64
8524 && TARGET_HARD_FLOAT && TARGET_FPRS
8525 && TYPE_MODE (type) == SDmode)
8526 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8528 gimplify_assign (addr, t, pre_p);
8530 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8532 stmt = gimple_build_label (lab_false);
8533 gimple_seq_add_stmt (pre_p, stmt);
8535 if ((n_reg == 2 && !regalign) || n_reg > 2)
8537 /* Ensure that we don't find any more args in regs.
8538 Alignment has taken care of for special cases. */
8539 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8543 /* ... otherwise out of the overflow area. */
8545 /* Care for on-stack alignment if needed. */
8549 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8550 t = fold_convert (sizetype, t);
8551 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8553 t = fold_convert (TREE_TYPE (ovf), t);
8555 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8557 gimplify_assign (unshare_expr (addr), t, pre_p);
8559 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8560 gimplify_assign (unshare_expr (ovf), t, pre_p);
8564 stmt = gimple_build_label (lab_over);
8565 gimple_seq_add_stmt (pre_p, stmt);
8568 if (STRICT_ALIGNMENT
8569 && (TYPE_ALIGN (type)
8570 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8572 /* The value (of type complex double, for example) may not be
8573 aligned in memory in the saved registers, so copy via a
8574 temporary. (This is the same code as used for SPARC.) */
8575 tree tmp = create_tmp_var (type, "va_arg_tmp");
8576 tree dest_addr = build_fold_addr_expr (tmp);
8578 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8579 3, dest_addr, addr, size_int (rsize * 4));
8581 gimplify_and_add (copy, pre_p);
8585 addr = fold_convert (ptrtype, addr);
8586 return build_va_arg_indirect_ref (addr);
8592 def_builtin (int mask, const char *name, tree type, int code)
8594 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8597 if (rs6000_builtin_decls[code])
8598 fatal_error ("internal error: builtin function to %s already processed.",
8601 rs6000_builtin_decls[code] = t =
8602 add_builtin_function (name, type, code, BUILT_IN_MD,
8605 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
8606 switch (builtin_classify[code])
8611 /* assume builtin can do anything. */
8612 case RS6000_BTC_MISC:
8615 /* const function, function only depends on the inputs. */
8616 case RS6000_BTC_CONST:
8617 TREE_READONLY (t) = 1;
8618 TREE_NOTHROW (t) = 1;
8621 /* pure function, function can read global memory. */
8622 case RS6000_BTC_PURE:
8623 DECL_PURE_P (t) = 1;
8624 TREE_NOTHROW (t) = 1;
8627 /* Function is a math function. If rounding mode is on, then treat
8628 the function as not reading global memory, but it can have
8629 arbitrary side effects. If it is off, then assume the function is
8630 a const function. This mimics the ATTR_MATHFN_FPROUNDING
8631 attribute in builtin-attribute.def that is used for the math
8633 case RS6000_BTC_FP_PURE:
8634 TREE_NOTHROW (t) = 1;
8635 if (flag_rounding_math)
8637 DECL_PURE_P (t) = 1;
8638 DECL_IS_NOVOPS (t) = 1;
8641 TREE_READONLY (t) = 1;
8647 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
8649 static const struct builtin_description bdesc_3arg[] =
8651 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
8652 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
8653 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
8654 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
8655 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
8656 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
8657 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
8658 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
8659 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
8660 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
8661 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
8662 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
8663 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
8664 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
8665 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
8666 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
8667 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
8668 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
8669 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
8670 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
8671 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
8672 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
8673 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
8674 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
8675 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
8676 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
8677 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
8678 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
8679 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
8680 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
8681 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
8682 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
8683 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
8684 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
8685 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
8687 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
8688 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
8689 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
8690 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
8691 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
8692 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
8693 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
8694 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
8695 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
8696 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
8697 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
8698 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
8699 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
8700 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
8701 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
8703 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
8704 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
8705 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
8706 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
8708 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
8709 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
8710 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
8711 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
8713 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
8714 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
8716 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
8717 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
8718 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
8719 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
8720 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
8721 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
8722 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
8723 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
8724 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
8725 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
8727 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
8728 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
8729 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
8730 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
8731 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
8732 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
8733 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
8734 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
8735 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
8736 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
8738 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
8739 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
8740 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
8741 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
8742 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
8743 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
8744 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
8745 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
8746 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
8748 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
8749 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
8750 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
8751 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
8752 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
8753 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
8754 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
8756 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
8757 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
8758 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
8759 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
8760 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
8761 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
8762 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
8763 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
8764 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
8767 /* DST operations: void foo (void *, const int, const char). */
8769 static const struct builtin_description bdesc_dst[] =
8771 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
8772 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
8773 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
8774 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
8776 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
8777 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
8778 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
8779 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
8782 /* Simple binary operations: VECc = foo (VECa, VECb). */
8784 static struct builtin_description bdesc_2arg[] =
8786 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
8787 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
8788 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
8789 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
8790 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
8791 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
8792 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
8793 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
8794 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
8795 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
8796 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
8797 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
8798 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
8799 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
8800 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
8801 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
8802 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
8803 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
8804 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
8805 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
8806 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
8807 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
8808 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
8809 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
8810 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
8811 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
8812 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
8813 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
8814 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
8815 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
8816 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
8817 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
8818 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
8819 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
8820 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
8821 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
8822 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
8823 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
8824 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
8825 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
8826 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
8827 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
8828 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
8829 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
8830 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
8831 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
8832 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
8833 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
8834 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
8835 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
8836 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
8837 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
8838 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
8839 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
8840 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
8841 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
8842 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
8843 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
8844 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
8845 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
8846 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
8847 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
8848 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
8849 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
8850 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
8851 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
8852 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
8853 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
8854 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
8855 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
8856 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
8857 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
8858 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
8859 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
8860 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
8861 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
8862 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
8863 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
8864 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
8865 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
8866 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
8867 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
8868 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
8869 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
8870 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
8871 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
8872 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
8873 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
8874 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
8875 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
8876 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
8877 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
8878 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
8879 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
8880 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
8881 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
8882 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
8883 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
8884 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
8885 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
8886 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
8887 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
8888 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
8889 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
8890 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
8891 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
8892 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
8893 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
8894 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
8895 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
8896 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
8897 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
8898 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
8899 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
8900 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
8901 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
8903 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
8904 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
8905 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
8906 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
8907 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
8908 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
8909 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
8910 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
8911 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
8912 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
8913 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
8915 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
8916 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
8917 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
8918 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
8919 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
8920 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
8921 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
8922 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
8923 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
8924 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
8925 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
8927 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
8928 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
8929 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
8930 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
8931 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
8932 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
8934 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
8935 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
8936 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
8937 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
8938 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
8939 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
8940 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
8941 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
8942 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
8943 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
8944 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
8945 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
8947 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
8948 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
8949 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
8950 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
8951 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
8952 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
8953 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
8954 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
8955 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
8956 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
8957 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
8958 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
8959 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
8960 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
8961 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
8962 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
8963 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
8964 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
8965 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
8966 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
8967 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
8968 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
8969 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
8970 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
8971 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
8972 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
8973 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
8974 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
8975 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
8976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
8977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
8978 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
8979 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
8980 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
8981 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
8982 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
8983 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
8984 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
8985 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
8986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
8987 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
8988 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
8989 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
8990 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
8991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
8992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
8993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
8994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
8995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
8996 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
8997 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
8998 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
8999 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9000 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9003 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9004 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9014 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9015 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9016 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9017 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9018 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9019 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9020 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9021 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9022 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9023 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9024 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9025 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9026 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9027 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9029 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9030 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9032 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9033 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9034 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9035 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9036 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9037 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9038 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9039 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9040 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9041 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9042 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9043 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9044 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9045 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9046 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9047 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9048 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9049 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9050 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9051 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9052 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9053 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9054 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9055 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9056 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9057 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9058 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9059 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9060 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9061 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9062 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9063 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9064 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9065 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9066 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9067 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9068 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9069 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9070 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9071 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9072 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9073 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9074 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9076 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9077 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9079 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9080 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9081 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9082 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9083 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9084 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9085 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9086 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9087 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9088 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9090 /* Place holder, leave as first spe builtin. */
9091 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9092 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9093 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9094 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9095 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9096 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9097 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9098 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9099 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9100 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9101 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9102 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9103 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9104 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9105 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9106 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9107 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9108 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9109 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9110 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9111 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9112 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9113 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9114 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9115 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9116 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9117 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9118 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9119 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9120 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9121 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9122 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9123 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9124 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9125 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9126 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9127 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9128 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9129 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9130 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9131 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9132 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9133 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9134 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9135 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9136 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9137 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9138 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9139 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9140 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9141 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9142 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9143 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9144 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9145 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9146 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9147 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9148 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9149 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9150 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9151 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9152 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9153 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9154 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9155 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9156 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9157 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9158 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9159 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9160 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9161 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9162 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9163 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9164 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9165 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9166 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9167 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9168 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9169 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9170 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9171 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9172 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9173 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9174 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9175 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9176 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9177 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9178 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9179 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9180 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9181 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9182 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9183 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9184 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9185 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9186 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9187 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9188 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9189 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9190 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9191 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9192 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9193 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9194 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9195 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9196 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9197 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9198 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9199 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9201 /* SPE binary operations expecting a 5-bit unsigned literal. */
9202 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9204 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9205 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9206 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9207 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9208 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9209 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9210 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9211 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9212 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9213 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9214 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9215 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9216 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9217 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9218 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9219 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9220 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9221 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9222 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9223 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9224 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9225 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9226 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9227 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9228 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9229 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9231 /* Place-holder. Leave as last binary SPE builtin. */
9232 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9235 /* AltiVec predicates. */
9237 struct builtin_description_predicates
9239 const unsigned int mask;
9240 const enum insn_code icode;
9241 const char *const name;
9242 const enum rs6000_builtins code;
9245 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9247 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9248 ALTIVEC_BUILTIN_VCMPBFP_P },
9249 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9250 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9251 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9252 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9253 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9254 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9255 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9256 ALTIVEC_BUILTIN_VCMPEQUW_P },
9257 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9258 ALTIVEC_BUILTIN_VCMPGTSW_P },
9259 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9260 ALTIVEC_BUILTIN_VCMPGTUW_P },
9261 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9262 ALTIVEC_BUILTIN_VCMPEQUH_P },
9263 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9264 ALTIVEC_BUILTIN_VCMPGTSH_P },
9265 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9266 ALTIVEC_BUILTIN_VCMPGTUH_P },
9267 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9268 ALTIVEC_BUILTIN_VCMPEQUB_P },
9269 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9270 ALTIVEC_BUILTIN_VCMPGTSB_P },
9271 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9272 ALTIVEC_BUILTIN_VCMPGTUB_P },
9274 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9275 VSX_BUILTIN_XVCMPEQSP_P },
9276 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9277 VSX_BUILTIN_XVCMPGESP_P },
9278 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9279 VSX_BUILTIN_XVCMPGTSP_P },
9280 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9281 VSX_BUILTIN_XVCMPEQDP_P },
9282 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9283 VSX_BUILTIN_XVCMPGEDP_P },
9284 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9285 VSX_BUILTIN_XVCMPGTDP_P },
9287 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9288 ALTIVEC_BUILTIN_VCMPEQ_P },
9289 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9290 ALTIVEC_BUILTIN_VCMPGT_P },
9291 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9292 ALTIVEC_BUILTIN_VCMPGE_P }
9295 /* SPE predicates. */
9296 static struct builtin_description bdesc_spe_predicates[] =
9298 /* Place-holder. Leave as first. */
9299 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9300 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9301 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9302 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9303 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9304 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9305 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9306 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9307 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9308 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9309 /* Place-holder. Leave as last. */
9310 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9313 /* SPE evsel predicates. */
9314 static struct builtin_description bdesc_spe_evsel[] =
9316 /* Place-holder. Leave as first. */
9317 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9318 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9319 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9320 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9321 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9322 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9323 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9324 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9325 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9326 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9327 /* Place-holder. Leave as last. */
9328 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9331 /* PAIRED predicates. */
9332 static const struct builtin_description bdesc_paired_preds[] =
9334 /* Place-holder. Leave as first. */
9335 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9336 /* Place-holder. Leave as last. */
9337 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9340 /* ABS* operations. */
9342 static const struct builtin_description bdesc_abs[] =
9344 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9345 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9346 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9347 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9348 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9349 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9350 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9351 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9352 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9353 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9354 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9357 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9360 static struct builtin_description bdesc_1arg[] =
9362 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9363 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9364 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9365 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9366 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9367 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9368 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9369 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9370 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9371 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9372 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9373 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9374 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9375 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9376 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9377 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9378 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9380 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9381 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9382 { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9383 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9384 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9385 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9387 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9388 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9389 { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9390 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9391 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9392 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9394 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9395 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9396 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9397 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9398 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9399 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9401 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9402 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9403 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9404 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9405 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9406 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9408 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9409 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9410 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9411 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9413 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9414 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9415 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9416 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9417 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9418 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9419 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9420 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9421 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9423 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9424 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9425 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9426 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9427 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9428 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9429 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9430 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9431 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9433 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9434 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9435 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9436 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9437 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9439 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9440 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9441 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9442 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9443 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9444 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9445 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9446 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9447 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9448 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9449 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9450 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9453 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9454 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9455 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9456 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9457 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9459 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9460 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9461 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9463 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9464 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9465 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9466 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9468 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9469 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9470 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9471 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9472 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9473 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9474 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9475 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9476 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9477 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9478 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9479 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9480 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9481 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9482 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9483 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9484 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9485 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9486 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9487 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9488 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9489 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9490 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9491 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9492 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9493 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9494 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9495 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9496 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9497 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9499 /* Place-holder. Leave as last unary SPE builtin. */
9500 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9502 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9503 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9504 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9505 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9506 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9510 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9513 tree arg0 = CALL_EXPR_ARG (exp, 0);
9514 rtx op0 = expand_normal (arg0);
9515 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9516 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9518 if (icode == CODE_FOR_nothing)
9519 /* Builtin not supported on this processor. */
9522 /* If we got invalid arguments bail out before generating bad rtl. */
9523 if (arg0 == error_mark_node)
9526 if (icode == CODE_FOR_altivec_vspltisb
9527 || icode == CODE_FOR_altivec_vspltish
9528 || icode == CODE_FOR_altivec_vspltisw
9529 || icode == CODE_FOR_spe_evsplatfi
9530 || icode == CODE_FOR_spe_evsplati)
9532 /* Only allow 5-bit *signed* literals. */
9533 if (GET_CODE (op0) != CONST_INT
9534 || INTVAL (op0) > 15
9535 || INTVAL (op0) < -16)
9537 error ("argument 1 must be a 5-bit signed literal");
9543 || GET_MODE (target) != tmode
9544 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9545 target = gen_reg_rtx (tmode);
9547 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9548 op0 = copy_to_mode_reg (mode0, op0);
9550 pat = GEN_FCN (icode) (target, op0);
9559 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9561 rtx pat, scratch1, scratch2;
9562 tree arg0 = CALL_EXPR_ARG (exp, 0);
9563 rtx op0 = expand_normal (arg0);
9564 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9565 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9567 /* If we have invalid arguments, bail out before generating bad rtl. */
9568 if (arg0 == error_mark_node)
9572 || GET_MODE (target) != tmode
9573 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9574 target = gen_reg_rtx (tmode);
9576 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9577 op0 = copy_to_mode_reg (mode0, op0);
9579 scratch1 = gen_reg_rtx (mode0);
9580 scratch2 = gen_reg_rtx (mode0);
9582 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9591 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
9594 tree arg0 = CALL_EXPR_ARG (exp, 0);
9595 tree arg1 = CALL_EXPR_ARG (exp, 1);
9596 rtx op0 = expand_normal (arg0);
9597 rtx op1 = expand_normal (arg1);
9598 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9599 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9600 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9602 if (icode == CODE_FOR_nothing)
9603 /* Builtin not supported on this processor. */
9606 /* If we got invalid arguments bail out before generating bad rtl. */
9607 if (arg0 == error_mark_node || arg1 == error_mark_node)
9610 if (icode == CODE_FOR_altivec_vcfux
9611 || icode == CODE_FOR_altivec_vcfsx
9612 || icode == CODE_FOR_altivec_vctsxs
9613 || icode == CODE_FOR_altivec_vctuxs
9614 || icode == CODE_FOR_altivec_vspltb
9615 || icode == CODE_FOR_altivec_vsplth
9616 || icode == CODE_FOR_altivec_vspltw
9617 || icode == CODE_FOR_spe_evaddiw
9618 || icode == CODE_FOR_spe_evldd
9619 || icode == CODE_FOR_spe_evldh
9620 || icode == CODE_FOR_spe_evldw
9621 || icode == CODE_FOR_spe_evlhhesplat
9622 || icode == CODE_FOR_spe_evlhhossplat
9623 || icode == CODE_FOR_spe_evlhhousplat
9624 || icode == CODE_FOR_spe_evlwhe
9625 || icode == CODE_FOR_spe_evlwhos
9626 || icode == CODE_FOR_spe_evlwhou
9627 || icode == CODE_FOR_spe_evlwhsplat
9628 || icode == CODE_FOR_spe_evlwwsplat
9629 || icode == CODE_FOR_spe_evrlwi
9630 || icode == CODE_FOR_spe_evslwi
9631 || icode == CODE_FOR_spe_evsrwis
9632 || icode == CODE_FOR_spe_evsubifw
9633 || icode == CODE_FOR_spe_evsrwiu)
9635 /* Only allow 5-bit unsigned literals. */
9637 if (TREE_CODE (arg1) != INTEGER_CST
9638 || TREE_INT_CST_LOW (arg1) & ~0x1f)
9640 error ("argument 2 must be a 5-bit unsigned literal");
9646 || GET_MODE (target) != tmode
9647 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9648 target = gen_reg_rtx (tmode);
9650 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9651 op0 = copy_to_mode_reg (mode0, op0);
9652 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9653 op1 = copy_to_mode_reg (mode1, op1);
9655 pat = GEN_FCN (icode) (target, op0, op1);
9664 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
9667 tree cr6_form = CALL_EXPR_ARG (exp, 0);
9668 tree arg0 = CALL_EXPR_ARG (exp, 1);
9669 tree arg1 = CALL_EXPR_ARG (exp, 2);
9670 rtx op0 = expand_normal (arg0);
9671 rtx op1 = expand_normal (arg1);
9672 enum machine_mode tmode = SImode;
9673 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9674 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9677 if (TREE_CODE (cr6_form) != INTEGER_CST)
9679 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9683 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
9685 gcc_assert (mode0 == mode1);
9687 /* If we have invalid arguments, bail out before generating bad rtl. */
9688 if (arg0 == error_mark_node || arg1 == error_mark_node)
9692 || GET_MODE (target) != tmode
9693 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9694 target = gen_reg_rtx (tmode);
9696 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9697 op0 = copy_to_mode_reg (mode0, op0);
9698 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9699 op1 = copy_to_mode_reg (mode1, op1);
9701 scratch = gen_reg_rtx (mode0);
9703 pat = GEN_FCN (icode) (scratch, op0, op1);
9708 /* The vec_any* and vec_all* predicates use the same opcodes for two
9709 different operations, but the bits in CR6 will be different
9710 depending on what information we want. So we have to play tricks
9711 with CR6 to get the right bits out.
9713 If you think this is disgusting, look at the specs for the
9714 AltiVec predicates. */
9716 switch (cr6_form_int)
9719 emit_insn (gen_cr6_test_for_zero (target));
9722 emit_insn (gen_cr6_test_for_zero_reverse (target));
9725 emit_insn (gen_cr6_test_for_lt (target));
9728 emit_insn (gen_cr6_test_for_lt_reverse (target));
9731 error ("argument 1 of __builtin_altivec_predicate is out of range");
9739 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
9742 tree arg0 = CALL_EXPR_ARG (exp, 0);
9743 tree arg1 = CALL_EXPR_ARG (exp, 1);
9744 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9745 enum machine_mode mode0 = Pmode;
9746 enum machine_mode mode1 = Pmode;
9747 rtx op0 = expand_normal (arg0);
9748 rtx op1 = expand_normal (arg1);
9750 if (icode == CODE_FOR_nothing)
9751 /* Builtin not supported on this processor. */
9754 /* If we got invalid arguments bail out before generating bad rtl. */
9755 if (arg0 == error_mark_node || arg1 == error_mark_node)
9759 || GET_MODE (target) != tmode
9760 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9761 target = gen_reg_rtx (tmode);
9763 op1 = copy_to_mode_reg (mode1, op1);
9765 if (op0 == const0_rtx)
9767 addr = gen_rtx_MEM (tmode, op1);
9771 op0 = copy_to_mode_reg (mode0, op0);
9772 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
9775 pat = GEN_FCN (icode) (target, addr);
9785 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
9788 tree arg0 = CALL_EXPR_ARG (exp, 0);
9789 tree arg1 = CALL_EXPR_ARG (exp, 1);
9790 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9791 enum machine_mode mode0 = Pmode;
9792 enum machine_mode mode1 = Pmode;
9793 rtx op0 = expand_normal (arg0);
9794 rtx op1 = expand_normal (arg1);
9796 if (icode == CODE_FOR_nothing)
9797 /* Builtin not supported on this processor. */
9800 /* If we got invalid arguments bail out before generating bad rtl. */
9801 if (arg0 == error_mark_node || arg1 == error_mark_node)
9805 || GET_MODE (target) != tmode
9806 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9807 target = gen_reg_rtx (tmode);
9809 op1 = copy_to_mode_reg (mode1, op1);
9811 if (op0 == const0_rtx)
9813 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
9817 op0 = copy_to_mode_reg (mode0, op0);
9818 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
9821 pat = GEN_FCN (icode) (target, addr);
9831 spe_expand_stv_builtin (enum insn_code icode, tree exp)
9833 tree arg0 = CALL_EXPR_ARG (exp, 0);
9834 tree arg1 = CALL_EXPR_ARG (exp, 1);
9835 tree arg2 = CALL_EXPR_ARG (exp, 2);
9836 rtx op0 = expand_normal (arg0);
9837 rtx op1 = expand_normal (arg1);
9838 rtx op2 = expand_normal (arg2);
9840 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
9841 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
9842 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
9844 /* Invalid arguments. Bail before doing anything stoopid! */
9845 if (arg0 == error_mark_node
9846 || arg1 == error_mark_node
9847 || arg2 == error_mark_node)
9850 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
9851 op0 = copy_to_mode_reg (mode2, op0);
9852 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
9853 op1 = copy_to_mode_reg (mode0, op1);
9854 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
9855 op2 = copy_to_mode_reg (mode1, op2);
9857 pat = GEN_FCN (icode) (op1, op2, op0);
9864 paired_expand_stv_builtin (enum insn_code icode, tree exp)
9866 tree arg0 = CALL_EXPR_ARG (exp, 0);
9867 tree arg1 = CALL_EXPR_ARG (exp, 1);
9868 tree arg2 = CALL_EXPR_ARG (exp, 2);
9869 rtx op0 = expand_normal (arg0);
9870 rtx op1 = expand_normal (arg1);
9871 rtx op2 = expand_normal (arg2);
9873 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9874 enum machine_mode mode1 = Pmode;
9875 enum machine_mode mode2 = Pmode;
9877 /* Invalid arguments. Bail before doing anything stoopid! */
9878 if (arg0 == error_mark_node
9879 || arg1 == error_mark_node
9880 || arg2 == error_mark_node)
9883 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9884 op0 = copy_to_mode_reg (tmode, op0);
9886 op2 = copy_to_mode_reg (mode2, op2);
9888 if (op1 == const0_rtx)
9890 addr = gen_rtx_MEM (tmode, op2);
9894 op1 = copy_to_mode_reg (mode1, op1);
9895 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9898 pat = GEN_FCN (icode) (addr, op0);
9905 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
9907 tree arg0 = CALL_EXPR_ARG (exp, 0);
9908 tree arg1 = CALL_EXPR_ARG (exp, 1);
9909 tree arg2 = CALL_EXPR_ARG (exp, 2);
9910 rtx op0 = expand_normal (arg0);
9911 rtx op1 = expand_normal (arg1);
9912 rtx op2 = expand_normal (arg2);
9914 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9915 enum machine_mode mode1 = Pmode;
9916 enum machine_mode mode2 = Pmode;
9918 /* Invalid arguments. Bail before doing anything stoopid! */
9919 if (arg0 == error_mark_node
9920 || arg1 == error_mark_node
9921 || arg2 == error_mark_node)
9924 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9925 op0 = copy_to_mode_reg (tmode, op0);
9927 op2 = copy_to_mode_reg (mode2, op2);
9929 if (op1 == const0_rtx)
9931 addr = gen_rtx_MEM (tmode, op2);
9935 op1 = copy_to_mode_reg (mode1, op1);
9936 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9939 pat = GEN_FCN (icode) (addr, op0);
9946 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
9949 tree arg0 = CALL_EXPR_ARG (exp, 0);
9950 tree arg1 = CALL_EXPR_ARG (exp, 1);
9951 tree arg2 = CALL_EXPR_ARG (exp, 2);
9952 rtx op0 = expand_normal (arg0);
9953 rtx op1 = expand_normal (arg1);
9954 rtx op2 = expand_normal (arg2);
9955 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9956 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9957 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9958 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
9960 if (icode == CODE_FOR_nothing)
9961 /* Builtin not supported on this processor. */
9964 /* If we got invalid arguments bail out before generating bad rtl. */
9965 if (arg0 == error_mark_node
9966 || arg1 == error_mark_node
9967 || arg2 == error_mark_node)
9972 case CODE_FOR_altivec_vsldoi_v4sf:
9973 case CODE_FOR_altivec_vsldoi_v4si:
9974 case CODE_FOR_altivec_vsldoi_v8hi:
9975 case CODE_FOR_altivec_vsldoi_v16qi:
9976 /* Only allow 4-bit unsigned literals. */
9978 if (TREE_CODE (arg2) != INTEGER_CST
9979 || TREE_INT_CST_LOW (arg2) & ~0xf)
9981 error ("argument 3 must be a 4-bit unsigned literal");
9986 case CODE_FOR_vsx_xxpermdi_v2df:
9987 case CODE_FOR_vsx_xxpermdi_v2di:
9988 case CODE_FOR_vsx_xxsldwi_v16qi:
9989 case CODE_FOR_vsx_xxsldwi_v8hi:
9990 case CODE_FOR_vsx_xxsldwi_v4si:
9991 case CODE_FOR_vsx_xxsldwi_v4sf:
9992 case CODE_FOR_vsx_xxsldwi_v2di:
9993 case CODE_FOR_vsx_xxsldwi_v2df:
9994 /* Only allow 2-bit unsigned literals. */
9996 if (TREE_CODE (arg2) != INTEGER_CST
9997 || TREE_INT_CST_LOW (arg2) & ~0x3)
9999 error ("argument 3 must be a 2-bit unsigned literal");
10004 case CODE_FOR_vsx_set_v2df:
10005 case CODE_FOR_vsx_set_v2di:
10006 /* Only allow 1-bit unsigned literals. */
10008 if (TREE_CODE (arg2) != INTEGER_CST
10009 || TREE_INT_CST_LOW (arg2) & ~0x1)
10011 error ("argument 3 must be a 1-bit unsigned literal");
10021 || GET_MODE (target) != tmode
10022 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10023 target = gen_reg_rtx (tmode);
10025 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10026 op0 = copy_to_mode_reg (mode0, op0);
10027 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10028 op1 = copy_to_mode_reg (mode1, op1);
10029 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10030 op2 = copy_to_mode_reg (mode2, op2);
10032 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10033 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10035 pat = GEN_FCN (icode) (target, op0, op1, op2);
10043 /* Expand the lvx builtins. */
10045 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10047 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10048 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10050 enum machine_mode tmode, mode0;
10052 enum insn_code icode;
10056 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10057 icode = CODE_FOR_vector_load_v16qi;
10059 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10060 icode = CODE_FOR_vector_load_v8hi;
10062 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10063 icode = CODE_FOR_vector_load_v4si;
10065 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10066 icode = CODE_FOR_vector_load_v4sf;
10069 *expandedp = false;
10075 arg0 = CALL_EXPR_ARG (exp, 0);
10076 op0 = expand_normal (arg0);
10077 tmode = insn_data[icode].operand[0].mode;
10078 mode0 = insn_data[icode].operand[1].mode;
10081 || GET_MODE (target) != tmode
10082 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10083 target = gen_reg_rtx (tmode);
10085 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10086 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10088 pat = GEN_FCN (icode) (target, op0);
10095 /* Expand the stvx builtins. */
10097 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10100 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10101 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10103 enum machine_mode mode0, mode1;
10105 enum insn_code icode;
10109 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10110 icode = CODE_FOR_vector_store_v16qi;
10112 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10113 icode = CODE_FOR_vector_store_v8hi;
10115 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10116 icode = CODE_FOR_vector_store_v4si;
10118 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10119 icode = CODE_FOR_vector_store_v4sf;
10122 *expandedp = false;
10126 arg0 = CALL_EXPR_ARG (exp, 0);
10127 arg1 = CALL_EXPR_ARG (exp, 1);
10128 op0 = expand_normal (arg0);
10129 op1 = expand_normal (arg1);
10130 mode0 = insn_data[icode].operand[0].mode;
10131 mode1 = insn_data[icode].operand[1].mode;
10133 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10134 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10135 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10136 op1 = copy_to_mode_reg (mode1, op1);
10138 pat = GEN_FCN (icode) (op0, op1);
10146 /* Expand the dst builtins. */
10148 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10151 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10152 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10153 tree arg0, arg1, arg2;
10154 enum machine_mode mode0, mode1;
10155 rtx pat, op0, op1, op2;
10156 const struct builtin_description *d;
10159 *expandedp = false;
10161 /* Handle DST variants. */
10163 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10164 if (d->code == fcode)
10166 arg0 = CALL_EXPR_ARG (exp, 0);
10167 arg1 = CALL_EXPR_ARG (exp, 1);
10168 arg2 = CALL_EXPR_ARG (exp, 2);
10169 op0 = expand_normal (arg0);
10170 op1 = expand_normal (arg1);
10171 op2 = expand_normal (arg2);
10172 mode0 = insn_data[d->icode].operand[0].mode;
10173 mode1 = insn_data[d->icode].operand[1].mode;
10175 /* Invalid arguments, bail out before generating bad rtl. */
10176 if (arg0 == error_mark_node
10177 || arg1 == error_mark_node
10178 || arg2 == error_mark_node)
10183 if (TREE_CODE (arg2) != INTEGER_CST
10184 || TREE_INT_CST_LOW (arg2) & ~0x3)
10186 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10190 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10191 op0 = copy_to_mode_reg (Pmode, op0);
10192 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10193 op1 = copy_to_mode_reg (mode1, op1);
10195 pat = GEN_FCN (d->icode) (op0, op1, op2);
10205 /* Expand vec_init builtin. */
10207 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10209 enum machine_mode tmode = TYPE_MODE (type);
10210 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10211 int i, n_elt = GET_MODE_NUNITS (tmode);
10212 rtvec v = rtvec_alloc (n_elt);
10214 gcc_assert (VECTOR_MODE_P (tmode));
10215 gcc_assert (n_elt == call_expr_nargs (exp));
10217 for (i = 0; i < n_elt; ++i)
10219 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10220 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10223 if (!target || !register_operand (target, tmode))
10224 target = gen_reg_rtx (tmode);
10226 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10230 /* Return the integer constant in ARG. Constrain it to be in the range
10231 of the subparts of VEC_TYPE; issue an error if not. */
10234 get_element_number (tree vec_type, tree arg)
10236 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10238 if (!host_integerp (arg, 1)
10239 || (elt = tree_low_cst (arg, 1), elt > max))
10241 error ("selector must be an integer constant in the range 0..%wi", max);
10248 /* Expand vec_set builtin. */
10250 altivec_expand_vec_set_builtin (tree exp)
10252 enum machine_mode tmode, mode1;
10253 tree arg0, arg1, arg2;
10257 arg0 = CALL_EXPR_ARG (exp, 0);
10258 arg1 = CALL_EXPR_ARG (exp, 1);
10259 arg2 = CALL_EXPR_ARG (exp, 2);
10261 tmode = TYPE_MODE (TREE_TYPE (arg0));
10262 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10263 gcc_assert (VECTOR_MODE_P (tmode));
10265 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10266 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10267 elt = get_element_number (TREE_TYPE (arg0), arg2);
10269 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10270 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10272 op0 = force_reg (tmode, op0);
10273 op1 = force_reg (mode1, op1);
10275 rs6000_expand_vector_set (op0, op1, elt);
10280 /* Expand vec_ext builtin. */
10282 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10284 enum machine_mode tmode, mode0;
10289 arg0 = CALL_EXPR_ARG (exp, 0);
10290 arg1 = CALL_EXPR_ARG (exp, 1);
10292 op0 = expand_normal (arg0);
10293 elt = get_element_number (TREE_TYPE (arg0), arg1);
10295 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10296 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10297 gcc_assert (VECTOR_MODE_P (mode0));
10299 op0 = force_reg (mode0, op0);
10301 if (optimize || !target || !register_operand (target, tmode))
10302 target = gen_reg_rtx (tmode);
10304 rs6000_expand_vector_extract (target, op0, elt);
10309 /* Expand the builtin in EXP and store the result in TARGET. Store
10310 true in *EXPANDEDP if we found a builtin to expand. */
10312 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10314 const struct builtin_description *d;
10315 const struct builtin_description_predicates *dp;
10317 enum insn_code icode;
10318 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10321 enum machine_mode tmode, mode0;
10322 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10324 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10325 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10326 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10327 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10330 error ("unresolved overload for Altivec builtin %qF", fndecl);
10334 target = altivec_expand_ld_builtin (exp, target, expandedp);
10338 target = altivec_expand_st_builtin (exp, target, expandedp);
10342 target = altivec_expand_dst_builtin (exp, target, expandedp);
10350 case ALTIVEC_BUILTIN_STVX:
10351 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10352 case ALTIVEC_BUILTIN_STVEBX:
10353 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10354 case ALTIVEC_BUILTIN_STVEHX:
10355 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10356 case ALTIVEC_BUILTIN_STVEWX:
10357 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10358 case ALTIVEC_BUILTIN_STVXL:
10359 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10361 case ALTIVEC_BUILTIN_STVLX:
10362 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10363 case ALTIVEC_BUILTIN_STVLXL:
10364 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10365 case ALTIVEC_BUILTIN_STVRX:
10366 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10367 case ALTIVEC_BUILTIN_STVRXL:
10368 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10370 case ALTIVEC_BUILTIN_MFVSCR:
10371 icode = CODE_FOR_altivec_mfvscr;
10372 tmode = insn_data[icode].operand[0].mode;
10375 || GET_MODE (target) != tmode
10376 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10377 target = gen_reg_rtx (tmode);
10379 pat = GEN_FCN (icode) (target);
10385 case ALTIVEC_BUILTIN_MTVSCR:
10386 icode = CODE_FOR_altivec_mtvscr;
10387 arg0 = CALL_EXPR_ARG (exp, 0);
10388 op0 = expand_normal (arg0);
10389 mode0 = insn_data[icode].operand[0].mode;
10391 /* If we got invalid arguments bail out before generating bad rtl. */
10392 if (arg0 == error_mark_node)
10395 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10396 op0 = copy_to_mode_reg (mode0, op0);
10398 pat = GEN_FCN (icode) (op0);
10403 case ALTIVEC_BUILTIN_DSSALL:
10404 emit_insn (gen_altivec_dssall ());
10407 case ALTIVEC_BUILTIN_DSS:
10408 icode = CODE_FOR_altivec_dss;
10409 arg0 = CALL_EXPR_ARG (exp, 0);
10411 op0 = expand_normal (arg0);
10412 mode0 = insn_data[icode].operand[0].mode;
10414 /* If we got invalid arguments bail out before generating bad rtl. */
10415 if (arg0 == error_mark_node)
10418 if (TREE_CODE (arg0) != INTEGER_CST
10419 || TREE_INT_CST_LOW (arg0) & ~0x3)
10421 error ("argument to dss must be a 2-bit unsigned literal");
10425 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10426 op0 = copy_to_mode_reg (mode0, op0);
10428 emit_insn (gen_altivec_dss (op0));
10431 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10432 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10433 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10434 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10435 case VSX_BUILTIN_VEC_INIT_V2DF:
10436 case VSX_BUILTIN_VEC_INIT_V2DI:
10437 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10439 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10440 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10441 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10442 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10443 case VSX_BUILTIN_VEC_SET_V2DF:
10444 case VSX_BUILTIN_VEC_SET_V2DI:
10445 return altivec_expand_vec_set_builtin (exp);
10447 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10448 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10449 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10450 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10451 case VSX_BUILTIN_VEC_EXT_V2DF:
10452 case VSX_BUILTIN_VEC_EXT_V2DI:
10453 return altivec_expand_vec_ext_builtin (exp, target);
10457 /* Fall through. */
10460 /* Expand abs* operations. */
10462 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10463 if (d->code == fcode)
10464 return altivec_expand_abs_builtin (d->icode, exp, target);
10466 /* Expand the AltiVec predicates. */
10467 dp = bdesc_altivec_preds;
10468 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10469 if (dp->code == fcode)
10470 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10472 /* LV* are funky. We initialized them differently. */
10475 case ALTIVEC_BUILTIN_LVSL:
10476 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10477 exp, target, false);
10478 case ALTIVEC_BUILTIN_LVSR:
10479 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10480 exp, target, false);
10481 case ALTIVEC_BUILTIN_LVEBX:
10482 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10483 exp, target, false);
10484 case ALTIVEC_BUILTIN_LVEHX:
10485 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10486 exp, target, false);
10487 case ALTIVEC_BUILTIN_LVEWX:
10488 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10489 exp, target, false);
10490 case ALTIVEC_BUILTIN_LVXL:
10491 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10492 exp, target, false);
10493 case ALTIVEC_BUILTIN_LVX:
10494 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10495 exp, target, false);
10496 case ALTIVEC_BUILTIN_LVLX:
10497 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10498 exp, target, true);
10499 case ALTIVEC_BUILTIN_LVLXL:
10500 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10501 exp, target, true);
10502 case ALTIVEC_BUILTIN_LVRX:
10503 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10504 exp, target, true);
10505 case ALTIVEC_BUILTIN_LVRXL:
10506 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10507 exp, target, true);
10510 /* Fall through. */
10513 *expandedp = false;
10517 /* Expand the builtin in EXP and store the result in TARGET. Store
10518 true in *EXPANDEDP if we found a builtin to expand. */
10520 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10522 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10523 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10524 const struct builtin_description *d;
10531 case PAIRED_BUILTIN_STX:
10532 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10533 case PAIRED_BUILTIN_LX:
10534 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10537 /* Fall through. */
10540 /* Expand the paired predicates. */
10541 d = bdesc_paired_preds;
10542 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10543 if (d->code == fcode)
10544 return paired_expand_predicate_builtin (d->icode, exp, target);
10546 *expandedp = false;
10550 /* Binops that need to be initialized manually, but can be expanded
10551 automagically by rs6000_expand_binop_builtin. */
10552 static struct builtin_description bdesc_2arg_spe[] =
10554 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10555 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10556 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10557 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10558 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10559 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10560 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10561 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10562 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10563 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10564 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10565 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10566 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10567 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10568 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10569 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10570 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10571 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10572 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10573 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10574 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10575 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10578 /* Expand the builtin in EXP and store the result in TARGET. Store
10579 true in *EXPANDEDP if we found a builtin to expand.
10581 This expands the SPE builtins that are not simple unary and binary
10584 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10586 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10588 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10589 enum insn_code icode;
10590 enum machine_mode tmode, mode0;
10592 struct builtin_description *d;
10597 /* Syntax check for a 5-bit unsigned immediate. */
10600 case SPE_BUILTIN_EVSTDD:
10601 case SPE_BUILTIN_EVSTDH:
10602 case SPE_BUILTIN_EVSTDW:
10603 case SPE_BUILTIN_EVSTWHE:
10604 case SPE_BUILTIN_EVSTWHO:
10605 case SPE_BUILTIN_EVSTWWE:
10606 case SPE_BUILTIN_EVSTWWO:
10607 arg1 = CALL_EXPR_ARG (exp, 2);
10608 if (TREE_CODE (arg1) != INTEGER_CST
10609 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10611 error ("argument 2 must be a 5-bit unsigned literal");
10619 /* The evsplat*i instructions are not quite generic. */
10622 case SPE_BUILTIN_EVSPLATFI:
10623 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
10625 case SPE_BUILTIN_EVSPLATI:
10626 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
10632 d = (struct builtin_description *) bdesc_2arg_spe;
10633 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
10634 if (d->code == fcode)
10635 return rs6000_expand_binop_builtin (d->icode, exp, target);
10637 d = (struct builtin_description *) bdesc_spe_predicates;
10638 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
10639 if (d->code == fcode)
10640 return spe_expand_predicate_builtin (d->icode, exp, target);
10642 d = (struct builtin_description *) bdesc_spe_evsel;
10643 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
10644 if (d->code == fcode)
10645 return spe_expand_evsel_builtin (d->icode, exp, target);
10649 case SPE_BUILTIN_EVSTDDX:
10650 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
10651 case SPE_BUILTIN_EVSTDHX:
10652 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
10653 case SPE_BUILTIN_EVSTDWX:
10654 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
10655 case SPE_BUILTIN_EVSTWHEX:
10656 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
10657 case SPE_BUILTIN_EVSTWHOX:
10658 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
10659 case SPE_BUILTIN_EVSTWWEX:
10660 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
10661 case SPE_BUILTIN_EVSTWWOX:
10662 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
10663 case SPE_BUILTIN_EVSTDD:
10664 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
10665 case SPE_BUILTIN_EVSTDH:
10666 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
10667 case SPE_BUILTIN_EVSTDW:
10668 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
10669 case SPE_BUILTIN_EVSTWHE:
10670 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
10671 case SPE_BUILTIN_EVSTWHO:
10672 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
10673 case SPE_BUILTIN_EVSTWWE:
10674 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
10675 case SPE_BUILTIN_EVSTWWO:
10676 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
10677 case SPE_BUILTIN_MFSPEFSCR:
10678 icode = CODE_FOR_spe_mfspefscr;
10679 tmode = insn_data[icode].operand[0].mode;
10682 || GET_MODE (target) != tmode
10683 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10684 target = gen_reg_rtx (tmode);
10686 pat = GEN_FCN (icode) (target);
10691 case SPE_BUILTIN_MTSPEFSCR:
10692 icode = CODE_FOR_spe_mtspefscr;
10693 arg0 = CALL_EXPR_ARG (exp, 0);
10694 op0 = expand_normal (arg0);
10695 mode0 = insn_data[icode].operand[0].mode;
10697 if (arg0 == error_mark_node)
10700 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10701 op0 = copy_to_mode_reg (mode0, op0);
10703 pat = GEN_FCN (icode) (op0);
10711 *expandedp = false;
10716 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10718 rtx pat, scratch, tmp;
10719 tree form = CALL_EXPR_ARG (exp, 0);
10720 tree arg0 = CALL_EXPR_ARG (exp, 1);
10721 tree arg1 = CALL_EXPR_ARG (exp, 2);
10722 rtx op0 = expand_normal (arg0);
10723 rtx op1 = expand_normal (arg1);
10724 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10725 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10727 enum rtx_code code;
10729 if (TREE_CODE (form) != INTEGER_CST)
10731 error ("argument 1 of __builtin_paired_predicate must be a constant");
10735 form_int = TREE_INT_CST_LOW (form);
10737 gcc_assert (mode0 == mode1);
10739 if (arg0 == error_mark_node || arg1 == error_mark_node)
10743 || GET_MODE (target) != SImode
10744 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
10745 target = gen_reg_rtx (SImode);
10746 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10747 op0 = copy_to_mode_reg (mode0, op0);
10748 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10749 op1 = copy_to_mode_reg (mode1, op1);
10751 scratch = gen_reg_rtx (CCFPmode);
10753 pat = GEN_FCN (icode) (scratch, op0, op1);
10775 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10778 error ("argument 1 of __builtin_paired_predicate is out of range");
10782 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10783 emit_move_insn (target, tmp);
10788 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10790 rtx pat, scratch, tmp;
10791 tree form = CALL_EXPR_ARG (exp, 0);
10792 tree arg0 = CALL_EXPR_ARG (exp, 1);
10793 tree arg1 = CALL_EXPR_ARG (exp, 2);
10794 rtx op0 = expand_normal (arg0);
10795 rtx op1 = expand_normal (arg1);
10796 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10797 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10799 enum rtx_code code;
10801 if (TREE_CODE (form) != INTEGER_CST)
10803 error ("argument 1 of __builtin_spe_predicate must be a constant");
10807 form_int = TREE_INT_CST_LOW (form);
10809 gcc_assert (mode0 == mode1);
10811 if (arg0 == error_mark_node || arg1 == error_mark_node)
10815 || GET_MODE (target) != SImode
10816 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
10817 target = gen_reg_rtx (SImode);
10819 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10820 op0 = copy_to_mode_reg (mode0, op0);
10821 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10822 op1 = copy_to_mode_reg (mode1, op1);
10824 scratch = gen_reg_rtx (CCmode);
10826 pat = GEN_FCN (icode) (scratch, op0, op1);
10831 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
10832 _lower_. We use one compare, but look in different bits of the
10833 CR for each variant.
10835 There are 2 elements in each SPE simd type (upper/lower). The CR
10836 bits are set as follows:
10838 BIT0 | BIT 1 | BIT 2 | BIT 3
10839 U | L | (U | L) | (U & L)
10841 So, for an "all" relationship, BIT 3 would be set.
10842 For an "any" relationship, BIT 2 would be set. Etc.
10844 Following traditional nomenclature, these bits map to:
10846 BIT0 | BIT 1 | BIT 2 | BIT 3
10849 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
10854 /* All variant. OV bit. */
10856 /* We need to get to the OV bit, which is the ORDERED bit. We
10857 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
10858 that's ugly and will make validate_condition_mode die.
10859 So let's just use another pattern. */
10860 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10862 /* Any variant. EQ bit. */
10866 /* Upper variant. LT bit. */
10870 /* Lower variant. GT bit. */
10875 error ("argument 1 of __builtin_spe_predicate is out of range");
10879 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10880 emit_move_insn (target, tmp);
10885 /* The evsel builtins look like this:
10887 e = __builtin_spe_evsel_OP (a, b, c, d);
10889 and work like this:
10891 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
10892 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
10896 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
10899 tree arg0 = CALL_EXPR_ARG (exp, 0);
10900 tree arg1 = CALL_EXPR_ARG (exp, 1);
10901 tree arg2 = CALL_EXPR_ARG (exp, 2);
10902 tree arg3 = CALL_EXPR_ARG (exp, 3);
10903 rtx op0 = expand_normal (arg0);
10904 rtx op1 = expand_normal (arg1);
10905 rtx op2 = expand_normal (arg2);
10906 rtx op3 = expand_normal (arg3);
10907 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10908 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10910 gcc_assert (mode0 == mode1);
10912 if (arg0 == error_mark_node || arg1 == error_mark_node
10913 || arg2 == error_mark_node || arg3 == error_mark_node)
10917 || GET_MODE (target) != mode0
10918 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
10919 target = gen_reg_rtx (mode0);
10921 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10922 op0 = copy_to_mode_reg (mode0, op0);
10923 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10924 op1 = copy_to_mode_reg (mode0, op1);
10925 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10926 op2 = copy_to_mode_reg (mode0, op2);
10927 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
10928 op3 = copy_to_mode_reg (mode0, op3);
10930 /* Generate the compare. */
10931 scratch = gen_reg_rtx (CCmode);
10932 pat = GEN_FCN (icode) (scratch, op0, op1);
10937 if (mode0 == V2SImode)
10938 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
10940 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
10945 /* Expand an expression EXP that calls a built-in function,
10946 with result going to TARGET if that's convenient
10947 (and in mode MODE if that's convenient).
10948 SUBTARGET may be used as the target for computing one of EXP's operands.
10949 IGNORE is nonzero if the value is to be ignored. */
10952 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10953 enum machine_mode mode ATTRIBUTE_UNUSED,
10954 int ignore ATTRIBUTE_UNUSED)
10956 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10957 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10958 const struct builtin_description *d;
10963 if (fcode == RS6000_BUILTIN_RECIP)
10964 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
10966 if (fcode == RS6000_BUILTIN_RECIPF)
10967 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
10969 if (fcode == RS6000_BUILTIN_RSQRTF)
10970 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
10972 if (fcode == RS6000_BUILTIN_BSWAP_HI)
10973 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
10975 if (fcode == POWER7_BUILTIN_BPERMD)
10976 return rs6000_expand_binop_builtin (((TARGET_64BIT)
10977 ? CODE_FOR_bpermd_di
10978 : CODE_FOR_bpermd_si), exp, target);
10980 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
10981 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10983 int icode = (int) CODE_FOR_altivec_lvsr;
10984 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10985 enum machine_mode mode = insn_data[icode].operand[1].mode;
10989 gcc_assert (TARGET_ALTIVEC);
10991 arg = CALL_EXPR_ARG (exp, 0);
10992 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
10993 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
10994 addr = memory_address (mode, op);
10995 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10999 /* For the load case need to negate the address. */
11000 op = gen_reg_rtx (GET_MODE (addr));
11001 emit_insn (gen_rtx_SET (VOIDmode, op,
11002 gen_rtx_NEG (GET_MODE (addr), addr)));
11004 op = gen_rtx_MEM (mode, op);
11007 || GET_MODE (target) != tmode
11008 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11009 target = gen_reg_rtx (tmode);
11011 /*pat = gen_altivec_lvsr (target, op);*/
11012 pat = GEN_FCN (icode) (target, op);
11020 /* FIXME: There's got to be a nicer way to handle this case than
11021 constructing a new CALL_EXPR. */
11022 if (fcode == ALTIVEC_BUILTIN_VCFUX
11023 || fcode == ALTIVEC_BUILTIN_VCFSX
11024 || fcode == ALTIVEC_BUILTIN_VCTUXS
11025 || fcode == ALTIVEC_BUILTIN_VCTSXS)
11027 if (call_expr_nargs (exp) == 1)
11028 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11029 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11032 if (TARGET_ALTIVEC)
11034 ret = altivec_expand_builtin (exp, target, &success);
11041 ret = spe_expand_builtin (exp, target, &success);
11046 if (TARGET_PAIRED_FLOAT)
11048 ret = paired_expand_builtin (exp, target, &success);
11054 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11056 /* Handle simple unary operations. */
11057 d = (struct builtin_description *) bdesc_1arg;
11058 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11059 if (d->code == fcode)
11060 return rs6000_expand_unop_builtin (d->icode, exp, target);
11062 /* Handle simple binary operations. */
11063 d = (struct builtin_description *) bdesc_2arg;
11064 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11065 if (d->code == fcode)
11066 return rs6000_expand_binop_builtin (d->icode, exp, target);
11068 /* Handle simple ternary operations. */
11070 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11071 if (d->code == fcode)
11072 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11074 gcc_unreachable ();
11078 rs6000_init_builtins (void)
11082 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11083 V2SF_type_node = build_vector_type (float_type_node, 2);
11084 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11085 V2DF_type_node = build_vector_type (double_type_node, 2);
11086 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11087 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11088 V4SF_type_node = build_vector_type (float_type_node, 4);
11089 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11090 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11092 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11093 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11094 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11095 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11097 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11098 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11099 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11100 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11102 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11103 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11104 'vector unsigned short'. */
11106 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11107 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11108 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11109 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11110 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11112 long_integer_type_internal_node = long_integer_type_node;
11113 long_unsigned_type_internal_node = long_unsigned_type_node;
11114 intQI_type_internal_node = intQI_type_node;
11115 uintQI_type_internal_node = unsigned_intQI_type_node;
11116 intHI_type_internal_node = intHI_type_node;
11117 uintHI_type_internal_node = unsigned_intHI_type_node;
11118 intSI_type_internal_node = intSI_type_node;
11119 uintSI_type_internal_node = unsigned_intSI_type_node;
11120 intDI_type_internal_node = intDI_type_node;
11121 uintDI_type_internal_node = unsigned_intDI_type_node;
11122 float_type_internal_node = float_type_node;
11123 double_type_internal_node = float_type_node;
11124 void_type_internal_node = void_type_node;
11126 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11128 builtin_mode_to_type[QImode][0] = integer_type_node;
11129 builtin_mode_to_type[HImode][0] = integer_type_node;
11130 builtin_mode_to_type[SImode][0] = intSI_type_node;
11131 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
11132 builtin_mode_to_type[DImode][0] = intDI_type_node;
11133 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
11134 builtin_mode_to_type[SFmode][0] = float_type_node;
11135 builtin_mode_to_type[DFmode][0] = double_type_node;
11136 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
11137 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
11138 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
11139 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
11140 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
11141 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
11142 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11143 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11144 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11145 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11146 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11147 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11148 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11150 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11151 get_identifier ("__bool char"),
11152 bool_char_type_node);
11153 TYPE_NAME (bool_char_type_node) = tdecl;
11154 (*lang_hooks.decls.pushdecl) (tdecl);
11155 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11156 get_identifier ("__bool short"),
11157 bool_short_type_node);
11158 TYPE_NAME (bool_short_type_node) = tdecl;
11159 (*lang_hooks.decls.pushdecl) (tdecl);
11160 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11161 get_identifier ("__bool int"),
11162 bool_int_type_node);
11163 TYPE_NAME (bool_int_type_node) = tdecl;
11164 (*lang_hooks.decls.pushdecl) (tdecl);
11165 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
11167 TYPE_NAME (pixel_type_node) = tdecl;
11168 (*lang_hooks.decls.pushdecl) (tdecl);
11170 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
11171 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11172 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11173 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11174 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11176 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11177 get_identifier ("__vector unsigned char"),
11178 unsigned_V16QI_type_node);
11179 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11180 (*lang_hooks.decls.pushdecl) (tdecl);
11181 tdecl = build_decl (BUILTINS_LOCATION,
11182 TYPE_DECL, get_identifier ("__vector signed char"),
11184 TYPE_NAME (V16QI_type_node) = tdecl;
11185 (*lang_hooks.decls.pushdecl) (tdecl);
11186 tdecl = build_decl (BUILTINS_LOCATION,
11187 TYPE_DECL, get_identifier ("__vector __bool char"),
11188 bool_V16QI_type_node);
11189 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11190 (*lang_hooks.decls.pushdecl) (tdecl);
11192 tdecl = build_decl (BUILTINS_LOCATION,
11193 TYPE_DECL, get_identifier ("__vector unsigned short"),
11194 unsigned_V8HI_type_node);
11195 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11196 (*lang_hooks.decls.pushdecl) (tdecl);
11197 tdecl = build_decl (BUILTINS_LOCATION,
11198 TYPE_DECL, get_identifier ("__vector signed short"),
11200 TYPE_NAME (V8HI_type_node) = tdecl;
11201 (*lang_hooks.decls.pushdecl) (tdecl);
11202 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11203 get_identifier ("__vector __bool short"),
11204 bool_V8HI_type_node);
11205 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11206 (*lang_hooks.decls.pushdecl) (tdecl);
11208 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11209 get_identifier ("__vector unsigned int"),
11210 unsigned_V4SI_type_node);
11211 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11212 (*lang_hooks.decls.pushdecl) (tdecl);
11213 tdecl = build_decl (BUILTINS_LOCATION,
11214 TYPE_DECL, get_identifier ("__vector signed int"),
11216 TYPE_NAME (V4SI_type_node) = tdecl;
11217 (*lang_hooks.decls.pushdecl) (tdecl);
11218 tdecl = build_decl (BUILTINS_LOCATION,
11219 TYPE_DECL, get_identifier ("__vector __bool int"),
11220 bool_V4SI_type_node);
11221 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11222 (*lang_hooks.decls.pushdecl) (tdecl);
11224 tdecl = build_decl (BUILTINS_LOCATION,
11225 TYPE_DECL, get_identifier ("__vector float"),
11227 TYPE_NAME (V4SF_type_node) = tdecl;
11228 (*lang_hooks.decls.pushdecl) (tdecl);
11229 tdecl = build_decl (BUILTINS_LOCATION,
11230 TYPE_DECL, get_identifier ("__vector __pixel"),
11231 pixel_V8HI_type_node);
11232 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11233 (*lang_hooks.decls.pushdecl) (tdecl);
11237 tdecl = build_decl (BUILTINS_LOCATION,
11238 TYPE_DECL, get_identifier ("__vector double"),
11240 TYPE_NAME (V2DF_type_node) = tdecl;
11241 (*lang_hooks.decls.pushdecl) (tdecl);
11243 tdecl = build_decl (BUILTINS_LOCATION,
11244 TYPE_DECL, get_identifier ("__vector long"),
11246 TYPE_NAME (V2DI_type_node) = tdecl;
11247 (*lang_hooks.decls.pushdecl) (tdecl);
11249 tdecl = build_decl (BUILTINS_LOCATION,
11250 TYPE_DECL, get_identifier ("__vector unsigned long"),
11251 unsigned_V2DI_type_node);
11252 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11253 (*lang_hooks.decls.pushdecl) (tdecl);
11255 tdecl = build_decl (BUILTINS_LOCATION,
11256 TYPE_DECL, get_identifier ("__vector __bool long"),
11257 bool_V2DI_type_node);
11258 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11259 (*lang_hooks.decls.pushdecl) (tdecl);
11262 if (TARGET_PAIRED_FLOAT)
11263 paired_init_builtins ();
11265 spe_init_builtins ();
11266 if (TARGET_ALTIVEC)
11267 altivec_init_builtins ();
11268 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11269 rs6000_common_init_builtins ();
11270 if (TARGET_PPC_GFXOPT)
11272 tree ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11273 RS6000_BUILTIN_RECIPF,
11274 "__builtin_recipdivf");
11275 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11276 RS6000_BUILTIN_RECIPF);
11278 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11279 RS6000_BUILTIN_RSQRTF,
11280 "__builtin_rsqrtf");
11281 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11282 RS6000_BUILTIN_RSQRTF);
11284 if (TARGET_POPCNTB)
11286 tree ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11287 RS6000_BUILTIN_RECIP,
11288 "__builtin_recipdiv");
11289 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11290 RS6000_BUILTIN_RECIP);
11293 if (TARGET_POPCNTD)
11295 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11296 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11297 POWER7_BUILTIN_BPERMD,
11298 "__builtin_bpermd");
11299 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11300 POWER7_BUILTIN_BPERMD);
11302 if (TARGET_POWERPC)
11304 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11305 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11306 unsigned_intHI_type_node,
11308 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11309 RS6000_BUILTIN_BSWAP_HI);
11313 /* AIX libm provides clog as __clog. */
11314 if (built_in_decls [BUILT_IN_CLOG])
11315 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11318 #ifdef SUBTARGET_INIT_BUILTINS
11319 SUBTARGET_INIT_BUILTINS;
11323 /* Returns the rs6000 builtin decl for CODE. */
11326 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
11328 if (code >= RS6000_BUILTIN_COUNT)
11329 return error_mark_node;
11331 return rs6000_builtin_decls[code];
11334 /* Search through a set of builtins and enable the mask bits.
11335 DESC is an array of builtins.
11336 SIZE is the total number of builtins.
11337 START is the builtin enum at which to start.
11338 END is the builtin enum at which to end. */
11340 enable_mask_for_builtins (struct builtin_description *desc, int size,
11341 enum rs6000_builtins start,
11342 enum rs6000_builtins end)
11346 for (i = 0; i < size; ++i)
11347 if (desc[i].code == start)
11353 for (; i < size; ++i)
11355 /* Flip all the bits on. */
11356 desc[i].mask = target_flags;
11357 if (desc[i].code == end)
11363 spe_init_builtins (void)
11365 tree endlink = void_list_node;
11366 tree puint_type_node = build_pointer_type (unsigned_type_node);
11367 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11368 struct builtin_description *d;
11371 tree v2si_ftype_4_v2si
11372 = build_function_type
11373 (opaque_V2SI_type_node,
11374 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11375 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11376 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11377 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11380 tree v2sf_ftype_4_v2sf
11381 = build_function_type
11382 (opaque_V2SF_type_node,
11383 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11384 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11385 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11386 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11389 tree int_ftype_int_v2si_v2si
11390 = build_function_type
11391 (integer_type_node,
11392 tree_cons (NULL_TREE, integer_type_node,
11393 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11394 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11397 tree int_ftype_int_v2sf_v2sf
11398 = build_function_type
11399 (integer_type_node,
11400 tree_cons (NULL_TREE, integer_type_node,
11401 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11402 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11405 tree void_ftype_v2si_puint_int
11406 = build_function_type (void_type_node,
11407 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11408 tree_cons (NULL_TREE, puint_type_node,
11409 tree_cons (NULL_TREE,
11413 tree void_ftype_v2si_puint_char
11414 = build_function_type (void_type_node,
11415 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11416 tree_cons (NULL_TREE, puint_type_node,
11417 tree_cons (NULL_TREE,
11421 tree void_ftype_v2si_pv2si_int
11422 = build_function_type (void_type_node,
11423 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11424 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11425 tree_cons (NULL_TREE,
11429 tree void_ftype_v2si_pv2si_char
11430 = build_function_type (void_type_node,
11431 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11432 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11433 tree_cons (NULL_TREE,
11437 tree void_ftype_int
11438 = build_function_type (void_type_node,
11439 tree_cons (NULL_TREE, integer_type_node, endlink));
11441 tree int_ftype_void
11442 = build_function_type (integer_type_node, endlink);
11444 tree v2si_ftype_pv2si_int
11445 = build_function_type (opaque_V2SI_type_node,
11446 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11447 tree_cons (NULL_TREE, integer_type_node,
11450 tree v2si_ftype_puint_int
11451 = build_function_type (opaque_V2SI_type_node,
11452 tree_cons (NULL_TREE, puint_type_node,
11453 tree_cons (NULL_TREE, integer_type_node,
11456 tree v2si_ftype_pushort_int
11457 = build_function_type (opaque_V2SI_type_node,
11458 tree_cons (NULL_TREE, pushort_type_node,
11459 tree_cons (NULL_TREE, integer_type_node,
11462 tree v2si_ftype_signed_char
11463 = build_function_type (opaque_V2SI_type_node,
11464 tree_cons (NULL_TREE, signed_char_type_node,
11467 /* The initialization of the simple binary and unary builtins is
11468 done in rs6000_common_init_builtins, but we have to enable the
11469 mask bits here manually because we have run out of `target_flags'
11470 bits. We really need to redesign this mask business. */
11472 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11473 ARRAY_SIZE (bdesc_2arg),
11474 SPE_BUILTIN_EVADDW,
11475 SPE_BUILTIN_EVXOR);
11476 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11477 ARRAY_SIZE (bdesc_1arg),
11479 SPE_BUILTIN_EVSUBFUSIAAW);
11480 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11481 ARRAY_SIZE (bdesc_spe_predicates),
11482 SPE_BUILTIN_EVCMPEQ,
11483 SPE_BUILTIN_EVFSTSTLT);
11484 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11485 ARRAY_SIZE (bdesc_spe_evsel),
11486 SPE_BUILTIN_EVSEL_CMPGTS,
11487 SPE_BUILTIN_EVSEL_FSTSTEQ);
11489 (*lang_hooks.decls.pushdecl)
11490 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11491 get_identifier ("__ev64_opaque__"),
11492 opaque_V2SI_type_node));
11494 /* Initialize irregular SPE builtins. */
11496 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11497 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11498 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11499 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11500 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11501 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11502 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11503 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11504 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11505 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11506 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11507 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11508 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11509 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11510 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11511 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11512 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11513 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11516 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11517 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11518 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11519 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11520 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11521 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11522 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11523 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11524 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11525 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11526 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11527 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11528 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11529 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11530 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11531 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11532 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11533 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11534 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11535 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11536 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11537 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11540 d = (struct builtin_description *) bdesc_spe_predicates;
11541 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11545 switch (insn_data[d->icode].operand[1].mode)
11548 type = int_ftype_int_v2si_v2si;
11551 type = int_ftype_int_v2sf_v2sf;
11554 gcc_unreachable ();
11557 def_builtin (d->mask, d->name, type, d->code);
11560 /* Evsel predicates. */
11561 d = (struct builtin_description *) bdesc_spe_evsel;
11562 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11566 switch (insn_data[d->icode].operand[1].mode)
11569 type = v2si_ftype_4_v2si;
11572 type = v2sf_ftype_4_v2sf;
11575 gcc_unreachable ();
11578 def_builtin (d->mask, d->name, type, d->code);
11583 paired_init_builtins (void)
11585 const struct builtin_description *d;
11587 tree endlink = void_list_node;
11589 tree int_ftype_int_v2sf_v2sf
11590 = build_function_type
11591 (integer_type_node,
11592 tree_cons (NULL_TREE, integer_type_node,
11593 tree_cons (NULL_TREE, V2SF_type_node,
11594 tree_cons (NULL_TREE, V2SF_type_node,
11596 tree pcfloat_type_node =
11597 build_pointer_type (build_qualified_type
11598 (float_type_node, TYPE_QUAL_CONST));
11600 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
11601 long_integer_type_node,
11604 tree void_ftype_v2sf_long_pcfloat =
11605 build_function_type_list (void_type_node,
11607 long_integer_type_node,
11612 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
11613 PAIRED_BUILTIN_LX);
11616 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
11617 PAIRED_BUILTIN_STX);
11620 d = bdesc_paired_preds;
11621 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
11625 switch (insn_data[d->icode].operand[1].mode)
11628 type = int_ftype_int_v2sf_v2sf;
11631 gcc_unreachable ();
11634 def_builtin (d->mask, d->name, type, d->code);
11639 altivec_init_builtins (void)
11641 const struct builtin_description *d;
11642 const struct builtin_description_predicates *dp;
11646 tree pfloat_type_node = build_pointer_type (float_type_node);
11647 tree pint_type_node = build_pointer_type (integer_type_node);
11648 tree pshort_type_node = build_pointer_type (short_integer_type_node);
11649 tree pchar_type_node = build_pointer_type (char_type_node);
11651 tree pvoid_type_node = build_pointer_type (void_type_node);
11653 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
11654 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
11655 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
11656 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
11658 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
11660 tree int_ftype_opaque
11661 = build_function_type_list (integer_type_node,
11662 opaque_V4SI_type_node, NULL_TREE);
11663 tree opaque_ftype_opaque
11664 = build_function_type (integer_type_node,
11666 tree opaque_ftype_opaque_int
11667 = build_function_type_list (opaque_V4SI_type_node,
11668 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
11669 tree opaque_ftype_opaque_opaque_int
11670 = build_function_type_list (opaque_V4SI_type_node,
11671 opaque_V4SI_type_node, opaque_V4SI_type_node,
11672 integer_type_node, NULL_TREE);
11673 tree int_ftype_int_opaque_opaque
11674 = build_function_type_list (integer_type_node,
11675 integer_type_node, opaque_V4SI_type_node,
11676 opaque_V4SI_type_node, NULL_TREE);
11677 tree int_ftype_int_v4si_v4si
11678 = build_function_type_list (integer_type_node,
11679 integer_type_node, V4SI_type_node,
11680 V4SI_type_node, NULL_TREE);
11681 tree v4sf_ftype_pcfloat
11682 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
11683 tree void_ftype_pfloat_v4sf
11684 = build_function_type_list (void_type_node,
11685 pfloat_type_node, V4SF_type_node, NULL_TREE);
11686 tree v4si_ftype_pcint
11687 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
11688 tree void_ftype_pint_v4si
11689 = build_function_type_list (void_type_node,
11690 pint_type_node, V4SI_type_node, NULL_TREE);
11691 tree v8hi_ftype_pcshort
11692 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
11693 tree void_ftype_pshort_v8hi
11694 = build_function_type_list (void_type_node,
11695 pshort_type_node, V8HI_type_node, NULL_TREE);
11696 tree v16qi_ftype_pcchar
11697 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
11698 tree void_ftype_pchar_v16qi
11699 = build_function_type_list (void_type_node,
11700 pchar_type_node, V16QI_type_node, NULL_TREE);
11701 tree void_ftype_v4si
11702 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
11703 tree v8hi_ftype_void
11704 = build_function_type (V8HI_type_node, void_list_node);
11705 tree void_ftype_void
11706 = build_function_type (void_type_node, void_list_node);
11707 tree void_ftype_int
11708 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
11710 tree opaque_ftype_long_pcvoid
11711 = build_function_type_list (opaque_V4SI_type_node,
11712 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11713 tree v16qi_ftype_long_pcvoid
11714 = build_function_type_list (V16QI_type_node,
11715 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11716 tree v8hi_ftype_long_pcvoid
11717 = build_function_type_list (V8HI_type_node,
11718 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11719 tree v4si_ftype_long_pcvoid
11720 = build_function_type_list (V4SI_type_node,
11721 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11723 tree void_ftype_opaque_long_pvoid
11724 = build_function_type_list (void_type_node,
11725 opaque_V4SI_type_node, long_integer_type_node,
11726 pvoid_type_node, NULL_TREE);
11727 tree void_ftype_v4si_long_pvoid
11728 = build_function_type_list (void_type_node,
11729 V4SI_type_node, long_integer_type_node,
11730 pvoid_type_node, NULL_TREE);
11731 tree void_ftype_v16qi_long_pvoid
11732 = build_function_type_list (void_type_node,
11733 V16QI_type_node, long_integer_type_node,
11734 pvoid_type_node, NULL_TREE);
11735 tree void_ftype_v8hi_long_pvoid
11736 = build_function_type_list (void_type_node,
11737 V8HI_type_node, long_integer_type_node,
11738 pvoid_type_node, NULL_TREE);
11739 tree int_ftype_int_v8hi_v8hi
11740 = build_function_type_list (integer_type_node,
11741 integer_type_node, V8HI_type_node,
11742 V8HI_type_node, NULL_TREE);
11743 tree int_ftype_int_v16qi_v16qi
11744 = build_function_type_list (integer_type_node,
11745 integer_type_node, V16QI_type_node,
11746 V16QI_type_node, NULL_TREE);
11747 tree int_ftype_int_v4sf_v4sf
11748 = build_function_type_list (integer_type_node,
11749 integer_type_node, V4SF_type_node,
11750 V4SF_type_node, NULL_TREE);
11751 tree int_ftype_int_v2df_v2df
11752 = build_function_type_list (integer_type_node,
11753 integer_type_node, V2DF_type_node,
11754 V2DF_type_node, NULL_TREE);
11755 tree v4si_ftype_v4si
11756 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
11757 tree v8hi_ftype_v8hi
11758 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
11759 tree v16qi_ftype_v16qi
11760 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
11761 tree v4sf_ftype_v4sf
11762 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
11763 tree v2df_ftype_v2df
11764 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
11765 tree void_ftype_pcvoid_int_int
11766 = build_function_type_list (void_type_node,
11767 pcvoid_type_node, integer_type_node,
11768 integer_type_node, NULL_TREE);
11770 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
11771 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
11772 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
11773 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
11774 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
11775 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
11776 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
11777 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
11778 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
11779 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
11780 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
11781 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
11782 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
11783 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
11784 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
11785 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
11786 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
11787 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
11788 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
11789 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
11790 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
11791 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
11792 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
11793 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
11794 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
11795 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
11796 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
11797 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
11798 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
11799 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
11800 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
11801 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
11802 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
11803 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
11804 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
11805 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
11806 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
11807 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
11808 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
11809 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
11810 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
11811 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
11812 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
11813 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
11814 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
11815 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
11817 if (rs6000_cpu == PROCESSOR_CELL)
11819 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
11820 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
11821 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
11822 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
11824 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
11825 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
11826 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
11827 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
11829 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
11830 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
11831 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
11832 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
11834 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
11835 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
11836 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
11837 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
11839 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
11840 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
11841 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
11843 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
11844 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
11845 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
11846 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
11847 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
11848 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
11849 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
11850 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
11851 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
11852 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
11853 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
11854 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
11856 /* Add the DST variants. */
11858 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11859 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
11861 /* Initialize the predicates. */
11862 dp = bdesc_altivec_preds;
11863 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11865 enum machine_mode mode1;
11867 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11868 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11869 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
11870 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
11875 mode1 = insn_data[dp->icode].operand[1].mode;
11880 type = int_ftype_int_opaque_opaque;
11883 type = int_ftype_int_v4si_v4si;
11886 type = int_ftype_int_v8hi_v8hi;
11889 type = int_ftype_int_v16qi_v16qi;
11892 type = int_ftype_int_v4sf_v4sf;
11895 type = int_ftype_int_v2df_v2df;
11898 gcc_unreachable ();
11901 def_builtin (dp->mask, dp->name, type, dp->code);
11904 /* Initialize the abs* operators. */
11906 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11908 enum machine_mode mode0;
11911 mode0 = insn_data[d->icode].operand[0].mode;
11916 type = v4si_ftype_v4si;
11919 type = v8hi_ftype_v8hi;
11922 type = v16qi_ftype_v16qi;
11925 type = v4sf_ftype_v4sf;
11928 type = v2df_ftype_v2df;
11931 gcc_unreachable ();
11934 def_builtin (d->mask, d->name, type, d->code);
11937 if (TARGET_ALTIVEC)
11941 /* Initialize target builtin that implements
11942 targetm.vectorize.builtin_mask_for_load. */
11944 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
11945 v16qi_ftype_long_pcvoid,
11946 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
11947 BUILT_IN_MD, NULL, NULL_TREE);
11948 TREE_READONLY (decl) = 1;
11949 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
11950 altivec_builtin_mask_for_load = decl;
11953 /* Access to the vec_init patterns. */
11954 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
11955 integer_type_node, integer_type_node,
11956 integer_type_node, NULL_TREE);
11957 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
11958 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
11960 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
11961 short_integer_type_node,
11962 short_integer_type_node,
11963 short_integer_type_node,
11964 short_integer_type_node,
11965 short_integer_type_node,
11966 short_integer_type_node,
11967 short_integer_type_node, NULL_TREE);
11968 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
11969 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
11971 ftype = build_function_type_list (V16QI_type_node, char_type_node,
11972 char_type_node, char_type_node,
11973 char_type_node, char_type_node,
11974 char_type_node, char_type_node,
11975 char_type_node, char_type_node,
11976 char_type_node, char_type_node,
11977 char_type_node, char_type_node,
11978 char_type_node, char_type_node,
11979 char_type_node, NULL_TREE);
11980 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
11981 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
11983 ftype = build_function_type_list (V4SF_type_node, float_type_node,
11984 float_type_node, float_type_node,
11985 float_type_node, NULL_TREE);
11986 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
11987 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
11991 ftype = build_function_type_list (V2DF_type_node, double_type_node,
11992 double_type_node, NULL_TREE);
11993 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
11994 VSX_BUILTIN_VEC_INIT_V2DF);
11996 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
11997 intDI_type_node, NULL_TREE);
11998 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
11999 VSX_BUILTIN_VEC_INIT_V2DI);
12002 /* Access to the vec_set patterns. */
12003 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12005 integer_type_node, NULL_TREE);
12006 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12007 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12009 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12011 integer_type_node, NULL_TREE);
12012 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12013 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12015 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12017 integer_type_node, NULL_TREE);
12018 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12019 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12021 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12023 integer_type_node, NULL_TREE);
12024 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12025 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12029 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12031 integer_type_node, NULL_TREE);
12032 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12033 VSX_BUILTIN_VEC_SET_V2DF);
12035 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12037 integer_type_node, NULL_TREE);
12038 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12039 VSX_BUILTIN_VEC_SET_V2DI);
12042 /* Access to the vec_extract patterns. */
12043 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12044 integer_type_node, NULL_TREE);
12045 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12046 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12048 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12049 integer_type_node, NULL_TREE);
12050 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12051 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12053 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12054 integer_type_node, NULL_TREE);
12055 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12056 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12058 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12059 integer_type_node, NULL_TREE);
12060 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12061 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12065 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12066 integer_type_node, NULL_TREE);
12067 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12068 VSX_BUILTIN_VEC_EXT_V2DF);
12070 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12071 integer_type_node, NULL_TREE);
12072 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12073 VSX_BUILTIN_VEC_EXT_V2DI);
12077 /* Hash function for builtin functions with up to 3 arguments and a return
12080 builtin_hash_function (const void *hash_entry)
12084 const struct builtin_hash_struct *bh =
12085 (const struct builtin_hash_struct *) hash_entry;
12087 for (i = 0; i < 4; i++)
12089 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12090 ret = (ret * 2) + bh->uns_p[i];
12096 /* Compare builtin hash entries H1 and H2 for equivalence. */
12098 builtin_hash_eq (const void *h1, const void *h2)
12100 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12101 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
12103 return ((p1->mode[0] == p2->mode[0])
12104 && (p1->mode[1] == p2->mode[1])
12105 && (p1->mode[2] == p2->mode[2])
12106 && (p1->mode[3] == p2->mode[3])
12107 && (p1->uns_p[0] == p2->uns_p[0])
12108 && (p1->uns_p[1] == p2->uns_p[1])
12109 && (p1->uns_p[2] == p2->uns_p[2])
12110 && (p1->uns_p[3] == p2->uns_p[3]));
12113 /* Map types for builtin functions with an explicit return type and up to 3
12114 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12115 of the argument. */
12117 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
12118 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
12119 enum rs6000_builtins builtin, const char *name)
12121 struct builtin_hash_struct h;
12122 struct builtin_hash_struct *h2;
12126 tree ret_type = NULL_TREE;
12127 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
12130 /* Create builtin_hash_table. */
12131 if (builtin_hash_table == NULL)
12132 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
12133 builtin_hash_eq, NULL);
12135 h.type = NULL_TREE;
12136 h.mode[0] = mode_ret;
12137 h.mode[1] = mode_arg0;
12138 h.mode[2] = mode_arg1;
12139 h.mode[3] = mode_arg2;
12145 /* If the builtin is a type that produces unsigned results or takes unsigned
12146 arguments, and it is returned as a decl for the vectorizer (such as
12147 widening multiplies, permute), make sure the arguments and return value
12148 are type correct. */
12151 /* unsigned 2 argument functions. */
12152 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12153 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12154 case ALTIVEC_BUILTIN_VMULOUB_UNS:
12155 case ALTIVEC_BUILTIN_VMULOUH_UNS:
12161 /* unsigned 3 argument functions. */
12162 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
12163 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
12164 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
12165 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
12166 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
12167 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
12168 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
12169 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
12170 case VSX_BUILTIN_VPERM_16QI_UNS:
12171 case VSX_BUILTIN_VPERM_8HI_UNS:
12172 case VSX_BUILTIN_VPERM_4SI_UNS:
12173 case VSX_BUILTIN_VPERM_2DI_UNS:
12174 case VSX_BUILTIN_XXSEL_16QI_UNS:
12175 case VSX_BUILTIN_XXSEL_8HI_UNS:
12176 case VSX_BUILTIN_XXSEL_4SI_UNS:
12177 case VSX_BUILTIN_XXSEL_2DI_UNS:
12184 /* signed permute functions with unsigned char mask. */
12185 case ALTIVEC_BUILTIN_VPERM_16QI:
12186 case ALTIVEC_BUILTIN_VPERM_8HI:
12187 case ALTIVEC_BUILTIN_VPERM_4SI:
12188 case ALTIVEC_BUILTIN_VPERM_4SF:
12189 case ALTIVEC_BUILTIN_VPERM_2DI:
12190 case ALTIVEC_BUILTIN_VPERM_2DF:
12191 case VSX_BUILTIN_VPERM_16QI:
12192 case VSX_BUILTIN_VPERM_8HI:
12193 case VSX_BUILTIN_VPERM_4SI:
12194 case VSX_BUILTIN_VPERM_4SF:
12195 case VSX_BUILTIN_VPERM_2DI:
12196 case VSX_BUILTIN_VPERM_2DF:
12200 /* unsigned args, signed return. */
12201 case VSX_BUILTIN_XVCVUXDDP_UNS:
12202 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12206 /* signed args, unsigned return. */
12207 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12208 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12216 /* Figure out how many args are present. */
12217 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12221 fatal_error ("internal error: builtin function %s had no type", name);
12223 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12224 if (!ret_type && h.uns_p[0])
12225 ret_type = builtin_mode_to_type[h.mode[0]][0];
12228 fatal_error ("internal error: builtin function %s had an unexpected "
12229 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12231 for (i = 0; i < num_args; i++)
12233 int m = (int) h.mode[i+1];
12234 int uns_p = h.uns_p[i+1];
12236 arg_type[i] = builtin_mode_to_type[m][uns_p];
12237 if (!arg_type[i] && uns_p)
12238 arg_type[i] = builtin_mode_to_type[m][0];
12241 fatal_error ("internal error: builtin function %s, argument %d "
12242 "had unexpected argument type %s", name, i,
12243 GET_MODE_NAME (m));
12246 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12247 if (*found == NULL)
12249 h2 = GGC_NEW (struct builtin_hash_struct);
12251 *found = (void *)h2;
12252 args = void_list_node;
12254 for (i = num_args - 1; i >= 0; i--)
12255 args = tree_cons (NULL_TREE, arg_type[i], args);
12257 h2->type = build_function_type (ret_type, args);
12260 return ((struct builtin_hash_struct *)(*found))->type;
12264 rs6000_common_init_builtins (void)
12266 const struct builtin_description *d;
12269 tree opaque_ftype_opaque = NULL_TREE;
12270 tree opaque_ftype_opaque_opaque = NULL_TREE;
12271 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12272 tree v2si_ftype_qi = NULL_TREE;
12273 tree v2si_ftype_v2si_qi = NULL_TREE;
12274 tree v2si_ftype_int_qi = NULL_TREE;
12276 if (!TARGET_PAIRED_FLOAT)
12278 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12279 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12282 /* Add the ternary operators. */
12284 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12287 int mask = d->mask;
12289 if ((mask != 0 && (mask & target_flags) == 0)
12290 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12293 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12294 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12295 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12296 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12298 if (! (type = opaque_ftype_opaque_opaque_opaque))
12299 type = opaque_ftype_opaque_opaque_opaque
12300 = build_function_type_list (opaque_V4SI_type_node,
12301 opaque_V4SI_type_node,
12302 opaque_V4SI_type_node,
12303 opaque_V4SI_type_node,
12308 enum insn_code icode = d->icode;
12309 if (d->name == 0 || icode == CODE_FOR_nothing)
12312 type = builtin_function_type (insn_data[icode].operand[0].mode,
12313 insn_data[icode].operand[1].mode,
12314 insn_data[icode].operand[2].mode,
12315 insn_data[icode].operand[3].mode,
12319 def_builtin (d->mask, d->name, type, d->code);
12322 /* Add the binary operators. */
12324 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12326 enum machine_mode mode0, mode1, mode2;
12328 int mask = d->mask;
12330 if ((mask != 0 && (mask & target_flags) == 0)
12331 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12334 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12335 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12336 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12337 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12339 if (! (type = opaque_ftype_opaque_opaque))
12340 type = opaque_ftype_opaque_opaque
12341 = build_function_type_list (opaque_V4SI_type_node,
12342 opaque_V4SI_type_node,
12343 opaque_V4SI_type_node,
12348 enum insn_code icode = d->icode;
12349 if (d->name == 0 || icode == CODE_FOR_nothing)
12352 mode0 = insn_data[icode].operand[0].mode;
12353 mode1 = insn_data[icode].operand[1].mode;
12354 mode2 = insn_data[icode].operand[2].mode;
12356 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12358 if (! (type = v2si_ftype_v2si_qi))
12359 type = v2si_ftype_v2si_qi
12360 = build_function_type_list (opaque_V2SI_type_node,
12361 opaque_V2SI_type_node,
12366 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12367 && mode2 == QImode)
12369 if (! (type = v2si_ftype_int_qi))
12370 type = v2si_ftype_int_qi
12371 = build_function_type_list (opaque_V2SI_type_node,
12378 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12382 def_builtin (d->mask, d->name, type, d->code);
12385 /* Add the simple unary operators. */
12386 d = (struct builtin_description *) bdesc_1arg;
12387 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12389 enum machine_mode mode0, mode1;
12391 int mask = d->mask;
12393 if ((mask != 0 && (mask & target_flags) == 0)
12394 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12397 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12398 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12399 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12400 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12402 if (! (type = opaque_ftype_opaque))
12403 type = opaque_ftype_opaque
12404 = build_function_type_list (opaque_V4SI_type_node,
12405 opaque_V4SI_type_node,
12410 enum insn_code icode = d->icode;
12411 if (d->name == 0 || icode == CODE_FOR_nothing)
12414 mode0 = insn_data[icode].operand[0].mode;
12415 mode1 = insn_data[icode].operand[1].mode;
12417 if (mode0 == V2SImode && mode1 == QImode)
12419 if (! (type = v2si_ftype_qi))
12420 type = v2si_ftype_qi
12421 = build_function_type_list (opaque_V2SI_type_node,
12427 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12431 def_builtin (d->mask, d->name, type, d->code);
12436 rs6000_init_libfuncs (void)
12438 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12439 && !TARGET_POWER2 && !TARGET_POWERPC)
12441 /* AIX library routines for float->int conversion. */
12442 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12443 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12444 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12445 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12448 if (!TARGET_IEEEQUAD)
12449 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12450 if (!TARGET_XL_COMPAT)
12452 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12453 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12454 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12455 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12457 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12459 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12460 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12461 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12462 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12463 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12464 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12465 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12467 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12468 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12469 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12470 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12471 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12472 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12473 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12474 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12477 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12478 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12482 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12483 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12484 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12485 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12489 /* 32-bit SVR4 quad floating point routines. */
12491 set_optab_libfunc (add_optab, TFmode, "_q_add");
12492 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12493 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12494 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12495 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12496 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12497 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12499 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12500 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12501 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12502 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12503 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12504 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12506 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12507 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12508 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12509 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12510 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12511 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12512 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12513 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12518 /* Expand a block clear operation, and return 1 if successful. Return 0
12519 if we should let the compiler generate normal code.
12521 operands[0] is the destination
12522 operands[1] is the length
12523 operands[3] is the alignment */
12526 expand_block_clear (rtx operands[])
12528 rtx orig_dest = operands[0];
12529 rtx bytes_rtx = operands[1];
12530 rtx align_rtx = operands[3];
12531 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12532 HOST_WIDE_INT align;
12533 HOST_WIDE_INT bytes;
12538 /* If this is not a fixed size move, just call memcpy */
12542 /* This must be a fixed size alignment */
12543 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12544 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12546 /* Anything to clear? */
12547 bytes = INTVAL (bytes_rtx);
12551 /* Use the builtin memset after a point, to avoid huge code bloat.
12552 When optimize_size, avoid any significant code bloat; calling
12553 memset is about 4 instructions, so allow for one instruction to
12554 load zero and three to do clearing. */
12555 if (TARGET_ALTIVEC && align >= 128)
12557 else if (TARGET_POWERPC64 && align >= 32)
12559 else if (TARGET_SPE && align >= 64)
12564 if (optimize_size && bytes > 3 * clear_step)
12566 if (! optimize_size && bytes > 8 * clear_step)
12569 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12571 enum machine_mode mode = BLKmode;
12574 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
12579 else if (bytes >= 8 && TARGET_SPE && align >= 64)
12584 else if (bytes >= 8 && TARGET_POWERPC64
12585 /* 64-bit loads and stores require word-aligned
12587 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12592 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12593 { /* move 4 bytes */
12597 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12598 { /* move 2 bytes */
12602 else /* move 1 byte at a time */
12608 dest = adjust_address (orig_dest, mode, offset);
12610 emit_move_insn (dest, CONST0_RTX (mode));
12617 /* Expand a block move operation, and return 1 if successful. Return 0
12618 if we should let the compiler generate normal code.
12620 operands[0] is the destination
12621 operands[1] is the source
12622 operands[2] is the length
12623 operands[3] is the alignment */
12625 #define MAX_MOVE_REG 4
12628 expand_block_move (rtx operands[])
12630 rtx orig_dest = operands[0];
12631 rtx orig_src = operands[1];
12632 rtx bytes_rtx = operands[2];
12633 rtx align_rtx = operands[3];
12634 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
12639 rtx stores[MAX_MOVE_REG];
12642 /* If this is not a fixed size move, just call memcpy */
12646 /* This must be a fixed size alignment */
12647 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12648 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12650 /* Anything to move? */
12651 bytes = INTVAL (bytes_rtx);
12655 /* store_one_arg depends on expand_block_move to handle at least the size of
12656 reg_parm_stack_space. */
12657 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
12660 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
12663 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
12664 rtx (*mov) (rtx, rtx);
12666 enum machine_mode mode = BLKmode;
12669 /* Altivec first, since it will be faster than a string move
12670 when it applies, and usually not significantly larger. */
12671 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
12675 gen_func.mov = gen_movv4si;
12677 else if (TARGET_SPE && bytes >= 8 && align >= 64)
12681 gen_func.mov = gen_movv2si;
12683 else if (TARGET_STRING
12684 && bytes > 24 /* move up to 32 bytes at a time */
12690 && ! fixed_regs[10]
12691 && ! fixed_regs[11]
12692 && ! fixed_regs[12])
12694 move_bytes = (bytes > 32) ? 32 : bytes;
12695 gen_func.movmemsi = gen_movmemsi_8reg;
12697 else if (TARGET_STRING
12698 && bytes > 16 /* move up to 24 bytes at a time */
12704 && ! fixed_regs[10])
12706 move_bytes = (bytes > 24) ? 24 : bytes;
12707 gen_func.movmemsi = gen_movmemsi_6reg;
12709 else if (TARGET_STRING
12710 && bytes > 8 /* move up to 16 bytes at a time */
12714 && ! fixed_regs[8])
12716 move_bytes = (bytes > 16) ? 16 : bytes;
12717 gen_func.movmemsi = gen_movmemsi_4reg;
12719 else if (bytes >= 8 && TARGET_POWERPC64
12720 /* 64-bit loads and stores require word-aligned
12722 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12726 gen_func.mov = gen_movdi;
12728 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
12729 { /* move up to 8 bytes at a time */
12730 move_bytes = (bytes > 8) ? 8 : bytes;
12731 gen_func.movmemsi = gen_movmemsi_2reg;
12733 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12734 { /* move 4 bytes */
12737 gen_func.mov = gen_movsi;
12739 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12740 { /* move 2 bytes */
12743 gen_func.mov = gen_movhi;
12745 else if (TARGET_STRING && bytes > 1)
12746 { /* move up to 4 bytes at a time */
12747 move_bytes = (bytes > 4) ? 4 : bytes;
12748 gen_func.movmemsi = gen_movmemsi_1reg;
12750 else /* move 1 byte at a time */
12754 gen_func.mov = gen_movqi;
12757 src = adjust_address (orig_src, mode, offset);
12758 dest = adjust_address (orig_dest, mode, offset);
12760 if (mode != BLKmode)
12762 rtx tmp_reg = gen_reg_rtx (mode);
12764 emit_insn ((*gen_func.mov) (tmp_reg, src));
12765 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
12768 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
12771 for (i = 0; i < num_reg; i++)
12772 emit_insn (stores[i]);
12776 if (mode == BLKmode)
12778 /* Move the address into scratch registers. The movmemsi
12779 patterns require zero offset. */
12780 if (!REG_P (XEXP (src, 0)))
12782 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
12783 src = replace_equiv_address (src, src_reg);
12785 set_mem_size (src, GEN_INT (move_bytes));
12787 if (!REG_P (XEXP (dest, 0)))
12789 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
12790 dest = replace_equiv_address (dest, dest_reg);
12792 set_mem_size (dest, GEN_INT (move_bytes));
12794 emit_insn ((*gen_func.movmemsi) (dest, src,
12795 GEN_INT (move_bytes & 31),
12804 /* Return a string to perform a load_multiple operation.
12805 operands[0] is the vector.
12806 operands[1] is the source address.
12807 operands[2] is the first destination register. */
12810 rs6000_output_load_multiple (rtx operands[3])
12812 /* We have to handle the case where the pseudo used to contain the address
12813 is assigned to one of the output registers. */
12815 int words = XVECLEN (operands[0], 0);
12818 if (XVECLEN (operands[0], 0) == 1)
12819 return "{l|lwz} %2,0(%1)";
12821 for (i = 0; i < words; i++)
12822 if (refers_to_regno_p (REGNO (operands[2]) + i,
12823 REGNO (operands[2]) + i + 1, operands[1], 0))
12827 xop[0] = GEN_INT (4 * (words-1));
12828 xop[1] = operands[1];
12829 xop[2] = operands[2];
12830 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
12835 xop[0] = GEN_INT (4 * (words-1));
12836 xop[1] = operands[1];
12837 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
12838 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);
12843 for (j = 0; j < words; j++)
12846 xop[0] = GEN_INT (j * 4);
12847 xop[1] = operands[1];
12848 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
12849 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
12851 xop[0] = GEN_INT (i * 4);
12852 xop[1] = operands[1];
12853 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
12858 return "{lsi|lswi} %2,%1,%N0";
12862 /* A validation routine: say whether CODE, a condition code, and MODE
12863 match. The other alternatives either don't make sense or should
12864 never be generated. */
12867 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
12869 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
12870 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
12871 && GET_MODE_CLASS (mode) == MODE_CC);
12873 /* These don't make sense. */
12874 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
12875 || mode != CCUNSmode);
12877 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
12878 || mode == CCUNSmode);
12880 gcc_assert (mode == CCFPmode
12881 || (code != ORDERED && code != UNORDERED
12882 && code != UNEQ && code != LTGT
12883 && code != UNGT && code != UNLT
12884 && code != UNGE && code != UNLE));
12886 /* These should never be generated except for
12887 flag_finite_math_only. */
12888 gcc_assert (mode != CCFPmode
12889 || flag_finite_math_only
12890 || (code != LE && code != GE
12891 && code != UNEQ && code != LTGT
12892 && code != UNGT && code != UNLT));
12894 /* These are invalid; the information is not there. */
12895 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
12899 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
12900 mask required to convert the result of a rotate insn into a shift
12901 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
12904 includes_lshift_p (rtx shiftop, rtx andop)
12906 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12908 shift_mask <<= INTVAL (shiftop);
12910 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12913 /* Similar, but for right shift. */
12916 includes_rshift_p (rtx shiftop, rtx andop)
12918 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12920 shift_mask >>= INTVAL (shiftop);
12922 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12925 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
12926 to perform a left shift. It must have exactly SHIFTOP least
12927 significant 0's, then one or more 1's, then zero or more 0's. */
12930 includes_rldic_lshift_p (rtx shiftop, rtx andop)
12932 if (GET_CODE (andop) == CONST_INT)
12934 HOST_WIDE_INT c, lsb, shift_mask;
12936 c = INTVAL (andop);
12937 if (c == 0 || c == ~0)
12941 shift_mask <<= INTVAL (shiftop);
12943 /* Find the least significant one bit. */
12946 /* It must coincide with the LSB of the shift mask. */
12947 if (-lsb != shift_mask)
12950 /* Invert to look for the next transition (if any). */
12953 /* Remove the low group of ones (originally low group of zeros). */
12956 /* Again find the lsb, and check we have all 1's above. */
12960 else if (GET_CODE (andop) == CONST_DOUBLE
12961 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12963 HOST_WIDE_INT low, high, lsb;
12964 HOST_WIDE_INT shift_mask_low, shift_mask_high;
12966 low = CONST_DOUBLE_LOW (andop);
12967 if (HOST_BITS_PER_WIDE_INT < 64)
12968 high = CONST_DOUBLE_HIGH (andop);
12970 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
12971 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
12974 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12976 shift_mask_high = ~0;
12977 if (INTVAL (shiftop) > 32)
12978 shift_mask_high <<= INTVAL (shiftop) - 32;
12980 lsb = high & -high;
12982 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
12988 lsb = high & -high;
12989 return high == -lsb;
12992 shift_mask_low = ~0;
12993 shift_mask_low <<= INTVAL (shiftop);
12997 if (-lsb != shift_mask_low)
13000 if (HOST_BITS_PER_WIDE_INT < 64)
13005 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13007 lsb = high & -high;
13008 return high == -lsb;
13012 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13018 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13019 to perform a left shift. It must have SHIFTOP or more least
13020 significant 0's, with the remainder of the word 1's. */
13023 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13025 if (GET_CODE (andop) == CONST_INT)
13027 HOST_WIDE_INT c, lsb, shift_mask;
13030 shift_mask <<= INTVAL (shiftop);
13031 c = INTVAL (andop);
13033 /* Find the least significant one bit. */
13036 /* It must be covered by the shift mask.
13037 This test also rejects c == 0. */
13038 if ((lsb & shift_mask) == 0)
13041 /* Check we have all 1's above the transition, and reject all 1's. */
13042 return c == -lsb && lsb != 1;
13044 else if (GET_CODE (andop) == CONST_DOUBLE
13045 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13047 HOST_WIDE_INT low, lsb, shift_mask_low;
13049 low = CONST_DOUBLE_LOW (andop);
13051 if (HOST_BITS_PER_WIDE_INT < 64)
13053 HOST_WIDE_INT high, shift_mask_high;
13055 high = CONST_DOUBLE_HIGH (andop);
13059 shift_mask_high = ~0;
13060 if (INTVAL (shiftop) > 32)
13061 shift_mask_high <<= INTVAL (shiftop) - 32;
13063 lsb = high & -high;
13065 if ((lsb & shift_mask_high) == 0)
13068 return high == -lsb;
13074 shift_mask_low = ~0;
13075 shift_mask_low <<= INTVAL (shiftop);
13079 if ((lsb & shift_mask_low) == 0)
13082 return low == -lsb && lsb != 1;
13088 /* Return 1 if operands will generate a valid arguments to rlwimi
13089 instruction for insert with right shift in 64-bit mode. The mask may
13090 not start on the first bit or stop on the last bit because wrap-around
13091 effects of instruction do not correspond to semantics of RTL insn. */
13094 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13096 if (INTVAL (startop) > 32
13097 && INTVAL (startop) < 64
13098 && INTVAL (sizeop) > 1
13099 && INTVAL (sizeop) + INTVAL (startop) < 64
13100 && INTVAL (shiftop) > 0
13101 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13102 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
13108 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13109 for lfq and stfq insns iff the registers are hard registers. */
13112 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
13114 /* We might have been passed a SUBREG. */
13115 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
13118 /* We might have been passed non floating point registers. */
13119 if (!FP_REGNO_P (REGNO (reg1))
13120 || !FP_REGNO_P (REGNO (reg2)))
13123 return (REGNO (reg1) == REGNO (reg2) - 1);
13126 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13127 addr1 and addr2 must be in consecutive memory locations
13128 (addr2 == addr1 + 8). */
13131 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
13134 unsigned int reg1, reg2;
13135 int offset1, offset2;
13137 /* The mems cannot be volatile. */
13138 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
13141 addr1 = XEXP (mem1, 0);
13142 addr2 = XEXP (mem2, 0);
13144 /* Extract an offset (if used) from the first addr. */
13145 if (GET_CODE (addr1) == PLUS)
13147 /* If not a REG, return zero. */
13148 if (GET_CODE (XEXP (addr1, 0)) != REG)
13152 reg1 = REGNO (XEXP (addr1, 0));
13153 /* The offset must be constant! */
13154 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13156 offset1 = INTVAL (XEXP (addr1, 1));
13159 else if (GET_CODE (addr1) != REG)
13163 reg1 = REGNO (addr1);
13164 /* This was a simple (mem (reg)) expression. Offset is 0. */
13168 /* And now for the second addr. */
13169 if (GET_CODE (addr2) == PLUS)
13171 /* If not a REG, return zero. */
13172 if (GET_CODE (XEXP (addr2, 0)) != REG)
13176 reg2 = REGNO (XEXP (addr2, 0));
13177 /* The offset must be constant. */
13178 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
13180 offset2 = INTVAL (XEXP (addr2, 1));
13183 else if (GET_CODE (addr2) != REG)
13187 reg2 = REGNO (addr2);
13188 /* This was a simple (mem (reg)) expression. Offset is 0. */
13192 /* Both of these must have the same base register. */
13196 /* The offset for the second addr must be 8 more than the first addr. */
13197 if (offset2 != offset1 + 8)
13200 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13207 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13209 static bool eliminated = false;
13212 if (mode != SDmode)
13213 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13216 rtx mem = cfun->machine->sdmode_stack_slot;
13217 gcc_assert (mem != NULL_RTX);
13221 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13222 cfun->machine->sdmode_stack_slot = mem;
13228 if (TARGET_DEBUG_ADDR)
13230 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13231 GET_MODE_NAME (mode));
13233 fprintf (stderr, "\tNULL_RTX\n");
13242 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13244 /* Don't walk into types. */
13245 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13247 *walk_subtrees = 0;
13251 switch (TREE_CODE (*tp))
13260 case ALIGN_INDIRECT_REF:
13261 case MISALIGNED_INDIRECT_REF:
13262 case VIEW_CONVERT_EXPR:
13263 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13273 enum reload_reg_type {
13275 VECTOR_REGISTER_TYPE,
13276 OTHER_REGISTER_TYPE
13279 static enum reload_reg_type
13280 rs6000_reload_register_type (enum reg_class rclass)
13286 return GPR_REGISTER_TYPE;
13291 return VECTOR_REGISTER_TYPE;
13294 return OTHER_REGISTER_TYPE;
13298 /* Inform reload about cases where moving X with a mode MODE to a register in
13299 RCLASS requires an extra scratch or immediate register. Return the class
13300 needed for the immediate register.
13302 For VSX and Altivec, we may need a register to convert sp+offset into
13305 static enum reg_class
13306 rs6000_secondary_reload (bool in_p,
13308 enum reg_class rclass,
13309 enum machine_mode mode,
13310 secondary_reload_info *sri)
13312 enum reg_class ret = ALL_REGS;
13313 enum insn_code icode;
13314 bool default_p = false;
13316 sri->icode = CODE_FOR_nothing;
13318 /* Convert vector loads and stores into gprs to use an additional base
13320 icode = rs6000_vector_reload[mode][in_p != false];
13321 if (icode != CODE_FOR_nothing)
13324 sri->icode = CODE_FOR_nothing;
13325 sri->extra_cost = 0;
13327 if (GET_CODE (x) == MEM)
13329 rtx addr = XEXP (x, 0);
13331 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13332 an extra register in that case, but it would need an extra
13333 register if the addressing is reg+reg or (reg+reg)&(-16). */
13334 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13336 if (!legitimate_indirect_address_p (addr, false)
13337 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13339 sri->icode = icode;
13340 /* account for splitting the loads, and converting the
13341 address from reg+reg to reg. */
13342 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13343 + ((GET_CODE (addr) == AND) ? 1 : 0));
13346 /* Loads to and stores from vector registers can only do reg+reg
13347 addressing. Altivec registers can also do (reg+reg)&(-16). */
13348 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13349 || rclass == FLOAT_REGS || rclass == NO_REGS)
13351 if (!VECTOR_MEM_ALTIVEC_P (mode)
13352 && GET_CODE (addr) == AND
13353 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13354 && INTVAL (XEXP (addr, 1)) == -16
13355 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13356 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13358 sri->icode = icode;
13359 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13362 else if (!legitimate_indirect_address_p (addr, false)
13363 && (rclass == NO_REGS
13364 || !legitimate_indexed_address_p (addr, false)))
13366 sri->icode = icode;
13367 sri->extra_cost = 1;
13370 icode = CODE_FOR_nothing;
13372 /* Any other loads, including to pseudo registers which haven't been
13373 assigned to a register yet, default to require a scratch
13377 sri->icode = icode;
13378 sri->extra_cost = 2;
13381 else if (REG_P (x))
13383 int regno = true_regnum (x);
13385 icode = CODE_FOR_nothing;
13386 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13390 enum reg_class xclass = REGNO_REG_CLASS (regno);
13391 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13392 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13394 /* If memory is needed, use default_secondary_reload to create the
13396 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13409 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13411 gcc_assert (ret != ALL_REGS);
13413 if (TARGET_DEBUG_ADDR)
13416 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13418 reg_class_names[ret],
13419 in_p ? "true" : "false",
13420 reg_class_names[rclass],
13421 GET_MODE_NAME (mode));
13424 fprintf (stderr, ", default secondary reload");
13426 if (sri->icode != CODE_FOR_nothing)
13427 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13428 insn_data[sri->icode].name, sri->extra_cost);
13430 fprintf (stderr, "\n");
13438 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13439 to SP+reg addressing. */
13442 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13444 int regno = true_regnum (reg);
13445 enum machine_mode mode = GET_MODE (reg);
13446 enum reg_class rclass;
13448 rtx and_op2 = NULL_RTX;
13451 rtx scratch_or_premodify = scratch;
13455 if (TARGET_DEBUG_ADDR)
13457 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13458 store_p ? "store" : "load");
13459 fprintf (stderr, "reg:\n");
13461 fprintf (stderr, "mem:\n");
13463 fprintf (stderr, "scratch:\n");
13464 debug_rtx (scratch);
13467 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13468 gcc_assert (GET_CODE (mem) == MEM);
13469 rclass = REGNO_REG_CLASS (regno);
13470 addr = XEXP (mem, 0);
13474 /* GPRs can handle reg + small constant, all other addresses need to use
13475 the scratch register. */
13478 if (GET_CODE (addr) == AND)
13480 and_op2 = XEXP (addr, 1);
13481 addr = XEXP (addr, 0);
13484 if (GET_CODE (addr) == PRE_MODIFY)
13486 scratch_or_premodify = XEXP (addr, 0);
13487 gcc_assert (REG_P (scratch_or_premodify));
13488 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13489 addr = XEXP (addr, 1);
13492 if (GET_CODE (addr) == PLUS
13493 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13494 || and_op2 != NULL_RTX))
13496 addr_op1 = XEXP (addr, 0);
13497 addr_op2 = XEXP (addr, 1);
13498 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13500 if (!REG_P (addr_op2)
13501 && (GET_CODE (addr_op2) != CONST_INT
13502 || !satisfies_constraint_I (addr_op2)))
13504 if (TARGET_DEBUG_ADDR)
13507 "\nMove plus addr to register %s, mode = %s: ",
13508 rs6000_reg_names[REGNO (scratch)],
13509 GET_MODE_NAME (mode));
13510 debug_rtx (addr_op2);
13512 rs6000_emit_move (scratch, addr_op2, Pmode);
13513 addr_op2 = scratch;
13516 emit_insn (gen_rtx_SET (VOIDmode,
13517 scratch_or_premodify,
13518 gen_rtx_PLUS (Pmode,
13522 addr = scratch_or_premodify;
13523 scratch_or_premodify = scratch;
13525 else if (!legitimate_indirect_address_p (addr, false)
13526 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13528 if (TARGET_DEBUG_ADDR)
13530 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13531 rs6000_reg_names[REGNO (scratch_or_premodify)],
13532 GET_MODE_NAME (mode));
13535 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13536 addr = scratch_or_premodify;
13537 scratch_or_premodify = scratch;
13541 /* Float/Altivec registers can only handle reg+reg addressing. Move
13542 other addresses into a scratch register. */
13547 /* With float regs, we need to handle the AND ourselves, since we can't
13548 use the Altivec instruction with an implicit AND -16. Allow scalar
13549 loads to float registers to use reg+offset even if VSX. */
13550 if (GET_CODE (addr) == AND
13551 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13552 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13553 || INTVAL (XEXP (addr, 1)) != -16
13554 || !VECTOR_MEM_ALTIVEC_P (mode)))
13556 and_op2 = XEXP (addr, 1);
13557 addr = XEXP (addr, 0);
13560 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13561 as the address later. */
13562 if (GET_CODE (addr) == PRE_MODIFY
13563 && (!VECTOR_MEM_VSX_P (mode)
13564 || and_op2 != NULL_RTX
13565 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13567 scratch_or_premodify = XEXP (addr, 0);
13568 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13570 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13571 addr = XEXP (addr, 1);
13574 if (legitimate_indirect_address_p (addr, false) /* reg */
13575 || legitimate_indexed_address_p (addr, false) /* reg+reg */
13576 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
13577 || (GET_CODE (addr) == AND /* Altivec memory */
13578 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13579 && INTVAL (XEXP (addr, 1)) == -16
13580 && VECTOR_MEM_ALTIVEC_P (mode))
13581 || (rclass == FLOAT_REGS /* legacy float mem */
13582 && GET_MODE_SIZE (mode) == 8
13583 && and_op2 == NULL_RTX
13584 && scratch_or_premodify == scratch
13585 && rs6000_legitimate_offset_address_p (mode, addr, false)))
13588 else if (GET_CODE (addr) == PLUS)
13590 addr_op1 = XEXP (addr, 0);
13591 addr_op2 = XEXP (addr, 1);
13592 gcc_assert (REG_P (addr_op1));
13594 if (TARGET_DEBUG_ADDR)
13596 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
13597 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13598 debug_rtx (addr_op2);
13600 rs6000_emit_move (scratch, addr_op2, Pmode);
13601 emit_insn (gen_rtx_SET (VOIDmode,
13602 scratch_or_premodify,
13603 gen_rtx_PLUS (Pmode,
13606 addr = scratch_or_premodify;
13607 scratch_or_premodify = scratch;
13610 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
13611 || GET_CODE (addr) == CONST_INT || REG_P (addr))
13613 if (TARGET_DEBUG_ADDR)
13615 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13616 rs6000_reg_names[REGNO (scratch_or_premodify)],
13617 GET_MODE_NAME (mode));
13621 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13622 addr = scratch_or_premodify;
13623 scratch_or_premodify = scratch;
13627 gcc_unreachable ();
13632 gcc_unreachable ();
13635 /* If the original address involved a pre-modify that we couldn't use the VSX
13636 memory instruction with update, and we haven't taken care of already,
13637 store the address in the pre-modify register and use that as the
13639 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
13641 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
13642 addr = scratch_or_premodify;
13645 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
13646 memory instruction, recreate the AND now, including the clobber which is
13647 generated by the general ANDSI3/ANDDI3 patterns for the
13648 andi. instruction. */
13649 if (and_op2 != NULL_RTX)
13651 if (! legitimate_indirect_address_p (addr, false))
13653 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
13657 if (TARGET_DEBUG_ADDR)
13659 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
13660 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13661 debug_rtx (and_op2);
13664 and_rtx = gen_rtx_SET (VOIDmode,
13666 gen_rtx_AND (Pmode,
13670 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
13671 emit_insn (gen_rtx_PARALLEL (VOIDmode,
13672 gen_rtvec (2, and_rtx, cc_clobber)));
13676 /* Adjust the address if it changed. */
13677 if (addr != XEXP (mem, 0))
13679 mem = change_address (mem, mode, addr);
13680 if (TARGET_DEBUG_ADDR)
13681 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
13684 /* Now create the move. */
13686 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
13688 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
13693 /* Target hook to return the cover classes for Integrated Register Allocator.
13694 Cover classes is a set of non-intersected register classes covering all hard
13695 registers used for register allocation purpose. Any move between two
13696 registers of a cover class should be cheaper than load or store of the
13697 registers. The value is array of register classes with LIM_REG_CLASSES used
13700 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
13701 account for the Altivec and Floating registers being subsets of the VSX
13702 register set under VSX, but distinct register sets on pre-VSX machines. */
13704 static const enum reg_class *
13705 rs6000_ira_cover_classes (void)
13707 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
13708 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
13710 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
13713 /* Allocate a 64-bit stack slot to be used for copying SDmode
13714 values through if this function has any SDmode references. */
13717 rs6000_alloc_sdmode_stack_slot (void)
13721 gimple_stmt_iterator gsi;
13723 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
13726 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
13728 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
13731 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13732 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13738 /* Check for any SDmode parameters of the function. */
13739 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
13741 if (TREE_TYPE (t) == error_mark_node)
13744 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
13745 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
13747 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13748 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13756 rs6000_instantiate_decls (void)
13758 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
13759 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
13762 /* Given an rtx X being reloaded into a reg required to be
13763 in class CLASS, return the class of reg to actually use.
13764 In general this is just CLASS; but on some machines
13765 in some cases it is preferable to use a more restrictive class.
13767 On the RS/6000, we have to return NO_REGS when we want to reload a
13768 floating-point CONST_DOUBLE to force it to be copied to memory.
13770 We also don't want to reload integer values into floating-point
13771 registers if we can at all help it. In fact, this can
13772 cause reload to die, if it tries to generate a reload of CTR
13773 into a FP register and discovers it doesn't have the memory location
13776 ??? Would it be a good idea to have reload do the converse, that is
13777 try to reload floating modes into FP registers if possible?
13780 static enum reg_class
13781 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
13783 enum machine_mode mode = GET_MODE (x);
13785 if (VECTOR_UNIT_VSX_P (mode)
13786 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
13789 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
13790 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
13791 && easy_vector_constant (x, mode))
13792 return ALTIVEC_REGS;
13794 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
13797 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
13798 return GENERAL_REGS;
13800 /* For VSX, prefer the traditional registers for DF if the address is of the
13801 form reg+offset because we can use the non-VSX loads. Prefer the Altivec
13802 registers if Altivec is handling the vector operations (i.e. V16QI, V8HI,
13804 if (rclass == VSX_REGS && VECTOR_MEM_VSX_P (mode))
13806 if (mode == DFmode && GET_CODE (x) == MEM)
13808 rtx addr = XEXP (x, 0);
13810 if (legitimate_indirect_address_p (addr, false)) /* reg */
13813 if (legitimate_indexed_address_p (addr, false)) /* reg+reg */
13816 if (GET_CODE (addr) == PRE_MODIFY
13817 && legitimate_indexed_address_p (XEXP (addr, 0), false))
13823 if (VECTOR_UNIT_ALTIVEC_P (mode))
13824 return ALTIVEC_REGS;
13832 /* Debug version of rs6000_preferred_reload_class. */
13833 static enum reg_class
13834 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
13836 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
13839 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
13841 reg_class_names[ret], reg_class_names[rclass],
13842 GET_MODE_NAME (GET_MODE (x)));
13848 /* If we are copying between FP or AltiVec registers and anything else, we need
13849 a memory location. The exception is when we are targeting ppc64 and the
13850 move to/from fpr to gpr instructions are available. Also, under VSX, you
13851 can copy vector registers from the FP register set to the Altivec register
13852 set and vice versa. */
13855 rs6000_secondary_memory_needed (enum reg_class class1,
13856 enum reg_class class2,
13857 enum machine_mode mode)
13859 if (class1 == class2)
13862 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
13863 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
13864 between these classes. But we need memory for other things that can go in
13865 FLOAT_REGS like SFmode. */
13867 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
13868 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
13869 || class1 == FLOAT_REGS))
13870 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
13871 && class2 != FLOAT_REGS);
13873 if (class1 == VSX_REGS || class2 == VSX_REGS)
13876 if (class1 == FLOAT_REGS
13877 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13878 || ((mode != DFmode)
13879 && (mode != DDmode)
13880 && (mode != DImode))))
13883 if (class2 == FLOAT_REGS
13884 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13885 || ((mode != DFmode)
13886 && (mode != DDmode)
13887 && (mode != DImode))))
13890 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
13896 /* Debug version of rs6000_secondary_memory_needed. */
13898 rs6000_debug_secondary_memory_needed (enum reg_class class1,
13899 enum reg_class class2,
13900 enum machine_mode mode)
13902 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
13905 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
13906 "class2 = %s, mode = %s\n",
13907 ret ? "true" : "false", reg_class_names[class1],
13908 reg_class_names[class2], GET_MODE_NAME (mode));
13913 /* Return the register class of a scratch register needed to copy IN into
13914 or out of a register in RCLASS in MODE. If it can be done directly,
13915 NO_REGS is returned. */
13917 static enum reg_class
13918 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
13923 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
13925 && MACHOPIC_INDIRECT
13929 /* We cannot copy a symbolic operand directly into anything
13930 other than BASE_REGS for TARGET_ELF. So indicate that a
13931 register from BASE_REGS is needed as an intermediate
13934 On Darwin, pic addresses require a load from memory, which
13935 needs a base register. */
13936 if (rclass != BASE_REGS
13937 && (GET_CODE (in) == SYMBOL_REF
13938 || GET_CODE (in) == HIGH
13939 || GET_CODE (in) == LABEL_REF
13940 || GET_CODE (in) == CONST))
13944 if (GET_CODE (in) == REG)
13946 regno = REGNO (in);
13947 if (regno >= FIRST_PSEUDO_REGISTER)
13949 regno = true_regnum (in);
13950 if (regno >= FIRST_PSEUDO_REGISTER)
13954 else if (GET_CODE (in) == SUBREG)
13956 regno = true_regnum (in);
13957 if (regno >= FIRST_PSEUDO_REGISTER)
13963 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
13965 if (rclass == GENERAL_REGS || rclass == BASE_REGS
13966 || (regno >= 0 && INT_REGNO_P (regno)))
13969 /* Constants, memory, and FP registers can go into FP registers. */
13970 if ((regno == -1 || FP_REGNO_P (regno))
13971 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
13972 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
13974 /* Memory, and FP/altivec registers can go into fp/altivec registers under
13977 && (regno == -1 || VSX_REGNO_P (regno))
13978 && VSX_REG_CLASS_P (rclass))
13981 /* Memory, and AltiVec registers can go into AltiVec registers. */
13982 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
13983 && rclass == ALTIVEC_REGS)
13986 /* We can copy among the CR registers. */
13987 if ((rclass == CR_REGS || rclass == CR0_REGS)
13988 && regno >= 0 && CR_REGNO_P (regno))
13991 /* Otherwise, we need GENERAL_REGS. */
13992 return GENERAL_REGS;
13995 /* Debug version of rs6000_secondary_reload_class. */
13996 static enum reg_class
13997 rs6000_debug_secondary_reload_class (enum reg_class rclass,
13998 enum machine_mode mode, rtx in)
14000 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14002 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14003 "mode = %s, input rtx:\n",
14004 reg_class_names[ret], reg_class_names[rclass],
14005 GET_MODE_NAME (mode));
14011 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14014 rs6000_cannot_change_mode_class (enum machine_mode from,
14015 enum machine_mode to,
14016 enum reg_class rclass)
14018 unsigned from_size = GET_MODE_SIZE (from);
14019 unsigned to_size = GET_MODE_SIZE (to);
14021 if (from_size != to_size)
14023 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14024 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14025 && reg_classes_intersect_p (xclass, rclass));
14028 if (TARGET_E500_DOUBLE
14029 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14030 || (((to) == TFmode) + ((from) == TFmode)) == 1
14031 || (((to) == DDmode) + ((from) == DDmode)) == 1
14032 || (((to) == TDmode) + ((from) == TDmode)) == 1
14033 || (((to) == DImode) + ((from) == DImode)) == 1))
14036 /* Since the VSX register set includes traditional floating point registers
14037 and altivec registers, just check for the size being different instead of
14038 trying to check whether the modes are vector modes. Otherwise it won't
14039 allow say DF and DI to change classes. */
14040 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14041 return (from_size != 8 && from_size != 16);
14043 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14044 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14047 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14048 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14054 /* Debug version of rs6000_cannot_change_mode_class. */
14056 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14057 enum machine_mode to,
14058 enum reg_class rclass)
14060 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
14063 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14064 "to = %s, rclass = %s\n",
14065 ret ? "true" : "false",
14066 GET_MODE_NAME (from), GET_MODE_NAME (to),
14067 reg_class_names[rclass]);
14072 /* Given a comparison operation, return the bit number in CCR to test. We
14073 know this is a valid comparison.
14075 SCC_P is 1 if this is for an scc. That means that %D will have been
14076 used instead of %C, so the bits will be in different places.
14078 Return -1 if OP isn't a valid comparison for some reason. */
14081 ccr_bit (rtx op, int scc_p)
14083 enum rtx_code code = GET_CODE (op);
14084 enum machine_mode cc_mode;
14089 if (!COMPARISON_P (op))
14092 reg = XEXP (op, 0);
14094 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14096 cc_mode = GET_MODE (reg);
14097 cc_regnum = REGNO (reg);
14098 base_bit = 4 * (cc_regnum - CR0_REGNO);
14100 validate_condition_mode (code, cc_mode);
14102 /* When generating a sCOND operation, only positive conditions are
14105 || code == EQ || code == GT || code == LT || code == UNORDERED
14106 || code == GTU || code == LTU);
14111 return scc_p ? base_bit + 3 : base_bit + 2;
14113 return base_bit + 2;
14114 case GT: case GTU: case UNLE:
14115 return base_bit + 1;
14116 case LT: case LTU: case UNGE:
14118 case ORDERED: case UNORDERED:
14119 return base_bit + 3;
14122 /* If scc, we will have done a cror to put the bit in the
14123 unordered position. So test that bit. For integer, this is ! LT
14124 unless this is an scc insn. */
14125 return scc_p ? base_bit + 3 : base_bit;
14128 return scc_p ? base_bit + 3 : base_bit + 1;
14131 gcc_unreachable ();
14135 /* Return the GOT register. */
14138 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
14140 /* The second flow pass currently (June 1999) can't update
14141 regs_ever_live without disturbing other parts of the compiler, so
14142 update it here to make the prolog/epilogue code happy. */
14143 if (!can_create_pseudo_p ()
14144 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
14145 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
14147 crtl->uses_pic_offset_table = 1;
14149 return pic_offset_table_rtx;
14152 /* Function to init struct machine_function.
14153 This will be called, via a pointer variable,
14154 from push_function_context. */
14156 static struct machine_function *
14157 rs6000_init_machine_status (void)
14159 return GGC_CNEW (machine_function);
14162 /* These macros test for integers and extract the low-order bits. */
14164 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
14165 && GET_MODE (X) == VOIDmode)
14167 #define INT_LOWPART(X) \
14168 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
14171 extract_MB (rtx op)
14174 unsigned long val = INT_LOWPART (op);
14176 /* If the high bit is zero, the value is the first 1 bit we find
14178 if ((val & 0x80000000) == 0)
14180 gcc_assert (val & 0xffffffff);
14183 while (((val <<= 1) & 0x80000000) == 0)
14188 /* If the high bit is set and the low bit is not, or the mask is all
14189 1's, the value is zero. */
14190 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14193 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14196 while (((val >>= 1) & 1) != 0)
14203 extract_ME (rtx op)
14206 unsigned long val = INT_LOWPART (op);
14208 /* If the low bit is zero, the value is the first 1 bit we find from
14210 if ((val & 1) == 0)
14212 gcc_assert (val & 0xffffffff);
14215 while (((val >>= 1) & 1) == 0)
14221 /* If the low bit is set and the high bit is not, or the mask is all
14222 1's, the value is 31. */
14223 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14226 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14229 while (((val <<= 1) & 0x80000000) != 0)
14235 /* Locate some local-dynamic symbol still in use by this function
14236 so that we can print its name in some tls_ld pattern. */
14238 static const char *
14239 rs6000_get_some_local_dynamic_name (void)
14243 if (cfun->machine->some_ld_name)
14244 return cfun->machine->some_ld_name;
14246 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14248 && for_each_rtx (&PATTERN (insn),
14249 rs6000_get_some_local_dynamic_name_1, 0))
14250 return cfun->machine->some_ld_name;
14252 gcc_unreachable ();
14255 /* Helper function for rs6000_get_some_local_dynamic_name. */
14258 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14262 if (GET_CODE (x) == SYMBOL_REF)
14264 const char *str = XSTR (x, 0);
14265 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14267 cfun->machine->some_ld_name = str;
14275 /* Write out a function code label. */
14278 rs6000_output_function_entry (FILE *file, const char *fname)
14280 if (fname[0] != '.')
14282 switch (DEFAULT_ABI)
14285 gcc_unreachable ();
14291 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14300 RS6000_OUTPUT_BASENAME (file, fname);
14302 assemble_name (file, fname);
14305 /* Print an operand. Recognize special options, documented below. */
14308 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14309 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14311 #define SMALL_DATA_RELOC "sda21"
14312 #define SMALL_DATA_REG 0
14316 print_operand (FILE *file, rtx x, int code)
14320 unsigned HOST_WIDE_INT uval;
14325 /* Write out an instruction after the call which may be replaced
14326 with glue code by the loader. This depends on the AIX version. */
14327 asm_fprintf (file, RS6000_CALL_GLUE);
14330 /* %a is output_address. */
14333 /* If X is a constant integer whose low-order 5 bits are zero,
14334 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14335 in the AIX assembler where "sri" with a zero shift count
14336 writes a trash instruction. */
14337 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14344 /* If constant, low-order 16 bits of constant, unsigned.
14345 Otherwise, write normally. */
14347 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14349 print_operand (file, x, 0);
14353 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14354 for 64-bit mask direction. */
14355 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14358 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14362 /* X is a CR register. Print the number of the GT bit of the CR. */
14363 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14364 output_operand_lossage ("invalid %%c value");
14366 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14370 /* Like 'J' but get to the GT bit only. */
14371 gcc_assert (GET_CODE (x) == REG);
14373 /* Bit 1 is GT bit. */
14374 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14376 /* Add one for shift count in rlinm for scc. */
14377 fprintf (file, "%d", i + 1);
14381 /* X is a CR register. Print the number of the EQ bit of the CR */
14382 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14383 output_operand_lossage ("invalid %%E value");
14385 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14389 /* X is a CR register. Print the shift count needed to move it
14390 to the high-order four bits. */
14391 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14392 output_operand_lossage ("invalid %%f value");
14394 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14398 /* Similar, but print the count for the rotate in the opposite
14400 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14401 output_operand_lossage ("invalid %%F value");
14403 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14407 /* X is a constant integer. If it is negative, print "m",
14408 otherwise print "z". This is to make an aze or ame insn. */
14409 if (GET_CODE (x) != CONST_INT)
14410 output_operand_lossage ("invalid %%G value");
14411 else if (INTVAL (x) >= 0)
14418 /* If constant, output low-order five bits. Otherwise, write
14421 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14423 print_operand (file, x, 0);
14427 /* If constant, output low-order six bits. Otherwise, write
14430 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14432 print_operand (file, x, 0);
14436 /* Print `i' if this is a constant, else nothing. */
14442 /* Write the bit number in CCR for jump. */
14443 i = ccr_bit (x, 0);
14445 output_operand_lossage ("invalid %%j code");
14447 fprintf (file, "%d", i);
14451 /* Similar, but add one for shift count in rlinm for scc and pass
14452 scc flag to `ccr_bit'. */
14453 i = ccr_bit (x, 1);
14455 output_operand_lossage ("invalid %%J code");
14457 /* If we want bit 31, write a shift count of zero, not 32. */
14458 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14462 /* X must be a constant. Write the 1's complement of the
14465 output_operand_lossage ("invalid %%k value");
14467 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14471 /* X must be a symbolic constant on ELF. Write an
14472 expression suitable for an 'addi' that adds in the low 16
14473 bits of the MEM. */
14474 if (GET_CODE (x) != CONST)
14476 print_operand_address (file, x);
14477 fputs ("@l", file);
14481 if (GET_CODE (XEXP (x, 0)) != PLUS
14482 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14483 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14484 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14485 output_operand_lossage ("invalid %%K value");
14486 print_operand_address (file, XEXP (XEXP (x, 0), 0));
14487 fputs ("@l", file);
14488 /* For GNU as, there must be a non-alphanumeric character
14489 between 'l' and the number. The '-' is added by
14490 print_operand() already. */
14491 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
14493 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
14497 /* %l is output_asm_label. */
14500 /* Write second word of DImode or DFmode reference. Works on register
14501 or non-indexed memory only. */
14502 if (GET_CODE (x) == REG)
14503 fputs (reg_names[REGNO (x) + 1], file);
14504 else if (GET_CODE (x) == MEM)
14506 /* Handle possible auto-increment. Since it is pre-increment and
14507 we have already done it, we can just use an offset of word. */
14508 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14509 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14510 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14512 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14513 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14516 output_address (XEXP (adjust_address_nv (x, SImode,
14520 if (small_data_operand (x, GET_MODE (x)))
14521 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14522 reg_names[SMALL_DATA_REG]);
14527 /* MB value for a mask operand. */
14528 if (! mask_operand (x, SImode))
14529 output_operand_lossage ("invalid %%m value");
14531 fprintf (file, "%d", extract_MB (x));
14535 /* ME value for a mask operand. */
14536 if (! mask_operand (x, SImode))
14537 output_operand_lossage ("invalid %%M value");
14539 fprintf (file, "%d", extract_ME (x));
14542 /* %n outputs the negative of its operand. */
14545 /* Write the number of elements in the vector times 4. */
14546 if (GET_CODE (x) != PARALLEL)
14547 output_operand_lossage ("invalid %%N value");
14549 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14553 /* Similar, but subtract 1 first. */
14554 if (GET_CODE (x) != PARALLEL)
14555 output_operand_lossage ("invalid %%O value");
14557 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14561 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14563 || INT_LOWPART (x) < 0
14564 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14565 output_operand_lossage ("invalid %%p value");
14567 fprintf (file, "%d", i);
14571 /* The operand must be an indirect memory reference. The result
14572 is the register name. */
14573 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14574 || REGNO (XEXP (x, 0)) >= 32)
14575 output_operand_lossage ("invalid %%P value");
14577 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14581 /* This outputs the logical code corresponding to a boolean
14582 expression. The expression may have one or both operands
14583 negated (if one, only the first one). For condition register
14584 logical operations, it will also treat the negated
14585 CR codes as NOTs, but not handle NOTs of them. */
14587 const char *const *t = 0;
14589 enum rtx_code code = GET_CODE (x);
14590 static const char * const tbl[3][3] = {
14591 { "and", "andc", "nor" },
14592 { "or", "orc", "nand" },
14593 { "xor", "eqv", "xor" } };
14597 else if (code == IOR)
14599 else if (code == XOR)
14602 output_operand_lossage ("invalid %%q value");
14604 if (GET_CODE (XEXP (x, 0)) != NOT)
14608 if (GET_CODE (XEXP (x, 1)) == NOT)
14626 /* X is a CR register. Print the mask for `mtcrf'. */
14627 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14628 output_operand_lossage ("invalid %%R value");
14630 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
14634 /* Low 5 bits of 32 - value */
14636 output_operand_lossage ("invalid %%s value");
14638 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
14642 /* PowerPC64 mask position. All 0's is excluded.
14643 CONST_INT 32-bit mask is considered sign-extended so any
14644 transition must occur within the CONST_INT, not on the boundary. */
14645 if (! mask64_operand (x, DImode))
14646 output_operand_lossage ("invalid %%S value");
14648 uval = INT_LOWPART (x);
14650 if (uval & 1) /* Clear Left */
14652 #if HOST_BITS_PER_WIDE_INT > 64
14653 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14657 else /* Clear Right */
14660 #if HOST_BITS_PER_WIDE_INT > 64
14661 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14667 gcc_assert (i >= 0);
14668 fprintf (file, "%d", i);
14672 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
14673 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
14675 /* Bit 3 is OV bit. */
14676 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
14678 /* If we want bit 31, write a shift count of zero, not 32. */
14679 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14683 /* Print the symbolic name of a branch target register. */
14684 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
14685 && REGNO (x) != CTR_REGNO))
14686 output_operand_lossage ("invalid %%T value");
14687 else if (REGNO (x) == LR_REGNO)
14688 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
14690 fputs ("ctr", file);
14694 /* High-order 16 bits of constant for use in unsigned operand. */
14696 output_operand_lossage ("invalid %%u value");
14698 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14699 (INT_LOWPART (x) >> 16) & 0xffff);
14703 /* High-order 16 bits of constant for use in signed operand. */
14705 output_operand_lossage ("invalid %%v value");
14707 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14708 (INT_LOWPART (x) >> 16) & 0xffff);
14712 /* Print `u' if this has an auto-increment or auto-decrement. */
14713 if (GET_CODE (x) == MEM
14714 && (GET_CODE (XEXP (x, 0)) == PRE_INC
14715 || GET_CODE (XEXP (x, 0)) == PRE_DEC
14716 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
14721 /* Print the trap code for this operand. */
14722 switch (GET_CODE (x))
14725 fputs ("eq", file); /* 4 */
14728 fputs ("ne", file); /* 24 */
14731 fputs ("lt", file); /* 16 */
14734 fputs ("le", file); /* 20 */
14737 fputs ("gt", file); /* 8 */
14740 fputs ("ge", file); /* 12 */
14743 fputs ("llt", file); /* 2 */
14746 fputs ("lle", file); /* 6 */
14749 fputs ("lgt", file); /* 1 */
14752 fputs ("lge", file); /* 5 */
14755 gcc_unreachable ();
14760 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
14763 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
14764 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
14766 print_operand (file, x, 0);
14770 /* MB value for a PowerPC64 rldic operand. */
14771 val = (GET_CODE (x) == CONST_INT
14772 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
14777 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
14778 if ((val <<= 1) < 0)
14781 #if HOST_BITS_PER_WIDE_INT == 32
14782 if (GET_CODE (x) == CONST_INT && i >= 0)
14783 i += 32; /* zero-extend high-part was all 0's */
14784 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
14786 val = CONST_DOUBLE_LOW (x);
14792 for ( ; i < 64; i++)
14793 if ((val <<= 1) < 0)
14798 fprintf (file, "%d", i + 1);
14802 /* X is a FPR or Altivec register used in a VSX context. */
14803 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
14804 output_operand_lossage ("invalid %%x value");
14807 int reg = REGNO (x);
14808 int vsx_reg = (FP_REGNO_P (reg)
14810 : reg - FIRST_ALTIVEC_REGNO + 32);
14812 #ifdef TARGET_REGNAMES
14813 if (TARGET_REGNAMES)
14814 fprintf (file, "%%vs%d", vsx_reg);
14817 fprintf (file, "%d", vsx_reg);
14822 if (GET_CODE (x) == MEM
14823 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
14824 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
14825 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
14830 /* Like 'L', for third word of TImode */
14831 if (GET_CODE (x) == REG)
14832 fputs (reg_names[REGNO (x) + 2], file);
14833 else if (GET_CODE (x) == MEM)
14835 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14836 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14837 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14838 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14839 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14841 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
14842 if (small_data_operand (x, GET_MODE (x)))
14843 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14844 reg_names[SMALL_DATA_REG]);
14849 /* X is a SYMBOL_REF. Write out the name preceded by a
14850 period and without any trailing data in brackets. Used for function
14851 names. If we are configured for System V (or the embedded ABI) on
14852 the PowerPC, do not emit the period, since those systems do not use
14853 TOCs and the like. */
14854 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14856 /* Mark the decl as referenced so that cgraph will output the
14858 if (SYMBOL_REF_DECL (x))
14859 mark_decl_referenced (SYMBOL_REF_DECL (x));
14861 /* For macho, check to see if we need a stub. */
14864 const char *name = XSTR (x, 0);
14866 if (MACHOPIC_INDIRECT
14867 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
14868 name = machopic_indirection_name (x, /*stub_p=*/true);
14870 assemble_name (file, name);
14872 else if (!DOT_SYMBOLS)
14873 assemble_name (file, XSTR (x, 0));
14875 rs6000_output_function_entry (file, XSTR (x, 0));
14879 /* Like 'L', for last word of TImode. */
14880 if (GET_CODE (x) == REG)
14881 fputs (reg_names[REGNO (x) + 3], file);
14882 else if (GET_CODE (x) == MEM)
14884 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14885 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14886 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14887 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14888 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14890 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
14891 if (small_data_operand (x, GET_MODE (x)))
14892 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14893 reg_names[SMALL_DATA_REG]);
14897 /* Print AltiVec or SPE memory operand. */
14902 gcc_assert (GET_CODE (x) == MEM);
14906 /* Ugly hack because %y is overloaded. */
14907 if ((TARGET_SPE || TARGET_E500_DOUBLE)
14908 && (GET_MODE_SIZE (GET_MODE (x)) == 8
14909 || GET_MODE (x) == TFmode
14910 || GET_MODE (x) == TImode))
14912 /* Handle [reg]. */
14913 if (GET_CODE (tmp) == REG)
14915 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
14918 /* Handle [reg+UIMM]. */
14919 else if (GET_CODE (tmp) == PLUS &&
14920 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
14924 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
14926 x = INTVAL (XEXP (tmp, 1));
14927 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
14931 /* Fall through. Must be [reg+reg]. */
14933 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
14934 && GET_CODE (tmp) == AND
14935 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
14936 && INTVAL (XEXP (tmp, 1)) == -16)
14937 tmp = XEXP (tmp, 0);
14938 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
14939 && GET_CODE (tmp) == PRE_MODIFY)
14940 tmp = XEXP (tmp, 1);
14941 if (GET_CODE (tmp) == REG)
14942 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
14945 if (!GET_CODE (tmp) == PLUS
14946 || !REG_P (XEXP (tmp, 0))
14947 || !REG_P (XEXP (tmp, 1)))
14949 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
14953 if (REGNO (XEXP (tmp, 0)) == 0)
14954 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
14955 reg_names[ REGNO (XEXP (tmp, 0)) ]);
14957 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
14958 reg_names[ REGNO (XEXP (tmp, 1)) ]);
14964 if (GET_CODE (x) == REG)
14965 fprintf (file, "%s", reg_names[REGNO (x)]);
14966 else if (GET_CODE (x) == MEM)
14968 /* We need to handle PRE_INC and PRE_DEC here, since we need to
14969 know the width from the mode. */
14970 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
14971 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
14972 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14973 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
14974 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
14975 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14976 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14977 output_address (XEXP (XEXP (x, 0), 1));
14979 output_address (XEXP (x, 0));
14982 output_addr_const (file, x);
14986 assemble_name (file, rs6000_get_some_local_dynamic_name ());
14990 output_operand_lossage ("invalid %%xn code");
14994 /* Print the address of an operand. */
14997 print_operand_address (FILE *file, rtx x)
14999 if (GET_CODE (x) == REG)
15000 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15001 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15002 || GET_CODE (x) == LABEL_REF)
15004 output_addr_const (file, x);
15005 if (small_data_operand (x, GET_MODE (x)))
15006 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15007 reg_names[SMALL_DATA_REG]);
15009 gcc_assert (!TARGET_TOC);
15011 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15013 gcc_assert (REG_P (XEXP (x, 0)));
15014 if (REGNO (XEXP (x, 0)) == 0)
15015 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15016 reg_names[ REGNO (XEXP (x, 0)) ]);
15018 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15019 reg_names[ REGNO (XEXP (x, 1)) ]);
15021 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15022 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15023 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15025 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15026 && CONSTANT_P (XEXP (x, 1)))
15028 output_addr_const (file, XEXP (x, 1));
15029 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15033 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15034 && CONSTANT_P (XEXP (x, 1)))
15036 fprintf (file, "lo16(");
15037 output_addr_const (file, XEXP (x, 1));
15038 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15041 else if (legitimate_constant_pool_address_p (x))
15043 output_addr_const (file, XEXP (x, 1));
15044 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15047 gcc_unreachable ();
15050 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
15053 rs6000_output_addr_const_extra (FILE *file, rtx x)
15055 if (GET_CODE (x) == UNSPEC)
15056 switch (XINT (x, 1))
15058 case UNSPEC_TOCREL:
15059 x = XVECEXP (x, 0, 0);
15060 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15061 output_addr_const (file, x);
15062 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
15065 assemble_name (file, toc_label_name);
15067 else if (TARGET_ELF)
15068 fputs ("@toc", file);
15072 case UNSPEC_MACHOPIC_OFFSET:
15073 output_addr_const (file, XVECEXP (x, 0, 0));
15075 machopic_output_function_base_name (file);
15082 /* Target hook for assembling integer objects. The PowerPC version has
15083 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15084 is defined. It also needs to handle DI-mode objects on 64-bit
15088 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15090 #ifdef RELOCATABLE_NEEDS_FIXUP
15091 /* Special handling for SI values. */
15092 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
15094 static int recurse = 0;
15096 /* For -mrelocatable, we mark all addresses that need to be fixed up
15097 in the .fixup section. */
15098 if (TARGET_RELOCATABLE
15099 && in_section != toc_section
15100 && in_section != text_section
15101 && !unlikely_text_section_p (in_section)
15103 && GET_CODE (x) != CONST_INT
15104 && GET_CODE (x) != CONST_DOUBLE
15110 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
15112 ASM_OUTPUT_LABEL (asm_out_file, buf);
15113 fprintf (asm_out_file, "\t.long\t(");
15114 output_addr_const (asm_out_file, x);
15115 fprintf (asm_out_file, ")@fixup\n");
15116 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
15117 ASM_OUTPUT_ALIGN (asm_out_file, 2);
15118 fprintf (asm_out_file, "\t.long\t");
15119 assemble_name (asm_out_file, buf);
15120 fprintf (asm_out_file, "\n\t.previous\n");
15124 /* Remove initial .'s to turn a -mcall-aixdesc function
15125 address into the address of the descriptor, not the function
15127 else if (GET_CODE (x) == SYMBOL_REF
15128 && XSTR (x, 0)[0] == '.'
15129 && DEFAULT_ABI == ABI_AIX)
15131 const char *name = XSTR (x, 0);
15132 while (*name == '.')
15135 fprintf (asm_out_file, "\t.long\t%s\n", name);
15139 #endif /* RELOCATABLE_NEEDS_FIXUP */
15140 return default_assemble_integer (x, size, aligned_p);
15143 #ifdef HAVE_GAS_HIDDEN
15144 /* Emit an assembler directive to set symbol visibility for DECL to
15145 VISIBILITY_TYPE. */
15148 rs6000_assemble_visibility (tree decl, int vis)
15150 /* Functions need to have their entry point symbol visibility set as
15151 well as their descriptor symbol visibility. */
15152 if (DEFAULT_ABI == ABI_AIX
15154 && TREE_CODE (decl) == FUNCTION_DECL)
15156 static const char * const visibility_types[] = {
15157 NULL, "internal", "hidden", "protected"
15160 const char *name, *type;
15162 name = ((* targetm.strip_name_encoding)
15163 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
15164 type = visibility_types[vis];
15166 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
15167 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
15170 default_assemble_visibility (decl, vis);
15175 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15177 /* Reversal of FP compares takes care -- an ordered compare
15178 becomes an unordered compare and vice versa. */
15179 if (mode == CCFPmode
15180 && (!flag_finite_math_only
15181 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15182 || code == UNEQ || code == LTGT))
15183 return reverse_condition_maybe_unordered (code);
15185 return reverse_condition (code);
15188 /* Generate a compare for CODE. Return a brand-new rtx that
15189 represents the result of the compare. */
15192 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15194 enum machine_mode comp_mode;
15195 rtx compare_result;
15196 enum rtx_code code = GET_CODE (cmp);
15197 rtx op0 = XEXP (cmp, 0);
15198 rtx op1 = XEXP (cmp, 1);
15200 if (FLOAT_MODE_P (mode))
15201 comp_mode = CCFPmode;
15202 else if (code == GTU || code == LTU
15203 || code == GEU || code == LEU)
15204 comp_mode = CCUNSmode;
15205 else if ((code == EQ || code == NE)
15206 && GET_CODE (op0) == SUBREG
15207 && GET_CODE (op1) == SUBREG
15208 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15209 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15210 /* These are unsigned values, perhaps there will be a later
15211 ordering compare that can be shared with this one.
15212 Unfortunately we cannot detect the signedness of the operands
15213 for non-subregs. */
15214 comp_mode = CCUNSmode;
15216 comp_mode = CCmode;
15218 /* First, the compare. */
15219 compare_result = gen_reg_rtx (comp_mode);
15221 /* E500 FP compare instructions on the GPRs. Yuck! */
15222 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15223 && FLOAT_MODE_P (mode))
15225 rtx cmp, or_result, compare_result2;
15226 enum machine_mode op_mode = GET_MODE (op0);
15228 if (op_mode == VOIDmode)
15229 op_mode = GET_MODE (op1);
15231 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15232 This explains the following mess. */
15236 case EQ: case UNEQ: case NE: case LTGT:
15240 cmp = (flag_finite_math_only && !flag_trapping_math)
15241 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15242 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15246 cmp = (flag_finite_math_only && !flag_trapping_math)
15247 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15248 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15252 cmp = (flag_finite_math_only && !flag_trapping_math)
15253 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15254 : gen_cmptfeq_gpr (compare_result, op0, op1);
15258 gcc_unreachable ();
15262 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15266 cmp = (flag_finite_math_only && !flag_trapping_math)
15267 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15268 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15272 cmp = (flag_finite_math_only && !flag_trapping_math)
15273 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15274 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15278 cmp = (flag_finite_math_only && !flag_trapping_math)
15279 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15280 : gen_cmptfgt_gpr (compare_result, op0, op1);
15284 gcc_unreachable ();
15288 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15292 cmp = (flag_finite_math_only && !flag_trapping_math)
15293 ? gen_tstsflt_gpr (compare_result, op0, op1)
15294 : gen_cmpsflt_gpr (compare_result, op0, op1);
15298 cmp = (flag_finite_math_only && !flag_trapping_math)
15299 ? gen_tstdflt_gpr (compare_result, op0, op1)
15300 : gen_cmpdflt_gpr (compare_result, op0, op1);
15304 cmp = (flag_finite_math_only && !flag_trapping_math)
15305 ? gen_tsttflt_gpr (compare_result, op0, op1)
15306 : gen_cmptflt_gpr (compare_result, op0, op1);
15310 gcc_unreachable ();
15314 gcc_unreachable ();
15317 /* Synthesize LE and GE from LT/GT || EQ. */
15318 if (code == LE || code == GE || code == LEU || code == GEU)
15324 case LE: code = LT; break;
15325 case GE: code = GT; break;
15326 case LEU: code = LT; break;
15327 case GEU: code = GT; break;
15328 default: gcc_unreachable ();
15331 compare_result2 = gen_reg_rtx (CCFPmode);
15337 cmp = (flag_finite_math_only && !flag_trapping_math)
15338 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15339 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15343 cmp = (flag_finite_math_only && !flag_trapping_math)
15344 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15345 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15349 cmp = (flag_finite_math_only && !flag_trapping_math)
15350 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15351 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15355 gcc_unreachable ();
15359 /* OR them together. */
15360 or_result = gen_reg_rtx (CCFPmode);
15361 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15363 compare_result = or_result;
15368 if (code == NE || code == LTGT)
15378 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15379 CLOBBERs to match cmptf_internal2 pattern. */
15380 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15381 && GET_MODE (op0) == TFmode
15382 && !TARGET_IEEEQUAD
15383 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15384 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15386 gen_rtx_SET (VOIDmode,
15388 gen_rtx_COMPARE (comp_mode, op0, op1)),
15389 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15390 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15391 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15392 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15393 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15394 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15395 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15396 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
15397 else if (GET_CODE (op1) == UNSPEC
15398 && XINT (op1, 1) == UNSPEC_SP_TEST)
15400 rtx op1b = XVECEXP (op1, 0, 0);
15401 comp_mode = CCEQmode;
15402 compare_result = gen_reg_rtx (CCEQmode);
15404 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15406 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15409 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15410 gen_rtx_COMPARE (comp_mode, op0, op1)));
15413 /* Some kinds of FP comparisons need an OR operation;
15414 under flag_finite_math_only we don't bother. */
15415 if (FLOAT_MODE_P (mode)
15416 && !flag_finite_math_only
15417 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15418 && (code == LE || code == GE
15419 || code == UNEQ || code == LTGT
15420 || code == UNGT || code == UNLT))
15422 enum rtx_code or1, or2;
15423 rtx or1_rtx, or2_rtx, compare2_rtx;
15424 rtx or_result = gen_reg_rtx (CCEQmode);
15428 case LE: or1 = LT; or2 = EQ; break;
15429 case GE: or1 = GT; or2 = EQ; break;
15430 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15431 case LTGT: or1 = LT; or2 = GT; break;
15432 case UNGT: or1 = UNORDERED; or2 = GT; break;
15433 case UNLT: or1 = UNORDERED; or2 = LT; break;
15434 default: gcc_unreachable ();
15436 validate_condition_mode (or1, comp_mode);
15437 validate_condition_mode (or2, comp_mode);
15438 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15439 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15440 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15441 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15443 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15445 compare_result = or_result;
15449 validate_condition_mode (code, GET_MODE (compare_result));
15451 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15455 /* Emit the RTL for an sCOND pattern. */
15458 rs6000_emit_sISEL (enum machine_mode mode, rtx operands[])
15461 enum machine_mode op_mode;
15462 enum rtx_code cond_code;
15463 rtx result = operands[0];
15465 condition_rtx = rs6000_generate_compare (operands[1], mode);
15466 cond_code = GET_CODE (condition_rtx);
15468 op_mode = GET_MODE (XEXP (operands[1], 0));
15469 if (op_mode == VOIDmode)
15470 op_mode = GET_MODE (XEXP (operands[1], 1));
15472 if (TARGET_POWERPC64 && GET_MODE (result) == DImode)
15474 PUT_MODE (condition_rtx, DImode);
15475 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15476 || cond_code == LTU)
15477 emit_insn (gen_isel_unsigned_di (result, condition_rtx,
15478 force_reg (DImode, const1_rtx),
15479 force_reg (DImode, const0_rtx),
15480 XEXP (condition_rtx, 0)));
15482 emit_insn (gen_isel_signed_di (result, condition_rtx,
15483 force_reg (DImode, const1_rtx),
15484 force_reg (DImode, const0_rtx),
15485 XEXP (condition_rtx, 0)));
15489 PUT_MODE (condition_rtx, SImode);
15490 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15491 || cond_code == LTU)
15492 emit_insn (gen_isel_unsigned_si (result, condition_rtx,
15493 force_reg (SImode, const1_rtx),
15494 force_reg (SImode, const0_rtx),
15495 XEXP (condition_rtx, 0)));
15497 emit_insn (gen_isel_signed_si (result, condition_rtx,
15498 force_reg (SImode, const1_rtx),
15499 force_reg (SImode, const0_rtx),
15500 XEXP (condition_rtx, 0)));
15505 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15508 enum machine_mode op_mode;
15509 enum rtx_code cond_code;
15510 rtx result = operands[0];
15512 if (TARGET_ISEL && (mode == SImode || mode == DImode))
15514 rs6000_emit_sISEL (mode, operands);
15518 condition_rtx = rs6000_generate_compare (operands[1], mode);
15519 cond_code = GET_CODE (condition_rtx);
15521 if (FLOAT_MODE_P (mode)
15522 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15526 PUT_MODE (condition_rtx, SImode);
15527 t = XEXP (condition_rtx, 0);
15529 gcc_assert (cond_code == NE || cond_code == EQ);
15531 if (cond_code == NE)
15532 emit_insn (gen_e500_flip_gt_bit (t, t));
15534 emit_insn (gen_move_from_CR_gt_bit (result, t));
15538 if (cond_code == NE
15539 || cond_code == GE || cond_code == LE
15540 || cond_code == GEU || cond_code == LEU
15541 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15543 rtx not_result = gen_reg_rtx (CCEQmode);
15544 rtx not_op, rev_cond_rtx;
15545 enum machine_mode cc_mode;
15547 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15549 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15550 SImode, XEXP (condition_rtx, 0), const0_rtx);
15551 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15552 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15553 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15556 op_mode = GET_MODE (XEXP (operands[1], 0));
15557 if (op_mode == VOIDmode)
15558 op_mode = GET_MODE (XEXP (operands[1], 1));
15560 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15562 PUT_MODE (condition_rtx, DImode);
15563 convert_move (result, condition_rtx, 0);
15567 PUT_MODE (condition_rtx, SImode);
15568 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15572 /* Emit a branch of kind CODE to location LOC. */
15575 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15577 rtx condition_rtx, loc_ref;
15579 condition_rtx = rs6000_generate_compare (operands[0], mode);
15580 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15581 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15582 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15583 loc_ref, pc_rtx)));
15586 /* Return the string to output a conditional branch to LABEL, which is
15587 the operand number of the label, or -1 if the branch is really a
15588 conditional return.
15590 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15591 condition code register and its mode specifies what kind of
15592 comparison we made.
15594 REVERSED is nonzero if we should reverse the sense of the comparison.
15596 INSN is the insn. */
15599 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
15601 static char string[64];
15602 enum rtx_code code = GET_CODE (op);
15603 rtx cc_reg = XEXP (op, 0);
15604 enum machine_mode mode = GET_MODE (cc_reg);
15605 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
15606 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
15607 int really_reversed = reversed ^ need_longbranch;
15613 validate_condition_mode (code, mode);
15615 /* Work out which way this really branches. We could use
15616 reverse_condition_maybe_unordered here always but this
15617 makes the resulting assembler clearer. */
15618 if (really_reversed)
15620 /* Reversal of FP compares takes care -- an ordered compare
15621 becomes an unordered compare and vice versa. */
15622 if (mode == CCFPmode)
15623 code = reverse_condition_maybe_unordered (code);
15625 code = reverse_condition (code);
15628 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
15630 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
15635 /* Opposite of GT. */
15644 gcc_unreachable ();
15650 /* Not all of these are actually distinct opcodes, but
15651 we distinguish them for clarity of the resulting assembler. */
15652 case NE: case LTGT:
15653 ccode = "ne"; break;
15654 case EQ: case UNEQ:
15655 ccode = "eq"; break;
15657 ccode = "ge"; break;
15658 case GT: case GTU: case UNGT:
15659 ccode = "gt"; break;
15661 ccode = "le"; break;
15662 case LT: case LTU: case UNLT:
15663 ccode = "lt"; break;
15664 case UNORDERED: ccode = "un"; break;
15665 case ORDERED: ccode = "nu"; break;
15666 case UNGE: ccode = "nl"; break;
15667 case UNLE: ccode = "ng"; break;
15669 gcc_unreachable ();
15672 /* Maybe we have a guess as to how likely the branch is.
15673 The old mnemonics don't have a way to specify this information. */
15675 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
15676 if (note != NULL_RTX)
15678 /* PROB is the difference from 50%. */
15679 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
15681 /* Only hint for highly probable/improbable branches on newer
15682 cpus as static prediction overrides processor dynamic
15683 prediction. For older cpus we may as well always hint, but
15684 assume not taken for branches that are very close to 50% as a
15685 mispredicted taken branch is more expensive than a
15686 mispredicted not-taken branch. */
15687 if (rs6000_always_hint
15688 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
15689 && br_prob_note_reliable_p (note)))
15691 if (abs (prob) > REG_BR_PROB_BASE / 20
15692 && ((prob > 0) ^ need_longbranch))
15700 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
15702 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
15704 /* We need to escape any '%' characters in the reg_names string.
15705 Assume they'd only be the first character.... */
15706 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
15708 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
15712 /* If the branch distance was too far, we may have to use an
15713 unconditional branch to go the distance. */
15714 if (need_longbranch)
15715 s += sprintf (s, ",$+8\n\tb %s", label);
15717 s += sprintf (s, ",%s", label);
15723 /* Return the string to flip the GT bit on a CR. */
15725 output_e500_flip_gt_bit (rtx dst, rtx src)
15727 static char string[64];
15730 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
15731 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
15734 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
15735 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
15737 sprintf (string, "crnot %d,%d", a, b);
15741 /* Return insn for VSX or Altivec comparisons. */
15744 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
15747 enum machine_mode mode = GET_MODE (op0);
15755 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
15761 mask = gen_reg_rtx (mode);
15762 emit_insn (gen_rtx_SET (VOIDmode,
15764 gen_rtx_fmt_ee (code, mode, op0, op1)));
15771 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
15772 DMODE is expected destination mode. This is a recursive function. */
15775 rs6000_emit_vector_compare (enum rtx_code rcode,
15777 enum machine_mode dmode)
15780 bool swap_operands = false;
15781 bool try_again = false;
15783 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
15784 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
15786 /* See if the comparison works as is. */
15787 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15795 swap_operands = true;
15800 swap_operands = true;
15808 /* Invert condition and try again.
15809 e.g., A != B becomes ~(A==B). */
15811 enum rtx_code rev_code;
15812 enum insn_code nor_code;
15815 rev_code = reverse_condition_maybe_unordered (rcode);
15816 if (rev_code == UNKNOWN)
15819 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
15820 if (nor_code == CODE_FOR_nothing)
15823 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
15827 mask = gen_reg_rtx (dmode);
15828 emit_insn (GEN_FCN (nor_code) (mask, mask2));
15836 /* Try GT/GTU/LT/LTU OR EQ */
15839 enum insn_code ior_code;
15840 enum rtx_code new_code;
15861 gcc_unreachable ();
15864 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
15865 if (ior_code == CODE_FOR_nothing)
15868 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
15872 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
15876 mask = gen_reg_rtx (dmode);
15877 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
15895 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15900 /* You only get two chances. */
15904 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
15905 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
15906 operands for the relation operation COND. */
15909 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
15910 rtx cond, rtx cc_op0, rtx cc_op1)
15912 enum machine_mode dest_mode = GET_MODE (dest);
15913 enum rtx_code rcode = GET_CODE (cond);
15914 enum machine_mode cc_mode = CCmode;
15918 bool invert_move = false;
15920 if (VECTOR_UNIT_NONE_P (dest_mode))
15925 /* Swap operands if we can, and fall back to doing the operation as
15926 specified, and doing a NOR to invert the test. */
15932 /* Invert condition and try again.
15933 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
15934 invert_move = true;
15935 rcode = reverse_condition_maybe_unordered (rcode);
15936 if (rcode == UNKNOWN)
15940 /* Mark unsigned tests with CCUNSmode. */
15945 cc_mode = CCUNSmode;
15952 /* Get the vector mask for the given relational operations. */
15953 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
15961 op_true = op_false;
15965 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
15966 emit_insn (gen_rtx_SET (VOIDmode,
15968 gen_rtx_IF_THEN_ELSE (dest_mode,
15975 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
15976 operands of the last comparison is nonzero/true, FALSE_COND if it
15977 is zero/false. Return 0 if the hardware has no such operation. */
15980 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15982 enum rtx_code code = GET_CODE (op);
15983 rtx op0 = XEXP (op, 0);
15984 rtx op1 = XEXP (op, 1);
15985 REAL_VALUE_TYPE c1;
15986 enum machine_mode compare_mode = GET_MODE (op0);
15987 enum machine_mode result_mode = GET_MODE (dest);
15989 bool is_against_zero;
15991 /* These modes should always match. */
15992 if (GET_MODE (op1) != compare_mode
15993 /* In the isel case however, we can use a compare immediate, so
15994 op1 may be a small constant. */
15995 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
15997 if (GET_MODE (true_cond) != result_mode)
15999 if (GET_MODE (false_cond) != result_mode)
16002 /* First, work out if the hardware can do this at all, or
16003 if it's too slow.... */
16004 if (!FLOAT_MODE_P (compare_mode))
16007 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16010 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16011 && SCALAR_FLOAT_MODE_P (compare_mode))
16014 is_against_zero = op1 == CONST0_RTX (compare_mode);
16016 /* A floating-point subtract might overflow, underflow, or produce
16017 an inexact result, thus changing the floating-point flags, so it
16018 can't be generated if we care about that. It's safe if one side
16019 of the construct is zero, since then no subtract will be
16021 if (SCALAR_FLOAT_MODE_P (compare_mode)
16022 && flag_trapping_math && ! is_against_zero)
16025 /* Eliminate half of the comparisons by switching operands, this
16026 makes the remaining code simpler. */
16027 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16028 || code == LTGT || code == LT || code == UNLE)
16030 code = reverse_condition_maybe_unordered (code);
16032 true_cond = false_cond;
16036 /* UNEQ and LTGT take four instructions for a comparison with zero,
16037 it'll probably be faster to use a branch here too. */
16038 if (code == UNEQ && HONOR_NANS (compare_mode))
16041 if (GET_CODE (op1) == CONST_DOUBLE)
16042 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16044 /* We're going to try to implement comparisons by performing
16045 a subtract, then comparing against zero. Unfortunately,
16046 Inf - Inf is NaN which is not zero, and so if we don't
16047 know that the operand is finite and the comparison
16048 would treat EQ different to UNORDERED, we can't do it. */
16049 if (HONOR_INFINITIES (compare_mode)
16050 && code != GT && code != UNGE
16051 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16052 /* Constructs of the form (a OP b ? a : b) are safe. */
16053 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16054 || (! rtx_equal_p (op0, true_cond)
16055 && ! rtx_equal_p (op1, true_cond))))
16058 /* At this point we know we can use fsel. */
16060 /* Reduce the comparison to a comparison against zero. */
16061 if (! is_against_zero)
16063 temp = gen_reg_rtx (compare_mode);
16064 emit_insn (gen_rtx_SET (VOIDmode, temp,
16065 gen_rtx_MINUS (compare_mode, op0, op1)));
16067 op1 = CONST0_RTX (compare_mode);
16070 /* If we don't care about NaNs we can reduce some of the comparisons
16071 down to faster ones. */
16072 if (! HONOR_NANS (compare_mode))
16078 true_cond = false_cond;
16091 /* Now, reduce everything down to a GE. */
16098 temp = gen_reg_rtx (compare_mode);
16099 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16104 temp = gen_reg_rtx (compare_mode);
16105 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
16110 temp = gen_reg_rtx (compare_mode);
16111 emit_insn (gen_rtx_SET (VOIDmode, temp,
16112 gen_rtx_NEG (compare_mode,
16113 gen_rtx_ABS (compare_mode, op0))));
16118 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16119 temp = gen_reg_rtx (result_mode);
16120 emit_insn (gen_rtx_SET (VOIDmode, temp,
16121 gen_rtx_IF_THEN_ELSE (result_mode,
16122 gen_rtx_GE (VOIDmode,
16124 true_cond, false_cond)));
16125 false_cond = true_cond;
16128 temp = gen_reg_rtx (compare_mode);
16129 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16134 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
16135 temp = gen_reg_rtx (result_mode);
16136 emit_insn (gen_rtx_SET (VOIDmode, temp,
16137 gen_rtx_IF_THEN_ELSE (result_mode,
16138 gen_rtx_GE (VOIDmode,
16140 true_cond, false_cond)));
16141 true_cond = false_cond;
16144 temp = gen_reg_rtx (compare_mode);
16145 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16150 gcc_unreachable ();
16153 emit_insn (gen_rtx_SET (VOIDmode, dest,
16154 gen_rtx_IF_THEN_ELSE (result_mode,
16155 gen_rtx_GE (VOIDmode,
16157 true_cond, false_cond)));
16161 /* Same as above, but for ints (isel). */
16164 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16166 rtx condition_rtx, cr;
16167 enum machine_mode mode = GET_MODE (dest);
16169 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
16172 /* We still have to do the compare, because isel doesn't do a
16173 compare, it just looks at the CRx bits set by a previous compare
16175 condition_rtx = rs6000_generate_compare (op, mode);
16176 cr = XEXP (condition_rtx, 0);
16178 if (mode == SImode)
16180 if (GET_MODE (cr) == CCmode)
16181 emit_insn (gen_isel_signed_si (dest, condition_rtx,
16182 true_cond, false_cond, cr));
16184 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
16185 true_cond, false_cond, cr));
16189 if (GET_MODE (cr) == CCmode)
16190 emit_insn (gen_isel_signed_di (dest, condition_rtx,
16191 true_cond, false_cond, cr));
16193 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
16194 true_cond, false_cond, cr));
16201 output_isel (rtx *operands)
16203 enum rtx_code code;
16205 code = GET_CODE (operands[1]);
16206 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
16208 PUT_CODE (operands[1], reverse_condition (code));
16209 return "isel %0,%3,%2,%j1";
16212 return "isel %0,%2,%3,%j1";
16216 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
16218 enum machine_mode mode = GET_MODE (op0);
16222 /* VSX/altivec have direct min/max insns. */
16223 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
16225 emit_insn (gen_rtx_SET (VOIDmode,
16227 gen_rtx_fmt_ee (code, mode, op0, op1)));
16231 if (code == SMAX || code == SMIN)
16236 if (code == SMAX || code == UMAX)
16237 target = emit_conditional_move (dest, c, op0, op1, mode,
16238 op0, op1, mode, 0);
16240 target = emit_conditional_move (dest, c, op0, op1, mode,
16241 op1, op0, mode, 0);
16242 gcc_assert (target);
16243 if (target != dest)
16244 emit_move_insn (dest, target);
16247 /* Emit instructions to perform a load-reserved/store-conditional operation.
16248 The operation performed is an atomic
16249 (set M (CODE:MODE M OP))
16250 If not NULL, BEFORE is atomically set to M before the operation, and
16251 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16252 If SYNC_P then a memory barrier is emitted before the operation.
16253 Either OP or M may be wrapped in a NOT operation. */
16256 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16257 rtx m, rtx op, rtx before_param, rtx after_param,
16260 enum machine_mode used_mode;
16261 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16264 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16265 rtx shift = NULL_RTX;
16268 emit_insn (gen_lwsync ());
16272 /* If this is smaller than SImode, we'll have to use SImode with
16274 if (mode == QImode || mode == HImode)
16278 if (MEM_ALIGN (used_m) >= 32)
16281 if (BYTES_BIG_ENDIAN)
16282 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16284 shift = GEN_INT (ishift);
16285 used_m = change_address (used_m, SImode, 0);
16289 rtx addrSI, aligned_addr;
16290 int shift_mask = mode == QImode ? 0x18 : 0x10;
16292 addrSI = gen_lowpart_common (SImode,
16293 force_reg (Pmode, XEXP (used_m, 0)));
16294 addrSI = force_reg (SImode, addrSI);
16295 shift = gen_reg_rtx (SImode);
16297 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16298 GEN_INT (shift_mask)));
16299 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16301 aligned_addr = expand_binop (Pmode, and_optab,
16303 GEN_INT (-4), NULL_RTX,
16304 1, OPTAB_LIB_WIDEN);
16305 used_m = change_address (used_m, SImode, aligned_addr);
16306 set_mem_align (used_m, 32);
16308 /* It's safe to keep the old alias set of USED_M, because
16309 the operation is atomic and only affects the original
16313 if (GET_CODE (op) == NOT)
16315 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16316 oldop = gen_rtx_NOT (SImode, oldop);
16319 oldop = lowpart_subreg (SImode, op, mode);
16325 newop = expand_binop (SImode, and_optab,
16326 oldop, GEN_INT (imask), NULL_RTX,
16327 1, OPTAB_LIB_WIDEN);
16328 emit_insn (gen_ashlsi3 (newop, newop, shift));
16331 case NOT: /* NAND */
16332 newop = expand_binop (SImode, ior_optab,
16333 oldop, GEN_INT (~imask), NULL_RTX,
16334 1, OPTAB_LIB_WIDEN);
16335 emit_insn (gen_rotlsi3 (newop, newop, shift));
16339 newop = expand_binop (SImode, ior_optab,
16340 oldop, GEN_INT (~imask), NULL_RTX,
16341 1, OPTAB_LIB_WIDEN);
16342 emit_insn (gen_rotlsi3 (newop, newop, shift));
16350 newop = expand_binop (SImode, and_optab,
16351 oldop, GEN_INT (imask), NULL_RTX,
16352 1, OPTAB_LIB_WIDEN);
16353 emit_insn (gen_ashlsi3 (newop, newop, shift));
16355 mask = gen_reg_rtx (SImode);
16356 emit_move_insn (mask, GEN_INT (imask));
16357 emit_insn (gen_ashlsi3 (mask, mask, shift));
16360 newop = gen_rtx_PLUS (SImode, m, newop);
16362 newop = gen_rtx_MINUS (SImode, m, newop);
16363 newop = gen_rtx_AND (SImode, newop, mask);
16364 newop = gen_rtx_IOR (SImode, newop,
16365 gen_rtx_AND (SImode,
16366 gen_rtx_NOT (SImode, mask),
16372 gcc_unreachable ();
16376 used_mode = SImode;
16377 before = gen_reg_rtx (used_mode);
16378 after = gen_reg_rtx (used_mode);
16383 before = before_param;
16384 after = after_param;
16386 if (before == NULL_RTX)
16387 before = gen_reg_rtx (used_mode);
16388 if (after == NULL_RTX)
16389 after = gen_reg_rtx (used_mode);
16392 if ((code == PLUS || code == MINUS)
16393 && used_mode != mode)
16394 the_op = op; /* Computed above. */
16395 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16396 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16397 else if (code == NOT)
16398 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16399 gen_rtx_NOT (used_mode, m),
16400 gen_rtx_NOT (used_mode, op));
16402 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16404 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16405 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16406 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16407 gen_rtx_UNSPEC (used_mode,
16408 gen_rtvec (1, the_op),
16410 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16412 if ((code == PLUS || code == MINUS) && used_mode != mode)
16413 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16414 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16416 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16417 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16419 /* Shift and mask the return values properly. */
16420 if (used_mode != mode && before_param)
16422 emit_insn (gen_lshrsi3 (before, before, shift));
16423 convert_move (before_param, before, 1);
16426 if (used_mode != mode && after_param)
16428 emit_insn (gen_lshrsi3 (after, after, shift));
16429 convert_move (after_param, after, 1);
16432 /* The previous sequence will end with a branch that's dependent on
16433 the conditional store, so placing an isync will ensure that no
16434 other instructions (especially, no load or store instructions)
16435 can start before the atomic operation completes. */
16437 emit_insn (gen_isync ());
16440 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16441 COND is true. Mark the jump as unlikely to be taken. */
16444 emit_unlikely_jump (rtx cond, rtx label)
16446 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16449 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16450 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16451 add_reg_note (x, REG_BR_PROB, very_unlikely);
16454 /* A subroutine of the atomic operation splitters. Emit a load-locked
16455 instruction in MODE. */
16458 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16460 rtx (*fn) (rtx, rtx) = NULL;
16461 if (mode == SImode)
16462 fn = gen_load_locked_si;
16463 else if (mode == DImode)
16464 fn = gen_load_locked_di;
16465 emit_insn (fn (reg, mem));
16468 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16469 instruction in MODE. */
16472 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16474 rtx (*fn) (rtx, rtx, rtx) = NULL;
16475 if (mode == SImode)
16476 fn = gen_store_conditional_si;
16477 else if (mode == DImode)
16478 fn = gen_store_conditional_di;
16480 /* Emit sync before stwcx. to address PPC405 Erratum. */
16481 if (PPC405_ERRATUM77)
16482 emit_insn (gen_memory_barrier ());
16484 emit_insn (fn (res, mem, val));
16487 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16488 to perform. MEM is the memory on which to operate. VAL is the second
16489 operand of the binary operator. BEFORE and AFTER are optional locations to
16490 return the value of MEM either before of after the operation. SCRATCH is
16491 a scratch register. */
16494 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16495 rtx before, rtx after, rtx scratch)
16497 enum machine_mode mode = GET_MODE (mem);
16498 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16500 emit_insn (gen_lwsync ());
16502 label = gen_label_rtx ();
16503 emit_label (label);
16504 label = gen_rtx_LABEL_REF (VOIDmode, label);
16506 if (before == NULL_RTX)
16508 emit_load_locked (mode, before, mem);
16511 x = gen_rtx_IOR (mode,
16512 gen_rtx_NOT (mode, before),
16513 gen_rtx_NOT (mode, val));
16514 else if (code == AND)
16515 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16517 x = gen_rtx_fmt_ee (code, mode, before, val);
16519 if (after != NULL_RTX)
16520 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16521 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16523 emit_store_conditional (mode, cond, mem, scratch);
16525 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16526 emit_unlikely_jump (x, label);
16528 emit_insn (gen_isync ());
16531 /* Expand an atomic compare and swap operation. MEM is the memory on which
16532 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16533 value to be stored. SCRATCH is a scratch GPR. */
16536 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16539 enum machine_mode mode = GET_MODE (mem);
16540 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16542 emit_insn (gen_lwsync ());
16544 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16545 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16546 emit_label (XEXP (label1, 0));
16548 emit_load_locked (mode, retval, mem);
16550 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16551 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16553 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16554 emit_unlikely_jump (x, label2);
16556 emit_move_insn (scratch, newval);
16557 emit_store_conditional (mode, cond, mem, scratch);
16559 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16560 emit_unlikely_jump (x, label1);
16562 emit_insn (gen_isync ());
16563 emit_label (XEXP (label2, 0));
16566 /* Expand an atomic test and set operation. MEM is the memory on which
16567 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16570 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16572 enum machine_mode mode = GET_MODE (mem);
16573 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16575 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16576 emit_label (XEXP (label, 0));
16578 emit_load_locked (mode, retval, mem);
16579 emit_move_insn (scratch, val);
16580 emit_store_conditional (mode, cond, mem, scratch);
16582 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16583 emit_unlikely_jump (x, label);
16585 emit_insn (gen_isync ());
16589 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
16591 enum machine_mode mode = GET_MODE (mem);
16592 rtx addrSI, align, wdst, shift, mask;
16593 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
16594 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16596 /* Shift amount for subword relative to aligned word. */
16597 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
16598 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
16599 shift = gen_reg_rtx (SImode);
16600 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16601 GEN_INT (shift_mask)));
16602 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16604 /* Shift and mask old value into position within word. */
16605 oldval = convert_modes (SImode, mode, oldval, 1);
16606 oldval = expand_binop (SImode, and_optab,
16607 oldval, GEN_INT (imask), NULL_RTX,
16608 1, OPTAB_LIB_WIDEN);
16609 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
16611 /* Shift and mask new value into position within word. */
16612 newval = convert_modes (SImode, mode, newval, 1);
16613 newval = expand_binop (SImode, and_optab,
16614 newval, GEN_INT (imask), NULL_RTX,
16615 1, OPTAB_LIB_WIDEN);
16616 emit_insn (gen_ashlsi3 (newval, newval, shift));
16618 /* Mask for insertion. */
16619 mask = gen_reg_rtx (SImode);
16620 emit_move_insn (mask, GEN_INT (imask));
16621 emit_insn (gen_ashlsi3 (mask, mask, shift));
16623 /* Address of aligned word containing subword. */
16624 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
16625 NULL_RTX, 1, OPTAB_LIB_WIDEN);
16626 mem = change_address (mem, SImode, align);
16627 set_mem_align (mem, 32);
16628 MEM_VOLATILE_P (mem) = 1;
16630 wdst = gen_reg_rtx (SImode);
16631 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
16632 oldval, newval, mem));
16634 /* Shift the result back. */
16635 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
16637 emit_move_insn (dst, gen_lowpart (mode, wdst));
16641 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
16642 rtx oldval, rtx newval, rtx mem,
16645 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16647 emit_insn (gen_lwsync ());
16648 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16649 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16650 emit_label (XEXP (label1, 0));
16652 emit_load_locked (SImode, scratch, mem);
16654 /* Mask subword within loaded value for comparison with oldval.
16655 Use UNSPEC_AND to avoid clobber.*/
16656 emit_insn (gen_rtx_SET (SImode, dest,
16657 gen_rtx_UNSPEC (SImode,
16658 gen_rtvec (2, scratch, mask),
16661 x = gen_rtx_COMPARE (CCmode, dest, oldval);
16662 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16664 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16665 emit_unlikely_jump (x, label2);
16667 /* Clear subword within loaded value for insertion of new value. */
16668 emit_insn (gen_rtx_SET (SImode, scratch,
16669 gen_rtx_AND (SImode,
16670 gen_rtx_NOT (SImode, mask), scratch)));
16671 emit_insn (gen_iorsi3 (scratch, scratch, newval));
16672 emit_store_conditional (SImode, cond, mem, scratch);
16674 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16675 emit_unlikely_jump (x, label1);
16677 emit_insn (gen_isync ());
16678 emit_label (XEXP (label2, 0));
16682 /* Emit instructions to move SRC to DST. Called by splitters for
16683 multi-register moves. It will emit at most one instruction for
16684 each register that is accessed; that is, it won't emit li/lis pairs
16685 (or equivalent for 64-bit code). One of SRC or DST must be a hard
16689 rs6000_split_multireg_move (rtx dst, rtx src)
16691 /* The register number of the first register being moved. */
16693 /* The mode that is to be moved. */
16694 enum machine_mode mode;
16695 /* The mode that the move is being done in, and its size. */
16696 enum machine_mode reg_mode;
16698 /* The number of registers that will be moved. */
16701 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
16702 mode = GET_MODE (dst);
16703 nregs = hard_regno_nregs[reg][mode];
16704 if (FP_REGNO_P (reg))
16705 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
16706 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
16707 else if (ALTIVEC_REGNO_P (reg))
16708 reg_mode = V16QImode;
16709 else if (TARGET_E500_DOUBLE && mode == TFmode)
16712 reg_mode = word_mode;
16713 reg_mode_size = GET_MODE_SIZE (reg_mode);
16715 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
16717 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
16719 /* Move register range backwards, if we might have destructive
16722 for (i = nregs - 1; i >= 0; i--)
16723 emit_insn (gen_rtx_SET (VOIDmode,
16724 simplify_gen_subreg (reg_mode, dst, mode,
16725 i * reg_mode_size),
16726 simplify_gen_subreg (reg_mode, src, mode,
16727 i * reg_mode_size)));
16733 bool used_update = false;
16734 rtx restore_basereg = NULL_RTX;
16736 if (MEM_P (src) && INT_REGNO_P (reg))
16740 if (GET_CODE (XEXP (src, 0)) == PRE_INC
16741 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
16744 breg = XEXP (XEXP (src, 0), 0);
16745 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
16746 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
16747 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
16748 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16749 src = replace_equiv_address (src, breg);
16751 else if (! rs6000_offsettable_memref_p (src))
16753 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
16755 rtx basereg = XEXP (XEXP (src, 0), 0);
16758 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
16759 emit_insn (gen_rtx_SET (VOIDmode, ndst,
16760 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
16761 used_update = true;
16764 emit_insn (gen_rtx_SET (VOIDmode, basereg,
16765 XEXP (XEXP (src, 0), 1)));
16766 src = replace_equiv_address (src, basereg);
16770 rtx basereg = gen_rtx_REG (Pmode, reg);
16771 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
16772 src = replace_equiv_address (src, basereg);
16776 breg = XEXP (src, 0);
16777 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
16778 breg = XEXP (breg, 0);
16780 /* If the base register we are using to address memory is
16781 also a destination reg, then change that register last. */
16783 && REGNO (breg) >= REGNO (dst)
16784 && REGNO (breg) < REGNO (dst) + nregs)
16785 j = REGNO (breg) - REGNO (dst);
16787 else if (MEM_P (dst) && INT_REGNO_P (reg))
16791 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
16792 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
16795 breg = XEXP (XEXP (dst, 0), 0);
16796 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
16797 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
16798 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
16800 /* We have to update the breg before doing the store.
16801 Use store with update, if available. */
16805 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16806 emit_insn (TARGET_32BIT
16807 ? (TARGET_POWERPC64
16808 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
16809 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
16810 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
16811 used_update = true;
16814 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16815 dst = replace_equiv_address (dst, breg);
16817 else if (!rs6000_offsettable_memref_p (dst)
16818 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
16820 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
16822 rtx basereg = XEXP (XEXP (dst, 0), 0);
16825 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16826 emit_insn (gen_rtx_SET (VOIDmode,
16827 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
16828 used_update = true;
16831 emit_insn (gen_rtx_SET (VOIDmode, basereg,
16832 XEXP (XEXP (dst, 0), 1)));
16833 dst = replace_equiv_address (dst, basereg);
16837 rtx basereg = XEXP (XEXP (dst, 0), 0);
16838 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
16839 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
16841 && REG_P (offsetreg)
16842 && REGNO (basereg) != REGNO (offsetreg));
16843 if (REGNO (basereg) == 0)
16845 rtx tmp = offsetreg;
16846 offsetreg = basereg;
16849 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
16850 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
16851 dst = replace_equiv_address (dst, basereg);
16854 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
16855 gcc_assert (rs6000_offsettable_memref_p (dst));
16858 for (i = 0; i < nregs; i++)
16860 /* Calculate index to next subword. */
16865 /* If compiler already emitted move of first word by
16866 store with update, no need to do anything. */
16867 if (j == 0 && used_update)
16870 emit_insn (gen_rtx_SET (VOIDmode,
16871 simplify_gen_subreg (reg_mode, dst, mode,
16872 j * reg_mode_size),
16873 simplify_gen_subreg (reg_mode, src, mode,
16874 j * reg_mode_size)));
16876 if (restore_basereg != NULL_RTX)
16877 emit_insn (restore_basereg);
16882 /* This page contains routines that are used to determine what the
16883 function prologue and epilogue code will do and write them out. */
16885 /* Return the first fixed-point register that is required to be
16886 saved. 32 if none. */
16889 first_reg_to_save (void)
16893 /* Find lowest numbered live register. */
16894 for (first_reg = 13; first_reg <= 31; first_reg++)
16895 if (df_regs_ever_live_p (first_reg)
16896 && (! call_used_regs[first_reg]
16897 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
16898 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
16899 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
16900 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
16905 && crtl->uses_pic_offset_table
16906 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
16907 return RS6000_PIC_OFFSET_TABLE_REGNUM;
16913 /* Similar, for FP regs. */
16916 first_fp_reg_to_save (void)
16920 /* Find lowest numbered live register. */
16921 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
16922 if (df_regs_ever_live_p (first_reg))
16928 /* Similar, for AltiVec regs. */
16931 first_altivec_reg_to_save (void)
16935 /* Stack frame remains as is unless we are in AltiVec ABI. */
16936 if (! TARGET_ALTIVEC_ABI)
16937 return LAST_ALTIVEC_REGNO + 1;
16939 /* On Darwin, the unwind routines are compiled without
16940 TARGET_ALTIVEC, and use save_world to save/restore the
16941 altivec registers when necessary. */
16942 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16943 && ! TARGET_ALTIVEC)
16944 return FIRST_ALTIVEC_REGNO + 20;
16946 /* Find lowest numbered live register. */
16947 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
16948 if (df_regs_ever_live_p (i))
16954 /* Return a 32-bit mask of the AltiVec registers we need to set in
16955 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
16956 the 32-bit word is 0. */
16958 static unsigned int
16959 compute_vrsave_mask (void)
16961 unsigned int i, mask = 0;
16963 /* On Darwin, the unwind routines are compiled without
16964 TARGET_ALTIVEC, and use save_world to save/restore the
16965 call-saved altivec registers when necessary. */
16966 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16967 && ! TARGET_ALTIVEC)
16970 /* First, find out if we use _any_ altivec registers. */
16971 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
16972 if (df_regs_ever_live_p (i))
16973 mask |= ALTIVEC_REG_BIT (i);
16978 /* Next, remove the argument registers from the set. These must
16979 be in the VRSAVE mask set by the caller, so we don't need to add
16980 them in again. More importantly, the mask we compute here is
16981 used to generate CLOBBERs in the set_vrsave insn, and we do not
16982 wish the argument registers to die. */
16983 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
16984 mask &= ~ALTIVEC_REG_BIT (i);
16986 /* Similarly, remove the return value from the set. */
16989 diddle_return_value (is_altivec_return_reg, &yes);
16991 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
16997 /* For a very restricted set of circumstances, we can cut down the
16998 size of prologues/epilogues by calling our own save/restore-the-world
17002 compute_save_world_info (rs6000_stack_t *info_ptr)
17004 info_ptr->world_save_p = 1;
17005 info_ptr->world_save_p
17006 = (WORLD_SAVE_P (info_ptr)
17007 && DEFAULT_ABI == ABI_DARWIN
17008 && ! (cfun->calls_setjmp && flag_exceptions)
17009 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17010 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17011 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17012 && info_ptr->cr_save_p);
17014 /* This will not work in conjunction with sibcalls. Make sure there
17015 are none. (This check is expensive, but seldom executed.) */
17016 if (WORLD_SAVE_P (info_ptr))
17019 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17020 if ( GET_CODE (insn) == CALL_INSN
17021 && SIBLING_CALL_P (insn))
17023 info_ptr->world_save_p = 0;
17028 if (WORLD_SAVE_P (info_ptr))
17030 /* Even if we're not touching VRsave, make sure there's room on the
17031 stack for it, if it looks like we're calling SAVE_WORLD, which
17032 will attempt to save it. */
17033 info_ptr->vrsave_size = 4;
17035 /* If we are going to save the world, we need to save the link register too. */
17036 info_ptr->lr_save_p = 1;
17038 /* "Save" the VRsave register too if we're saving the world. */
17039 if (info_ptr->vrsave_mask == 0)
17040 info_ptr->vrsave_mask = compute_vrsave_mask ();
17042 /* Because the Darwin register save/restore routines only handle
17043 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17045 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17046 && (info_ptr->first_altivec_reg_save
17047 >= FIRST_SAVED_ALTIVEC_REGNO));
17054 is_altivec_return_reg (rtx reg, void *xyes)
17056 bool *yes = (bool *) xyes;
17057 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17062 /* Calculate the stack information for the current function. This is
17063 complicated by having two separate calling sequences, the AIX calling
17064 sequence and the V.4 calling sequence.
17066 AIX (and Darwin/Mac OS X) stack frames look like:
17068 SP----> +---------------------------------------+
17069 | back chain to caller | 0 0
17070 +---------------------------------------+
17071 | saved CR | 4 8 (8-11)
17072 +---------------------------------------+
17074 +---------------------------------------+
17075 | reserved for compilers | 12 24
17076 +---------------------------------------+
17077 | reserved for binders | 16 32
17078 +---------------------------------------+
17079 | saved TOC pointer | 20 40
17080 +---------------------------------------+
17081 | Parameter save area (P) | 24 48
17082 +---------------------------------------+
17083 | Alloca space (A) | 24+P etc.
17084 +---------------------------------------+
17085 | Local variable space (L) | 24+P+A
17086 +---------------------------------------+
17087 | Float/int conversion temporary (X) | 24+P+A+L
17088 +---------------------------------------+
17089 | Save area for AltiVec registers (W) | 24+P+A+L+X
17090 +---------------------------------------+
17091 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
17092 +---------------------------------------+
17093 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
17094 +---------------------------------------+
17095 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
17096 +---------------------------------------+
17097 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
17098 +---------------------------------------+
17099 old SP->| back chain to caller's caller |
17100 +---------------------------------------+
17102 The required alignment for AIX configurations is two words (i.e., 8
17106 V.4 stack frames look like:
17108 SP----> +---------------------------------------+
17109 | back chain to caller | 0
17110 +---------------------------------------+
17111 | caller's saved LR | 4
17112 +---------------------------------------+
17113 | Parameter save area (P) | 8
17114 +---------------------------------------+
17115 | Alloca space (A) | 8+P
17116 +---------------------------------------+
17117 | Varargs save area (V) | 8+P+A
17118 +---------------------------------------+
17119 | Local variable space (L) | 8+P+A+V
17120 +---------------------------------------+
17121 | Float/int conversion temporary (X) | 8+P+A+V+L
17122 +---------------------------------------+
17123 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
17124 +---------------------------------------+
17125 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
17126 +---------------------------------------+
17127 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
17128 +---------------------------------------+
17129 | SPE: area for 64-bit GP registers |
17130 +---------------------------------------+
17131 | SPE alignment padding |
17132 +---------------------------------------+
17133 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
17134 +---------------------------------------+
17135 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
17136 +---------------------------------------+
17137 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
17138 +---------------------------------------+
17139 old SP->| back chain to caller's caller |
17140 +---------------------------------------+
17142 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
17143 given. (But note below and in sysv4.h that we require only 8 and
17144 may round up the size of our stack frame anyways. The historical
17145 reason is early versions of powerpc-linux which didn't properly
17146 align the stack at program startup. A happy side-effect is that
17147 -mno-eabi libraries can be used with -meabi programs.)
17149 The EABI configuration defaults to the V.4 layout. However,
17150 the stack alignment requirements may differ. If -mno-eabi is not
17151 given, the required stack alignment is 8 bytes; if -mno-eabi is
17152 given, the required alignment is 16 bytes. (But see V.4 comment
17155 #ifndef ABI_STACK_BOUNDARY
17156 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
17159 static rs6000_stack_t *
17160 rs6000_stack_info (void)
17162 static rs6000_stack_t info;
17163 rs6000_stack_t *info_ptr = &info;
17164 int reg_size = TARGET_32BIT ? 4 : 8;
17168 HOST_WIDE_INT non_fixed_size;
17170 memset (&info, 0, sizeof (info));
17174 /* Cache value so we don't rescan instruction chain over and over. */
17175 if (cfun->machine->insn_chain_scanned_p == 0)
17176 cfun->machine->insn_chain_scanned_p
17177 = spe_func_has_64bit_regs_p () + 1;
17178 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
17181 /* Select which calling sequence. */
17182 info_ptr->abi = DEFAULT_ABI;
17184 /* Calculate which registers need to be saved & save area size. */
17185 info_ptr->first_gp_reg_save = first_reg_to_save ();
17186 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
17187 even if it currently looks like we won't. Reload may need it to
17188 get at a constant; if so, it will have already created a constant
17189 pool entry for it. */
17190 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
17191 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
17192 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
17193 && crtl->uses_const_pool
17194 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
17195 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
17197 first_gp = info_ptr->first_gp_reg_save;
17199 info_ptr->gp_size = reg_size * (32 - first_gp);
17201 /* For the SPE, we have an additional upper 32-bits on each GPR.
17202 Ideally we should save the entire 64-bits only when the upper
17203 half is used in SIMD instructions. Since we only record
17204 registers live (not the size they are used in), this proves
17205 difficult because we'd have to traverse the instruction chain at
17206 the right time, taking reload into account. This is a real pain,
17207 so we opt to save the GPRs in 64-bits always if but one register
17208 gets used in 64-bits. Otherwise, all the registers in the frame
17209 get saved in 32-bits.
17211 So... since when we save all GPRs (except the SP) in 64-bits, the
17212 traditional GP save area will be empty. */
17213 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17214 info_ptr->gp_size = 0;
17216 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
17217 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
17219 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
17220 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
17221 - info_ptr->first_altivec_reg_save);
17223 /* Does this function call anything? */
17224 info_ptr->calls_p = (! current_function_is_leaf
17225 || cfun->machine->ra_needs_full_frame);
17227 /* Determine if we need to save the link register. */
17228 if ((DEFAULT_ABI == ABI_AIX
17230 && !TARGET_PROFILE_KERNEL)
17231 #ifdef TARGET_RELOCATABLE
17232 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
17234 || (info_ptr->first_fp_reg_save != 64
17235 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
17236 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
17237 || info_ptr->calls_p
17238 || rs6000_ra_ever_killed ())
17240 info_ptr->lr_save_p = 1;
17241 df_set_regs_ever_live (LR_REGNO, true);
17244 /* Determine if we need to save the condition code registers. */
17245 if (df_regs_ever_live_p (CR2_REGNO)
17246 || df_regs_ever_live_p (CR3_REGNO)
17247 || df_regs_ever_live_p (CR4_REGNO))
17249 info_ptr->cr_save_p = 1;
17250 if (DEFAULT_ABI == ABI_V4)
17251 info_ptr->cr_size = reg_size;
17254 /* If the current function calls __builtin_eh_return, then we need
17255 to allocate stack space for registers that will hold data for
17256 the exception handler. */
17257 if (crtl->calls_eh_return)
17260 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
17263 /* SPE saves EH registers in 64-bits. */
17264 ehrd_size = i * (TARGET_SPE_ABI
17265 && info_ptr->spe_64bit_regs_used != 0
17266 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
17271 /* Determine various sizes. */
17272 info_ptr->reg_size = reg_size;
17273 info_ptr->fixed_size = RS6000_SAVE_AREA;
17274 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
17275 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
17276 TARGET_ALTIVEC ? 16 : 8);
17277 if (FRAME_GROWS_DOWNWARD)
17278 info_ptr->vars_size
17279 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
17280 + info_ptr->parm_size,
17281 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
17282 - (info_ptr->fixed_size + info_ptr->vars_size
17283 + info_ptr->parm_size);
17285 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17286 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17288 info_ptr->spe_gp_size = 0;
17290 if (TARGET_ALTIVEC_ABI)
17291 info_ptr->vrsave_mask = compute_vrsave_mask ();
17293 info_ptr->vrsave_mask = 0;
17295 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17296 info_ptr->vrsave_size = 4;
17298 info_ptr->vrsave_size = 0;
17300 compute_save_world_info (info_ptr);
17302 /* Calculate the offsets. */
17303 switch (DEFAULT_ABI)
17307 gcc_unreachable ();
17311 info_ptr->fp_save_offset = - info_ptr->fp_size;
17312 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17314 if (TARGET_ALTIVEC_ABI)
17316 info_ptr->vrsave_save_offset
17317 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17319 /* Align stack so vector save area is on a quadword boundary.
17320 The padding goes above the vectors. */
17321 if (info_ptr->altivec_size != 0)
17322 info_ptr->altivec_padding_size
17323 = info_ptr->vrsave_save_offset & 0xF;
17325 info_ptr->altivec_padding_size = 0;
17327 info_ptr->altivec_save_offset
17328 = info_ptr->vrsave_save_offset
17329 - info_ptr->altivec_padding_size
17330 - info_ptr->altivec_size;
17331 gcc_assert (info_ptr->altivec_size == 0
17332 || info_ptr->altivec_save_offset % 16 == 0);
17334 /* Adjust for AltiVec case. */
17335 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17338 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17339 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17340 info_ptr->lr_save_offset = 2*reg_size;
17344 info_ptr->fp_save_offset = - info_ptr->fp_size;
17345 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17346 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17348 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17350 /* Align stack so SPE GPR save area is aligned on a
17351 double-word boundary. */
17352 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17353 info_ptr->spe_padding_size
17354 = 8 - (-info_ptr->cr_save_offset % 8);
17356 info_ptr->spe_padding_size = 0;
17358 info_ptr->spe_gp_save_offset
17359 = info_ptr->cr_save_offset
17360 - info_ptr->spe_padding_size
17361 - info_ptr->spe_gp_size;
17363 /* Adjust for SPE case. */
17364 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17366 else if (TARGET_ALTIVEC_ABI)
17368 info_ptr->vrsave_save_offset
17369 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17371 /* Align stack so vector save area is on a quadword boundary. */
17372 if (info_ptr->altivec_size != 0)
17373 info_ptr->altivec_padding_size
17374 = 16 - (-info_ptr->vrsave_save_offset % 16);
17376 info_ptr->altivec_padding_size = 0;
17378 info_ptr->altivec_save_offset
17379 = info_ptr->vrsave_save_offset
17380 - info_ptr->altivec_padding_size
17381 - info_ptr->altivec_size;
17383 /* Adjust for AltiVec case. */
17384 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17387 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17388 info_ptr->ehrd_offset -= ehrd_size;
17389 info_ptr->lr_save_offset = reg_size;
17393 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17394 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17395 + info_ptr->gp_size
17396 + info_ptr->altivec_size
17397 + info_ptr->altivec_padding_size
17398 + info_ptr->spe_gp_size
17399 + info_ptr->spe_padding_size
17401 + info_ptr->cr_size
17402 + info_ptr->vrsave_size,
17405 non_fixed_size = (info_ptr->vars_size
17406 + info_ptr->parm_size
17407 + info_ptr->save_size);
17409 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17410 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17412 /* Determine if we need to allocate any stack frame:
17414 For AIX we need to push the stack if a frame pointer is needed
17415 (because the stack might be dynamically adjusted), if we are
17416 debugging, if we make calls, or if the sum of fp_save, gp_save,
17417 and local variables are more than the space needed to save all
17418 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17419 + 18*8 = 288 (GPR13 reserved).
17421 For V.4 we don't have the stack cushion that AIX uses, but assume
17422 that the debugger can handle stackless frames. */
17424 if (info_ptr->calls_p)
17425 info_ptr->push_p = 1;
17427 else if (DEFAULT_ABI == ABI_V4)
17428 info_ptr->push_p = non_fixed_size != 0;
17430 else if (frame_pointer_needed)
17431 info_ptr->push_p = 1;
17433 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17434 info_ptr->push_p = 1;
17437 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17439 /* Zero offsets if we're not saving those registers. */
17440 if (info_ptr->fp_size == 0)
17441 info_ptr->fp_save_offset = 0;
17443 if (info_ptr->gp_size == 0)
17444 info_ptr->gp_save_offset = 0;
17446 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17447 info_ptr->altivec_save_offset = 0;
17449 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17450 info_ptr->vrsave_save_offset = 0;
17452 if (! TARGET_SPE_ABI
17453 || info_ptr->spe_64bit_regs_used == 0
17454 || info_ptr->spe_gp_size == 0)
17455 info_ptr->spe_gp_save_offset = 0;
17457 if (! info_ptr->lr_save_p)
17458 info_ptr->lr_save_offset = 0;
17460 if (! info_ptr->cr_save_p)
17461 info_ptr->cr_save_offset = 0;
17466 /* Return true if the current function uses any GPRs in 64-bit SIMD
17470 spe_func_has_64bit_regs_p (void)
17474 /* Functions that save and restore all the call-saved registers will
17475 need to save/restore the registers in 64-bits. */
17476 if (crtl->calls_eh_return
17477 || cfun->calls_setjmp
17478 || crtl->has_nonlocal_goto)
17481 insns = get_insns ();
17483 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17489 /* FIXME: This should be implemented with attributes...
17491 (set_attr "spe64" "true")....then,
17492 if (get_spe64(insn)) return true;
17494 It's the only reliable way to do the stuff below. */
17496 i = PATTERN (insn);
17497 if (GET_CODE (i) == SET)
17499 enum machine_mode mode = GET_MODE (SET_SRC (i));
17501 if (SPE_VECTOR_MODE (mode))
17503 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17513 debug_stack_info (rs6000_stack_t *info)
17515 const char *abi_string;
17518 info = rs6000_stack_info ();
17520 fprintf (stderr, "\nStack information for function %s:\n",
17521 ((current_function_decl && DECL_NAME (current_function_decl))
17522 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17527 default: abi_string = "Unknown"; break;
17528 case ABI_NONE: abi_string = "NONE"; break;
17529 case ABI_AIX: abi_string = "AIX"; break;
17530 case ABI_DARWIN: abi_string = "Darwin"; break;
17531 case ABI_V4: abi_string = "V.4"; break;
17534 fprintf (stderr, "\tABI = %5s\n", abi_string);
17536 if (TARGET_ALTIVEC_ABI)
17537 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17539 if (TARGET_SPE_ABI)
17540 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17542 if (info->first_gp_reg_save != 32)
17543 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17545 if (info->first_fp_reg_save != 64)
17546 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17548 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17549 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17550 info->first_altivec_reg_save);
17552 if (info->lr_save_p)
17553 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17555 if (info->cr_save_p)
17556 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17558 if (info->vrsave_mask)
17559 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17562 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17565 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17567 if (info->gp_save_offset)
17568 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17570 if (info->fp_save_offset)
17571 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17573 if (info->altivec_save_offset)
17574 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17575 info->altivec_save_offset);
17577 if (info->spe_gp_save_offset)
17578 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17579 info->spe_gp_save_offset);
17581 if (info->vrsave_save_offset)
17582 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17583 info->vrsave_save_offset);
17585 if (info->lr_save_offset)
17586 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
17588 if (info->cr_save_offset)
17589 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
17591 if (info->varargs_save_offset)
17592 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
17594 if (info->total_size)
17595 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17598 if (info->vars_size)
17599 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17602 if (info->parm_size)
17603 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
17605 if (info->fixed_size)
17606 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
17609 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
17611 if (info->spe_gp_size)
17612 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
17615 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
17617 if (info->altivec_size)
17618 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
17620 if (info->vrsave_size)
17621 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
17623 if (info->altivec_padding_size)
17624 fprintf (stderr, "\taltivec_padding_size= %5d\n",
17625 info->altivec_padding_size);
17627 if (info->spe_padding_size)
17628 fprintf (stderr, "\tspe_padding_size = %5d\n",
17629 info->spe_padding_size);
17632 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
17634 if (info->save_size)
17635 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
17637 if (info->reg_size != 4)
17638 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
17640 fprintf (stderr, "\n");
17644 rs6000_return_addr (int count, rtx frame)
17646 /* Currently we don't optimize very well between prolog and body
17647 code and for PIC code the code can be actually quite bad, so
17648 don't try to be too clever here. */
17649 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
17651 cfun->machine->ra_needs_full_frame = 1;
17658 plus_constant (copy_to_reg
17659 (gen_rtx_MEM (Pmode,
17660 memory_address (Pmode, frame))),
17661 RETURN_ADDRESS_OFFSET)));
17664 cfun->machine->ra_need_lr = 1;
17665 return get_hard_reg_initial_val (Pmode, LR_REGNO);
17668 /* Say whether a function is a candidate for sibcall handling or not.
17669 We do not allow indirect calls to be optimized into sibling calls.
17670 Also, we can't do it if there are any vector parameters; there's
17671 nowhere to put the VRsave code so it works; note that functions with
17672 vector parameters are required to have a prototype, so the argument
17673 type info must be available here. (The tail recursion case can work
17674 with vector parameters, but there's no way to distinguish here.) */
17676 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
17681 if (TARGET_ALTIVEC_VRSAVE)
17683 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
17684 type; type = TREE_CHAIN (type))
17686 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
17690 if (DEFAULT_ABI == ABI_DARWIN
17691 || ((*targetm.binds_local_p) (decl)
17692 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
17694 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
17696 if (!lookup_attribute ("longcall", attr_list)
17697 || lookup_attribute ("shortcall", attr_list))
17704 /* NULL if INSN insn is valid within a low-overhead loop.
17705 Otherwise return why doloop cannot be applied.
17706 PowerPC uses the COUNT register for branch on table instructions. */
17708 static const char *
17709 rs6000_invalid_within_doloop (const_rtx insn)
17712 return "Function call in the loop.";
17715 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
17716 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
17717 return "Computed branch in the loop.";
17723 rs6000_ra_ever_killed (void)
17729 if (cfun->is_thunk)
17732 /* regs_ever_live has LR marked as used if any sibcalls are present,
17733 but this should not force saving and restoring in the
17734 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
17735 clobbers LR, so that is inappropriate. */
17737 /* Also, the prologue can generate a store into LR that
17738 doesn't really count, like this:
17741 bcl to set PIC register
17745 When we're called from the epilogue, we need to avoid counting
17746 this as a store. */
17748 push_topmost_sequence ();
17749 top = get_insns ();
17750 pop_topmost_sequence ();
17751 reg = gen_rtx_REG (Pmode, LR_REGNO);
17753 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
17759 if (!SIBLING_CALL_P (insn))
17762 else if (find_regno_note (insn, REG_INC, LR_REGNO))
17764 else if (set_of (reg, insn) != NULL_RTX
17765 && !prologue_epilogue_contains (insn))
17772 /* Emit instructions needed to load the TOC register.
17773 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
17774 a constant pool; or for SVR4 -fpic. */
17777 rs6000_emit_load_toc_table (int fromprolog)
17780 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
17782 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
17785 rtx lab, tmp1, tmp2, got;
17787 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17788 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17790 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17792 got = rs6000_got_sym ();
17793 tmp1 = tmp2 = dest;
17796 tmp1 = gen_reg_rtx (Pmode);
17797 tmp2 = gen_reg_rtx (Pmode);
17799 emit_insn (gen_load_toc_v4_PIC_1 (lab));
17800 emit_move_insn (tmp1,
17801 gen_rtx_REG (Pmode, LR_REGNO));
17802 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
17803 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
17805 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
17807 emit_insn (gen_load_toc_v4_pic_si ());
17808 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
17810 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
17813 rtx temp0 = (fromprolog
17814 ? gen_rtx_REG (Pmode, 0)
17815 : gen_reg_rtx (Pmode));
17821 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17822 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17824 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
17825 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17827 emit_insn (gen_load_toc_v4_PIC_1 (symF));
17828 emit_move_insn (dest,
17829 gen_rtx_REG (Pmode, LR_REGNO));
17830 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
17836 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17837 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
17838 emit_move_insn (dest,
17839 gen_rtx_REG (Pmode, LR_REGNO));
17840 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
17842 emit_insn (gen_addsi3 (dest, temp0, dest));
17844 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
17846 /* This is for AIX code running in non-PIC ELF32. */
17849 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
17850 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17852 emit_insn (gen_elf_high (dest, realsym));
17853 emit_insn (gen_elf_low (dest, dest, realsym));
17857 gcc_assert (DEFAULT_ABI == ABI_AIX);
17860 emit_insn (gen_load_toc_aix_si (dest));
17862 emit_insn (gen_load_toc_aix_di (dest));
17866 /* Emit instructions to restore the link register after determining where
17867 its value has been stored. */
17870 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
17872 rs6000_stack_t *info = rs6000_stack_info ();
17875 operands[0] = source;
17876 operands[1] = scratch;
17878 if (info->lr_save_p)
17880 rtx frame_rtx = stack_pointer_rtx;
17881 HOST_WIDE_INT sp_offset = 0;
17884 if (frame_pointer_needed
17885 || cfun->calls_alloca
17886 || info->total_size > 32767)
17888 tmp = gen_frame_mem (Pmode, frame_rtx);
17889 emit_move_insn (operands[1], tmp);
17890 frame_rtx = operands[1];
17892 else if (info->push_p)
17893 sp_offset = info->total_size;
17895 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
17896 tmp = gen_frame_mem (Pmode, tmp);
17897 emit_move_insn (tmp, operands[0]);
17900 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
17903 static GTY(()) alias_set_type set = -1;
17906 get_TOC_alias_set (void)
17909 set = new_alias_set ();
17913 /* This returns nonzero if the current function uses the TOC. This is
17914 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
17915 is generated by the ABI_V4 load_toc_* patterns. */
17922 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
17925 rtx pat = PATTERN (insn);
17928 if (GET_CODE (pat) == PARALLEL)
17929 for (i = 0; i < XVECLEN (pat, 0); i++)
17931 rtx sub = XVECEXP (pat, 0, i);
17932 if (GET_CODE (sub) == USE)
17934 sub = XEXP (sub, 0);
17935 if (GET_CODE (sub) == UNSPEC
17936 && XINT (sub, 1) == UNSPEC_TOC)
17946 create_TOC_reference (rtx symbol)
17948 if (TARGET_DEBUG_ADDR)
17950 if (GET_CODE (symbol) == SYMBOL_REF)
17951 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
17955 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
17956 GET_RTX_NAME (GET_CODE (symbol)));
17957 debug_rtx (symbol);
17961 if (!can_create_pseudo_p ())
17962 df_set_regs_ever_live (TOC_REGISTER, true);
17963 return gen_rtx_PLUS (Pmode,
17964 gen_rtx_REG (Pmode, TOC_REGISTER),
17965 gen_rtx_CONST (Pmode,
17966 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL)));
17969 /* Issue assembly directives that create a reference to the given DWARF
17970 FRAME_TABLE_LABEL from the current function section. */
17972 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
17974 fprintf (asm_out_file, "\t.ref %s\n",
17975 TARGET_STRIP_NAME_ENCODING (frame_table_label));
17978 /* If _Unwind_* has been called from within the same module,
17979 toc register is not guaranteed to be saved to 40(1) on function
17980 entry. Save it there in that case. */
17983 rs6000_aix_emit_builtin_unwind_init (void)
17986 rtx stack_top = gen_reg_rtx (Pmode);
17987 rtx opcode_addr = gen_reg_rtx (Pmode);
17988 rtx opcode = gen_reg_rtx (SImode);
17989 rtx tocompare = gen_reg_rtx (SImode);
17990 rtx no_toc_save_needed = gen_label_rtx ();
17992 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
17993 emit_move_insn (stack_top, mem);
17995 mem = gen_frame_mem (Pmode,
17996 gen_rtx_PLUS (Pmode, stack_top,
17997 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
17998 emit_move_insn (opcode_addr, mem);
17999 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
18000 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
18001 : 0xE8410028, SImode));
18003 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
18004 SImode, NULL_RTX, NULL_RTX,
18005 no_toc_save_needed, -1);
18007 mem = gen_frame_mem (Pmode,
18008 gen_rtx_PLUS (Pmode, stack_top,
18009 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
18010 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
18011 emit_label (no_toc_save_needed);
18014 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18015 and the change to the stack pointer. */
18018 rs6000_emit_stack_tie (void)
18020 rtx mem = gen_frame_mem (BLKmode,
18021 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
18023 emit_insn (gen_stack_tie (mem));
18026 /* Emit the correct code for allocating stack space, as insns.
18027 If COPY_R12, make sure a copy of the old frame is left in r12.
18028 If COPY_R11, make sure a copy of the old frame is left in r11,
18029 in preference to r12 if COPY_R12.
18030 The generated code may use hard register 0 as a temporary. */
18033 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
18036 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18037 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
18038 rtx todec = gen_int_mode (-size, Pmode);
18041 if (INTVAL (todec) != -size)
18043 warning (0, "stack frame too large");
18044 emit_insn (gen_trap ());
18048 if (crtl->limit_stack)
18050 if (REG_P (stack_limit_rtx)
18051 && REGNO (stack_limit_rtx) > 1
18052 && REGNO (stack_limit_rtx) <= 31)
18054 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
18055 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18058 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
18060 && DEFAULT_ABI == ABI_V4)
18062 rtx toload = gen_rtx_CONST (VOIDmode,
18063 gen_rtx_PLUS (Pmode,
18067 emit_insn (gen_elf_high (tmp_reg, toload));
18068 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
18069 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18073 warning (0, "stack limit expression is not supported");
18076 if (copy_r12 || copy_r11)
18077 emit_move_insn (copy_r11
18078 ? gen_rtx_REG (Pmode, 11)
18079 : gen_rtx_REG (Pmode, 12),
18084 /* Need a note here so that try_split doesn't get confused. */
18085 if (get_last_insn () == NULL_RTX)
18086 emit_note (NOTE_INSN_DELETED);
18087 insn = emit_move_insn (tmp_reg, todec);
18088 try_split (PATTERN (insn), insn, 0);
18092 insn = emit_insn (TARGET_32BIT
18093 ? gen_movsi_update_stack (stack_reg, stack_reg,
18095 : gen_movdi_di_update_stack (stack_reg, stack_reg,
18096 todec, stack_reg));
18097 /* Since we didn't use gen_frame_mem to generate the MEM, grab
18098 it now and set the alias set/attributes. The above gen_*_update
18099 calls will generate a PARALLEL with the MEM set being the first
18101 par = PATTERN (insn);
18102 gcc_assert (GET_CODE (par) == PARALLEL);
18103 set = XVECEXP (par, 0, 0);
18104 gcc_assert (GET_CODE (set) == SET);
18105 mem = SET_DEST (set);
18106 gcc_assert (MEM_P (mem));
18107 MEM_NOTRAP_P (mem) = 1;
18108 set_mem_alias_set (mem, get_frame_alias_set ());
18110 RTX_FRAME_RELATED_P (insn) = 1;
18111 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
18112 gen_rtx_SET (VOIDmode, stack_reg,
18113 gen_rtx_PLUS (Pmode, stack_reg,
18114 GEN_INT (-size))));
18117 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
18118 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
18119 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
18120 deduce these equivalences by itself so it wasn't necessary to hold
18121 its hand so much. */
18124 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
18125 rtx reg2, rtx rreg)
18129 /* copy_rtx will not make unique copies of registers, so we need to
18130 ensure we don't have unwanted sharing here. */
18132 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18135 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18137 real = copy_rtx (PATTERN (insn));
18139 if (reg2 != NULL_RTX)
18140 real = replace_rtx (real, reg2, rreg);
18142 real = replace_rtx (real, reg,
18143 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
18144 STACK_POINTER_REGNUM),
18147 /* We expect that 'real' is either a SET or a PARALLEL containing
18148 SETs (and possibly other stuff). In a PARALLEL, all the SETs
18149 are important so they all have to be marked RTX_FRAME_RELATED_P. */
18151 if (GET_CODE (real) == SET)
18155 temp = simplify_rtx (SET_SRC (set));
18157 SET_SRC (set) = temp;
18158 temp = simplify_rtx (SET_DEST (set));
18160 SET_DEST (set) = temp;
18161 if (GET_CODE (SET_DEST (set)) == MEM)
18163 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18165 XEXP (SET_DEST (set), 0) = temp;
18172 gcc_assert (GET_CODE (real) == PARALLEL);
18173 for (i = 0; i < XVECLEN (real, 0); i++)
18174 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
18176 rtx set = XVECEXP (real, 0, i);
18178 temp = simplify_rtx (SET_SRC (set));
18180 SET_SRC (set) = temp;
18181 temp = simplify_rtx (SET_DEST (set));
18183 SET_DEST (set) = temp;
18184 if (GET_CODE (SET_DEST (set)) == MEM)
18186 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18188 XEXP (SET_DEST (set), 0) = temp;
18190 RTX_FRAME_RELATED_P (set) = 1;
18194 RTX_FRAME_RELATED_P (insn) = 1;
18195 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
18198 /* Returns an insn that has a vrsave set operation with the
18199 appropriate CLOBBERs. */
18202 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
18205 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
18206 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18209 = gen_rtx_SET (VOIDmode,
18211 gen_rtx_UNSPEC_VOLATILE (SImode,
18212 gen_rtvec (2, reg, vrsave),
18213 UNSPECV_SET_VRSAVE));
18217 /* We need to clobber the registers in the mask so the scheduler
18218 does not move sets to VRSAVE before sets of AltiVec registers.
18220 However, if the function receives nonlocal gotos, reload will set
18221 all call saved registers live. We will end up with:
18223 (set (reg 999) (mem))
18224 (parallel [ (set (reg vrsave) (unspec blah))
18225 (clobber (reg 999))])
18227 The clobber will cause the store into reg 999 to be dead, and
18228 flow will attempt to delete an epilogue insn. In this case, we
18229 need an unspec use/set of the register. */
18231 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18232 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18234 if (!epiloguep || call_used_regs [i])
18235 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
18236 gen_rtx_REG (V4SImode, i));
18239 rtx reg = gen_rtx_REG (V4SImode, i);
18242 = gen_rtx_SET (VOIDmode,
18244 gen_rtx_UNSPEC (V4SImode,
18245 gen_rtvec (1, reg), 27));
18249 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
18251 for (i = 0; i < nclobs; ++i)
18252 XVECEXP (insn, 0, i) = clobs[i];
18257 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
18258 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
18261 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
18262 unsigned int regno, int offset, HOST_WIDE_INT total_size)
18264 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
18265 rtx replacea, replaceb;
18267 int_rtx = GEN_INT (offset);
18269 /* Some cases that need register indexed addressing. */
18270 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
18271 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
18272 || (TARGET_E500_DOUBLE && mode == DFmode)
18274 && SPE_VECTOR_MODE (mode)
18275 && !SPE_CONST_OFFSET_OK (offset)))
18277 /* Whomever calls us must make sure r11 is available in the
18278 flow path of instructions in the prologue. */
18279 offset_rtx = gen_rtx_REG (Pmode, 11);
18280 emit_move_insn (offset_rtx, int_rtx);
18282 replacea = offset_rtx;
18283 replaceb = int_rtx;
18287 offset_rtx = int_rtx;
18288 replacea = NULL_RTX;
18289 replaceb = NULL_RTX;
18292 reg = gen_rtx_REG (mode, regno);
18293 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18294 mem = gen_frame_mem (mode, addr);
18296 insn = emit_move_insn (mem, reg);
18298 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18301 /* Emit an offset memory reference suitable for a frame store, while
18302 converting to a valid addressing mode. */
18305 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18307 rtx int_rtx, offset_rtx;
18309 int_rtx = GEN_INT (offset);
18311 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18312 || (TARGET_E500_DOUBLE && mode == DFmode))
18314 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18315 emit_move_insn (offset_rtx, int_rtx);
18318 offset_rtx = int_rtx;
18320 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18323 /* Look for user-defined global regs. We should not save and restore these,
18324 and cannot use stmw/lmw if there are any in its range. */
18327 no_global_regs_above (int first, bool gpr)
18330 int last = gpr ? 32 : 64;
18331 for (i = first; i < last; i++)
18332 if (global_regs[i])
18337 #ifndef TARGET_FIX_AND_CONTINUE
18338 #define TARGET_FIX_AND_CONTINUE 0
18341 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18342 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18343 #define LAST_SAVRES_REGISTER 31
18344 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18346 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18348 /* Temporary holding space for an out-of-line register save/restore
18350 static char savres_routine_name[30];
18352 /* Return the name for an out-of-line register save/restore routine.
18353 We are saving/restoring GPRs if GPR is true. */
18356 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18357 bool savep, bool gpr, bool lr)
18359 const char *prefix = "";
18360 const char *suffix = "";
18362 /* Different targets are supposed to define
18363 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18364 routine name could be defined with:
18366 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18368 This is a nice idea in practice, but in reality, things are
18369 complicated in several ways:
18371 - ELF targets have save/restore routines for GPRs.
18373 - SPE targets use different prefixes for 32/64-bit registers, and
18374 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18376 - PPC64 ELF targets have routines for save/restore of GPRs that
18377 differ in what they do with the link register, so having a set
18378 prefix doesn't work. (We only use one of the save routines at
18379 the moment, though.)
18381 - PPC32 elf targets have "exit" versions of the restore routines
18382 that restore the link register and can save some extra space.
18383 These require an extra suffix. (There are also "tail" versions
18384 of the restore routines and "GOT" versions of the save routines,
18385 but we don't generate those at present. Same problems apply,
18388 We deal with all this by synthesizing our own prefix/suffix and
18389 using that for the simple sprintf call shown above. */
18392 /* No floating point saves on the SPE. */
18396 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
18398 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
18403 else if (DEFAULT_ABI == ABI_V4)
18409 prefix = savep ? "_savegpr_" : "_restgpr_";
18411 prefix = savep ? "_savefpr_" : "_restfpr_";
18416 else if (DEFAULT_ABI == ABI_AIX)
18418 #ifndef POWERPC_LINUX
18419 /* No out-of-line save/restore routines for GPRs on AIX. */
18420 gcc_assert (!TARGET_AIX || !gpr);
18426 ? (lr ? "_savegpr0_" : "_savegpr1_")
18427 : (lr ? "_restgpr0_" : "_restgpr1_"));
18428 #ifdef POWERPC_LINUX
18430 prefix = (savep ? "_savefpr_" : "_restfpr_");
18434 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
18435 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
18438 else if (DEFAULT_ABI == ABI_DARWIN)
18439 sorry ("Out-of-line save/restore routines not supported on Darwin");
18441 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
18443 return savres_routine_name;
18446 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18447 We are saving/restoring GPRs if GPR is true. */
18450 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
18453 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18455 int select = ((savep ? 1 : 0) << 2
18457 /* On the SPE, we never have any FPRs, but we do have
18458 32/64-bit versions of the routines. */
18459 ? (info->spe_64bit_regs_used ? 1 : 0)
18460 : (gpr ? 1 : 0)) << 1)
18463 /* Don't generate bogus routine names. */
18464 gcc_assert (FIRST_SAVRES_REGISTER <= regno
18465 && regno <= LAST_SAVRES_REGISTER);
18467 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18473 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
18475 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18476 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18477 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
18483 /* Emit a sequence of insns, including a stack tie if needed, for
18484 resetting the stack pointer. If SAVRES is true, then don't reset the
18485 stack pointer, but move the base of the frame into r11 for use by
18486 out-of-line register restore routines. */
18489 rs6000_emit_stack_reset (rs6000_stack_t *info,
18490 rtx sp_reg_rtx, rtx frame_reg_rtx,
18491 int sp_offset, bool savres)
18493 /* This blockage is needed so that sched doesn't decide to move
18494 the sp change before the register restores. */
18495 if (frame_reg_rtx != sp_reg_rtx
18497 && info->spe_64bit_regs_used != 0
18498 && info->first_gp_reg_save != 32))
18499 rs6000_emit_stack_tie ();
18501 if (frame_reg_rtx != sp_reg_rtx)
18503 if (sp_offset != 0)
18505 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
18506 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
18507 GEN_INT (sp_offset)));
18510 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18512 else if (sp_offset != 0)
18514 /* If we are restoring registers out-of-line, we will be using the
18515 "exit" variants of the restore routines, which will reset the
18516 stack for us. But we do need to point r11 into the right place
18517 for those routines. */
18518 rtx dest_reg = (savres
18519 ? gen_rtx_REG (Pmode, 11)
18522 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18523 GEN_INT (sp_offset)));
18530 /* Construct a parallel rtx describing the effect of a call to an
18531 out-of-line register save/restore routine. */
18534 rs6000_make_savres_rtx (rs6000_stack_t *info,
18535 rtx frame_reg_rtx, int save_area_offset,
18536 enum machine_mode reg_mode,
18537 bool savep, bool gpr, bool lr)
18540 int offset, start_reg, end_reg, n_regs;
18541 int reg_size = GET_MODE_SIZE (reg_mode);
18547 ? info->first_gp_reg_save
18548 : info->first_fp_reg_save);
18549 end_reg = gpr ? 32 : 64;
18550 n_regs = end_reg - start_reg;
18551 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
18554 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18556 RTVEC_ELT (p, offset++)
18557 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18559 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
18560 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18561 RTVEC_ELT (p, offset++)
18562 = gen_rtx_USE (VOIDmode,
18563 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
18567 for (i = 0; i < end_reg - start_reg; i++)
18569 rtx addr, reg, mem;
18570 reg = gen_rtx_REG (reg_mode, start_reg + i);
18571 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18572 GEN_INT (save_area_offset + reg_size*i));
18573 mem = gen_frame_mem (reg_mode, addr);
18575 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
18577 savep ? reg : mem);
18582 rtx addr, reg, mem;
18583 reg = gen_rtx_REG (Pmode, 0);
18584 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18585 GEN_INT (info->lr_save_offset));
18586 mem = gen_frame_mem (Pmode, addr);
18587 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
18590 return gen_rtx_PARALLEL (VOIDmode, p);
18593 /* Determine whether the gp REG is really used. */
18596 rs6000_reg_live_or_pic_offset_p (int reg)
18598 return ((df_regs_ever_live_p (reg)
18599 && (!call_used_regs[reg]
18600 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18601 && TARGET_TOC && TARGET_MINIMAL_TOC)))
18602 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18603 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18604 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
18608 SAVRES_MULTIPLE = 0x1,
18609 SAVRES_INLINE_FPRS = 0x2,
18610 SAVRES_INLINE_GPRS = 0x4,
18611 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
18612 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
18613 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
18616 /* Determine the strategy for savings/restoring registers. */
18619 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
18620 int using_static_chain_p, int sibcall)
18622 bool using_multiple_p;
18624 bool savres_fprs_inline;
18625 bool savres_gprs_inline;
18626 bool noclobber_global_gprs
18627 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
18630 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
18631 && (!TARGET_SPE_ABI
18632 || info->spe_64bit_regs_used == 0)
18633 && info->first_gp_reg_save < 31
18634 && noclobber_global_gprs);
18635 /* Don't bother to try to save things out-of-line if r11 is occupied
18636 by the static chain. It would require too much fiddling and the
18637 static chain is rarely used anyway. */
18638 common = (using_static_chain_p
18640 || crtl->calls_eh_return
18641 || !info->lr_save_p
18642 || cfun->machine->ra_need_lr
18643 || info->total_size > 32767);
18644 savres_fprs_inline = (common
18645 || info->first_fp_reg_save == 64
18646 || !no_global_regs_above (info->first_fp_reg_save,
18648 /* The out-of-line FP routines use
18649 double-precision stores; we can't use those
18650 routines if we don't have such stores. */
18651 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18652 || FP_SAVE_INLINE (info->first_fp_reg_save));
18653 savres_gprs_inline = (common
18654 /* Saving CR interferes with the exit routines
18655 used on the SPE, so just punt here. */
18658 && info->spe_64bit_regs_used != 0
18659 && info->cr_save_p != 0)
18660 || info->first_gp_reg_save == 32
18661 || !noclobber_global_gprs
18662 || GP_SAVE_INLINE (info->first_gp_reg_save));
18665 /* If we are going to use store multiple, then don't even bother
18666 with the out-of-line routines, since the store-multiple instruction
18667 will always be smaller. */
18668 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18671 /* The situation is more complicated with load multiple. We'd
18672 prefer to use the out-of-line routines for restores, since the
18673 "exit" out-of-line routines can handle the restore of LR and
18674 the frame teardown. But we can only use the out-of-line
18675 routines if we know that we've used store multiple or
18676 out-of-line routines in the prologue, i.e. if we've saved all
18677 the registers from first_gp_reg_save. Otherwise, we risk
18678 loading garbage from the stack. Furthermore, we can only use
18679 the "exit" out-of-line gpr restore if we haven't saved any
18681 bool saved_all = !savres_gprs_inline || using_multiple_p;
18683 if (saved_all && info->first_fp_reg_save != 64)
18684 /* We can't use the exit routine; use load multiple if it's
18686 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18689 strategy = (using_multiple_p
18690 | (savres_fprs_inline << 1)
18691 | (savres_gprs_inline << 2));
18692 #ifdef POWERPC_LINUX
18695 if (!savres_fprs_inline)
18696 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
18697 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
18698 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
18701 if (TARGET_AIX && !savres_fprs_inline)
18702 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18707 /* Emit function prologue as insns. */
18710 rs6000_emit_prologue (void)
18712 rs6000_stack_t *info = rs6000_stack_info ();
18713 enum machine_mode reg_mode = Pmode;
18714 int reg_size = TARGET_32BIT ? 4 : 8;
18715 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18716 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
18717 rtx frame_reg_rtx = sp_reg_rtx;
18718 rtx cr_save_rtx = NULL_RTX;
18721 int saving_FPRs_inline;
18722 int saving_GPRs_inline;
18723 int using_store_multiple;
18724 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18725 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18726 && call_used_regs[STATIC_CHAIN_REGNUM]);
18727 HOST_WIDE_INT sp_offset = 0;
18729 if (TARGET_FIX_AND_CONTINUE)
18731 /* gdb on darwin arranges to forward a function from the old
18732 address by modifying the first 5 instructions of the function
18733 to branch to the overriding function. This is necessary to
18734 permit function pointers that point to the old function to
18735 actually forward to the new function. */
18736 emit_insn (gen_nop ());
18737 emit_insn (gen_nop ());
18738 emit_insn (gen_nop ());
18739 emit_insn (gen_nop ());
18740 emit_insn (gen_nop ());
18743 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
18745 reg_mode = V2SImode;
18749 strategy = rs6000_savres_strategy (info, /*savep=*/true,
18750 /*static_chain_p=*/using_static_chain_p,
18752 using_store_multiple = strategy & SAVRES_MULTIPLE;
18753 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
18754 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
18756 /* For V.4, update stack before we do any saving and set back pointer. */
18757 if (! WORLD_SAVE_P (info)
18759 && (DEFAULT_ABI == ABI_V4
18760 || crtl->calls_eh_return))
18762 bool need_r11 = (TARGET_SPE
18763 ? (!saving_GPRs_inline
18764 && info->spe_64bit_regs_used == 0)
18765 : (!saving_FPRs_inline || !saving_GPRs_inline));
18766 if (info->total_size < 32767)
18767 sp_offset = info->total_size;
18769 frame_reg_rtx = (need_r11
18770 ? gen_rtx_REG (Pmode, 11)
18772 rs6000_emit_allocate_stack (info->total_size,
18773 (frame_reg_rtx != sp_reg_rtx
18774 && (info->cr_save_p
18776 || info->first_fp_reg_save < 64
18777 || info->first_gp_reg_save < 32
18780 if (frame_reg_rtx != sp_reg_rtx)
18781 rs6000_emit_stack_tie ();
18784 /* Handle world saves specially here. */
18785 if (WORLD_SAVE_P (info))
18792 /* save_world expects lr in r0. */
18793 reg0 = gen_rtx_REG (Pmode, 0);
18794 if (info->lr_save_p)
18796 insn = emit_move_insn (reg0,
18797 gen_rtx_REG (Pmode, LR_REGNO));
18798 RTX_FRAME_RELATED_P (insn) = 1;
18801 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
18802 assumptions about the offsets of various bits of the stack
18804 gcc_assert (info->gp_save_offset == -220
18805 && info->fp_save_offset == -144
18806 && info->lr_save_offset == 8
18807 && info->cr_save_offset == 4
18810 && (!crtl->calls_eh_return
18811 || info->ehrd_offset == -432)
18812 && info->vrsave_save_offset == -224
18813 && info->altivec_save_offset == -416);
18815 treg = gen_rtx_REG (SImode, 11);
18816 emit_move_insn (treg, GEN_INT (-info->total_size));
18818 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
18819 in R11. It also clobbers R12, so beware! */
18821 /* Preserve CR2 for save_world prologues */
18823 sz += 32 - info->first_gp_reg_save;
18824 sz += 64 - info->first_fp_reg_save;
18825 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
18826 p = rtvec_alloc (sz);
18828 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
18829 gen_rtx_REG (SImode,
18831 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
18832 gen_rtx_SYMBOL_REF (Pmode,
18834 /* We do floats first so that the instruction pattern matches
18836 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18838 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18839 ? DFmode : SFmode),
18840 info->first_fp_reg_save + i);
18841 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18842 GEN_INT (info->fp_save_offset
18843 + sp_offset + 8 * i));
18844 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18845 ? DFmode : SFmode), addr);
18847 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18849 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
18851 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
18852 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18853 GEN_INT (info->altivec_save_offset
18854 + sp_offset + 16 * i));
18855 rtx mem = gen_frame_mem (V4SImode, addr);
18857 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18859 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18861 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18862 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18863 GEN_INT (info->gp_save_offset
18864 + sp_offset + reg_size * i));
18865 rtx mem = gen_frame_mem (reg_mode, addr);
18867 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18871 /* CR register traditionally saved as CR2. */
18872 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
18873 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18874 GEN_INT (info->cr_save_offset
18876 rtx mem = gen_frame_mem (reg_mode, addr);
18878 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18880 /* Explain about use of R0. */
18881 if (info->lr_save_p)
18883 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18884 GEN_INT (info->lr_save_offset
18886 rtx mem = gen_frame_mem (reg_mode, addr);
18888 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
18890 /* Explain what happens to the stack pointer. */
18892 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
18893 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
18896 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18897 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18898 treg, GEN_INT (-info->total_size));
18899 sp_offset = info->total_size;
18902 /* If we use the link register, get it into r0. */
18903 if (!WORLD_SAVE_P (info) && info->lr_save_p)
18905 rtx addr, reg, mem;
18907 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
18908 gen_rtx_REG (Pmode, LR_REGNO));
18909 RTX_FRAME_RELATED_P (insn) = 1;
18911 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
18912 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
18914 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18915 GEN_INT (info->lr_save_offset + sp_offset));
18916 reg = gen_rtx_REG (Pmode, 0);
18917 mem = gen_rtx_MEM (Pmode, addr);
18918 /* This should not be of rs6000_sr_alias_set, because of
18919 __builtin_return_address. */
18921 insn = emit_move_insn (mem, reg);
18922 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18923 NULL_RTX, NULL_RTX);
18927 /* If we need to save CR, put it into r12 or r11. */
18928 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
18933 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
18935 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18936 RTX_FRAME_RELATED_P (insn) = 1;
18937 /* Now, there's no way that dwarf2out_frame_debug_expr is going
18938 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
18939 But that's OK. All we have to do is specify that _one_ condition
18940 code register is saved in this stack slot. The thrower's epilogue
18941 will then restore all the call-saved registers.
18942 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
18943 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
18944 gen_rtx_REG (SImode, CR2_REGNO));
18945 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18948 /* Do any required saving of fpr's. If only one or two to save, do
18949 it ourselves. Otherwise, call function. */
18950 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
18953 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18954 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
18955 && ! call_used_regs[info->first_fp_reg_save+i]))
18956 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
18957 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18959 info->first_fp_reg_save + i,
18960 info->fp_save_offset + sp_offset + 8 * i,
18963 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
18967 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18968 info->fp_save_offset + sp_offset,
18970 /*savep=*/true, /*gpr=*/false,
18972 & SAVRES_NOINLINE_FPRS_SAVES_LR)
18974 insn = emit_insn (par);
18975 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18976 NULL_RTX, NULL_RTX);
18979 /* Save GPRs. This is done as a PARALLEL if we are using
18980 the store-multiple instructions. */
18981 if (!WORLD_SAVE_P (info)
18983 && info->spe_64bit_regs_used != 0
18984 && info->first_gp_reg_save != 32)
18987 rtx spe_save_area_ptr;
18989 /* Determine whether we can address all of the registers that need
18990 to be saved with an offset from the stack pointer that fits in
18991 the small const field for SPE memory instructions. */
18992 int spe_regs_addressable_via_sp
18993 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
18994 + (32 - info->first_gp_reg_save - 1) * reg_size)
18995 && saving_GPRs_inline);
18998 if (spe_regs_addressable_via_sp)
19000 spe_save_area_ptr = frame_reg_rtx;
19001 spe_offset = info->spe_gp_save_offset + sp_offset;
19005 /* Make r11 point to the start of the SPE save area. We need
19006 to be careful here if r11 is holding the static chain. If
19007 it is, then temporarily save it in r0. We would use r0 as
19008 our base register here, but using r0 as a base register in
19009 loads and stores means something different from what we
19011 int ool_adjust = (saving_GPRs_inline
19013 : (info->first_gp_reg_save
19014 - (FIRST_SAVRES_REGISTER+1))*8);
19015 HOST_WIDE_INT offset = (info->spe_gp_save_offset
19016 + sp_offset - ool_adjust);
19018 if (using_static_chain_p)
19020 rtx r0 = gen_rtx_REG (Pmode, 0);
19021 gcc_assert (info->first_gp_reg_save > 11);
19023 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
19026 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
19027 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
19029 GEN_INT (offset)));
19030 /* We need to make sure the move to r11 gets noted for
19031 properly outputting unwind information. */
19032 if (!saving_GPRs_inline)
19033 rs6000_frame_related (insn, frame_reg_rtx, offset,
19034 NULL_RTX, NULL_RTX);
19038 if (saving_GPRs_inline)
19040 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19041 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19043 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19044 rtx offset, addr, mem;
19046 /* We're doing all this to ensure that the offset fits into
19047 the immediate offset of 'evstdd'. */
19048 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
19050 offset = GEN_INT (reg_size * i + spe_offset);
19051 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
19052 mem = gen_rtx_MEM (V2SImode, addr);
19054 insn = emit_move_insn (mem, reg);
19056 rs6000_frame_related (insn, spe_save_area_ptr,
19057 info->spe_gp_save_offset
19058 + sp_offset + reg_size * i,
19059 offset, const0_rtx);
19066 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19068 /*savep=*/true, /*gpr=*/true,
19070 insn = emit_insn (par);
19071 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19072 NULL_RTX, NULL_RTX);
19076 /* Move the static chain pointer back. */
19077 if (using_static_chain_p && !spe_regs_addressable_via_sp)
19078 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
19080 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
19084 /* Need to adjust r11 (r12) if we saved any FPRs. */
19085 if (info->first_fp_reg_save != 64)
19087 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
19089 rtx offset = GEN_INT (sp_offset
19090 + (-8 * (64-info->first_fp_reg_save)));
19091 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
19094 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19095 info->gp_save_offset + sp_offset,
19097 /*savep=*/true, /*gpr=*/true,
19099 & SAVRES_NOINLINE_GPRS_SAVES_LR)
19101 insn = emit_insn (par);
19102 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19103 NULL_RTX, NULL_RTX);
19105 else if (!WORLD_SAVE_P (info) && using_store_multiple)
19109 p = rtvec_alloc (32 - info->first_gp_reg_save);
19110 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19112 rtx addr, reg, mem;
19113 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19114 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19115 GEN_INT (info->gp_save_offset
19118 mem = gen_frame_mem (reg_mode, addr);
19120 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
19122 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19123 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19124 NULL_RTX, NULL_RTX);
19126 else if (!WORLD_SAVE_P (info))
19129 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19130 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19132 rtx addr, reg, mem;
19133 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19135 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19136 GEN_INT (info->gp_save_offset
19139 mem = gen_frame_mem (reg_mode, addr);
19141 insn = emit_move_insn (mem, reg);
19142 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19143 NULL_RTX, NULL_RTX);
19147 /* ??? There's no need to emit actual instructions here, but it's the
19148 easiest way to get the frame unwind information emitted. */
19149 if (crtl->calls_eh_return)
19151 unsigned int i, regno;
19153 /* In AIX ABI we need to pretend we save r2 here. */
19156 rtx addr, reg, mem;
19158 reg = gen_rtx_REG (reg_mode, 2);
19159 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19160 GEN_INT (sp_offset + 5 * reg_size));
19161 mem = gen_frame_mem (reg_mode, addr);
19163 insn = emit_move_insn (mem, reg);
19164 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19165 NULL_RTX, NULL_RTX);
19166 PATTERN (insn) = gen_blockage ();
19171 regno = EH_RETURN_DATA_REGNO (i);
19172 if (regno == INVALID_REGNUM)
19175 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
19176 info->ehrd_offset + sp_offset
19177 + reg_size * (int) i,
19182 /* Save CR if we use any that must be preserved. */
19183 if (!WORLD_SAVE_P (info) && info->cr_save_p)
19185 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19186 GEN_INT (info->cr_save_offset + sp_offset));
19187 rtx mem = gen_frame_mem (SImode, addr);
19188 /* See the large comment above about why CR2_REGNO is used. */
19189 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
19191 /* If r12 was used to hold the original sp, copy cr into r0 now
19193 if (REGNO (frame_reg_rtx) == 12)
19197 cr_save_rtx = gen_rtx_REG (SImode, 0);
19198 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19199 RTX_FRAME_RELATED_P (insn) = 1;
19200 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
19201 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19203 insn = emit_move_insn (mem, cr_save_rtx);
19205 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19206 NULL_RTX, NULL_RTX);
19209 /* Update stack and set back pointer unless this is V.4,
19210 for which it was done previously. */
19211 if (!WORLD_SAVE_P (info) && info->push_p
19212 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
19214 if (info->total_size < 32767)
19215 sp_offset = info->total_size;
19217 frame_reg_rtx = frame_ptr_rtx;
19218 rs6000_emit_allocate_stack (info->total_size,
19219 (frame_reg_rtx != sp_reg_rtx
19220 && ((info->altivec_size != 0)
19221 || (info->vrsave_mask != 0)
19224 if (frame_reg_rtx != sp_reg_rtx)
19225 rs6000_emit_stack_tie ();
19228 /* Set frame pointer, if needed. */
19229 if (frame_pointer_needed)
19231 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
19233 RTX_FRAME_RELATED_P (insn) = 1;
19236 /* Save AltiVec registers if needed. Save here because the red zone does
19237 not include AltiVec registers. */
19238 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
19242 /* There should be a non inline version of this, for when we
19243 are saving lots of vector registers. */
19244 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19245 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19247 rtx areg, savereg, mem;
19250 offset = info->altivec_save_offset + sp_offset
19251 + 16 * (i - info->first_altivec_reg_save);
19253 savereg = gen_rtx_REG (V4SImode, i);
19255 areg = gen_rtx_REG (Pmode, 0);
19256 emit_move_insn (areg, GEN_INT (offset));
19258 /* AltiVec addressing mode is [reg+reg]. */
19259 mem = gen_frame_mem (V4SImode,
19260 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
19262 insn = emit_move_insn (mem, savereg);
19264 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19265 areg, GEN_INT (offset));
19269 /* VRSAVE is a bit vector representing which AltiVec registers
19270 are used. The OS uses this to determine which vector
19271 registers to save on a context switch. We need to save
19272 VRSAVE on the stack frame, add whatever AltiVec registers we
19273 used in this function, and do the corresponding magic in the
19276 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
19277 && info->vrsave_mask != 0)
19279 rtx reg, mem, vrsave;
19282 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
19283 as frame_reg_rtx and r11 as the static chain pointer for
19284 nested functions. */
19285 reg = gen_rtx_REG (SImode, 0);
19286 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19288 emit_insn (gen_get_vrsave_internal (reg));
19290 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19292 if (!WORLD_SAVE_P (info))
19295 offset = info->vrsave_save_offset + sp_offset;
19296 mem = gen_frame_mem (SImode,
19297 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19298 GEN_INT (offset)));
19299 insn = emit_move_insn (mem, reg);
19302 /* Include the registers in the mask. */
19303 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19305 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19308 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19309 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19310 || (DEFAULT_ABI == ABI_V4
19311 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19312 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19314 /* If emit_load_toc_table will use the link register, we need to save
19315 it. We use R12 for this purpose because emit_load_toc_table
19316 can use register 0. This allows us to use a plain 'blr' to return
19317 from the procedure more often. */
19318 int save_LR_around_toc_setup = (TARGET_ELF
19319 && DEFAULT_ABI != ABI_AIX
19321 && ! info->lr_save_p
19322 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19323 if (save_LR_around_toc_setup)
19325 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19327 insn = emit_move_insn (frame_ptr_rtx, lr);
19328 RTX_FRAME_RELATED_P (insn) = 1;
19330 rs6000_emit_load_toc_table (TRUE);
19332 insn = emit_move_insn (lr, frame_ptr_rtx);
19333 RTX_FRAME_RELATED_P (insn) = 1;
19336 rs6000_emit_load_toc_table (TRUE);
19340 if (DEFAULT_ABI == ABI_DARWIN
19341 && flag_pic && crtl->uses_pic_offset_table)
19343 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19344 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19346 /* Save and restore LR locally around this call (in R0). */
19347 if (!info->lr_save_p)
19348 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19350 emit_insn (gen_load_macho_picbase (src));
19352 emit_move_insn (gen_rtx_REG (Pmode,
19353 RS6000_PIC_OFFSET_TABLE_REGNUM),
19356 if (!info->lr_save_p)
19357 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19362 /* Write function prologue. */
19365 rs6000_output_function_prologue (FILE *file,
19366 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19368 rs6000_stack_t *info = rs6000_stack_info ();
19370 if (TARGET_DEBUG_STACK)
19371 debug_stack_info (info);
19373 /* Write .extern for any function we will call to save and restore
19375 if (info->first_fp_reg_save < 64
19376 && !FP_SAVE_INLINE (info->first_fp_reg_save))
19379 int regno = info->first_fp_reg_save - 32;
19381 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
19382 /*gpr=*/false, /*lr=*/false);
19383 fprintf (file, "\t.extern %s\n", name);
19385 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
19386 /*gpr=*/false, /*lr=*/true);
19387 fprintf (file, "\t.extern %s\n", name);
19390 /* Write .extern for AIX common mode routines, if needed. */
19391 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
19393 fputs ("\t.extern __mulh\n", file);
19394 fputs ("\t.extern __mull\n", file);
19395 fputs ("\t.extern __divss\n", file);
19396 fputs ("\t.extern __divus\n", file);
19397 fputs ("\t.extern __quoss\n", file);
19398 fputs ("\t.extern __quous\n", file);
19399 common_mode_defined = 1;
19402 if (! HAVE_prologue)
19408 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19409 the "toplevel" insn chain. */
19410 emit_note (NOTE_INSN_DELETED);
19411 rs6000_emit_prologue ();
19412 emit_note (NOTE_INSN_DELETED);
19414 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19418 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19420 INSN_ADDRESSES_NEW (insn, addr);
19425 prologue = get_insns ();
19428 if (TARGET_DEBUG_STACK)
19429 debug_rtx_list (prologue, 100);
19431 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
19435 rs6000_pic_labelno++;
19438 /* Non-zero if vmx regs are restored before the frame pop, zero if
19439 we restore after the pop when possible. */
19440 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19442 /* Reload CR from REG. */
19445 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
19450 if (using_mfcr_multiple)
19452 for (i = 0; i < 8; i++)
19453 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19455 gcc_assert (count);
19458 if (using_mfcr_multiple && count > 1)
19463 p = rtvec_alloc (count);
19466 for (i = 0; i < 8; i++)
19467 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19469 rtvec r = rtvec_alloc (2);
19470 RTVEC_ELT (r, 0) = reg;
19471 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19472 RTVEC_ELT (p, ndx) =
19473 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19474 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19477 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19478 gcc_assert (ndx == count);
19481 for (i = 0; i < 8; i++)
19482 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19484 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19490 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19491 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19492 below stack pointer not cloberred by signals. */
19495 offset_below_red_zone_p (HOST_WIDE_INT offset)
19497 return offset < (DEFAULT_ABI == ABI_V4
19499 : TARGET_32BIT ? -220 : -288);
19502 /* Emit function epilogue as insns. */
19505 rs6000_emit_epilogue (int sibcall)
19507 rs6000_stack_t *info;
19508 int restoring_GPRs_inline;
19509 int restoring_FPRs_inline;
19510 int using_load_multiple;
19511 int using_mtcr_multiple;
19512 int use_backchain_to_restore_sp;
19516 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19517 rtx frame_reg_rtx = sp_reg_rtx;
19518 rtx cfa_restores = NULL_RTX;
19520 rtx cr_save_reg = NULL_RTX;
19521 enum machine_mode reg_mode = Pmode;
19522 int reg_size = TARGET_32BIT ? 4 : 8;
19525 info = rs6000_stack_info ();
19527 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19529 reg_mode = V2SImode;
19533 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19534 /*static_chain_p=*/0, sibcall);
19535 using_load_multiple = strategy & SAVRES_MULTIPLE;
19536 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19537 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19538 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19539 || rs6000_cpu == PROCESSOR_PPC603
19540 || rs6000_cpu == PROCESSOR_PPC750
19542 /* Restore via the backchain when we have a large frame, since this
19543 is more efficient than an addis, addi pair. The second condition
19544 here will not trigger at the moment; We don't actually need a
19545 frame pointer for alloca, but the generic parts of the compiler
19546 give us one anyway. */
19547 use_backchain_to_restore_sp = (info->total_size > 32767
19548 || info->total_size
19549 + (info->lr_save_p ? info->lr_save_offset : 0)
19551 || (cfun->calls_alloca
19552 && !frame_pointer_needed));
19553 restore_lr = (info->lr_save_p
19554 && (restoring_FPRs_inline
19555 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
19556 && (restoring_GPRs_inline
19557 || info->first_fp_reg_save < 64));
19559 if (WORLD_SAVE_P (info))
19563 const char *alloc_rname;
19566 /* eh_rest_world_r10 will return to the location saved in the LR
19567 stack slot (which is not likely to be our caller.)
19568 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19569 rest_world is similar, except any R10 parameter is ignored.
19570 The exception-handling stuff that was here in 2.95 is no
19571 longer necessary. */
19575 + 32 - info->first_gp_reg_save
19576 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
19577 + 63 + 1 - info->first_fp_reg_save);
19579 strcpy (rname, ((crtl->calls_eh_return) ?
19580 "*eh_rest_world_r10" : "*rest_world"));
19581 alloc_rname = ggc_strdup (rname);
19584 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
19585 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19586 gen_rtx_REG (Pmode,
19589 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
19590 /* The instruction pattern requires a clobber here;
19591 it is shared with the restVEC helper. */
19593 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
19596 /* CR register traditionally saved as CR2. */
19597 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19598 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19599 GEN_INT (info->cr_save_offset));
19600 rtx mem = gen_frame_mem (reg_mode, addr);
19602 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19605 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19607 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19608 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19609 GEN_INT (info->gp_save_offset
19611 rtx mem = gen_frame_mem (reg_mode, addr);
19613 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19615 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19617 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19618 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19619 GEN_INT (info->altivec_save_offset
19621 rtx mem = gen_frame_mem (V4SImode, addr);
19623 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19625 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
19627 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19628 ? DFmode : SFmode),
19629 info->first_fp_reg_save + i);
19630 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19631 GEN_INT (info->fp_save_offset
19633 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19634 ? DFmode : SFmode), addr);
19636 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19639 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
19641 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
19643 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
19645 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
19647 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
19648 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19653 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
19655 sp_offset = info->total_size;
19657 /* Restore AltiVec registers if we must do so before adjusting the
19659 if (TARGET_ALTIVEC_ABI
19660 && info->altivec_size != 0
19661 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19662 || (DEFAULT_ABI != ABI_V4
19663 && offset_below_red_zone_p (info->altivec_save_offset))))
19667 if (use_backchain_to_restore_sp)
19669 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19670 emit_move_insn (frame_reg_rtx,
19671 gen_rtx_MEM (Pmode, sp_reg_rtx));
19674 else if (frame_pointer_needed)
19675 frame_reg_rtx = hard_frame_pointer_rtx;
19677 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19678 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19680 rtx addr, areg, mem, reg;
19682 areg = gen_rtx_REG (Pmode, 0);
19684 (areg, GEN_INT (info->altivec_save_offset
19686 + 16 * (i - info->first_altivec_reg_save)));
19688 /* AltiVec addressing mode is [reg+reg]. */
19689 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19690 mem = gen_frame_mem (V4SImode, addr);
19692 reg = gen_rtx_REG (V4SImode, i);
19693 emit_move_insn (reg, mem);
19694 if (offset_below_red_zone_p (info->altivec_save_offset
19695 + (i - info->first_altivec_reg_save)
19697 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19702 /* Restore VRSAVE if we must do so before adjusting the stack. */
19704 && TARGET_ALTIVEC_VRSAVE
19705 && info->vrsave_mask != 0
19706 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19707 || (DEFAULT_ABI != ABI_V4
19708 && offset_below_red_zone_p (info->vrsave_save_offset))))
19710 rtx addr, mem, reg;
19712 if (frame_reg_rtx == sp_reg_rtx)
19714 if (use_backchain_to_restore_sp)
19716 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19717 emit_move_insn (frame_reg_rtx,
19718 gen_rtx_MEM (Pmode, sp_reg_rtx));
19721 else if (frame_pointer_needed)
19722 frame_reg_rtx = hard_frame_pointer_rtx;
19725 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19726 GEN_INT (info->vrsave_save_offset + sp_offset));
19727 mem = gen_frame_mem (SImode, addr);
19728 reg = gen_rtx_REG (SImode, 12);
19729 emit_move_insn (reg, mem);
19731 emit_insn (generate_set_vrsave (reg, info, 1));
19735 /* If we have a large stack frame, restore the old stack pointer
19736 using the backchain. */
19737 if (use_backchain_to_restore_sp)
19739 if (frame_reg_rtx == sp_reg_rtx)
19741 /* Under V.4, don't reset the stack pointer until after we're done
19742 loading the saved registers. */
19743 if (DEFAULT_ABI == ABI_V4)
19744 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19746 insn = emit_move_insn (frame_reg_rtx,
19747 gen_rtx_MEM (Pmode, sp_reg_rtx));
19750 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19751 && DEFAULT_ABI == ABI_V4)
19752 /* frame_reg_rtx has been set up by the altivec restore. */
19756 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19757 frame_reg_rtx = sp_reg_rtx;
19760 /* If we have a frame pointer, we can restore the old stack pointer
19762 else if (frame_pointer_needed)
19764 frame_reg_rtx = sp_reg_rtx;
19765 if (DEFAULT_ABI == ABI_V4)
19766 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19768 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
19769 GEN_INT (info->total_size)));
19772 else if (info->push_p
19773 && DEFAULT_ABI != ABI_V4
19774 && !crtl->calls_eh_return)
19776 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
19777 GEN_INT (info->total_size)));
19780 if (insn && frame_reg_rtx == sp_reg_rtx)
19784 REG_NOTES (insn) = cfa_restores;
19785 cfa_restores = NULL_RTX;
19787 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19788 RTX_FRAME_RELATED_P (insn) = 1;
19791 /* Restore AltiVec registers if we have not done so already. */
19792 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19793 && TARGET_ALTIVEC_ABI
19794 && info->altivec_size != 0
19795 && (DEFAULT_ABI == ABI_V4
19796 || !offset_below_red_zone_p (info->altivec_save_offset)))
19800 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19801 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19803 rtx addr, areg, mem, reg;
19805 areg = gen_rtx_REG (Pmode, 0);
19807 (areg, GEN_INT (info->altivec_save_offset
19809 + 16 * (i - info->first_altivec_reg_save)));
19811 /* AltiVec addressing mode is [reg+reg]. */
19812 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19813 mem = gen_frame_mem (V4SImode, addr);
19815 reg = gen_rtx_REG (V4SImode, i);
19816 emit_move_insn (reg, mem);
19817 if (DEFAULT_ABI == ABI_V4)
19818 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19823 /* Restore VRSAVE if we have not done so already. */
19824 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19826 && TARGET_ALTIVEC_VRSAVE
19827 && info->vrsave_mask != 0
19828 && (DEFAULT_ABI == ABI_V4
19829 || !offset_below_red_zone_p (info->vrsave_save_offset)))
19831 rtx addr, mem, reg;
19833 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19834 GEN_INT (info->vrsave_save_offset + sp_offset));
19835 mem = gen_frame_mem (SImode, addr);
19836 reg = gen_rtx_REG (SImode, 12);
19837 emit_move_insn (reg, mem);
19839 emit_insn (generate_set_vrsave (reg, info, 1));
19842 /* Get the old lr if we saved it. If we are restoring registers
19843 out-of-line, then the out-of-line routines can do this for us. */
19844 if (restore_lr && restoring_GPRs_inline)
19846 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19847 info->lr_save_offset + sp_offset);
19849 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19852 /* Get the old cr if we saved it. */
19853 if (info->cr_save_p)
19855 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19856 GEN_INT (info->cr_save_offset + sp_offset));
19857 rtx mem = gen_frame_mem (SImode, addr);
19859 cr_save_reg = gen_rtx_REG (SImode,
19860 DEFAULT_ABI == ABI_AIX
19861 && !restoring_GPRs_inline
19862 && info->first_fp_reg_save < 64
19864 emit_move_insn (cr_save_reg, mem);
19867 /* Set LR here to try to overlap restores below. LR is always saved
19868 above incoming stack, so it never needs REG_CFA_RESTORE. */
19869 if (restore_lr && restoring_GPRs_inline)
19870 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19871 gen_rtx_REG (Pmode, 0));
19873 /* Load exception handler data registers, if needed. */
19874 if (crtl->calls_eh_return)
19876 unsigned int i, regno;
19880 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19881 GEN_INT (sp_offset + 5 * reg_size));
19882 rtx mem = gen_frame_mem (reg_mode, addr);
19884 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
19891 regno = EH_RETURN_DATA_REGNO (i);
19892 if (regno == INVALID_REGNUM)
19895 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
19896 info->ehrd_offset + sp_offset
19897 + reg_size * (int) i);
19899 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
19903 /* Restore GPRs. This is done as a PARALLEL if we are using
19904 the load-multiple instructions. */
19906 && info->spe_64bit_regs_used != 0
19907 && info->first_gp_reg_save != 32)
19909 /* Determine whether we can address all of the registers that need
19910 to be saved with an offset from the stack pointer that fits in
19911 the small const field for SPE memory instructions. */
19912 int spe_regs_addressable_via_sp
19913 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19914 + (32 - info->first_gp_reg_save - 1) * reg_size)
19915 && restoring_GPRs_inline);
19918 if (spe_regs_addressable_via_sp)
19919 spe_offset = info->spe_gp_save_offset + sp_offset;
19922 rtx old_frame_reg_rtx = frame_reg_rtx;
19923 /* Make r11 point to the start of the SPE save area. We worried about
19924 not clobbering it when we were saving registers in the prologue.
19925 There's no need to worry here because the static chain is passed
19926 anew to every function. */
19927 int ool_adjust = (restoring_GPRs_inline
19929 : (info->first_gp_reg_save
19930 - (FIRST_SAVRES_REGISTER+1))*8);
19932 if (frame_reg_rtx == sp_reg_rtx)
19933 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19934 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
19935 GEN_INT (info->spe_gp_save_offset
19938 /* Keep the invariant that frame_reg_rtx + sp_offset points
19939 at the top of the stack frame. */
19940 sp_offset = -info->spe_gp_save_offset;
19945 if (restoring_GPRs_inline)
19947 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19948 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19950 rtx offset, addr, mem, reg;
19952 /* We're doing all this to ensure that the immediate offset
19953 fits into the immediate field of 'evldd'. */
19954 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
19956 offset = GEN_INT (spe_offset + reg_size * i);
19957 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
19958 mem = gen_rtx_MEM (V2SImode, addr);
19959 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19961 insn = emit_move_insn (reg, mem);
19962 if (DEFAULT_ABI == ABI_V4)
19964 if (frame_pointer_needed
19965 && info->first_gp_reg_save + i
19966 == HARD_FRAME_POINTER_REGNUM)
19968 add_reg_note (insn, REG_CFA_DEF_CFA,
19969 plus_constant (frame_reg_rtx,
19971 RTX_FRAME_RELATED_P (insn) = 1;
19974 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19983 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19985 /*savep=*/false, /*gpr=*/true,
19987 emit_jump_insn (par);
19988 /* We don't want anybody else emitting things after we jumped
19993 else if (!restoring_GPRs_inline)
19995 /* We are jumping to an out-of-line function. */
19996 bool can_use_exit = info->first_fp_reg_save == 64;
19999 /* Emit stack reset code if we need it. */
20001 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20002 sp_offset, can_use_exit);
20005 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
20008 GEN_INT (sp_offset - info->fp_size)));
20009 if (REGNO (frame_reg_rtx) == 11)
20010 sp_offset += info->fp_size;
20013 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20014 info->gp_save_offset, reg_mode,
20015 /*savep=*/false, /*gpr=*/true,
20016 /*lr=*/can_use_exit);
20020 if (info->cr_save_p)
20022 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20023 if (DEFAULT_ABI == ABI_V4)
20025 = alloc_reg_note (REG_CFA_RESTORE,
20026 gen_rtx_REG (SImode, CR2_REGNO),
20030 emit_jump_insn (par);
20032 /* We don't want anybody else emitting things after we jumped
20037 insn = emit_insn (par);
20038 if (DEFAULT_ABI == ABI_V4)
20040 if (frame_pointer_needed)
20042 add_reg_note (insn, REG_CFA_DEF_CFA,
20043 plus_constant (frame_reg_rtx, sp_offset));
20044 RTX_FRAME_RELATED_P (insn) = 1;
20047 for (i = info->first_gp_reg_save; i < 32; i++)
20049 = alloc_reg_note (REG_CFA_RESTORE,
20050 gen_rtx_REG (reg_mode, i), cfa_restores);
20053 else if (using_load_multiple)
20056 p = rtvec_alloc (32 - info->first_gp_reg_save);
20057 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20059 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20060 GEN_INT (info->gp_save_offset
20063 rtx mem = gen_frame_mem (reg_mode, addr);
20064 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20066 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
20067 if (DEFAULT_ABI == ABI_V4)
20068 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20071 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20072 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
20074 add_reg_note (insn, REG_CFA_DEF_CFA,
20075 plus_constant (frame_reg_rtx, sp_offset));
20076 RTX_FRAME_RELATED_P (insn) = 1;
20081 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20082 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20084 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20085 GEN_INT (info->gp_save_offset
20088 rtx mem = gen_frame_mem (reg_mode, addr);
20089 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20091 insn = emit_move_insn (reg, mem);
20092 if (DEFAULT_ABI == ABI_V4)
20094 if (frame_pointer_needed
20095 && info->first_gp_reg_save + i
20096 == HARD_FRAME_POINTER_REGNUM)
20098 add_reg_note (insn, REG_CFA_DEF_CFA,
20099 plus_constant (frame_reg_rtx, sp_offset));
20100 RTX_FRAME_RELATED_P (insn) = 1;
20103 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20109 if (restore_lr && !restoring_GPRs_inline)
20111 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20112 info->lr_save_offset + sp_offset);
20114 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20115 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20116 gen_rtx_REG (Pmode, 0));
20119 /* Restore fpr's if we need to do it without calling a function. */
20120 if (restoring_FPRs_inline)
20121 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20122 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20123 && ! call_used_regs[info->first_fp_reg_save+i]))
20125 rtx addr, mem, reg;
20126 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20127 GEN_INT (info->fp_save_offset
20130 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20131 ? DFmode : SFmode), addr);
20132 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20133 ? DFmode : SFmode),
20134 info->first_fp_reg_save + i);
20136 emit_move_insn (reg, mem);
20137 if (DEFAULT_ABI == ABI_V4)
20138 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20142 /* If we saved cr, restore it here. Just those that were used. */
20143 if (info->cr_save_p)
20145 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20146 if (DEFAULT_ABI == ABI_V4)
20148 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
20152 /* If this is V.4, unwind the stack pointer after all of the loads
20154 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20155 sp_offset, !restoring_FPRs_inline);
20160 REG_NOTES (insn) = cfa_restores;
20161 cfa_restores = NULL_RTX;
20163 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20164 RTX_FRAME_RELATED_P (insn) = 1;
20167 if (crtl->calls_eh_return)
20169 rtx sa = EH_RETURN_STACKADJ_RTX;
20170 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
20176 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
20177 if (! restoring_FPRs_inline)
20178 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
20180 p = rtvec_alloc (2);
20182 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
20183 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
20184 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
20185 : gen_rtx_CLOBBER (VOIDmode,
20186 gen_rtx_REG (Pmode, 65)));
20188 /* If we have to restore more than two FP registers, branch to the
20189 restore function. It will return to our caller. */
20190 if (! restoring_FPRs_inline)
20195 sym = rs6000_savres_routine_sym (info,
20199 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
20200 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
20201 gen_rtx_REG (Pmode,
20202 DEFAULT_ABI == ABI_AIX
20204 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20207 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
20208 GEN_INT (info->fp_save_offset + 8*i));
20209 mem = gen_frame_mem (DFmode, addr);
20211 RTVEC_ELT (p, i+4) =
20212 gen_rtx_SET (VOIDmode,
20213 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
20218 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20222 /* Write function epilogue. */
20225 rs6000_output_function_epilogue (FILE *file,
20226 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20228 if (! HAVE_epilogue)
20230 rtx insn = get_last_insn ();
20231 /* If the last insn was a BARRIER, we don't have to write anything except
20232 the trace table. */
20233 if (GET_CODE (insn) == NOTE)
20234 insn = prev_nonnote_insn (insn);
20235 if (insn == 0 || GET_CODE (insn) != BARRIER)
20237 /* This is slightly ugly, but at least we don't have two
20238 copies of the epilogue-emitting code. */
20241 /* A NOTE_INSN_DELETED is supposed to be at the start
20242 and end of the "toplevel" insn chain. */
20243 emit_note (NOTE_INSN_DELETED);
20244 rs6000_emit_epilogue (FALSE);
20245 emit_note (NOTE_INSN_DELETED);
20247 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20251 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20253 INSN_ADDRESSES_NEW (insn, addr);
20258 if (TARGET_DEBUG_STACK)
20259 debug_rtx_list (get_insns (), 100);
20260 final (get_insns (), file, FALSE);
20266 macho_branch_islands ();
20267 /* Mach-O doesn't support labels at the end of objects, so if
20268 it looks like we might want one, insert a NOP. */
20270 rtx insn = get_last_insn ();
20273 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
20274 insn = PREV_INSN (insn);
20278 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
20279 fputs ("\tnop\n", file);
20283 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20286 We don't output a traceback table if -finhibit-size-directive was
20287 used. The documentation for -finhibit-size-directive reads
20288 ``don't output a @code{.size} assembler directive, or anything
20289 else that would cause trouble if the function is split in the
20290 middle, and the two halves are placed at locations far apart in
20291 memory.'' The traceback table has this property, since it
20292 includes the offset from the start of the function to the
20293 traceback table itself.
20295 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20296 different traceback table. */
20297 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20298 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20300 const char *fname = NULL;
20301 const char *language_string = lang_hooks.name;
20302 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20304 int optional_tbtab;
20305 rs6000_stack_t *info = rs6000_stack_info ();
20307 if (rs6000_traceback == traceback_full)
20308 optional_tbtab = 1;
20309 else if (rs6000_traceback == traceback_part)
20310 optional_tbtab = 0;
20312 optional_tbtab = !optimize_size && !TARGET_ELF;
20314 if (optional_tbtab)
20316 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20317 while (*fname == '.') /* V.4 encodes . in the name */
20320 /* Need label immediately before tbtab, so we can compute
20321 its offset from the function start. */
20322 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20323 ASM_OUTPUT_LABEL (file, fname);
20326 /* The .tbtab pseudo-op can only be used for the first eight
20327 expressions, since it can't handle the possibly variable
20328 length fields that follow. However, if you omit the optional
20329 fields, the assembler outputs zeros for all optional fields
20330 anyways, giving each variable length field is minimum length
20331 (as defined in sys/debug.h). Thus we can not use the .tbtab
20332 pseudo-op at all. */
20334 /* An all-zero word flags the start of the tbtab, for debuggers
20335 that have to find it by searching forward from the entry
20336 point or from the current pc. */
20337 fputs ("\t.long 0\n", file);
20339 /* Tbtab format type. Use format type 0. */
20340 fputs ("\t.byte 0,", file);
20342 /* Language type. Unfortunately, there does not seem to be any
20343 official way to discover the language being compiled, so we
20344 use language_string.
20345 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20346 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20347 a number, so for now use 9. LTO isn't assigned a number either,
20348 so for now use 0. */
20349 if (! strcmp (language_string, "GNU C")
20350 || ! strcmp (language_string, "GNU GIMPLE"))
20352 else if (! strcmp (language_string, "GNU F77")
20353 || ! strcmp (language_string, "GNU Fortran"))
20355 else if (! strcmp (language_string, "GNU Pascal"))
20357 else if (! strcmp (language_string, "GNU Ada"))
20359 else if (! strcmp (language_string, "GNU C++")
20360 || ! strcmp (language_string, "GNU Objective-C++"))
20362 else if (! strcmp (language_string, "GNU Java"))
20364 else if (! strcmp (language_string, "GNU Objective-C"))
20367 gcc_unreachable ();
20368 fprintf (file, "%d,", i);
20370 /* 8 single bit fields: global linkage (not set for C extern linkage,
20371 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20372 from start of procedure stored in tbtab, internal function, function
20373 has controlled storage, function has no toc, function uses fp,
20374 function logs/aborts fp operations. */
20375 /* Assume that fp operations are used if any fp reg must be saved. */
20376 fprintf (file, "%d,",
20377 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
20379 /* 6 bitfields: function is interrupt handler, name present in
20380 proc table, function calls alloca, on condition directives
20381 (controls stack walks, 3 bits), saves condition reg, saves
20383 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20384 set up as a frame pointer, even when there is no alloca call. */
20385 fprintf (file, "%d,",
20386 ((optional_tbtab << 6)
20387 | ((optional_tbtab & frame_pointer_needed) << 5)
20388 | (info->cr_save_p << 1)
20389 | (info->lr_save_p)));
20391 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20393 fprintf (file, "%d,",
20394 (info->push_p << 7) | (64 - info->first_fp_reg_save));
20396 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20397 fprintf (file, "%d,", (32 - first_reg_to_save ()));
20399 if (optional_tbtab)
20401 /* Compute the parameter info from the function decl argument
20404 int next_parm_info_bit = 31;
20406 for (decl = DECL_ARGUMENTS (current_function_decl);
20407 decl; decl = TREE_CHAIN (decl))
20409 rtx parameter = DECL_INCOMING_RTL (decl);
20410 enum machine_mode mode = GET_MODE (parameter);
20412 if (GET_CODE (parameter) == REG)
20414 if (SCALAR_FLOAT_MODE_P (mode))
20435 gcc_unreachable ();
20438 /* If only one bit will fit, don't or in this entry. */
20439 if (next_parm_info_bit > 0)
20440 parm_info |= (bits << (next_parm_info_bit - 1));
20441 next_parm_info_bit -= 2;
20445 fixed_parms += ((GET_MODE_SIZE (mode)
20446 + (UNITS_PER_WORD - 1))
20448 next_parm_info_bit -= 1;
20454 /* Number of fixed point parameters. */
20455 /* This is actually the number of words of fixed point parameters; thus
20456 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20457 fprintf (file, "%d,", fixed_parms);
20459 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20461 /* This is actually the number of fp registers that hold parameters;
20462 and thus the maximum value is 13. */
20463 /* Set parameters on stack bit if parameters are not in their original
20464 registers, regardless of whether they are on the stack? Xlc
20465 seems to set the bit when not optimizing. */
20466 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
20468 if (! optional_tbtab)
20471 /* Optional fields follow. Some are variable length. */
20473 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20474 11 double float. */
20475 /* There is an entry for each parameter in a register, in the order that
20476 they occur in the parameter list. Any intervening arguments on the
20477 stack are ignored. If the list overflows a long (max possible length
20478 34 bits) then completely leave off all elements that don't fit. */
20479 /* Only emit this long if there was at least one parameter. */
20480 if (fixed_parms || float_parms)
20481 fprintf (file, "\t.long %d\n", parm_info);
20483 /* Offset from start of code to tb table. */
20484 fputs ("\t.long ", file);
20485 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20487 RS6000_OUTPUT_BASENAME (file, fname);
20489 assemble_name (file, fname);
20491 rs6000_output_function_entry (file, fname);
20494 /* Interrupt handler mask. */
20495 /* Omit this long, since we never set the interrupt handler bit
20498 /* Number of CTL (controlled storage) anchors. */
20499 /* Omit this long, since the has_ctl bit is never set above. */
20501 /* Displacement into stack of each CTL anchor. */
20502 /* Omit this list of longs, because there are no CTL anchors. */
20504 /* Length of function name. */
20507 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20509 /* Function name. */
20510 assemble_string (fname, strlen (fname));
20512 /* Register for alloca automatic storage; this is always reg 31.
20513 Only emit this if the alloca bit was set above. */
20514 if (frame_pointer_needed)
20515 fputs ("\t.byte 31\n", file);
20517 fputs ("\t.align 2\n", file);
20521 /* A C compound statement that outputs the assembler code for a thunk
20522 function, used to implement C++ virtual function calls with
20523 multiple inheritance. The thunk acts as a wrapper around a virtual
20524 function, adjusting the implicit object parameter before handing
20525 control off to the real function.
20527 First, emit code to add the integer DELTA to the location that
20528 contains the incoming first argument. Assume that this argument
20529 contains a pointer, and is the one used to pass the `this' pointer
20530 in C++. This is the incoming argument *before* the function
20531 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20532 values of all other incoming arguments.
20534 After the addition, emit code to jump to FUNCTION, which is a
20535 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20536 not touch the return address. Hence returning from FUNCTION will
20537 return to whoever called the current `thunk'.
20539 The effect must be as if FUNCTION had been called directly with the
20540 adjusted first argument. This macro is responsible for emitting
20541 all of the code for a thunk function; output_function_prologue()
20542 and output_function_epilogue() are not invoked.
20544 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20545 been extracted from it.) It might possibly be useful on some
20546 targets, but probably not.
20548 If you do not define this macro, the target-independent code in the
20549 C++ frontend will generate a less efficient heavyweight thunk that
20550 calls FUNCTION instead of jumping to it. The generic approach does
20551 not support varargs. */
20554 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
20555 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
20558 rtx this_rtx, insn, funexp;
20560 reload_completed = 1;
20561 epilogue_completed = 1;
20563 /* Mark the end of the (empty) prologue. */
20564 emit_note (NOTE_INSN_PROLOGUE_END);
20566 /* Find the "this" pointer. If the function returns a structure,
20567 the structure return pointer is in r3. */
20568 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
20569 this_rtx = gen_rtx_REG (Pmode, 4);
20571 this_rtx = gen_rtx_REG (Pmode, 3);
20573 /* Apply the constant offset, if required. */
20575 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
20577 /* Apply the offset from the vtable, if required. */
20580 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
20581 rtx tmp = gen_rtx_REG (Pmode, 12);
20583 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
20584 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
20586 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
20587 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
20591 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
20593 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
20595 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
20598 /* Generate a tail call to the target function. */
20599 if (!TREE_USED (function))
20601 assemble_external (function);
20602 TREE_USED (function) = 1;
20604 funexp = XEXP (DECL_RTL (function), 0);
20605 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
20608 if (MACHOPIC_INDIRECT)
20609 funexp = machopic_indirect_call_target (funexp);
20612 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
20613 generate sibcall RTL explicitly. */
20614 insn = emit_call_insn (
20615 gen_rtx_PARALLEL (VOIDmode,
20617 gen_rtx_CALL (VOIDmode,
20618 funexp, const0_rtx),
20619 gen_rtx_USE (VOIDmode, const0_rtx),
20620 gen_rtx_USE (VOIDmode,
20621 gen_rtx_REG (SImode,
20623 gen_rtx_RETURN (VOIDmode))));
20624 SIBLING_CALL_P (insn) = 1;
20627 /* Run just enough of rest_of_compilation to get the insns emitted.
20628 There's not really enough bulk here to make other passes such as
20629 instruction scheduling worth while. Note that use_thunk calls
20630 assemble_start_function and assemble_end_function. */
20631 insn = get_insns ();
20632 insn_locators_alloc ();
20633 shorten_branches (insn);
20634 final_start_function (insn, file, 1);
20635 final (insn, file, 1);
20636 final_end_function ();
20638 reload_completed = 0;
20639 epilogue_completed = 0;
20642 /* A quick summary of the various types of 'constant-pool tables'
20645 Target Flags Name One table per
20646 AIX (none) AIX TOC object file
20647 AIX -mfull-toc AIX TOC object file
20648 AIX -mminimal-toc AIX minimal TOC translation unit
20649 SVR4/EABI (none) SVR4 SDATA object file
20650 SVR4/EABI -fpic SVR4 pic object file
20651 SVR4/EABI -fPIC SVR4 PIC translation unit
20652 SVR4/EABI -mrelocatable EABI TOC function
20653 SVR4/EABI -maix AIX TOC object file
20654 SVR4/EABI -maix -mminimal-toc
20655 AIX minimal TOC translation unit
20657 Name Reg. Set by entries contains:
20658 made by addrs? fp? sum?
20660 AIX TOC 2 crt0 as Y option option
20661 AIX minimal TOC 30 prolog gcc Y Y option
20662 SVR4 SDATA 13 crt0 gcc N Y N
20663 SVR4 pic 30 prolog ld Y not yet N
20664 SVR4 PIC 30 prolog gcc Y option option
20665 EABI TOC 30 prolog gcc Y option option
20669 /* Hash functions for the hash table. */
20672 rs6000_hash_constant (rtx k)
20674 enum rtx_code code = GET_CODE (k);
20675 enum machine_mode mode = GET_MODE (k);
20676 unsigned result = (code << 3) ^ mode;
20677 const char *format;
20680 format = GET_RTX_FORMAT (code);
20681 flen = strlen (format);
20687 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
20690 if (mode != VOIDmode)
20691 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
20703 for (; fidx < flen; fidx++)
20704 switch (format[fidx])
20709 const char *str = XSTR (k, fidx);
20710 len = strlen (str);
20711 result = result * 613 + len;
20712 for (i = 0; i < len; i++)
20713 result = result * 613 + (unsigned) str[i];
20718 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
20722 result = result * 613 + (unsigned) XINT (k, fidx);
20725 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
20726 result = result * 613 + (unsigned) XWINT (k, fidx);
20730 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
20731 result = result * 613 + (unsigned) (XWINT (k, fidx)
20738 gcc_unreachable ();
20745 toc_hash_function (const void *hash_entry)
20747 const struct toc_hash_struct *thc =
20748 (const struct toc_hash_struct *) hash_entry;
20749 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
20752 /* Compare H1 and H2 for equivalence. */
20755 toc_hash_eq (const void *h1, const void *h2)
20757 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
20758 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
20760 if (((const struct toc_hash_struct *) h1)->key_mode
20761 != ((const struct toc_hash_struct *) h2)->key_mode)
20764 return rtx_equal_p (r1, r2);
20767 /* These are the names given by the C++ front-end to vtables, and
20768 vtable-like objects. Ideally, this logic should not be here;
20769 instead, there should be some programmatic way of inquiring as
20770 to whether or not an object is a vtable. */
20772 #define VTABLE_NAME_P(NAME) \
20773 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
20774 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
20775 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
20776 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
20777 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
20779 #ifdef NO_DOLLAR_IN_LABEL
20780 /* Return a GGC-allocated character string translating dollar signs in
20781 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
20784 rs6000_xcoff_strip_dollar (const char *name)
20789 p = strchr (name, '$');
20791 if (p == 0 || p == name)
20794 len = strlen (name);
20795 strip = (char *) alloca (len + 1);
20796 strcpy (strip, name);
20797 p = strchr (strip, '$');
20801 p = strchr (p + 1, '$');
20804 return ggc_alloc_string (strip, len);
20809 rs6000_output_symbol_ref (FILE *file, rtx x)
20811 /* Currently C++ toc references to vtables can be emitted before it
20812 is decided whether the vtable is public or private. If this is
20813 the case, then the linker will eventually complain that there is
20814 a reference to an unknown section. Thus, for vtables only,
20815 we emit the TOC reference to reference the symbol and not the
20817 const char *name = XSTR (x, 0);
20819 if (VTABLE_NAME_P (name))
20821 RS6000_OUTPUT_BASENAME (file, name);
20824 assemble_name (file, name);
20827 /* Output a TOC entry. We derive the entry name from what is being
20831 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
20834 const char *name = buf;
20836 HOST_WIDE_INT offset = 0;
20838 gcc_assert (!TARGET_NO_TOC);
20840 /* When the linker won't eliminate them, don't output duplicate
20841 TOC entries (this happens on AIX if there is any kind of TOC,
20842 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
20844 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
20846 struct toc_hash_struct *h;
20849 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
20850 time because GGC is not initialized at that point. */
20851 if (toc_hash_table == NULL)
20852 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
20853 toc_hash_eq, NULL);
20855 h = GGC_NEW (struct toc_hash_struct);
20857 h->key_mode = mode;
20858 h->labelno = labelno;
20860 found = htab_find_slot (toc_hash_table, h, INSERT);
20861 if (*found == NULL)
20863 else /* This is indeed a duplicate.
20864 Set this label equal to that label. */
20866 fputs ("\t.set ", file);
20867 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20868 fprintf (file, "%d,", labelno);
20869 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20870 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
20876 /* If we're going to put a double constant in the TOC, make sure it's
20877 aligned properly when strict alignment is on. */
20878 if (GET_CODE (x) == CONST_DOUBLE
20879 && STRICT_ALIGNMENT
20880 && GET_MODE_BITSIZE (mode) >= 64
20881 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
20882 ASM_OUTPUT_ALIGN (file, 3);
20885 (*targetm.asm_out.internal_label) (file, "LC", labelno);
20887 /* Handle FP constants specially. Note that if we have a minimal
20888 TOC, things we put here aren't actually in the TOC, so we can allow
20890 if (GET_CODE (x) == CONST_DOUBLE &&
20891 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
20893 REAL_VALUE_TYPE rv;
20896 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20897 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20898 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
20900 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
20904 if (TARGET_MINIMAL_TOC)
20905 fputs (DOUBLE_INT_ASM_OP, file);
20907 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20908 k[0] & 0xffffffff, k[1] & 0xffffffff,
20909 k[2] & 0xffffffff, k[3] & 0xffffffff);
20910 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
20911 k[0] & 0xffffffff, k[1] & 0xffffffff,
20912 k[2] & 0xffffffff, k[3] & 0xffffffff);
20917 if (TARGET_MINIMAL_TOC)
20918 fputs ("\t.long ", file);
20920 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20921 k[0] & 0xffffffff, k[1] & 0xffffffff,
20922 k[2] & 0xffffffff, k[3] & 0xffffffff);
20923 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
20924 k[0] & 0xffffffff, k[1] & 0xffffffff,
20925 k[2] & 0xffffffff, k[3] & 0xffffffff);
20929 else if (GET_CODE (x) == CONST_DOUBLE &&
20930 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
20932 REAL_VALUE_TYPE rv;
20935 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20937 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20938 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
20940 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
20944 if (TARGET_MINIMAL_TOC)
20945 fputs (DOUBLE_INT_ASM_OP, file);
20947 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20948 k[0] & 0xffffffff, k[1] & 0xffffffff);
20949 fprintf (file, "0x%lx%08lx\n",
20950 k[0] & 0xffffffff, k[1] & 0xffffffff);
20955 if (TARGET_MINIMAL_TOC)
20956 fputs ("\t.long ", file);
20958 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20959 k[0] & 0xffffffff, k[1] & 0xffffffff);
20960 fprintf (file, "0x%lx,0x%lx\n",
20961 k[0] & 0xffffffff, k[1] & 0xffffffff);
20965 else if (GET_CODE (x) == CONST_DOUBLE &&
20966 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
20968 REAL_VALUE_TYPE rv;
20971 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20972 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20973 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
20975 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
20979 if (TARGET_MINIMAL_TOC)
20980 fputs (DOUBLE_INT_ASM_OP, file);
20982 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20983 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
20988 if (TARGET_MINIMAL_TOC)
20989 fputs ("\t.long ", file);
20991 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20992 fprintf (file, "0x%lx\n", l & 0xffffffff);
20996 else if (GET_MODE (x) == VOIDmode
20997 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
20999 unsigned HOST_WIDE_INT low;
21000 HOST_WIDE_INT high;
21002 if (GET_CODE (x) == CONST_DOUBLE)
21004 low = CONST_DOUBLE_LOW (x);
21005 high = CONST_DOUBLE_HIGH (x);
21008 #if HOST_BITS_PER_WIDE_INT == 32
21011 high = (low & 0x80000000) ? ~0 : 0;
21015 low = INTVAL (x) & 0xffffffff;
21016 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
21020 /* TOC entries are always Pmode-sized, but since this
21021 is a bigendian machine then if we're putting smaller
21022 integer constants in the TOC we have to pad them.
21023 (This is still a win over putting the constants in
21024 a separate constant pool, because then we'd have
21025 to have both a TOC entry _and_ the actual constant.)
21027 For a 32-bit target, CONST_INT values are loaded and shifted
21028 entirely within `low' and can be stored in one TOC entry. */
21030 /* It would be easy to make this work, but it doesn't now. */
21031 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
21033 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
21035 #if HOST_BITS_PER_WIDE_INT == 32
21036 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
21037 POINTER_SIZE, &low, &high, 0);
21040 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
21041 high = (HOST_WIDE_INT) low >> 32;
21048 if (TARGET_MINIMAL_TOC)
21049 fputs (DOUBLE_INT_ASM_OP, file);
21051 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21052 (long) high & 0xffffffff, (long) low & 0xffffffff);
21053 fprintf (file, "0x%lx%08lx\n",
21054 (long) high & 0xffffffff, (long) low & 0xffffffff);
21059 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
21061 if (TARGET_MINIMAL_TOC)
21062 fputs ("\t.long ", file);
21064 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21065 (long) high & 0xffffffff, (long) low & 0xffffffff);
21066 fprintf (file, "0x%lx,0x%lx\n",
21067 (long) high & 0xffffffff, (long) low & 0xffffffff);
21071 if (TARGET_MINIMAL_TOC)
21072 fputs ("\t.long ", file);
21074 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
21075 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
21081 if (GET_CODE (x) == CONST)
21083 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
21084 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
21086 base = XEXP (XEXP (x, 0), 0);
21087 offset = INTVAL (XEXP (XEXP (x, 0), 1));
21090 switch (GET_CODE (base))
21093 name = XSTR (base, 0);
21097 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
21098 CODE_LABEL_NUMBER (XEXP (base, 0)));
21102 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
21106 gcc_unreachable ();
21109 if (TARGET_MINIMAL_TOC)
21110 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
21113 fputs ("\t.tc ", file);
21114 RS6000_OUTPUT_BASENAME (file, name);
21117 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
21119 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
21121 fputs ("[TC],", file);
21124 /* Currently C++ toc references to vtables can be emitted before it
21125 is decided whether the vtable is public or private. If this is
21126 the case, then the linker will eventually complain that there is
21127 a TOC reference to an unknown section. Thus, for vtables only,
21128 we emit the TOC reference to reference the symbol and not the
21130 if (VTABLE_NAME_P (name))
21132 RS6000_OUTPUT_BASENAME (file, name);
21134 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
21135 else if (offset > 0)
21136 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
21139 output_addr_const (file, x);
21143 /* Output an assembler pseudo-op to write an ASCII string of N characters
21144 starting at P to FILE.
21146 On the RS/6000, we have to do this using the .byte operation and
21147 write out special characters outside the quoted string.
21148 Also, the assembler is broken; very long strings are truncated,
21149 so we must artificially break them up early. */
21152 output_ascii (FILE *file, const char *p, int n)
21155 int i, count_string;
21156 const char *for_string = "\t.byte \"";
21157 const char *for_decimal = "\t.byte ";
21158 const char *to_close = NULL;
21161 for (i = 0; i < n; i++)
21164 if (c >= ' ' && c < 0177)
21167 fputs (for_string, file);
21170 /* Write two quotes to get one. */
21178 for_decimal = "\"\n\t.byte ";
21182 if (count_string >= 512)
21184 fputs (to_close, file);
21186 for_string = "\t.byte \"";
21187 for_decimal = "\t.byte ";
21195 fputs (for_decimal, file);
21196 fprintf (file, "%d", c);
21198 for_string = "\n\t.byte \"";
21199 for_decimal = ", ";
21205 /* Now close the string if we have written one. Then end the line. */
21207 fputs (to_close, file);
21210 /* Generate a unique section name for FILENAME for a section type
21211 represented by SECTION_DESC. Output goes into BUF.
21213 SECTION_DESC can be any string, as long as it is different for each
21214 possible section type.
21216 We name the section in the same manner as xlc. The name begins with an
21217 underscore followed by the filename (after stripping any leading directory
21218 names) with the last period replaced by the string SECTION_DESC. If
21219 FILENAME does not contain a period, SECTION_DESC is appended to the end of
21223 rs6000_gen_section_name (char **buf, const char *filename,
21224 const char *section_desc)
21226 const char *q, *after_last_slash, *last_period = 0;
21230 after_last_slash = filename;
21231 for (q = filename; *q; q++)
21234 after_last_slash = q + 1;
21235 else if (*q == '.')
21239 len = strlen (after_last_slash) + strlen (section_desc) + 2;
21240 *buf = (char *) xmalloc (len);
21245 for (q = after_last_slash; *q; q++)
21247 if (q == last_period)
21249 strcpy (p, section_desc);
21250 p += strlen (section_desc);
21254 else if (ISALNUM (*q))
21258 if (last_period == 0)
21259 strcpy (p, section_desc);
21264 /* Emit profile function. */
21267 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
21269 /* Non-standard profiling for kernels, which just saves LR then calls
21270 _mcount without worrying about arg saves. The idea is to change
21271 the function prologue as little as possible as it isn't easy to
21272 account for arg save/restore code added just for _mcount. */
21273 if (TARGET_PROFILE_KERNEL)
21276 if (DEFAULT_ABI == ABI_AIX)
21278 #ifndef NO_PROFILE_COUNTERS
21279 # define NO_PROFILE_COUNTERS 0
21281 if (NO_PROFILE_COUNTERS)
21282 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21283 LCT_NORMAL, VOIDmode, 0);
21287 const char *label_name;
21290 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21291 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21292 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21294 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21295 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21298 else if (DEFAULT_ABI == ABI_DARWIN)
21300 const char *mcount_name = RS6000_MCOUNT;
21301 int caller_addr_regno = LR_REGNO;
21303 /* Be conservative and always set this, at least for now. */
21304 crtl->uses_pic_offset_table = 1;
21307 /* For PIC code, set up a stub and collect the caller's address
21308 from r0, which is where the prologue puts it. */
21309 if (MACHOPIC_INDIRECT
21310 && crtl->uses_pic_offset_table)
21311 caller_addr_regno = 0;
21313 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21314 LCT_NORMAL, VOIDmode, 1,
21315 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21319 /* Write function profiler code. */
21322 output_function_profiler (FILE *file, int labelno)
21326 switch (DEFAULT_ABI)
21329 gcc_unreachable ();
21334 warning (0, "no profiling of 64-bit code for this ABI");
21337 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21338 fprintf (file, "\tmflr %s\n", reg_names[0]);
21339 if (NO_PROFILE_COUNTERS)
21341 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21342 reg_names[0], reg_names[1]);
21344 else if (TARGET_SECURE_PLT && flag_pic)
21346 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21347 reg_names[0], reg_names[1]);
21348 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21349 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21350 reg_names[12], reg_names[12]);
21351 assemble_name (file, buf);
21352 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21353 assemble_name (file, buf);
21354 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21356 else if (flag_pic == 1)
21358 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21359 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21360 reg_names[0], reg_names[1]);
21361 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21362 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
21363 assemble_name (file, buf);
21364 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
21366 else if (flag_pic > 1)
21368 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21369 reg_names[0], reg_names[1]);
21370 /* Now, we need to get the address of the label. */
21371 fputs ("\tbcl 20,31,1f\n\t.long ", file);
21372 assemble_name (file, buf);
21373 fputs ("-.\n1:", file);
21374 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
21375 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
21376 reg_names[0], reg_names[11]);
21377 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
21378 reg_names[0], reg_names[0], reg_names[11]);
21382 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
21383 assemble_name (file, buf);
21384 fputs ("@ha\n", file);
21385 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21386 reg_names[0], reg_names[1]);
21387 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
21388 assemble_name (file, buf);
21389 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
21392 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21393 fprintf (file, "\tbl %s%s\n",
21394 RS6000_MCOUNT, flag_pic ? "@plt" : "");
21399 if (!TARGET_PROFILE_KERNEL)
21401 /* Don't do anything, done in output_profile_hook (). */
21405 gcc_assert (!TARGET_32BIT);
21407 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
21408 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
21410 if (cfun->static_chain_decl != NULL)
21412 asm_fprintf (file, "\tstd %s,24(%s)\n",
21413 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21414 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21415 asm_fprintf (file, "\tld %s,24(%s)\n",
21416 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21419 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21427 /* The following variable value is the last issued insn. */
21429 static rtx last_scheduled_insn;
21431 /* The following variable helps to balance issuing of load and
21432 store instructions */
21434 static int load_store_pendulum;
21436 /* Power4 load update and store update instructions are cracked into a
21437 load or store and an integer insn which are executed in the same cycle.
21438 Branches have their own dispatch slot which does not count against the
21439 GCC issue rate, but it changes the program flow so there are no other
21440 instructions to issue in this cycle. */
21443 rs6000_variable_issue_1 (rtx insn, int more)
21445 last_scheduled_insn = insn;
21446 if (GET_CODE (PATTERN (insn)) == USE
21447 || GET_CODE (PATTERN (insn)) == CLOBBER)
21449 cached_can_issue_more = more;
21450 return cached_can_issue_more;
21453 if (insn_terminates_group_p (insn, current_group))
21455 cached_can_issue_more = 0;
21456 return cached_can_issue_more;
21459 /* If no reservation, but reach here */
21460 if (recog_memoized (insn) < 0)
21463 if (rs6000_sched_groups)
21465 if (is_microcoded_insn (insn))
21466 cached_can_issue_more = 0;
21467 else if (is_cracked_insn (insn))
21468 cached_can_issue_more = more > 2 ? more - 2 : 0;
21470 cached_can_issue_more = more - 1;
21472 return cached_can_issue_more;
21475 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21478 cached_can_issue_more = more - 1;
21479 return cached_can_issue_more;
21483 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
21485 int r = rs6000_variable_issue_1 (insn, more);
21487 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
21491 /* Adjust the cost of a scheduling dependency. Return the new cost of
21492 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21495 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21497 enum attr_type attr_type;
21499 if (! recog_memoized (insn))
21502 switch (REG_NOTE_KIND (link))
21506 /* Data dependency; DEP_INSN writes a register that INSN reads
21507 some cycles later. */
21509 /* Separate a load from a narrower, dependent store. */
21510 if (rs6000_sched_groups
21511 && GET_CODE (PATTERN (insn)) == SET
21512 && GET_CODE (PATTERN (dep_insn)) == SET
21513 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21514 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21515 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21516 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21519 attr_type = get_attr_type (insn);
21524 /* Tell the first scheduling pass about the latency between
21525 a mtctr and bctr (and mtlr and br/blr). The first
21526 scheduling pass will not know about this latency since
21527 the mtctr instruction, which has the latency associated
21528 to it, will be generated by reload. */
21529 return TARGET_POWER ? 5 : 4;
21531 /* Leave some extra cycles between a compare and its
21532 dependent branch, to inhibit expensive mispredicts. */
21533 if ((rs6000_cpu_attr == CPU_PPC603
21534 || rs6000_cpu_attr == CPU_PPC604
21535 || rs6000_cpu_attr == CPU_PPC604E
21536 || rs6000_cpu_attr == CPU_PPC620
21537 || rs6000_cpu_attr == CPU_PPC630
21538 || rs6000_cpu_attr == CPU_PPC750
21539 || rs6000_cpu_attr == CPU_PPC7400
21540 || rs6000_cpu_attr == CPU_PPC7450
21541 || rs6000_cpu_attr == CPU_POWER4
21542 || rs6000_cpu_attr == CPU_POWER5
21543 || rs6000_cpu_attr == CPU_POWER7
21544 || rs6000_cpu_attr == CPU_CELL)
21545 && recog_memoized (dep_insn)
21546 && (INSN_CODE (dep_insn) >= 0))
21548 switch (get_attr_type (dep_insn))
21552 case TYPE_DELAYED_COMPARE:
21553 case TYPE_IMUL_COMPARE:
21554 case TYPE_LMUL_COMPARE:
21555 case TYPE_FPCOMPARE:
21556 case TYPE_CR_LOGICAL:
21557 case TYPE_DELAYED_CR:
21566 case TYPE_STORE_UX:
21568 case TYPE_FPSTORE_U:
21569 case TYPE_FPSTORE_UX:
21570 if ((rs6000_cpu == PROCESSOR_POWER6)
21571 && recog_memoized (dep_insn)
21572 && (INSN_CODE (dep_insn) >= 0))
21575 if (GET_CODE (PATTERN (insn)) != SET)
21576 /* If this happens, we have to extend this to schedule
21577 optimally. Return default for now. */
21580 /* Adjust the cost for the case where the value written
21581 by a fixed point operation is used as the address
21582 gen value on a store. */
21583 switch (get_attr_type (dep_insn))
21590 if (! store_data_bypass_p (dep_insn, insn))
21594 case TYPE_LOAD_EXT:
21595 case TYPE_LOAD_EXT_U:
21596 case TYPE_LOAD_EXT_UX:
21597 case TYPE_VAR_SHIFT_ROTATE:
21598 case TYPE_VAR_DELAYED_COMPARE:
21600 if (! store_data_bypass_p (dep_insn, insn))
21606 case TYPE_FAST_COMPARE:
21609 case TYPE_INSERT_WORD:
21610 case TYPE_INSERT_DWORD:
21611 case TYPE_FPLOAD_U:
21612 case TYPE_FPLOAD_UX:
21614 case TYPE_STORE_UX:
21615 case TYPE_FPSTORE_U:
21616 case TYPE_FPSTORE_UX:
21618 if (! store_data_bypass_p (dep_insn, insn))
21626 case TYPE_IMUL_COMPARE:
21627 case TYPE_LMUL_COMPARE:
21629 if (! store_data_bypass_p (dep_insn, insn))
21635 if (! store_data_bypass_p (dep_insn, insn))
21641 if (! store_data_bypass_p (dep_insn, insn))
21654 case TYPE_LOAD_EXT:
21655 case TYPE_LOAD_EXT_U:
21656 case TYPE_LOAD_EXT_UX:
21657 if ((rs6000_cpu == PROCESSOR_POWER6)
21658 && recog_memoized (dep_insn)
21659 && (INSN_CODE (dep_insn) >= 0))
21662 /* Adjust the cost for the case where the value written
21663 by a fixed point instruction is used within the address
21664 gen portion of a subsequent load(u)(x) */
21665 switch (get_attr_type (dep_insn))
21672 if (set_to_load_agen (dep_insn, insn))
21676 case TYPE_LOAD_EXT:
21677 case TYPE_LOAD_EXT_U:
21678 case TYPE_LOAD_EXT_UX:
21679 case TYPE_VAR_SHIFT_ROTATE:
21680 case TYPE_VAR_DELAYED_COMPARE:
21682 if (set_to_load_agen (dep_insn, insn))
21688 case TYPE_FAST_COMPARE:
21691 case TYPE_INSERT_WORD:
21692 case TYPE_INSERT_DWORD:
21693 case TYPE_FPLOAD_U:
21694 case TYPE_FPLOAD_UX:
21696 case TYPE_STORE_UX:
21697 case TYPE_FPSTORE_U:
21698 case TYPE_FPSTORE_UX:
21700 if (set_to_load_agen (dep_insn, insn))
21708 case TYPE_IMUL_COMPARE:
21709 case TYPE_LMUL_COMPARE:
21711 if (set_to_load_agen (dep_insn, insn))
21717 if (set_to_load_agen (dep_insn, insn))
21723 if (set_to_load_agen (dep_insn, insn))
21734 if ((rs6000_cpu == PROCESSOR_POWER6)
21735 && recog_memoized (dep_insn)
21736 && (INSN_CODE (dep_insn) >= 0)
21737 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
21744 /* Fall out to return default cost. */
21748 case REG_DEP_OUTPUT:
21749 /* Output dependency; DEP_INSN writes a register that INSN writes some
21751 if ((rs6000_cpu == PROCESSOR_POWER6)
21752 && recog_memoized (dep_insn)
21753 && (INSN_CODE (dep_insn) >= 0))
21755 attr_type = get_attr_type (insn);
21760 if (get_attr_type (dep_insn) == TYPE_FP)
21764 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
21772 /* Anti dependency; DEP_INSN reads a register that INSN writes some
21777 gcc_unreachable ();
21783 /* Debug version of rs6000_adjust_cost. */
21786 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21788 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
21794 switch (REG_NOTE_KIND (link))
21796 default: dep = "unknown depencency"; break;
21797 case REG_DEP_TRUE: dep = "data dependency"; break;
21798 case REG_DEP_OUTPUT: dep = "output dependency"; break;
21799 case REG_DEP_ANTI: dep = "anti depencency"; break;
21803 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
21804 "%s, insn:\n", ret, cost, dep);
21812 /* The function returns a true if INSN is microcoded.
21813 Return false otherwise. */
21816 is_microcoded_insn (rtx insn)
21818 if (!insn || !NONDEBUG_INSN_P (insn)
21819 || GET_CODE (PATTERN (insn)) == USE
21820 || GET_CODE (PATTERN (insn)) == CLOBBER)
21823 if (rs6000_cpu_attr == CPU_CELL)
21824 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
21826 if (rs6000_sched_groups)
21828 enum attr_type type = get_attr_type (insn);
21829 if (type == TYPE_LOAD_EXT_U
21830 || type == TYPE_LOAD_EXT_UX
21831 || type == TYPE_LOAD_UX
21832 || type == TYPE_STORE_UX
21833 || type == TYPE_MFCR)
21840 /* The function returns true if INSN is cracked into 2 instructions
21841 by the processor (and therefore occupies 2 issue slots). */
21844 is_cracked_insn (rtx insn)
21846 if (!insn || !NONDEBUG_INSN_P (insn)
21847 || GET_CODE (PATTERN (insn)) == USE
21848 || GET_CODE (PATTERN (insn)) == CLOBBER)
21851 if (rs6000_sched_groups)
21853 enum attr_type type = get_attr_type (insn);
21854 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
21855 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
21856 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
21857 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
21858 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
21859 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
21860 || type == TYPE_IDIV || type == TYPE_LDIV
21861 || type == TYPE_INSERT_WORD)
21868 /* The function returns true if INSN can be issued only from
21869 the branch slot. */
21872 is_branch_slot_insn (rtx insn)
21874 if (!insn || !NONDEBUG_INSN_P (insn)
21875 || GET_CODE (PATTERN (insn)) == USE
21876 || GET_CODE (PATTERN (insn)) == CLOBBER)
21879 if (rs6000_sched_groups)
21881 enum attr_type type = get_attr_type (insn);
21882 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
21890 /* The function returns true if out_inst sets a value that is
21891 used in the address generation computation of in_insn */
21893 set_to_load_agen (rtx out_insn, rtx in_insn)
21895 rtx out_set, in_set;
21897 /* For performance reasons, only handle the simple case where
21898 both loads are a single_set. */
21899 out_set = single_set (out_insn);
21902 in_set = single_set (in_insn);
21904 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
21910 /* The function returns true if the target storage location of
21911 out_insn is adjacent to the target storage location of in_insn */
21912 /* Return 1 if memory locations are adjacent. */
21915 adjacent_mem_locations (rtx insn1, rtx insn2)
21918 rtx a = get_store_dest (PATTERN (insn1));
21919 rtx b = get_store_dest (PATTERN (insn2));
21921 if ((GET_CODE (XEXP (a, 0)) == REG
21922 || (GET_CODE (XEXP (a, 0)) == PLUS
21923 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
21924 && (GET_CODE (XEXP (b, 0)) == REG
21925 || (GET_CODE (XEXP (b, 0)) == PLUS
21926 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
21928 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
21931 if (GET_CODE (XEXP (a, 0)) == PLUS)
21933 reg0 = XEXP (XEXP (a, 0), 0);
21934 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
21937 reg0 = XEXP (a, 0);
21939 if (GET_CODE (XEXP (b, 0)) == PLUS)
21941 reg1 = XEXP (XEXP (b, 0), 0);
21942 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
21945 reg1 = XEXP (b, 0);
21947 val_diff = val1 - val0;
21949 return ((REGNO (reg0) == REGNO (reg1))
21950 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
21951 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
21957 /* A C statement (sans semicolon) to update the integer scheduling
21958 priority INSN_PRIORITY (INSN). Increase the priority to execute the
21959 INSN earlier, reduce the priority to execute INSN later. Do not
21960 define this macro if you do not need to adjust the scheduling
21961 priorities of insns. */
21964 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
21966 /* On machines (like the 750) which have asymmetric integer units,
21967 where one integer unit can do multiply and divides and the other
21968 can't, reduce the priority of multiply/divide so it is scheduled
21969 before other integer operations. */
21972 if (! INSN_P (insn))
21975 if (GET_CODE (PATTERN (insn)) == USE)
21978 switch (rs6000_cpu_attr) {
21980 switch (get_attr_type (insn))
21987 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
21988 priority, priority);
21989 if (priority >= 0 && priority < 0x01000000)
21996 if (insn_must_be_first_in_group (insn)
21997 && reload_completed
21998 && current_sched_info->sched_max_insns_priority
21999 && rs6000_sched_restricted_insns_priority)
22002 /* Prioritize insns that can be dispatched only in the first
22004 if (rs6000_sched_restricted_insns_priority == 1)
22005 /* Attach highest priority to insn. This means that in
22006 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
22007 precede 'priority' (critical path) considerations. */
22008 return current_sched_info->sched_max_insns_priority;
22009 else if (rs6000_sched_restricted_insns_priority == 2)
22010 /* Increase priority of insn by a minimal amount. This means that in
22011 haifa-sched.c:ready_sort(), only 'priority' (critical path)
22012 considerations precede dispatch-slot restriction considerations. */
22013 return (priority + 1);
22016 if (rs6000_cpu == PROCESSOR_POWER6
22017 && ((load_store_pendulum == -2 && is_load_insn (insn))
22018 || (load_store_pendulum == 2 && is_store_insn (insn))))
22019 /* Attach highest priority to insn if the scheduler has just issued two
22020 stores and this instruction is a load, or two loads and this instruction
22021 is a store. Power6 wants loads and stores scheduled alternately
22023 return current_sched_info->sched_max_insns_priority;
22028 /* Return true if the instruction is nonpipelined on the Cell. */
22030 is_nonpipeline_insn (rtx insn)
22032 enum attr_type type;
22033 if (!insn || !NONDEBUG_INSN_P (insn)
22034 || GET_CODE (PATTERN (insn)) == USE
22035 || GET_CODE (PATTERN (insn)) == CLOBBER)
22038 type = get_attr_type (insn);
22039 if (type == TYPE_IMUL
22040 || type == TYPE_IMUL2
22041 || type == TYPE_IMUL3
22042 || type == TYPE_LMUL
22043 || type == TYPE_IDIV
22044 || type == TYPE_LDIV
22045 || type == TYPE_SDIV
22046 || type == TYPE_DDIV
22047 || type == TYPE_SSQRT
22048 || type == TYPE_DSQRT
22049 || type == TYPE_MFCR
22050 || type == TYPE_MFCRF
22051 || type == TYPE_MFJMPR)
22059 /* Return how many instructions the machine can issue per cycle. */
22062 rs6000_issue_rate (void)
22064 /* Unless scheduling for register pressure, use issue rate of 1 for
22065 first scheduling pass to decrease degradation. */
22066 if (!reload_completed && !flag_sched_pressure)
22069 switch (rs6000_cpu_attr) {
22070 case CPU_RIOS1: /* ? */
22072 case CPU_PPC601: /* ? */
22081 case CPU_PPCE300C2:
22082 case CPU_PPCE300C3:
22083 case CPU_PPCE500MC:
22084 case CPU_PPCE500MC64:
22103 /* Return how many instructions to look ahead for better insn
22107 rs6000_use_sched_lookahead (void)
22109 if (rs6000_cpu_attr == CPU_PPC8540)
22111 if (rs6000_cpu_attr == CPU_CELL)
22112 return (reload_completed ? 8 : 0);
22116 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
22118 rs6000_use_sched_lookahead_guard (rtx insn)
22120 if (rs6000_cpu_attr != CPU_CELL)
22123 if (insn == NULL_RTX || !INSN_P (insn))
22126 if (!reload_completed
22127 || is_nonpipeline_insn (insn)
22128 || is_microcoded_insn (insn))
22134 /* Determine is PAT refers to memory. */
22137 is_mem_ref (rtx pat)
22143 /* stack_tie does not produce any real memory traffic. */
22144 if (GET_CODE (pat) == UNSPEC
22145 && XINT (pat, 1) == UNSPEC_TIE)
22148 if (GET_CODE (pat) == MEM)
22151 /* Recursively process the pattern. */
22152 fmt = GET_RTX_FORMAT (GET_CODE (pat));
22154 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
22157 ret |= is_mem_ref (XEXP (pat, i));
22158 else if (fmt[i] == 'E')
22159 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
22160 ret |= is_mem_ref (XVECEXP (pat, i, j));
22166 /* Determine if PAT is a PATTERN of a load insn. */
22169 is_load_insn1 (rtx pat)
22171 if (!pat || pat == NULL_RTX)
22174 if (GET_CODE (pat) == SET)
22175 return is_mem_ref (SET_SRC (pat));
22177 if (GET_CODE (pat) == PARALLEL)
22181 for (i = 0; i < XVECLEN (pat, 0); i++)
22182 if (is_load_insn1 (XVECEXP (pat, 0, i)))
22189 /* Determine if INSN loads from memory. */
22192 is_load_insn (rtx insn)
22194 if (!insn || !INSN_P (insn))
22197 if (GET_CODE (insn) == CALL_INSN)
22200 return is_load_insn1 (PATTERN (insn));
22203 /* Determine if PAT is a PATTERN of a store insn. */
22206 is_store_insn1 (rtx pat)
22208 if (!pat || pat == NULL_RTX)
22211 if (GET_CODE (pat) == SET)
22212 return is_mem_ref (SET_DEST (pat));
22214 if (GET_CODE (pat) == PARALLEL)
22218 for (i = 0; i < XVECLEN (pat, 0); i++)
22219 if (is_store_insn1 (XVECEXP (pat, 0, i)))
22226 /* Determine if INSN stores to memory. */
22229 is_store_insn (rtx insn)
22231 if (!insn || !INSN_P (insn))
22234 return is_store_insn1 (PATTERN (insn));
22237 /* Return the dest of a store insn. */
22240 get_store_dest (rtx pat)
22242 gcc_assert (is_store_insn1 (pat));
22244 if (GET_CODE (pat) == SET)
22245 return SET_DEST (pat);
22246 else if (GET_CODE (pat) == PARALLEL)
22250 for (i = 0; i < XVECLEN (pat, 0); i++)
22252 rtx inner_pat = XVECEXP (pat, 0, i);
22253 if (GET_CODE (inner_pat) == SET
22254 && is_mem_ref (SET_DEST (inner_pat)))
22258 /* We shouldn't get here, because we should have either a simple
22259 store insn or a store with update which are covered above. */
22263 /* Returns whether the dependence between INSN and NEXT is considered
22264 costly by the given target. */
22267 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
22272 /* If the flag is not enabled - no dependence is considered costly;
22273 allow all dependent insns in the same group.
22274 This is the most aggressive option. */
22275 if (rs6000_sched_costly_dep == no_dep_costly)
22278 /* If the flag is set to 1 - a dependence is always considered costly;
22279 do not allow dependent instructions in the same group.
22280 This is the most conservative option. */
22281 if (rs6000_sched_costly_dep == all_deps_costly)
22284 insn = DEP_PRO (dep);
22285 next = DEP_CON (dep);
22287 if (rs6000_sched_costly_dep == store_to_load_dep_costly
22288 && is_load_insn (next)
22289 && is_store_insn (insn))
22290 /* Prevent load after store in the same group. */
22293 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
22294 && is_load_insn (next)
22295 && is_store_insn (insn)
22296 && DEP_TYPE (dep) == REG_DEP_TRUE)
22297 /* Prevent load after store in the same group if it is a true
22301 /* The flag is set to X; dependences with latency >= X are considered costly,
22302 and will not be scheduled in the same group. */
22303 if (rs6000_sched_costly_dep <= max_dep_latency
22304 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22310 /* Return the next insn after INSN that is found before TAIL is reached,
22311 skipping any "non-active" insns - insns that will not actually occupy
22312 an issue slot. Return NULL_RTX if such an insn is not found. */
22315 get_next_active_insn (rtx insn, rtx tail)
22317 if (insn == NULL_RTX || insn == tail)
22322 insn = NEXT_INSN (insn);
22323 if (insn == NULL_RTX || insn == tail)
22328 || (NONJUMP_INSN_P (insn)
22329 && GET_CODE (PATTERN (insn)) != USE
22330 && GET_CODE (PATTERN (insn)) != CLOBBER
22331 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22337 /* We are about to begin issuing insns for this clock cycle. */
22340 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22341 rtx *ready ATTRIBUTE_UNUSED,
22342 int *pn_ready ATTRIBUTE_UNUSED,
22343 int clock_var ATTRIBUTE_UNUSED)
22345 int n_ready = *pn_ready;
22348 fprintf (dump, "// rs6000_sched_reorder :\n");
22350 /* Reorder the ready list, if the second to last ready insn
22351 is a nonepipeline insn. */
22352 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22354 if (is_nonpipeline_insn (ready[n_ready - 1])
22355 && (recog_memoized (ready[n_ready - 2]) > 0))
22356 /* Simply swap first two insns. */
22358 rtx tmp = ready[n_ready - 1];
22359 ready[n_ready - 1] = ready[n_ready - 2];
22360 ready[n_ready - 2] = tmp;
22364 if (rs6000_cpu == PROCESSOR_POWER6)
22365 load_store_pendulum = 0;
22367 return rs6000_issue_rate ();
22370 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22373 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
22374 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
22377 fprintf (dump, "// rs6000_sched_reorder2 :\n");
22379 /* For Power6, we need to handle some special cases to try and keep the
22380 store queue from overflowing and triggering expensive flushes.
22382 This code monitors how load and store instructions are being issued
22383 and skews the ready list one way or the other to increase the likelihood
22384 that a desired instruction is issued at the proper time.
22386 A couple of things are done. First, we maintain a "load_store_pendulum"
22387 to track the current state of load/store issue.
22389 - If the pendulum is at zero, then no loads or stores have been
22390 issued in the current cycle so we do nothing.
22392 - If the pendulum is 1, then a single load has been issued in this
22393 cycle and we attempt to locate another load in the ready list to
22396 - If the pendulum is -2, then two stores have already been
22397 issued in this cycle, so we increase the priority of the first load
22398 in the ready list to increase it's likelihood of being chosen first
22401 - If the pendulum is -1, then a single store has been issued in this
22402 cycle and we attempt to locate another store in the ready list to
22403 issue with it, preferring a store to an adjacent memory location to
22404 facilitate store pairing in the store queue.
22406 - If the pendulum is 2, then two loads have already been
22407 issued in this cycle, so we increase the priority of the first store
22408 in the ready list to increase it's likelihood of being chosen first
22411 - If the pendulum < -2 or > 2, then do nothing.
22413 Note: This code covers the most common scenarios. There exist non
22414 load/store instructions which make use of the LSU and which
22415 would need to be accounted for to strictly model the behavior
22416 of the machine. Those instructions are currently unaccounted
22417 for to help minimize compile time overhead of this code.
22419 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
22425 if (is_store_insn (last_scheduled_insn))
22426 /* Issuing a store, swing the load_store_pendulum to the left */
22427 load_store_pendulum--;
22428 else if (is_load_insn (last_scheduled_insn))
22429 /* Issuing a load, swing the load_store_pendulum to the right */
22430 load_store_pendulum++;
22432 return cached_can_issue_more;
22434 /* If the pendulum is balanced, or there is only one instruction on
22435 the ready list, then all is well, so return. */
22436 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
22437 return cached_can_issue_more;
22439 if (load_store_pendulum == 1)
22441 /* A load has been issued in this cycle. Scan the ready list
22442 for another load to issue with it */
22447 if (is_load_insn (ready[pos]))
22449 /* Found a load. Move it to the head of the ready list,
22450 and adjust it's priority so that it is more likely to
22453 for (i=pos; i<*pn_ready-1; i++)
22454 ready[i] = ready[i + 1];
22455 ready[*pn_ready-1] = tmp;
22457 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22458 INSN_PRIORITY (tmp)++;
22464 else if (load_store_pendulum == -2)
22466 /* Two stores have been issued in this cycle. Increase the
22467 priority of the first load in the ready list to favor it for
22468 issuing in the next cycle. */
22473 if (is_load_insn (ready[pos])
22475 && INSN_PRIORITY_KNOWN (ready[pos]))
22477 INSN_PRIORITY (ready[pos])++;
22479 /* Adjust the pendulum to account for the fact that a load
22480 was found and increased in priority. This is to prevent
22481 increasing the priority of multiple loads */
22482 load_store_pendulum--;
22489 else if (load_store_pendulum == -1)
22491 /* A store has been issued in this cycle. Scan the ready list for
22492 another store to issue with it, preferring a store to an adjacent
22494 int first_store_pos = -1;
22500 if (is_store_insn (ready[pos]))
22502 /* Maintain the index of the first store found on the
22504 if (first_store_pos == -1)
22505 first_store_pos = pos;
22507 if (is_store_insn (last_scheduled_insn)
22508 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22510 /* Found an adjacent store. Move it to the head of the
22511 ready list, and adjust it's priority so that it is
22512 more likely to stay there */
22514 for (i=pos; i<*pn_ready-1; i++)
22515 ready[i] = ready[i + 1];
22516 ready[*pn_ready-1] = tmp;
22518 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22519 INSN_PRIORITY (tmp)++;
22521 first_store_pos = -1;
22529 if (first_store_pos >= 0)
22531 /* An adjacent store wasn't found, but a non-adjacent store was,
22532 so move the non-adjacent store to the front of the ready
22533 list, and adjust its priority so that it is more likely to
22535 tmp = ready[first_store_pos];
22536 for (i=first_store_pos; i<*pn_ready-1; i++)
22537 ready[i] = ready[i + 1];
22538 ready[*pn_ready-1] = tmp;
22539 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22540 INSN_PRIORITY (tmp)++;
22543 else if (load_store_pendulum == 2)
22545 /* Two loads have been issued in this cycle. Increase the priority
22546 of the first store in the ready list to favor it for issuing in
22552 if (is_store_insn (ready[pos])
22554 && INSN_PRIORITY_KNOWN (ready[pos]))
22556 INSN_PRIORITY (ready[pos])++;
22558 /* Adjust the pendulum to account for the fact that a store
22559 was found and increased in priority. This is to prevent
22560 increasing the priority of multiple stores */
22561 load_store_pendulum++;
22570 return cached_can_issue_more;
22573 /* Return whether the presence of INSN causes a dispatch group termination
22574 of group WHICH_GROUP.
22576 If WHICH_GROUP == current_group, this function will return true if INSN
22577 causes the termination of the current group (i.e, the dispatch group to
22578 which INSN belongs). This means that INSN will be the last insn in the
22579 group it belongs to.
22581 If WHICH_GROUP == previous_group, this function will return true if INSN
22582 causes the termination of the previous group (i.e, the dispatch group that
22583 precedes the group to which INSN belongs). This means that INSN will be
22584 the first insn in the group it belongs to). */
22587 insn_terminates_group_p (rtx insn, enum group_termination which_group)
22594 first = insn_must_be_first_in_group (insn);
22595 last = insn_must_be_last_in_group (insn);
22600 if (which_group == current_group)
22602 else if (which_group == previous_group)
22610 insn_must_be_first_in_group (rtx insn)
22612 enum attr_type type;
22615 || GET_CODE (insn) == NOTE
22616 || DEBUG_INSN_P (insn)
22617 || GET_CODE (PATTERN (insn)) == USE
22618 || GET_CODE (PATTERN (insn)) == CLOBBER)
22621 switch (rs6000_cpu)
22623 case PROCESSOR_POWER5:
22624 if (is_cracked_insn (insn))
22626 case PROCESSOR_POWER4:
22627 if (is_microcoded_insn (insn))
22630 if (!rs6000_sched_groups)
22633 type = get_attr_type (insn);
22640 case TYPE_DELAYED_CR:
22641 case TYPE_CR_LOGICAL:
22655 case PROCESSOR_POWER6:
22656 type = get_attr_type (insn);
22660 case TYPE_INSERT_DWORD:
22664 case TYPE_VAR_SHIFT_ROTATE:
22671 case TYPE_INSERT_WORD:
22672 case TYPE_DELAYED_COMPARE:
22673 case TYPE_IMUL_COMPARE:
22674 case TYPE_LMUL_COMPARE:
22675 case TYPE_FPCOMPARE:
22686 case TYPE_LOAD_EXT_UX:
22688 case TYPE_STORE_UX:
22689 case TYPE_FPLOAD_U:
22690 case TYPE_FPLOAD_UX:
22691 case TYPE_FPSTORE_U:
22692 case TYPE_FPSTORE_UX:
22698 case PROCESSOR_POWER7:
22699 type = get_attr_type (insn);
22703 case TYPE_CR_LOGICAL:
22710 case TYPE_DELAYED_COMPARE:
22711 case TYPE_VAR_DELAYED_COMPARE:
22717 case TYPE_LOAD_EXT:
22718 case TYPE_LOAD_EXT_U:
22719 case TYPE_LOAD_EXT_UX:
22721 case TYPE_STORE_UX:
22722 case TYPE_FPLOAD_U:
22723 case TYPE_FPLOAD_UX:
22724 case TYPE_FPSTORE_U:
22725 case TYPE_FPSTORE_UX:
22741 insn_must_be_last_in_group (rtx insn)
22743 enum attr_type type;
22746 || GET_CODE (insn) == NOTE
22747 || DEBUG_INSN_P (insn)
22748 || GET_CODE (PATTERN (insn)) == USE
22749 || GET_CODE (PATTERN (insn)) == CLOBBER)
22752 switch (rs6000_cpu) {
22753 case PROCESSOR_POWER4:
22754 case PROCESSOR_POWER5:
22755 if (is_microcoded_insn (insn))
22758 if (is_branch_slot_insn (insn))
22762 case PROCESSOR_POWER6:
22763 type = get_attr_type (insn);
22770 case TYPE_VAR_SHIFT_ROTATE:
22777 case TYPE_DELAYED_COMPARE:
22778 case TYPE_IMUL_COMPARE:
22779 case TYPE_LMUL_COMPARE:
22780 case TYPE_FPCOMPARE:
22794 case PROCESSOR_POWER7:
22795 type = get_attr_type (insn);
22803 case TYPE_LOAD_EXT_U:
22804 case TYPE_LOAD_EXT_UX:
22805 case TYPE_STORE_UX:
22818 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
22819 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
22822 is_costly_group (rtx *group_insns, rtx next_insn)
22825 int issue_rate = rs6000_issue_rate ();
22827 for (i = 0; i < issue_rate; i++)
22829 sd_iterator_def sd_it;
22831 rtx insn = group_insns[i];
22836 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
22838 rtx next = DEP_CON (dep);
22840 if (next == next_insn
22841 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
22849 /* Utility of the function redefine_groups.
22850 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
22851 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
22852 to keep it "far" (in a separate group) from GROUP_INSNS, following
22853 one of the following schemes, depending on the value of the flag
22854 -minsert_sched_nops = X:
22855 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
22856 in order to force NEXT_INSN into a separate group.
22857 (2) X < sched_finish_regroup_exact: insert exactly X nops.
22858 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
22859 insertion (has a group just ended, how many vacant issue slots remain in the
22860 last group, and how many dispatch groups were encountered so far). */
22863 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
22864 rtx next_insn, bool *group_end, int can_issue_more,
22869 int issue_rate = rs6000_issue_rate ();
22870 bool end = *group_end;
22873 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
22874 return can_issue_more;
22876 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
22877 return can_issue_more;
22879 force = is_costly_group (group_insns, next_insn);
22881 return can_issue_more;
22883 if (sched_verbose > 6)
22884 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
22885 *group_count ,can_issue_more);
22887 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
22890 can_issue_more = 0;
22892 /* Since only a branch can be issued in the last issue_slot, it is
22893 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
22894 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
22895 in this case the last nop will start a new group and the branch
22896 will be forced to the new group. */
22897 if (can_issue_more && !is_branch_slot_insn (next_insn))
22900 while (can_issue_more > 0)
22903 emit_insn_before (nop, next_insn);
22911 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
22913 int n_nops = rs6000_sched_insert_nops;
22915 /* Nops can't be issued from the branch slot, so the effective
22916 issue_rate for nops is 'issue_rate - 1'. */
22917 if (can_issue_more == 0)
22918 can_issue_more = issue_rate;
22920 if (can_issue_more == 0)
22922 can_issue_more = issue_rate - 1;
22925 for (i = 0; i < issue_rate; i++)
22927 group_insns[i] = 0;
22934 emit_insn_before (nop, next_insn);
22935 if (can_issue_more == issue_rate - 1) /* new group begins */
22938 if (can_issue_more == 0)
22940 can_issue_more = issue_rate - 1;
22943 for (i = 0; i < issue_rate; i++)
22945 group_insns[i] = 0;
22951 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
22954 /* Is next_insn going to start a new group? */
22957 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22958 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22959 || (can_issue_more < issue_rate &&
22960 insn_terminates_group_p (next_insn, previous_group)));
22961 if (*group_end && end)
22964 if (sched_verbose > 6)
22965 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
22966 *group_count, can_issue_more);
22967 return can_issue_more;
22970 return can_issue_more;
22973 /* This function tries to synch the dispatch groups that the compiler "sees"
22974 with the dispatch groups that the processor dispatcher is expected to
22975 form in practice. It tries to achieve this synchronization by forcing the
22976 estimated processor grouping on the compiler (as opposed to the function
22977 'pad_goups' which tries to force the scheduler's grouping on the processor).
22979 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
22980 examines the (estimated) dispatch groups that will be formed by the processor
22981 dispatcher. It marks these group boundaries to reflect the estimated
22982 processor grouping, overriding the grouping that the scheduler had marked.
22983 Depending on the value of the flag '-minsert-sched-nops' this function can
22984 force certain insns into separate groups or force a certain distance between
22985 them by inserting nops, for example, if there exists a "costly dependence"
22988 The function estimates the group boundaries that the processor will form as
22989 follows: It keeps track of how many vacant issue slots are available after
22990 each insn. A subsequent insn will start a new group if one of the following
22992 - no more vacant issue slots remain in the current dispatch group.
22993 - only the last issue slot, which is the branch slot, is vacant, but the next
22994 insn is not a branch.
22995 - only the last 2 or less issue slots, including the branch slot, are vacant,
22996 which means that a cracked insn (which occupies two issue slots) can't be
22997 issued in this group.
22998 - less than 'issue_rate' slots are vacant, and the next insn always needs to
22999 start a new group. */
23002 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23004 rtx insn, next_insn;
23006 int can_issue_more;
23009 int group_count = 0;
23013 issue_rate = rs6000_issue_rate ();
23014 group_insns = XALLOCAVEC (rtx, issue_rate);
23015 for (i = 0; i < issue_rate; i++)
23017 group_insns[i] = 0;
23019 can_issue_more = issue_rate;
23021 insn = get_next_active_insn (prev_head_insn, tail);
23024 while (insn != NULL_RTX)
23026 slot = (issue_rate - can_issue_more);
23027 group_insns[slot] = insn;
23029 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23030 if (insn_terminates_group_p (insn, current_group))
23031 can_issue_more = 0;
23033 next_insn = get_next_active_insn (insn, tail);
23034 if (next_insn == NULL_RTX)
23035 return group_count + 1;
23037 /* Is next_insn going to start a new group? */
23039 = (can_issue_more == 0
23040 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23041 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23042 || (can_issue_more < issue_rate &&
23043 insn_terminates_group_p (next_insn, previous_group)));
23045 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
23046 next_insn, &group_end, can_issue_more,
23052 can_issue_more = 0;
23053 for (i = 0; i < issue_rate; i++)
23055 group_insns[i] = 0;
23059 if (GET_MODE (next_insn) == TImode && can_issue_more)
23060 PUT_MODE (next_insn, VOIDmode);
23061 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
23062 PUT_MODE (next_insn, TImode);
23065 if (can_issue_more == 0)
23066 can_issue_more = issue_rate;
23069 return group_count;
23072 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
23073 dispatch group boundaries that the scheduler had marked. Pad with nops
23074 any dispatch groups which have vacant issue slots, in order to force the
23075 scheduler's grouping on the processor dispatcher. The function
23076 returns the number of dispatch groups found. */
23079 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23081 rtx insn, next_insn;
23084 int can_issue_more;
23086 int group_count = 0;
23088 /* Initialize issue_rate. */
23089 issue_rate = rs6000_issue_rate ();
23090 can_issue_more = issue_rate;
23092 insn = get_next_active_insn (prev_head_insn, tail);
23093 next_insn = get_next_active_insn (insn, tail);
23095 while (insn != NULL_RTX)
23098 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23100 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
23102 if (next_insn == NULL_RTX)
23107 /* If the scheduler had marked group termination at this location
23108 (between insn and next_insn), and neither insn nor next_insn will
23109 force group termination, pad the group with nops to force group
23112 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
23113 && !insn_terminates_group_p (insn, current_group)
23114 && !insn_terminates_group_p (next_insn, previous_group))
23116 if (!is_branch_slot_insn (next_insn))
23119 while (can_issue_more)
23122 emit_insn_before (nop, next_insn);
23127 can_issue_more = issue_rate;
23132 next_insn = get_next_active_insn (insn, tail);
23135 return group_count;
23138 /* We're beginning a new block. Initialize data structures as necessary. */
23141 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
23142 int sched_verbose ATTRIBUTE_UNUSED,
23143 int max_ready ATTRIBUTE_UNUSED)
23145 last_scheduled_insn = NULL_RTX;
23146 load_store_pendulum = 0;
23149 /* The following function is called at the end of scheduling BB.
23150 After reload, it inserts nops at insn group bundling. */
23153 rs6000_sched_finish (FILE *dump, int sched_verbose)
23158 fprintf (dump, "=== Finishing schedule.\n");
23160 if (reload_completed && rs6000_sched_groups)
23162 /* Do not run sched_finish hook when selective scheduling enabled. */
23163 if (sel_sched_p ())
23166 if (rs6000_sched_insert_nops == sched_finish_none)
23169 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
23170 n_groups = pad_groups (dump, sched_verbose,
23171 current_sched_info->prev_head,
23172 current_sched_info->next_tail);
23174 n_groups = redefine_groups (dump, sched_verbose,
23175 current_sched_info->prev_head,
23176 current_sched_info->next_tail);
23178 if (sched_verbose >= 6)
23180 fprintf (dump, "ngroups = %d\n", n_groups);
23181 print_rtl (dump, current_sched_info->prev_head);
23182 fprintf (dump, "Done finish_sched\n");
23187 struct _rs6000_sched_context
23189 short cached_can_issue_more;
23190 rtx last_scheduled_insn;
23191 int load_store_pendulum;
23194 typedef struct _rs6000_sched_context rs6000_sched_context_def;
23195 typedef rs6000_sched_context_def *rs6000_sched_context_t;
23197 /* Allocate store for new scheduling context. */
23199 rs6000_alloc_sched_context (void)
23201 return xmalloc (sizeof (rs6000_sched_context_def));
23204 /* If CLEAN_P is true then initializes _SC with clean data,
23205 and from the global context otherwise. */
23207 rs6000_init_sched_context (void *_sc, bool clean_p)
23209 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23213 sc->cached_can_issue_more = 0;
23214 sc->last_scheduled_insn = NULL_RTX;
23215 sc->load_store_pendulum = 0;
23219 sc->cached_can_issue_more = cached_can_issue_more;
23220 sc->last_scheduled_insn = last_scheduled_insn;
23221 sc->load_store_pendulum = load_store_pendulum;
23225 /* Sets the global scheduling context to the one pointed to by _SC. */
23227 rs6000_set_sched_context (void *_sc)
23229 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23231 gcc_assert (sc != NULL);
23233 cached_can_issue_more = sc->cached_can_issue_more;
23234 last_scheduled_insn = sc->last_scheduled_insn;
23235 load_store_pendulum = sc->load_store_pendulum;
23240 rs6000_free_sched_context (void *_sc)
23242 gcc_assert (_sc != NULL);
23248 /* Length in units of the trampoline for entering a nested function. */
23251 rs6000_trampoline_size (void)
23255 switch (DEFAULT_ABI)
23258 gcc_unreachable ();
23261 ret = (TARGET_32BIT) ? 12 : 24;
23266 ret = (TARGET_32BIT) ? 40 : 48;
23273 /* Emit RTL insns to initialize the variable parts of a trampoline.
23274 FNADDR is an RTX for the address of the function's pure code.
23275 CXT is an RTX for the static chain value for the function. */
23278 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
23280 int regsize = (TARGET_32BIT) ? 4 : 8;
23281 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
23282 rtx ctx_reg = force_reg (Pmode, cxt);
23283 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
23285 switch (DEFAULT_ABI)
23288 gcc_unreachable ();
23290 /* Under AIX, just build the 3 word function descriptor */
23293 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
23294 rtx fn_reg = gen_reg_rtx (Pmode);
23295 rtx toc_reg = gen_reg_rtx (Pmode);
23297 /* Macro to shorten the code expansions below. */
23298 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23300 m_tramp = replace_equiv_address (m_tramp, addr);
23302 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
23303 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23304 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23305 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23306 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23312 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23315 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23316 LCT_NORMAL, VOIDmode, 4,
23318 GEN_INT (rs6000_trampoline_size ()), SImode,
23326 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
23327 identifier as an argument, so the front end shouldn't look it up. */
23330 rs6000_attribute_takes_identifier_p (const_tree attr_id)
23332 return is_attribute_p ("altivec", attr_id);
23335 /* Handle the "altivec" attribute. The attribute may have
23336 arguments as follows:
23338 __attribute__((altivec(vector__)))
23339 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23340 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23342 and may appear more than once (e.g., 'vector bool char') in a
23343 given declaration. */
23346 rs6000_handle_altivec_attribute (tree *node,
23347 tree name ATTRIBUTE_UNUSED,
23349 int flags ATTRIBUTE_UNUSED,
23350 bool *no_add_attrs)
23352 tree type = *node, result = NULL_TREE;
23353 enum machine_mode mode;
23356 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23357 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23358 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23361 while (POINTER_TYPE_P (type)
23362 || TREE_CODE (type) == FUNCTION_TYPE
23363 || TREE_CODE (type) == METHOD_TYPE
23364 || TREE_CODE (type) == ARRAY_TYPE)
23365 type = TREE_TYPE (type);
23367 mode = TYPE_MODE (type);
23369 /* Check for invalid AltiVec type qualifiers. */
23370 if (type == long_double_type_node)
23371 error ("use of %<long double%> in AltiVec types is invalid");
23372 else if (type == boolean_type_node)
23373 error ("use of boolean types in AltiVec types is invalid");
23374 else if (TREE_CODE (type) == COMPLEX_TYPE)
23375 error ("use of %<complex%> in AltiVec types is invalid");
23376 else if (DECIMAL_FLOAT_MODE_P (mode))
23377 error ("use of decimal floating point types in AltiVec types is invalid");
23378 else if (!TARGET_VSX)
23380 if (type == long_unsigned_type_node || type == long_integer_type_node)
23383 error ("use of %<long%> in AltiVec types is invalid for "
23384 "64-bit code without -mvsx");
23385 else if (rs6000_warn_altivec_long)
23386 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23389 else if (type == long_long_unsigned_type_node
23390 || type == long_long_integer_type_node)
23391 error ("use of %<long long%> in AltiVec types is invalid without "
23393 else if (type == double_type_node)
23394 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23397 switch (altivec_type)
23400 unsigned_p = TYPE_UNSIGNED (type);
23404 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
23407 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
23410 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
23413 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
23415 case SFmode: result = V4SF_type_node; break;
23416 case DFmode: result = V2DF_type_node; break;
23417 /* If the user says 'vector int bool', we may be handed the 'bool'
23418 attribute _before_ the 'vector' attribute, and so select the
23419 proper type in the 'b' case below. */
23420 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
23421 case V2DImode: case V2DFmode:
23429 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
23430 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
23431 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
23432 case QImode: case V16QImode: result = bool_V16QI_type_node;
23439 case V8HImode: result = pixel_V8HI_type_node;
23445 /* Propagate qualifiers attached to the element type
23446 onto the vector type. */
23447 if (result && result != type && TYPE_QUALS (type))
23448 result = build_qualified_type (result, TYPE_QUALS (type));
23450 *no_add_attrs = true; /* No need to hang on to the attribute. */
23453 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
23458 /* AltiVec defines four built-in scalar types that serve as vector
23459 elements; we must teach the compiler how to mangle them. */
23461 static const char *
23462 rs6000_mangle_type (const_tree type)
23464 type = TYPE_MAIN_VARIANT (type);
23466 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
23467 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
23470 if (type == bool_char_type_node) return "U6__boolc";
23471 if (type == bool_short_type_node) return "U6__bools";
23472 if (type == pixel_type_node) return "u7__pixel";
23473 if (type == bool_int_type_node) return "U6__booli";
23474 if (type == bool_long_type_node) return "U6__booll";
23476 /* Mangle IBM extended float long double as `g' (__float128) on
23477 powerpc*-linux where long-double-64 previously was the default. */
23478 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
23480 && TARGET_LONG_DOUBLE_128
23481 && !TARGET_IEEEQUAD)
23484 /* For all other types, use normal C++ mangling. */
23488 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23489 struct attribute_spec.handler. */
23492 rs6000_handle_longcall_attribute (tree *node, tree name,
23493 tree args ATTRIBUTE_UNUSED,
23494 int flags ATTRIBUTE_UNUSED,
23495 bool *no_add_attrs)
23497 if (TREE_CODE (*node) != FUNCTION_TYPE
23498 && TREE_CODE (*node) != FIELD_DECL
23499 && TREE_CODE (*node) != TYPE_DECL)
23501 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23503 *no_add_attrs = true;
23509 /* Set longcall attributes on all functions declared when
23510 rs6000_default_long_calls is true. */
23512 rs6000_set_default_type_attributes (tree type)
23514 if (rs6000_default_long_calls
23515 && (TREE_CODE (type) == FUNCTION_TYPE
23516 || TREE_CODE (type) == METHOD_TYPE))
23517 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23519 TYPE_ATTRIBUTES (type));
23522 darwin_set_default_type_attributes (type);
23526 /* Return a reference suitable for calling a function with the
23527 longcall attribute. */
23530 rs6000_longcall_ref (rtx call_ref)
23532 const char *call_name;
23535 if (GET_CODE (call_ref) != SYMBOL_REF)
23538 /* System V adds '.' to the internal name, so skip them. */
23539 call_name = XSTR (call_ref, 0);
23540 if (*call_name == '.')
23542 while (*call_name == '.')
23545 node = get_identifier (call_name);
23546 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
23549 return force_reg (Pmode, call_ref);
23552 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23553 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23556 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23557 struct attribute_spec.handler. */
23559 rs6000_handle_struct_attribute (tree *node, tree name,
23560 tree args ATTRIBUTE_UNUSED,
23561 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
23564 if (DECL_P (*node))
23566 if (TREE_CODE (*node) == TYPE_DECL)
23567 type = &TREE_TYPE (*node);
23572 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
23573 || TREE_CODE (*type) == UNION_TYPE)))
23575 warning (OPT_Wattributes, "%qE attribute ignored", name);
23576 *no_add_attrs = true;
23579 else if ((is_attribute_p ("ms_struct", name)
23580 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
23581 || ((is_attribute_p ("gcc_struct", name)
23582 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
23584 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
23586 *no_add_attrs = true;
23593 rs6000_ms_bitfield_layout_p (const_tree record_type)
23595 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
23596 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
23597 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
23600 #ifdef USING_ELFOS_H
23602 /* A get_unnamed_section callback, used for switching to toc_section. */
23605 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23607 if (DEFAULT_ABI == ABI_AIX
23608 && TARGET_MINIMAL_TOC
23609 && !TARGET_RELOCATABLE)
23611 if (!toc_initialized)
23613 toc_initialized = 1;
23614 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23615 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
23616 fprintf (asm_out_file, "\t.tc ");
23617 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
23618 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23619 fprintf (asm_out_file, "\n");
23621 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23622 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23623 fprintf (asm_out_file, " = .+32768\n");
23626 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23628 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
23629 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23632 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23633 if (!toc_initialized)
23635 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23636 fprintf (asm_out_file, " = .+32768\n");
23637 toc_initialized = 1;
23642 /* Implement TARGET_ASM_INIT_SECTIONS. */
23645 rs6000_elf_asm_init_sections (void)
23648 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
23651 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
23652 SDATA2_SECTION_ASM_OP);
23655 /* Implement TARGET_SELECT_RTX_SECTION. */
23658 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
23659 unsigned HOST_WIDE_INT align)
23661 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23662 return toc_section;
23664 return default_elf_select_rtx_section (mode, x, align);
23667 /* For a SYMBOL_REF, set generic flags and then perform some
23668 target-specific processing.
23670 When the AIX ABI is requested on a non-AIX system, replace the
23671 function name with the real name (with a leading .) rather than the
23672 function descriptor name. This saves a lot of overriding code to
23673 read the prefixes. */
23676 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
23678 default_encode_section_info (decl, rtl, first);
23681 && TREE_CODE (decl) == FUNCTION_DECL
23683 && DEFAULT_ABI == ABI_AIX)
23685 rtx sym_ref = XEXP (rtl, 0);
23686 size_t len = strlen (XSTR (sym_ref, 0));
23687 char *str = XALLOCAVEC (char, len + 2);
23689 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
23690 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
23695 compare_section_name (const char *section, const char *templ)
23699 len = strlen (templ);
23700 return (strncmp (section, templ, len) == 0
23701 && (section[len] == 0 || section[len] == '.'));
23705 rs6000_elf_in_small_data_p (const_tree decl)
23707 if (rs6000_sdata == SDATA_NONE)
23710 /* We want to merge strings, so we never consider them small data. */
23711 if (TREE_CODE (decl) == STRING_CST)
23714 /* Functions are never in the small data area. */
23715 if (TREE_CODE (decl) == FUNCTION_DECL)
23718 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
23720 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
23721 if (compare_section_name (section, ".sdata")
23722 || compare_section_name (section, ".sdata2")
23723 || compare_section_name (section, ".gnu.linkonce.s")
23724 || compare_section_name (section, ".sbss")
23725 || compare_section_name (section, ".sbss2")
23726 || compare_section_name (section, ".gnu.linkonce.sb")
23727 || strcmp (section, ".PPC.EMB.sdata0") == 0
23728 || strcmp (section, ".PPC.EMB.sbss0") == 0)
23733 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
23736 && (unsigned HOST_WIDE_INT) size <= g_switch_value
23737 /* If it's not public, and we're not going to reference it there,
23738 there's no need to put it in the small data section. */
23739 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
23746 #endif /* USING_ELFOS_H */
23748 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
23751 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
23753 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
23756 /* Return a REG that occurs in ADDR with coefficient 1.
23757 ADDR can be effectively incremented by incrementing REG.
23759 r0 is special and we must not select it as an address
23760 register by this routine since our caller will try to
23761 increment the returned register via an "la" instruction. */
23764 find_addr_reg (rtx addr)
23766 while (GET_CODE (addr) == PLUS)
23768 if (GET_CODE (XEXP (addr, 0)) == REG
23769 && REGNO (XEXP (addr, 0)) != 0)
23770 addr = XEXP (addr, 0);
23771 else if (GET_CODE (XEXP (addr, 1)) == REG
23772 && REGNO (XEXP (addr, 1)) != 0)
23773 addr = XEXP (addr, 1);
23774 else if (CONSTANT_P (XEXP (addr, 0)))
23775 addr = XEXP (addr, 1);
23776 else if (CONSTANT_P (XEXP (addr, 1)))
23777 addr = XEXP (addr, 0);
23779 gcc_unreachable ();
23781 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
23786 rs6000_fatal_bad_address (rtx op)
23788 fatal_insn ("bad address", op);
23793 static tree branch_island_list = 0;
23795 /* Remember to generate a branch island for far calls to the given
23799 add_compiler_branch_island (tree label_name, tree function_name,
23802 tree branch_island = build_tree_list (function_name, label_name);
23803 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
23804 TREE_CHAIN (branch_island) = branch_island_list;
23805 branch_island_list = branch_island;
23808 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
23809 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
23810 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
23811 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
23813 /* Generate far-jump branch islands for everything on the
23814 branch_island_list. Invoked immediately after the last instruction
23815 of the epilogue has been emitted; the branch-islands must be
23816 appended to, and contiguous with, the function body. Mach-O stubs
23817 are generated in machopic_output_stub(). */
23820 macho_branch_islands (void)
23823 tree branch_island;
23825 for (branch_island = branch_island_list;
23827 branch_island = TREE_CHAIN (branch_island))
23829 const char *label =
23830 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
23832 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
23833 char name_buf[512];
23834 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
23835 if (name[0] == '*' || name[0] == '&')
23836 strcpy (name_buf, name+1);
23840 strcpy (name_buf+1, name);
23842 strcpy (tmp_buf, "\n");
23843 strcat (tmp_buf, label);
23844 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23845 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23846 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23847 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23850 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
23851 strcat (tmp_buf, label);
23852 strcat (tmp_buf, "_pic\n");
23853 strcat (tmp_buf, label);
23854 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
23856 strcat (tmp_buf, "\taddis r11,r11,ha16(");
23857 strcat (tmp_buf, name_buf);
23858 strcat (tmp_buf, " - ");
23859 strcat (tmp_buf, label);
23860 strcat (tmp_buf, "_pic)\n");
23862 strcat (tmp_buf, "\tmtlr r0\n");
23864 strcat (tmp_buf, "\taddi r12,r11,lo16(");
23865 strcat (tmp_buf, name_buf);
23866 strcat (tmp_buf, " - ");
23867 strcat (tmp_buf, label);
23868 strcat (tmp_buf, "_pic)\n");
23870 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
23874 strcat (tmp_buf, ":\nlis r12,hi16(");
23875 strcat (tmp_buf, name_buf);
23876 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
23877 strcat (tmp_buf, name_buf);
23878 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
23880 output_asm_insn (tmp_buf, 0);
23881 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23882 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23883 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23884 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23887 branch_island_list = 0;
23890 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
23891 already there or not. */
23894 no_previous_def (tree function_name)
23896 tree branch_island;
23897 for (branch_island = branch_island_list;
23899 branch_island = TREE_CHAIN (branch_island))
23900 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23905 /* GET_PREV_LABEL gets the label name from the previous definition of
23909 get_prev_label (tree function_name)
23911 tree branch_island;
23912 for (branch_island = branch_island_list;
23914 branch_island = TREE_CHAIN (branch_island))
23915 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23916 return BRANCH_ISLAND_LABEL_NAME (branch_island);
23920 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
23921 #define DARWIN_LINKER_GENERATES_ISLANDS 0
23924 /* KEXTs still need branch islands. */
23925 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
23926 || flag_mkernel || flag_apple_kext)
23928 /* INSN is either a function call or a millicode call. It may have an
23929 unconditional jump in its delay slot.
23931 CALL_DEST is the routine we are calling. */
23934 output_call (rtx insn, rtx *operands, int dest_operand_number,
23935 int cookie_operand_number)
23937 static char buf[256];
23938 if (DARWIN_GENERATE_ISLANDS
23939 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
23940 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
23943 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
23945 if (no_previous_def (funname))
23947 rtx label_rtx = gen_label_rtx ();
23948 char *label_buf, temp_buf[256];
23949 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
23950 CODE_LABEL_NUMBER (label_rtx));
23951 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
23952 labelname = get_identifier (label_buf);
23953 add_compiler_branch_island (labelname, funname, insn_line (insn));
23956 labelname = get_prev_label (funname);
23958 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
23959 instruction will reach 'foo', otherwise link as 'bl L42'".
23960 "L42" should be a 'branch island', that will do a far jump to
23961 'foo'. Branch islands are generated in
23962 macho_branch_islands(). */
23963 sprintf (buf, "jbsr %%z%d,%.246s",
23964 dest_operand_number, IDENTIFIER_POINTER (labelname));
23967 sprintf (buf, "bl %%z%d", dest_operand_number);
23971 /* Generate PIC and indirect symbol stubs. */
23974 machopic_output_stub (FILE *file, const char *symb, const char *stub)
23976 unsigned int length;
23977 char *symbol_name, *lazy_ptr_name;
23978 char *local_label_0;
23979 static int label = 0;
23981 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
23982 symb = (*targetm.strip_name_encoding) (symb);
23985 length = strlen (symb);
23986 symbol_name = XALLOCAVEC (char, length + 32);
23987 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
23989 lazy_ptr_name = XALLOCAVEC (char, length + 32);
23990 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
23993 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
23995 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
23999 fprintf (file, "\t.align 5\n");
24001 fprintf (file, "%s:\n", stub);
24002 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24005 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
24006 sprintf (local_label_0, "\"L%011d$spb\"", label);
24008 fprintf (file, "\tmflr r0\n");
24009 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
24010 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
24011 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
24012 lazy_ptr_name, local_label_0);
24013 fprintf (file, "\tmtlr r0\n");
24014 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
24015 (TARGET_64BIT ? "ldu" : "lwzu"),
24016 lazy_ptr_name, local_label_0);
24017 fprintf (file, "\tmtctr r12\n");
24018 fprintf (file, "\tbctr\n");
24022 fprintf (file, "\t.align 4\n");
24024 fprintf (file, "%s:\n", stub);
24025 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24027 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
24028 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
24029 (TARGET_64BIT ? "ldu" : "lwzu"),
24031 fprintf (file, "\tmtctr r12\n");
24032 fprintf (file, "\tbctr\n");
24035 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
24036 fprintf (file, "%s:\n", lazy_ptr_name);
24037 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24038 fprintf (file, "%sdyld_stub_binding_helper\n",
24039 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
24042 /* Legitimize PIC addresses. If the address is already
24043 position-independent, we return ORIG. Newly generated
24044 position-independent addresses go into a reg. This is REG if non
24045 zero, otherwise we allocate register(s) as necessary. */
24047 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
24050 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
24055 if (reg == NULL && ! reload_in_progress && ! reload_completed)
24056 reg = gen_reg_rtx (Pmode);
24058 if (GET_CODE (orig) == CONST)
24062 if (GET_CODE (XEXP (orig, 0)) == PLUS
24063 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
24066 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
24068 /* Use a different reg for the intermediate value, as
24069 it will be marked UNCHANGING. */
24070 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
24071 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
24074 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
24077 if (GET_CODE (offset) == CONST_INT)
24079 if (SMALL_INT (offset))
24080 return plus_constant (base, INTVAL (offset));
24081 else if (! reload_in_progress && ! reload_completed)
24082 offset = force_reg (Pmode, offset);
24085 rtx mem = force_const_mem (Pmode, orig);
24086 return machopic_legitimize_pic_address (mem, Pmode, reg);
24089 return gen_rtx_PLUS (Pmode, base, offset);
24092 /* Fall back on generic machopic code. */
24093 return machopic_legitimize_pic_address (orig, mode, reg);
24096 /* Output a .machine directive for the Darwin assembler, and call
24097 the generic start_file routine. */
24100 rs6000_darwin_file_start (void)
24102 static const struct
24108 { "ppc64", "ppc64", MASK_64BIT },
24109 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
24110 { "power4", "ppc970", 0 },
24111 { "G5", "ppc970", 0 },
24112 { "7450", "ppc7450", 0 },
24113 { "7400", "ppc7400", MASK_ALTIVEC },
24114 { "G4", "ppc7400", 0 },
24115 { "750", "ppc750", 0 },
24116 { "740", "ppc750", 0 },
24117 { "G3", "ppc750", 0 },
24118 { "604e", "ppc604e", 0 },
24119 { "604", "ppc604", 0 },
24120 { "603e", "ppc603", 0 },
24121 { "603", "ppc603", 0 },
24122 { "601", "ppc601", 0 },
24123 { NULL, "ppc", 0 } };
24124 const char *cpu_id = "";
24127 rs6000_file_start ();
24128 darwin_file_start ();
24130 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
24131 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
24132 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
24133 && rs6000_select[i].string[0] != '\0')
24134 cpu_id = rs6000_select[i].string;
24136 /* Look through the mapping array. Pick the first name that either
24137 matches the argument, has a bit set in IF_SET that is also set
24138 in the target flags, or has a NULL name. */
24141 while (mapping[i].arg != NULL
24142 && strcmp (mapping[i].arg, cpu_id) != 0
24143 && (mapping[i].if_set & target_flags) == 0)
24146 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
24149 #endif /* TARGET_MACHO */
24153 rs6000_elf_reloc_rw_mask (void)
24157 else if (DEFAULT_ABI == ABI_AIX)
24163 /* Record an element in the table of global constructors. SYMBOL is
24164 a SYMBOL_REF of the function to be called; PRIORITY is a number
24165 between 0 and MAX_INIT_PRIORITY.
24167 This differs from default_named_section_asm_out_constructor in
24168 that we have special handling for -mrelocatable. */
24171 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
24173 const char *section = ".ctors";
24176 if (priority != DEFAULT_INIT_PRIORITY)
24178 sprintf (buf, ".ctors.%.5u",
24179 /* Invert the numbering so the linker puts us in the proper
24180 order; constructors are run from right to left, and the
24181 linker sorts in increasing order. */
24182 MAX_INIT_PRIORITY - priority);
24186 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24187 assemble_align (POINTER_SIZE);
24189 if (TARGET_RELOCATABLE)
24191 fputs ("\t.long (", asm_out_file);
24192 output_addr_const (asm_out_file, symbol);
24193 fputs (")@fixup\n", asm_out_file);
24196 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24200 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
24202 const char *section = ".dtors";
24205 if (priority != DEFAULT_INIT_PRIORITY)
24207 sprintf (buf, ".dtors.%.5u",
24208 /* Invert the numbering so the linker puts us in the proper
24209 order; constructors are run from right to left, and the
24210 linker sorts in increasing order. */
24211 MAX_INIT_PRIORITY - priority);
24215 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24216 assemble_align (POINTER_SIZE);
24218 if (TARGET_RELOCATABLE)
24220 fputs ("\t.long (", asm_out_file);
24221 output_addr_const (asm_out_file, symbol);
24222 fputs (")@fixup\n", asm_out_file);
24225 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24229 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
24233 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
24234 ASM_OUTPUT_LABEL (file, name);
24235 fputs (DOUBLE_INT_ASM_OP, file);
24236 rs6000_output_function_entry (file, name);
24237 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
24240 fputs ("\t.size\t", file);
24241 assemble_name (file, name);
24242 fputs (",24\n\t.type\t.", file);
24243 assemble_name (file, name);
24244 fputs (",@function\n", file);
24245 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
24247 fputs ("\t.globl\t.", file);
24248 assemble_name (file, name);
24253 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24254 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24255 rs6000_output_function_entry (file, name);
24256 fputs (":\n", file);
24260 if (TARGET_RELOCATABLE
24261 && !TARGET_SECURE_PLT
24262 && (get_pool_size () != 0 || crtl->profile)
24267 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
24269 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
24270 fprintf (file, "\t.long ");
24271 assemble_name (file, buf);
24273 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
24274 assemble_name (file, buf);
24278 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24279 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24281 if (DEFAULT_ABI == ABI_AIX)
24283 const char *desc_name, *orig_name;
24285 orig_name = (*targetm.strip_name_encoding) (name);
24286 desc_name = orig_name;
24287 while (*desc_name == '.')
24290 if (TREE_PUBLIC (decl))
24291 fprintf (file, "\t.globl %s\n", desc_name);
24293 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24294 fprintf (file, "%s:\n", desc_name);
24295 fprintf (file, "\t.long %s\n", orig_name);
24296 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
24297 if (DEFAULT_ABI == ABI_AIX)
24298 fputs ("\t.long 0\n", file);
24299 fprintf (file, "\t.previous\n");
24301 ASM_OUTPUT_LABEL (file, name);
24305 rs6000_elf_end_indicate_exec_stack (void)
24308 file_end_indicate_exec_stack ();
24314 rs6000_xcoff_asm_output_anchor (rtx symbol)
24318 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24319 SYMBOL_REF_BLOCK_OFFSET (symbol));
24320 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24324 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24326 fputs (GLOBAL_ASM_OP, stream);
24327 RS6000_OUTPUT_BASENAME (stream, name);
24328 putc ('\n', stream);
24331 /* A get_unnamed_decl callback, used for read-only sections. PTR
24332 points to the section string variable. */
24335 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24337 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24338 *(const char *const *) directive,
24339 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24342 /* Likewise for read-write sections. */
24345 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24347 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24348 *(const char *const *) directive,
24349 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24352 /* A get_unnamed_section callback, used for switching to toc_section. */
24355 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24357 if (TARGET_MINIMAL_TOC)
24359 /* toc_section is always selected at least once from
24360 rs6000_xcoff_file_start, so this is guaranteed to
24361 always be defined once and only once in each file. */
24362 if (!toc_initialized)
24364 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24365 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24366 toc_initialized = 1;
24368 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
24369 (TARGET_32BIT ? "" : ",3"));
24372 fputs ("\t.toc\n", asm_out_file);
24375 /* Implement TARGET_ASM_INIT_SECTIONS. */
24378 rs6000_xcoff_asm_init_sections (void)
24380 read_only_data_section
24381 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24382 &xcoff_read_only_section_name);
24384 private_data_section
24385 = get_unnamed_section (SECTION_WRITE,
24386 rs6000_xcoff_output_readwrite_section_asm_op,
24387 &xcoff_private_data_section_name);
24389 read_only_private_data_section
24390 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24391 &xcoff_private_data_section_name);
24394 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
24396 readonly_data_section = read_only_data_section;
24397 exception_section = data_section;
24401 rs6000_xcoff_reloc_rw_mask (void)
24407 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
24408 tree decl ATTRIBUTE_UNUSED)
24411 static const char * const suffix[3] = { "PR", "RO", "RW" };
24413 if (flags & SECTION_CODE)
24415 else if (flags & SECTION_WRITE)
24420 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
24421 (flags & SECTION_CODE) ? "." : "",
24422 name, suffix[smclass], flags & SECTION_ENTSIZE);
24426 rs6000_xcoff_select_section (tree decl, int reloc,
24427 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24429 if (decl_readonly_section (decl, reloc))
24431 if (TREE_PUBLIC (decl))
24432 return read_only_data_section;
24434 return read_only_private_data_section;
24438 if (TREE_PUBLIC (decl))
24439 return data_section;
24441 return private_data_section;
24446 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
24450 /* Use select_section for private and uninitialized data. */
24451 if (!TREE_PUBLIC (decl)
24452 || DECL_COMMON (decl)
24453 || DECL_INITIAL (decl) == NULL_TREE
24454 || DECL_INITIAL (decl) == error_mark_node
24455 || (flag_zero_initialized_in_bss
24456 && initializer_zerop (DECL_INITIAL (decl))))
24459 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
24460 name = (*targetm.strip_name_encoding) (name);
24461 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
24464 /* Select section for constant in constant pool.
24466 On RS/6000, all constants are in the private read-only data area.
24467 However, if this is being placed in the TOC it must be output as a
24471 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
24472 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24474 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24475 return toc_section;
24477 return read_only_private_data_section;
24480 /* Remove any trailing [DS] or the like from the symbol name. */
24482 static const char *
24483 rs6000_xcoff_strip_name_encoding (const char *name)
24488 len = strlen (name);
24489 if (name[len - 1] == ']')
24490 return ggc_alloc_string (name, len - 4);
24495 /* Section attributes. AIX is always PIC. */
24497 static unsigned int
24498 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24500 unsigned int align;
24501 unsigned int flags = default_section_type_flags (decl, name, reloc);
24503 /* Align to at least UNIT size. */
24504 if (flags & SECTION_CODE)
24505 align = MIN_UNITS_PER_WORD;
24507 /* Increase alignment of large objects if not already stricter. */
24508 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24509 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24510 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24512 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24515 /* Output at beginning of assembler file.
24517 Initialize the section names for the RS/6000 at this point.
24519 Specify filename, including full path, to assembler.
24521 We want to go into the TOC section so at least one .toc will be emitted.
24522 Also, in order to output proper .bs/.es pairs, we need at least one static
24523 [RW] section emitted.
24525 Finally, declare mcount when profiling to make the assembler happy. */
24528 rs6000_xcoff_file_start (void)
24530 rs6000_gen_section_name (&xcoff_bss_section_name,
24531 main_input_filename, ".bss_");
24532 rs6000_gen_section_name (&xcoff_private_data_section_name,
24533 main_input_filename, ".rw_");
24534 rs6000_gen_section_name (&xcoff_read_only_section_name,
24535 main_input_filename, ".ro_");
24537 fputs ("\t.file\t", asm_out_file);
24538 output_quoted_string (asm_out_file, main_input_filename);
24539 fputc ('\n', asm_out_file);
24540 if (write_symbols != NO_DEBUG)
24541 switch_to_section (private_data_section);
24542 switch_to_section (text_section);
24544 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
24545 rs6000_file_start ();
24548 /* Output at end of assembler file.
24549 On the RS/6000, referencing data should automatically pull in text. */
24552 rs6000_xcoff_file_end (void)
24554 switch_to_section (text_section);
24555 fputs ("_section_.text:\n", asm_out_file);
24556 switch_to_section (data_section);
24557 fputs (TARGET_32BIT
24558 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24561 #endif /* TARGET_XCOFF */
24563 /* Compute a (partial) cost for rtx X. Return true if the complete
24564 cost has been computed, and false if subexpressions should be
24565 scanned. In either case, *TOTAL contains the cost result. */
24568 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
24571 enum machine_mode mode = GET_MODE (x);
24575 /* On the RS/6000, if it is valid in the insn, it is free. */
24577 if (((outer_code == SET
24578 || outer_code == PLUS
24579 || outer_code == MINUS)
24580 && (satisfies_constraint_I (x)
24581 || satisfies_constraint_L (x)))
24582 || (outer_code == AND
24583 && (satisfies_constraint_K (x)
24585 ? satisfies_constraint_L (x)
24586 : satisfies_constraint_J (x))
24587 || mask_operand (x, mode)
24589 && mask64_operand (x, DImode))))
24590 || ((outer_code == IOR || outer_code == XOR)
24591 && (satisfies_constraint_K (x)
24593 ? satisfies_constraint_L (x)
24594 : satisfies_constraint_J (x))))
24595 || outer_code == ASHIFT
24596 || outer_code == ASHIFTRT
24597 || outer_code == LSHIFTRT
24598 || outer_code == ROTATE
24599 || outer_code == ROTATERT
24600 || outer_code == ZERO_EXTRACT
24601 || (outer_code == MULT
24602 && satisfies_constraint_I (x))
24603 || ((outer_code == DIV || outer_code == UDIV
24604 || outer_code == MOD || outer_code == UMOD)
24605 && exact_log2 (INTVAL (x)) >= 0)
24606 || (outer_code == COMPARE
24607 && (satisfies_constraint_I (x)
24608 || satisfies_constraint_K (x)))
24609 || (outer_code == EQ
24610 && (satisfies_constraint_I (x)
24611 || satisfies_constraint_K (x)
24613 ? satisfies_constraint_L (x)
24614 : satisfies_constraint_J (x))))
24615 || (outer_code == GTU
24616 && satisfies_constraint_I (x))
24617 || (outer_code == LTU
24618 && satisfies_constraint_P (x)))
24623 else if ((outer_code == PLUS
24624 && reg_or_add_cint_operand (x, VOIDmode))
24625 || (outer_code == MINUS
24626 && reg_or_sub_cint_operand (x, VOIDmode))
24627 || ((outer_code == SET
24628 || outer_code == IOR
24629 || outer_code == XOR)
24631 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
24633 *total = COSTS_N_INSNS (1);
24639 if (mode == DImode && code == CONST_DOUBLE)
24641 if ((outer_code == IOR || outer_code == XOR)
24642 && CONST_DOUBLE_HIGH (x) == 0
24643 && (CONST_DOUBLE_LOW (x)
24644 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
24649 else if ((outer_code == AND && and64_2_operand (x, DImode))
24650 || ((outer_code == SET
24651 || outer_code == IOR
24652 || outer_code == XOR)
24653 && CONST_DOUBLE_HIGH (x) == 0))
24655 *total = COSTS_N_INSNS (1);
24665 /* When optimizing for size, MEM should be slightly more expensive
24666 than generating address, e.g., (plus (reg) (const)).
24667 L1 cache latency is about two instructions. */
24668 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
24676 if (mode == DFmode)
24678 if (GET_CODE (XEXP (x, 0)) == MULT)
24680 /* FNMA accounted in outer NEG. */
24681 if (outer_code == NEG)
24682 *total = rs6000_cost->dmul - rs6000_cost->fp;
24684 *total = rs6000_cost->dmul;
24687 *total = rs6000_cost->fp;
24689 else if (mode == SFmode)
24691 /* FNMA accounted in outer NEG. */
24692 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24695 *total = rs6000_cost->fp;
24698 *total = COSTS_N_INSNS (1);
24702 if (mode == DFmode)
24704 if (GET_CODE (XEXP (x, 0)) == MULT
24705 || GET_CODE (XEXP (x, 1)) == MULT)
24707 /* FNMA accounted in outer NEG. */
24708 if (outer_code == NEG)
24709 *total = rs6000_cost->dmul - rs6000_cost->fp;
24711 *total = rs6000_cost->dmul;
24714 *total = rs6000_cost->fp;
24716 else if (mode == SFmode)
24718 /* FNMA accounted in outer NEG. */
24719 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24722 *total = rs6000_cost->fp;
24725 *total = COSTS_N_INSNS (1);
24729 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24730 && satisfies_constraint_I (XEXP (x, 1)))
24732 if (INTVAL (XEXP (x, 1)) >= -256
24733 && INTVAL (XEXP (x, 1)) <= 255)
24734 *total = rs6000_cost->mulsi_const9;
24736 *total = rs6000_cost->mulsi_const;
24738 /* FMA accounted in outer PLUS/MINUS. */
24739 else if ((mode == DFmode || mode == SFmode)
24740 && (outer_code == PLUS || outer_code == MINUS))
24742 else if (mode == DFmode)
24743 *total = rs6000_cost->dmul;
24744 else if (mode == SFmode)
24745 *total = rs6000_cost->fp;
24746 else if (mode == DImode)
24747 *total = rs6000_cost->muldi;
24749 *total = rs6000_cost->mulsi;
24754 if (FLOAT_MODE_P (mode))
24756 *total = mode == DFmode ? rs6000_cost->ddiv
24757 : rs6000_cost->sdiv;
24764 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24765 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
24767 if (code == DIV || code == MOD)
24769 *total = COSTS_N_INSNS (2);
24772 *total = COSTS_N_INSNS (1);
24776 if (GET_MODE (XEXP (x, 1)) == DImode)
24777 *total = rs6000_cost->divdi;
24779 *total = rs6000_cost->divsi;
24781 /* Add in shift and subtract for MOD. */
24782 if (code == MOD || code == UMOD)
24783 *total += COSTS_N_INSNS (2);
24788 *total = COSTS_N_INSNS (4);
24792 *total = COSTS_N_INSNS (6);
24796 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
24808 *total = COSTS_N_INSNS (1);
24816 /* Handle mul_highpart. */
24817 if (outer_code == TRUNCATE
24818 && GET_CODE (XEXP (x, 0)) == MULT)
24820 if (mode == DImode)
24821 *total = rs6000_cost->muldi;
24823 *total = rs6000_cost->mulsi;
24826 else if (outer_code == AND)
24829 *total = COSTS_N_INSNS (1);
24834 if (GET_CODE (XEXP (x, 0)) == MEM)
24837 *total = COSTS_N_INSNS (1);
24843 if (!FLOAT_MODE_P (mode))
24845 *total = COSTS_N_INSNS (1);
24851 case UNSIGNED_FLOAT:
24854 case FLOAT_TRUNCATE:
24855 *total = rs6000_cost->fp;
24859 if (mode == DFmode)
24862 *total = rs6000_cost->fp;
24866 switch (XINT (x, 1))
24869 *total = rs6000_cost->fp;
24881 *total = COSTS_N_INSNS (1);
24884 else if (FLOAT_MODE_P (mode)
24885 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
24887 *total = rs6000_cost->fp;
24895 /* Carry bit requires mode == Pmode.
24896 NEG or PLUS already counted so only add one. */
24898 && (outer_code == NEG || outer_code == PLUS))
24900 *total = COSTS_N_INSNS (1);
24903 if (outer_code == SET)
24905 if (XEXP (x, 1) == const0_rtx)
24907 if (TARGET_ISEL && !TARGET_MFCRF)
24908 *total = COSTS_N_INSNS (8);
24910 *total = COSTS_N_INSNS (2);
24913 else if (mode == Pmode)
24915 *total = COSTS_N_INSNS (3);
24924 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
24926 if (TARGET_ISEL && !TARGET_MFCRF)
24927 *total = COSTS_N_INSNS (8);
24929 *total = COSTS_N_INSNS (2);
24933 if (outer_code == COMPARE)
24947 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
24950 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
24953 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
24956 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
24957 "total = %d, speed = %s, x:\n",
24958 ret ? "complete" : "scan inner",
24959 GET_RTX_NAME (code),
24960 GET_RTX_NAME (outer_code),
24962 speed ? "true" : "false");
24969 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
24972 rs6000_debug_address_cost (rtx x, bool speed)
24974 int ret = TARGET_ADDRESS_COST (x, speed);
24976 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
24977 ret, speed ? "true" : "false");
24984 /* A C expression returning the cost of moving data from a register of class
24985 CLASS1 to one of CLASS2. */
24988 rs6000_register_move_cost (enum machine_mode mode,
24989 enum reg_class from, enum reg_class to)
24993 /* Moves from/to GENERAL_REGS. */
24994 if (reg_classes_intersect_p (to, GENERAL_REGS)
24995 || reg_classes_intersect_p (from, GENERAL_REGS))
24997 if (! reg_classes_intersect_p (to, GENERAL_REGS))
25000 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
25001 ret = (rs6000_memory_move_cost (mode, from, 0)
25002 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
25004 /* It's more expensive to move CR_REGS than CR0_REGS because of the
25006 else if (from == CR_REGS)
25009 /* Power6 has slower LR/CTR moves so make them more expensive than
25010 memory in order to bias spills to memory .*/
25011 else if (rs6000_cpu == PROCESSOR_POWER6
25012 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
25013 ret = 6 * hard_regno_nregs[0][mode];
25016 /* A move will cost one instruction per GPR moved. */
25017 ret = 2 * hard_regno_nregs[0][mode];
25020 /* If we have VSX, we can easily move between FPR or Altivec registers. */
25021 else if (VECTOR_UNIT_VSX_P (mode)
25022 && reg_classes_intersect_p (to, VSX_REGS)
25023 && reg_classes_intersect_p (from, VSX_REGS))
25024 ret = 2 * hard_regno_nregs[32][mode];
25026 /* Moving between two similar registers is just one instruction. */
25027 else if (reg_classes_intersect_p (to, from))
25028 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
25030 /* Everything else has to go through GENERAL_REGS. */
25032 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
25033 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
25035 if (TARGET_DEBUG_COST)
25037 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
25038 ret, GET_MODE_NAME (mode), reg_class_names[from],
25039 reg_class_names[to]);
25044 /* A C expressions returning the cost of moving data of MODE from a register to
25048 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
25049 int in ATTRIBUTE_UNUSED)
25053 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
25054 ret = 4 * hard_regno_nregs[0][mode];
25055 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
25056 ret = 4 * hard_regno_nregs[32][mode];
25057 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
25058 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
25060 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
25062 if (TARGET_DEBUG_COST)
25064 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
25065 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
25070 /* Returns a code for a target-specific builtin that implements
25071 reciprocal of the function, or NULL_TREE if not available. */
25074 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
25075 bool sqrt ATTRIBUTE_UNUSED)
25077 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
25078 && flag_finite_math_only && !flag_trapping_math
25079 && flag_unsafe_math_optimizations))
25087 case BUILT_IN_SQRTF:
25088 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
25095 /* Newton-Raphson approximation of single-precision floating point divide n/d.
25096 Assumes no trapping math and finite arguments. */
25099 rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
25101 rtx x0, e0, e1, y1, u0, v0, one;
25103 x0 = gen_reg_rtx (SFmode);
25104 e0 = gen_reg_rtx (SFmode);
25105 e1 = gen_reg_rtx (SFmode);
25106 y1 = gen_reg_rtx (SFmode);
25107 u0 = gen_reg_rtx (SFmode);
25108 v0 = gen_reg_rtx (SFmode);
25109 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
25111 /* x0 = 1./d estimate */
25112 emit_insn (gen_rtx_SET (VOIDmode, x0,
25113 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
25115 /* e0 = 1. - d * x0 */
25116 emit_insn (gen_rtx_SET (VOIDmode, e0,
25117 gen_rtx_MINUS (SFmode, one,
25118 gen_rtx_MULT (SFmode, d, x0))));
25119 /* e1 = e0 + e0 * e0 */
25120 emit_insn (gen_rtx_SET (VOIDmode, e1,
25121 gen_rtx_PLUS (SFmode,
25122 gen_rtx_MULT (SFmode, e0, e0), e0)));
25123 /* y1 = x0 + e1 * x0 */
25124 emit_insn (gen_rtx_SET (VOIDmode, y1,
25125 gen_rtx_PLUS (SFmode,
25126 gen_rtx_MULT (SFmode, e1, x0), x0)));
25128 emit_insn (gen_rtx_SET (VOIDmode, u0,
25129 gen_rtx_MULT (SFmode, n, y1)));
25130 /* v0 = n - d * u0 */
25131 emit_insn (gen_rtx_SET (VOIDmode, v0,
25132 gen_rtx_MINUS (SFmode, n,
25133 gen_rtx_MULT (SFmode, d, u0))));
25134 /* dst = u0 + v0 * y1 */
25135 emit_insn (gen_rtx_SET (VOIDmode, dst,
25136 gen_rtx_PLUS (SFmode,
25137 gen_rtx_MULT (SFmode, v0, y1), u0)));
25140 /* Newton-Raphson approximation of double-precision floating point divide n/d.
25141 Assumes no trapping math and finite arguments. */
25144 rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
25146 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
25148 x0 = gen_reg_rtx (DFmode);
25149 e0 = gen_reg_rtx (DFmode);
25150 e1 = gen_reg_rtx (DFmode);
25151 e2 = gen_reg_rtx (DFmode);
25152 y1 = gen_reg_rtx (DFmode);
25153 y2 = gen_reg_rtx (DFmode);
25154 y3 = gen_reg_rtx (DFmode);
25155 u0 = gen_reg_rtx (DFmode);
25156 v0 = gen_reg_rtx (DFmode);
25157 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
25159 /* x0 = 1./d estimate */
25160 emit_insn (gen_rtx_SET (VOIDmode, x0,
25161 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
25163 /* e0 = 1. - d * x0 */
25164 emit_insn (gen_rtx_SET (VOIDmode, e0,
25165 gen_rtx_MINUS (DFmode, one,
25166 gen_rtx_MULT (SFmode, d, x0))));
25167 /* y1 = x0 + e0 * x0 */
25168 emit_insn (gen_rtx_SET (VOIDmode, y1,
25169 gen_rtx_PLUS (DFmode,
25170 gen_rtx_MULT (DFmode, e0, x0), x0)));
25172 emit_insn (gen_rtx_SET (VOIDmode, e1,
25173 gen_rtx_MULT (DFmode, e0, e0)));
25174 /* y2 = y1 + e1 * y1 */
25175 emit_insn (gen_rtx_SET (VOIDmode, y2,
25176 gen_rtx_PLUS (DFmode,
25177 gen_rtx_MULT (DFmode, e1, y1), y1)));
25179 emit_insn (gen_rtx_SET (VOIDmode, e2,
25180 gen_rtx_MULT (DFmode, e1, e1)));
25181 /* y3 = y2 + e2 * y2 */
25182 emit_insn (gen_rtx_SET (VOIDmode, y3,
25183 gen_rtx_PLUS (DFmode,
25184 gen_rtx_MULT (DFmode, e2, y2), y2)));
25186 emit_insn (gen_rtx_SET (VOIDmode, u0,
25187 gen_rtx_MULT (DFmode, n, y3)));
25188 /* v0 = n - d * u0 */
25189 emit_insn (gen_rtx_SET (VOIDmode, v0,
25190 gen_rtx_MINUS (DFmode, n,
25191 gen_rtx_MULT (DFmode, d, u0))));
25192 /* dst = u0 + v0 * y3 */
25193 emit_insn (gen_rtx_SET (VOIDmode, dst,
25194 gen_rtx_PLUS (DFmode,
25195 gen_rtx_MULT (DFmode, v0, y3), u0)));
25199 /* Newton-Raphson approximation of single-precision floating point rsqrt.
25200 Assumes no trapping math and finite arguments. */
25203 rs6000_emit_swrsqrtsf (rtx dst, rtx src)
25205 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
25206 half, one, halfthree, c1, cond, label;
25208 x0 = gen_reg_rtx (SFmode);
25209 x1 = gen_reg_rtx (SFmode);
25210 x2 = gen_reg_rtx (SFmode);
25211 y1 = gen_reg_rtx (SFmode);
25212 u0 = gen_reg_rtx (SFmode);
25213 u1 = gen_reg_rtx (SFmode);
25214 u2 = gen_reg_rtx (SFmode);
25215 v0 = gen_reg_rtx (SFmode);
25216 v1 = gen_reg_rtx (SFmode);
25217 v2 = gen_reg_rtx (SFmode);
25218 t0 = gen_reg_rtx (SFmode);
25219 halfthree = gen_reg_rtx (SFmode);
25220 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
25221 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
25223 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
25224 emit_insn (gen_rtx_SET (VOIDmode, t0,
25225 gen_rtx_MULT (SFmode, src, src)));
25227 emit_insn (gen_rtx_SET (VOIDmode, cond,
25228 gen_rtx_COMPARE (CCFPmode, t0, src)));
25229 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
25230 emit_unlikely_jump (c1, label);
25232 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
25233 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
25235 /* halfthree = 1.5 = 1.0 + 0.5 */
25236 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
25237 gen_rtx_PLUS (SFmode, one, half)));
25239 /* x0 = rsqrt estimate */
25240 emit_insn (gen_rtx_SET (VOIDmode, x0,
25241 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
25244 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
25245 emit_insn (gen_rtx_SET (VOIDmode, y1,
25246 gen_rtx_MINUS (SFmode,
25247 gen_rtx_MULT (SFmode, src, halfthree),
25250 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
25251 emit_insn (gen_rtx_SET (VOIDmode, u0,
25252 gen_rtx_MULT (SFmode, x0, x0)));
25253 emit_insn (gen_rtx_SET (VOIDmode, v0,
25254 gen_rtx_MINUS (SFmode,
25256 gen_rtx_MULT (SFmode, y1, u0))));
25257 emit_insn (gen_rtx_SET (VOIDmode, x1,
25258 gen_rtx_MULT (SFmode, x0, v0)));
25260 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
25261 emit_insn (gen_rtx_SET (VOIDmode, u1,
25262 gen_rtx_MULT (SFmode, x1, x1)));
25263 emit_insn (gen_rtx_SET (VOIDmode, v1,
25264 gen_rtx_MINUS (SFmode,
25266 gen_rtx_MULT (SFmode, y1, u1))));
25267 emit_insn (gen_rtx_SET (VOIDmode, x2,
25268 gen_rtx_MULT (SFmode, x1, v1)));
25270 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
25271 emit_insn (gen_rtx_SET (VOIDmode, u2,
25272 gen_rtx_MULT (SFmode, x2, x2)));
25273 emit_insn (gen_rtx_SET (VOIDmode, v2,
25274 gen_rtx_MINUS (SFmode,
25276 gen_rtx_MULT (SFmode, y1, u2))));
25277 emit_insn (gen_rtx_SET (VOIDmode, dst,
25278 gen_rtx_MULT (SFmode, x2, v2)));
25280 emit_label (XEXP (label, 0));
25283 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
25284 (Power7) targets. DST is the target, and SRC is the argument operand. */
25287 rs6000_emit_popcount (rtx dst, rtx src)
25289 enum machine_mode mode = GET_MODE (dst);
25292 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
25293 if (TARGET_POPCNTD)
25295 if (mode == SImode)
25296 emit_insn (gen_popcntwsi2 (dst, src));
25298 emit_insn (gen_popcntddi2 (dst, src));
25302 tmp1 = gen_reg_rtx (mode);
25304 if (mode == SImode)
25306 emit_insn (gen_popcntbsi2 (tmp1, src));
25307 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
25309 tmp2 = force_reg (SImode, tmp2);
25310 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
25314 emit_insn (gen_popcntbdi2 (tmp1, src));
25315 tmp2 = expand_mult (DImode, tmp1,
25316 GEN_INT ((HOST_WIDE_INT)
25317 0x01010101 << 32 | 0x01010101),
25319 tmp2 = force_reg (DImode, tmp2);
25320 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
25325 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25326 target, and SRC is the argument operand. */
25329 rs6000_emit_parity (rtx dst, rtx src)
25331 enum machine_mode mode = GET_MODE (dst);
25334 tmp = gen_reg_rtx (mode);
25335 if (mode == SImode)
25337 /* Is mult+shift >= shift+xor+shift+xor? */
25338 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
25340 rtx tmp1, tmp2, tmp3, tmp4;
25342 tmp1 = gen_reg_rtx (SImode);
25343 emit_insn (gen_popcntbsi2 (tmp1, src));
25345 tmp2 = gen_reg_rtx (SImode);
25346 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
25347 tmp3 = gen_reg_rtx (SImode);
25348 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
25350 tmp4 = gen_reg_rtx (SImode);
25351 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
25352 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
25355 rs6000_emit_popcount (tmp, src);
25356 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
25360 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25361 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
25363 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
25365 tmp1 = gen_reg_rtx (DImode);
25366 emit_insn (gen_popcntbdi2 (tmp1, src));
25368 tmp2 = gen_reg_rtx (DImode);
25369 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
25370 tmp3 = gen_reg_rtx (DImode);
25371 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
25373 tmp4 = gen_reg_rtx (DImode);
25374 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
25375 tmp5 = gen_reg_rtx (DImode);
25376 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
25378 tmp6 = gen_reg_rtx (DImode);
25379 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
25380 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
25383 rs6000_emit_popcount (tmp, src);
25384 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
25388 /* Return an RTX representing where to find the function value of a
25389 function returning MODE. */
25391 rs6000_complex_function_value (enum machine_mode mode)
25393 unsigned int regno;
25395 enum machine_mode inner = GET_MODE_INNER (mode);
25396 unsigned int inner_bytes = GET_MODE_SIZE (inner);
25398 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25399 regno = FP_ARG_RETURN;
25402 regno = GP_ARG_RETURN;
25404 /* 32-bit is OK since it'll go in r3/r4. */
25405 if (TARGET_32BIT && inner_bytes >= 4)
25406 return gen_rtx_REG (mode, regno);
25409 if (inner_bytes >= 8)
25410 return gen_rtx_REG (mode, regno);
25412 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
25414 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
25415 GEN_INT (inner_bytes));
25416 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
25419 /* Target hook for TARGET_FUNCTION_VALUE.
25421 On the SPE, both FPs and vectors are returned in r3.
25423 On RS/6000 an integer value is in r3 and a floating-point value is in
25424 fp1, unless -msoft-float. */
25427 rs6000_function_value (const_tree valtype,
25428 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
25429 bool outgoing ATTRIBUTE_UNUSED)
25431 enum machine_mode mode;
25432 unsigned int regno;
25434 /* Special handling for structs in darwin64. */
25435 if (rs6000_darwin64_abi
25436 && TYPE_MODE (valtype) == BLKmode
25437 && TREE_CODE (valtype) == RECORD_TYPE
25438 && int_size_in_bytes (valtype) > 0)
25440 CUMULATIVE_ARGS valcum;
25444 valcum.fregno = FP_ARG_MIN_REG;
25445 valcum.vregno = ALTIVEC_ARG_MIN_REG;
25446 /* Do a trial code generation as if this were going to be passed as
25447 an argument; if any part goes in memory, we return NULL. */
25448 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
25451 /* Otherwise fall through to standard ABI rules. */
25454 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
25456 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25457 return gen_rtx_PARALLEL (DImode,
25459 gen_rtx_EXPR_LIST (VOIDmode,
25460 gen_rtx_REG (SImode, GP_ARG_RETURN),
25462 gen_rtx_EXPR_LIST (VOIDmode,
25463 gen_rtx_REG (SImode,
25464 GP_ARG_RETURN + 1),
25467 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
25469 return gen_rtx_PARALLEL (DCmode,
25471 gen_rtx_EXPR_LIST (VOIDmode,
25472 gen_rtx_REG (SImode, GP_ARG_RETURN),
25474 gen_rtx_EXPR_LIST (VOIDmode,
25475 gen_rtx_REG (SImode,
25476 GP_ARG_RETURN + 1),
25478 gen_rtx_EXPR_LIST (VOIDmode,
25479 gen_rtx_REG (SImode,
25480 GP_ARG_RETURN + 2),
25482 gen_rtx_EXPR_LIST (VOIDmode,
25483 gen_rtx_REG (SImode,
25484 GP_ARG_RETURN + 3),
25488 mode = TYPE_MODE (valtype);
25489 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
25490 || POINTER_TYPE_P (valtype))
25491 mode = TARGET_32BIT ? SImode : DImode;
25493 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25494 /* _Decimal128 must use an even/odd register pair. */
25495 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25496 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
25497 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
25498 regno = FP_ARG_RETURN;
25499 else if (TREE_CODE (valtype) == COMPLEX_TYPE
25500 && targetm.calls.split_complex_arg)
25501 return rs6000_complex_function_value (mode);
25502 else if (TREE_CODE (valtype) == VECTOR_TYPE
25503 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
25504 && ALTIVEC_VECTOR_MODE (mode))
25505 regno = ALTIVEC_ARG_RETURN;
25506 else if (TREE_CODE (valtype) == VECTOR_TYPE
25507 && TARGET_VSX && TARGET_ALTIVEC_ABI
25508 && VSX_VECTOR_MODE (mode))
25509 regno = ALTIVEC_ARG_RETURN;
25510 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25511 && (mode == DFmode || mode == DCmode
25512 || mode == TFmode || mode == TCmode))
25513 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25515 regno = GP_ARG_RETURN;
25517 return gen_rtx_REG (mode, regno);
25520 /* Define how to find the value returned by a library function
25521 assuming the value has mode MODE. */
25523 rs6000_libcall_value (enum machine_mode mode)
25525 unsigned int regno;
25527 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
25529 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25530 return gen_rtx_PARALLEL (DImode,
25532 gen_rtx_EXPR_LIST (VOIDmode,
25533 gen_rtx_REG (SImode, GP_ARG_RETURN),
25535 gen_rtx_EXPR_LIST (VOIDmode,
25536 gen_rtx_REG (SImode,
25537 GP_ARG_RETURN + 1),
25541 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25542 /* _Decimal128 must use an even/odd register pair. */
25543 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25544 else if (SCALAR_FLOAT_MODE_P (mode)
25545 && TARGET_HARD_FLOAT && TARGET_FPRS
25546 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
25547 regno = FP_ARG_RETURN;
25548 else if (ALTIVEC_VECTOR_MODE (mode)
25549 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
25550 regno = ALTIVEC_ARG_RETURN;
25551 else if (VSX_VECTOR_MODE (mode)
25552 && TARGET_VSX && TARGET_ALTIVEC_ABI)
25553 regno = ALTIVEC_ARG_RETURN;
25554 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
25555 return rs6000_complex_function_value (mode);
25556 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25557 && (mode == DFmode || mode == DCmode
25558 || mode == TFmode || mode == TCmode))
25559 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25561 regno = GP_ARG_RETURN;
25563 return gen_rtx_REG (mode, regno);
25567 /* Given FROM and TO register numbers, say whether this elimination is allowed.
25568 Frame pointer elimination is automatically handled.
25570 For the RS/6000, if frame pointer elimination is being done, we would like
25571 to convert ap into fp, not sp.
25573 We need r30 if -mminimal-toc was specified, and there are constant pool
25577 rs6000_can_eliminate (const int from, const int to)
25579 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
25580 ? ! frame_pointer_needed
25581 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
25582 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
25586 /* Define the offset between two registers, FROM to be eliminated and its
25587 replacement TO, at the start of a routine. */
25589 rs6000_initial_elimination_offset (int from, int to)
25591 rs6000_stack_t *info = rs6000_stack_info ();
25592 HOST_WIDE_INT offset;
25594 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25595 offset = info->push_p ? 0 : -info->total_size;
25596 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25598 offset = info->push_p ? 0 : -info->total_size;
25599 if (FRAME_GROWS_DOWNWARD)
25600 offset += info->fixed_size + info->vars_size + info->parm_size;
25602 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25603 offset = FRAME_GROWS_DOWNWARD
25604 ? info->fixed_size + info->vars_size + info->parm_size
25606 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25607 offset = info->total_size;
25608 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25609 offset = info->push_p ? info->total_size : 0;
25610 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
25613 gcc_unreachable ();
25619 rs6000_dwarf_register_span (rtx reg)
25623 unsigned regno = REGNO (reg);
25624 enum machine_mode mode = GET_MODE (reg);
25628 && (SPE_VECTOR_MODE (GET_MODE (reg))
25629 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
25630 && mode != SFmode && mode != SDmode && mode != SCmode)))
25635 regno = REGNO (reg);
25637 /* The duality of the SPE register size wreaks all kinds of havoc.
25638 This is a way of distinguishing r0 in 32-bits from r0 in
25640 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
25641 gcc_assert (words <= 4);
25642 for (i = 0; i < words; i++, regno++)
25644 if (BYTES_BIG_ENDIAN)
25646 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
25647 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
25651 parts[2 * i] = gen_rtx_REG (SImode, regno);
25652 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
25656 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
25659 /* Fill in sizes for SPE register high parts in table used by unwinder. */
25662 rs6000_init_dwarf_reg_sizes_extra (tree address)
25667 enum machine_mode mode = TYPE_MODE (char_type_node);
25668 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
25669 rtx mem = gen_rtx_MEM (BLKmode, addr);
25670 rtx value = gen_int_mode (4, mode);
25672 for (i = 1201; i < 1232; i++)
25674 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
25675 HOST_WIDE_INT offset
25676 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
25678 emit_move_insn (adjust_address (mem, mode, offset), value);
25683 /* Map internal gcc register numbers to DWARF2 register numbers. */
25686 rs6000_dbx_register_number (unsigned int regno)
25688 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
25690 if (regno == MQ_REGNO)
25692 if (regno == LR_REGNO)
25694 if (regno == CTR_REGNO)
25696 if (CR_REGNO_P (regno))
25697 return regno - CR0_REGNO + 86;
25698 if (regno == XER_REGNO)
25700 if (ALTIVEC_REGNO_P (regno))
25701 return regno - FIRST_ALTIVEC_REGNO + 1124;
25702 if (regno == VRSAVE_REGNO)
25704 if (regno == VSCR_REGNO)
25706 if (regno == SPE_ACC_REGNO)
25708 if (regno == SPEFSCR_REGNO)
25710 /* SPE high reg number. We get these values of regno from
25711 rs6000_dwarf_register_span. */
25712 gcc_assert (regno >= 1200 && regno < 1232);
25716 /* target hook eh_return_filter_mode */
25717 static enum machine_mode
25718 rs6000_eh_return_filter_mode (void)
25720 return TARGET_32BIT ? SImode : word_mode;
25723 /* Target hook for scalar_mode_supported_p. */
25725 rs6000_scalar_mode_supported_p (enum machine_mode mode)
25727 if (DECIMAL_FLOAT_MODE_P (mode))
25728 return default_decimal_float_supported_p ();
25730 return default_scalar_mode_supported_p (mode);
25733 /* Target hook for vector_mode_supported_p. */
25735 rs6000_vector_mode_supported_p (enum machine_mode mode)
25738 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
25741 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
25744 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
25751 /* Target hook for invalid_arg_for_unprototyped_fn. */
25752 static const char *
25753 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
25755 return (!rs6000_darwin64_abi
25757 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
25758 && (funcdecl == NULL_TREE
25759 || (TREE_CODE (funcdecl) == FUNCTION_DECL
25760 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
25761 ? N_("AltiVec argument passed to unprototyped function")
25765 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
25766 setup by using __stack_chk_fail_local hidden function instead of
25767 calling __stack_chk_fail directly. Otherwise it is better to call
25768 __stack_chk_fail directly. */
25771 rs6000_stack_protect_fail (void)
25773 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
25774 ? default_hidden_stack_protect_fail ()
25775 : default_external_stack_protect_fail ();
25779 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
25780 int num_operands ATTRIBUTE_UNUSED)
25782 if (rs6000_warn_cell_microcode)
25785 int insn_code_number = recog_memoized (insn);
25786 location_t location = locator_location (INSN_LOCATOR (insn));
25788 /* Punt on insns we cannot recognize. */
25789 if (insn_code_number < 0)
25792 temp = get_insn_template (insn_code_number, insn);
25794 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
25795 warning_at (location, OPT_mwarn_cell_microcode,
25796 "emitting microcode insn %s\t[%s] #%d",
25797 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25798 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
25799 warning_at (location, OPT_mwarn_cell_microcode,
25800 "emitting conditional microcode insn %s\t[%s] #%d",
25801 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25805 #include "gt-rs6000.h"