1 /* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
29 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-attr.h"
43 #include "basic-block.h"
44 #include "integrate.h"
50 #include "target-def.h"
51 #include "langhooks.h"
53 #include "cfglayout.h"
54 #include "sched-int.h"
56 #include "tree-flow.h"
59 #include "tm-constrs.h"
61 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
64 #include "gstab.h" /* for N_SLINE */
67 #ifndef TARGET_NO_PROTOTYPE
68 #define TARGET_NO_PROTOTYPE 0
71 #define min(A,B) ((A) < (B) ? (A) : (B))
72 #define max(A,B) ((A) > (B) ? (A) : (B))
74 /* Structure used to define the rs6000 stack */
75 typedef struct rs6000_stack {
76 int first_gp_reg_save; /* first callee saved GP register used */
77 int first_fp_reg_save; /* first callee saved FP register used */
78 int first_altivec_reg_save; /* first callee saved AltiVec register used */
79 int lr_save_p; /* true if the link reg needs to be saved */
80 int cr_save_p; /* true if the CR reg needs to be saved */
81 unsigned int vrsave_mask; /* mask of vec registers to save */
82 int push_p; /* true if we need to allocate stack space */
83 int calls_p; /* true if the function makes any calls */
84 int world_save_p; /* true if we're saving *everything*:
85 r13-r31, cr, f14-f31, vrsave, v20-v31 */
86 enum rs6000_abi abi; /* which ABI to use */
87 int gp_save_offset; /* offset to save GP regs from initial SP */
88 int fp_save_offset; /* offset to save FP regs from initial SP */
89 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
90 int lr_save_offset; /* offset to save LR from initial SP */
91 int cr_save_offset; /* offset to save CR from initial SP */
92 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
93 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
94 int varargs_save_offset; /* offset to save the varargs registers */
95 int ehrd_offset; /* offset to EH return data */
96 int reg_size; /* register size (4 or 8) */
97 HOST_WIDE_INT vars_size; /* variable save area size */
98 int parm_size; /* outgoing parameter size */
99 int save_size; /* save area size */
100 int fixed_size; /* fixed size of stack frame */
101 int gp_size; /* size of saved GP registers */
102 int fp_size; /* size of saved FP registers */
103 int altivec_size; /* size of saved AltiVec registers */
104 int cr_size; /* size to hold CR if not in save_size */
105 int vrsave_size; /* size to hold VRSAVE if not in save_size */
106 int altivec_padding_size; /* size of altivec alignment padding if
108 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
109 int spe_padding_size;
110 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
111 int spe_64bit_regs_used;
114 /* A C structure for machine-specific, per-function data.
115 This is added to the cfun structure. */
116 typedef struct GTY(()) machine_function
118 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
119 int ra_needs_full_frame;
120 /* Some local-dynamic symbol. */
121 const char *some_ld_name;
122 /* Whether the instruction chain has been scanned already. */
123 int insn_chain_scanned_p;
124 /* Flags if __builtin_return_address (0) was used. */
126 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
127 varargs save area. */
128 HOST_WIDE_INT varargs_save_offset;
129 /* Temporary stack slot to use for SDmode copies. This slot is
130 64-bits wide and is allocated early enough so that the offset
131 does not overflow the 16-bit load/store offset field. */
132 rtx sdmode_stack_slot;
135 /* Target cpu type */
137 enum processor_type rs6000_cpu;
138 struct rs6000_cpu_select rs6000_select[3] =
140 /* switch name, tune arch */
141 { (const char *)0, "--with-cpu=", 1, 1 },
142 { (const char *)0, "-mcpu=", 1, 1 },
143 { (const char *)0, "-mtune=", 1, 0 },
146 /* Always emit branch hint bits. */
147 static GTY(()) bool rs6000_always_hint;
149 /* Schedule instructions for group formation. */
150 static GTY(()) bool rs6000_sched_groups;
152 /* Align branch targets. */
153 static GTY(()) bool rs6000_align_branch_targets;
155 /* Support for -msched-costly-dep option. */
156 const char *rs6000_sched_costly_dep_str;
157 enum rs6000_dependence_cost rs6000_sched_costly_dep;
159 /* Support for -minsert-sched-nops option. */
160 const char *rs6000_sched_insert_nops_str;
161 enum rs6000_nop_insertion rs6000_sched_insert_nops;
163 /* Support targetm.vectorize.builtin_mask_for_load. */
164 static GTY(()) tree altivec_builtin_mask_for_load;
166 /* Size of long double. */
167 int rs6000_long_double_type_size;
169 /* IEEE quad extended precision long double. */
172 /* Nonzero to use AltiVec ABI. */
173 int rs6000_altivec_abi;
175 /* Nonzero if we want SPE SIMD instructions. */
178 /* Nonzero if we want SPE ABI extensions. */
181 /* Nonzero if floating point operations are done in the GPRs. */
182 int rs6000_float_gprs = 0;
184 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
185 int rs6000_darwin64_abi;
187 /* Set to nonzero once AIX common-mode calls have been defined. */
188 static GTY(()) int common_mode_defined;
190 /* Label number of label created for -mrelocatable, to call to so we can
191 get the address of the GOT section */
192 int rs6000_pic_labelno;
195 /* Which abi to adhere to */
196 const char *rs6000_abi_name;
198 /* Semantics of the small data area */
199 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
201 /* Which small data model to use */
202 const char *rs6000_sdata_name = (char *)0;
204 /* Counter for labels which are to be placed in .fixup. */
205 int fixuplabelno = 0;
208 /* Bit size of immediate TLS offsets and string from which it is decoded. */
209 int rs6000_tls_size = 32;
210 const char *rs6000_tls_size_string;
212 /* ABI enumeration available for subtarget to use. */
213 enum rs6000_abi rs6000_current_abi;
215 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
219 const char *rs6000_debug_name;
220 int rs6000_debug_stack; /* debug stack applications */
221 int rs6000_debug_arg; /* debug argument handling */
222 int rs6000_debug_reg; /* debug register classes */
223 int rs6000_debug_addr; /* debug memory addressing */
224 int rs6000_debug_cost; /* debug rtx_costs */
226 /* Specify the machine mode that pointers have. After generation of rtl, the
227 compiler makes no further distinction between pointers and any other objects
228 of this machine mode. The type is unsigned since not all things that
229 include rs6000.h also include machmode.h. */
230 unsigned rs6000_pmode;
232 /* Width in bits of a pointer. */
233 unsigned rs6000_pointer_size;
236 /* Value is TRUE if register/mode pair is acceptable. */
237 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
239 /* Maximum number of registers needed for a given register class and mode. */
240 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
242 /* How many registers are needed for a given register and mode. */
243 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
245 /* Map register number to register class. */
246 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
248 /* Reload functions based on the type and the vector unit. */
249 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
251 /* Built in types. */
252 tree rs6000_builtin_types[RS6000_BTI_MAX];
253 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
255 const char *rs6000_traceback_name;
257 traceback_default = 0,
263 /* Flag to say the TOC is initialized */
265 char toc_label_name[10];
267 /* Cached value of rs6000_variable_issue. This is cached in
268 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
269 static short cached_can_issue_more;
271 static GTY(()) section *read_only_data_section;
272 static GTY(()) section *private_data_section;
273 static GTY(()) section *read_only_private_data_section;
274 static GTY(()) section *sdata2_section;
275 static GTY(()) section *toc_section;
277 /* Control alignment for fields within structures. */
278 /* String from -malign-XXXXX. */
279 int rs6000_alignment_flags;
281 /* True for any options that were explicitly set. */
283 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
284 bool alignment; /* True if -malign- was used. */
285 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
286 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
287 bool spe; /* True if -mspe= was used. */
288 bool float_gprs; /* True if -mfloat-gprs= was used. */
289 bool long_double; /* True if -mlong-double- was used. */
290 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
291 bool vrsave; /* True if -mvrsave was used. */
292 } rs6000_explicit_options;
294 struct builtin_description
296 /* mask is not const because we're going to alter it below. This
297 nonsense will go away when we rewrite the -march infrastructure
298 to give us more target flag bits. */
300 const enum insn_code icode;
301 const char *const name;
302 const enum rs6000_builtins code;
305 /* Describe the vector unit used for modes. */
306 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
307 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
309 /* Register classes for various constraints that are based on the target
311 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
313 /* Describe the alignment of a vector. */
314 int rs6000_vector_align[NUM_MACHINE_MODES];
316 /* Map selected modes to types for builtins. */
317 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
319 /* Target cpu costs. */
321 struct processor_costs {
322 const int mulsi; /* cost of SImode multiplication. */
323 const int mulsi_const; /* cost of SImode multiplication by constant. */
324 const int mulsi_const9; /* cost of SImode mult by short constant. */
325 const int muldi; /* cost of DImode multiplication. */
326 const int divsi; /* cost of SImode division. */
327 const int divdi; /* cost of DImode division. */
328 const int fp; /* cost of simple SFmode and DFmode insns. */
329 const int dmul; /* cost of DFmode multiplication (and fmadd). */
330 const int sdiv; /* cost of SFmode division (fdivs). */
331 const int ddiv; /* cost of DFmode division (fdiv). */
332 const int cache_line_size; /* cache line size in bytes. */
333 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
334 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
335 const int simultaneous_prefetches; /* number of parallel prefetch
339 const struct processor_costs *rs6000_cost;
341 /* Processor costs (relative to an add) */
343 /* Instruction size costs on 32bit processors. */
345 struct processor_costs size32_cost = {
346 COSTS_N_INSNS (1), /* mulsi */
347 COSTS_N_INSNS (1), /* mulsi_const */
348 COSTS_N_INSNS (1), /* mulsi_const9 */
349 COSTS_N_INSNS (1), /* muldi */
350 COSTS_N_INSNS (1), /* divsi */
351 COSTS_N_INSNS (1), /* divdi */
352 COSTS_N_INSNS (1), /* fp */
353 COSTS_N_INSNS (1), /* dmul */
354 COSTS_N_INSNS (1), /* sdiv */
355 COSTS_N_INSNS (1), /* ddiv */
362 /* Instruction size costs on 64bit processors. */
364 struct processor_costs size64_cost = {
365 COSTS_N_INSNS (1), /* mulsi */
366 COSTS_N_INSNS (1), /* mulsi_const */
367 COSTS_N_INSNS (1), /* mulsi_const9 */
368 COSTS_N_INSNS (1), /* muldi */
369 COSTS_N_INSNS (1), /* divsi */
370 COSTS_N_INSNS (1), /* divdi */
371 COSTS_N_INSNS (1), /* fp */
372 COSTS_N_INSNS (1), /* dmul */
373 COSTS_N_INSNS (1), /* sdiv */
374 COSTS_N_INSNS (1), /* ddiv */
381 /* Instruction costs on RIOS1 processors. */
383 struct processor_costs rios1_cost = {
384 COSTS_N_INSNS (5), /* mulsi */
385 COSTS_N_INSNS (4), /* mulsi_const */
386 COSTS_N_INSNS (3), /* mulsi_const9 */
387 COSTS_N_INSNS (5), /* muldi */
388 COSTS_N_INSNS (19), /* divsi */
389 COSTS_N_INSNS (19), /* divdi */
390 COSTS_N_INSNS (2), /* fp */
391 COSTS_N_INSNS (2), /* dmul */
392 COSTS_N_INSNS (19), /* sdiv */
393 COSTS_N_INSNS (19), /* ddiv */
394 128, /* cache line size */
400 /* Instruction costs on RIOS2 processors. */
402 struct processor_costs rios2_cost = {
403 COSTS_N_INSNS (2), /* mulsi */
404 COSTS_N_INSNS (2), /* mulsi_const */
405 COSTS_N_INSNS (2), /* mulsi_const9 */
406 COSTS_N_INSNS (2), /* muldi */
407 COSTS_N_INSNS (13), /* divsi */
408 COSTS_N_INSNS (13), /* divdi */
409 COSTS_N_INSNS (2), /* fp */
410 COSTS_N_INSNS (2), /* dmul */
411 COSTS_N_INSNS (17), /* sdiv */
412 COSTS_N_INSNS (17), /* ddiv */
413 256, /* cache line size */
419 /* Instruction costs on RS64A processors. */
421 struct processor_costs rs64a_cost = {
422 COSTS_N_INSNS (20), /* mulsi */
423 COSTS_N_INSNS (12), /* mulsi_const */
424 COSTS_N_INSNS (8), /* mulsi_const9 */
425 COSTS_N_INSNS (34), /* muldi */
426 COSTS_N_INSNS (65), /* divsi */
427 COSTS_N_INSNS (67), /* divdi */
428 COSTS_N_INSNS (4), /* fp */
429 COSTS_N_INSNS (4), /* dmul */
430 COSTS_N_INSNS (31), /* sdiv */
431 COSTS_N_INSNS (31), /* ddiv */
432 128, /* cache line size */
438 /* Instruction costs on MPCCORE processors. */
440 struct processor_costs mpccore_cost = {
441 COSTS_N_INSNS (2), /* mulsi */
442 COSTS_N_INSNS (2), /* mulsi_const */
443 COSTS_N_INSNS (2), /* mulsi_const9 */
444 COSTS_N_INSNS (2), /* muldi */
445 COSTS_N_INSNS (6), /* divsi */
446 COSTS_N_INSNS (6), /* divdi */
447 COSTS_N_INSNS (4), /* fp */
448 COSTS_N_INSNS (5), /* dmul */
449 COSTS_N_INSNS (10), /* sdiv */
450 COSTS_N_INSNS (17), /* ddiv */
451 32, /* cache line size */
457 /* Instruction costs on PPC403 processors. */
459 struct processor_costs ppc403_cost = {
460 COSTS_N_INSNS (4), /* mulsi */
461 COSTS_N_INSNS (4), /* mulsi_const */
462 COSTS_N_INSNS (4), /* mulsi_const9 */
463 COSTS_N_INSNS (4), /* muldi */
464 COSTS_N_INSNS (33), /* divsi */
465 COSTS_N_INSNS (33), /* divdi */
466 COSTS_N_INSNS (11), /* fp */
467 COSTS_N_INSNS (11), /* dmul */
468 COSTS_N_INSNS (11), /* sdiv */
469 COSTS_N_INSNS (11), /* ddiv */
470 32, /* cache line size */
476 /* Instruction costs on PPC405 processors. */
478 struct processor_costs ppc405_cost = {
479 COSTS_N_INSNS (5), /* mulsi */
480 COSTS_N_INSNS (4), /* mulsi_const */
481 COSTS_N_INSNS (3), /* mulsi_const9 */
482 COSTS_N_INSNS (5), /* muldi */
483 COSTS_N_INSNS (35), /* divsi */
484 COSTS_N_INSNS (35), /* divdi */
485 COSTS_N_INSNS (11), /* fp */
486 COSTS_N_INSNS (11), /* dmul */
487 COSTS_N_INSNS (11), /* sdiv */
488 COSTS_N_INSNS (11), /* ddiv */
489 32, /* cache line size */
495 /* Instruction costs on PPC440 processors. */
497 struct processor_costs ppc440_cost = {
498 COSTS_N_INSNS (3), /* mulsi */
499 COSTS_N_INSNS (2), /* mulsi_const */
500 COSTS_N_INSNS (2), /* mulsi_const9 */
501 COSTS_N_INSNS (3), /* muldi */
502 COSTS_N_INSNS (34), /* divsi */
503 COSTS_N_INSNS (34), /* divdi */
504 COSTS_N_INSNS (5), /* fp */
505 COSTS_N_INSNS (5), /* dmul */
506 COSTS_N_INSNS (19), /* sdiv */
507 COSTS_N_INSNS (33), /* ddiv */
508 32, /* cache line size */
514 /* Instruction costs on PPC476 processors. */
516 struct processor_costs ppc476_cost = {
517 COSTS_N_INSNS (4), /* mulsi */
518 COSTS_N_INSNS (4), /* mulsi_const */
519 COSTS_N_INSNS (4), /* mulsi_const9 */
520 COSTS_N_INSNS (4), /* muldi */
521 COSTS_N_INSNS (11), /* divsi */
522 COSTS_N_INSNS (11), /* divdi */
523 COSTS_N_INSNS (6), /* fp */
524 COSTS_N_INSNS (6), /* dmul */
525 COSTS_N_INSNS (19), /* sdiv */
526 COSTS_N_INSNS (33), /* ddiv */
527 32, /* l1 cache line size */
533 /* Instruction costs on PPC601 processors. */
535 struct processor_costs ppc601_cost = {
536 COSTS_N_INSNS (5), /* mulsi */
537 COSTS_N_INSNS (5), /* mulsi_const */
538 COSTS_N_INSNS (5), /* mulsi_const9 */
539 COSTS_N_INSNS (5), /* muldi */
540 COSTS_N_INSNS (36), /* divsi */
541 COSTS_N_INSNS (36), /* divdi */
542 COSTS_N_INSNS (4), /* fp */
543 COSTS_N_INSNS (5), /* dmul */
544 COSTS_N_INSNS (17), /* sdiv */
545 COSTS_N_INSNS (31), /* ddiv */
546 32, /* cache line size */
552 /* Instruction costs on PPC603 processors. */
554 struct processor_costs ppc603_cost = {
555 COSTS_N_INSNS (5), /* mulsi */
556 COSTS_N_INSNS (3), /* mulsi_const */
557 COSTS_N_INSNS (2), /* mulsi_const9 */
558 COSTS_N_INSNS (5), /* muldi */
559 COSTS_N_INSNS (37), /* divsi */
560 COSTS_N_INSNS (37), /* divdi */
561 COSTS_N_INSNS (3), /* fp */
562 COSTS_N_INSNS (4), /* dmul */
563 COSTS_N_INSNS (18), /* sdiv */
564 COSTS_N_INSNS (33), /* ddiv */
565 32, /* cache line size */
571 /* Instruction costs on PPC604 processors. */
573 struct processor_costs ppc604_cost = {
574 COSTS_N_INSNS (4), /* mulsi */
575 COSTS_N_INSNS (4), /* mulsi_const */
576 COSTS_N_INSNS (4), /* mulsi_const9 */
577 COSTS_N_INSNS (4), /* muldi */
578 COSTS_N_INSNS (20), /* divsi */
579 COSTS_N_INSNS (20), /* divdi */
580 COSTS_N_INSNS (3), /* fp */
581 COSTS_N_INSNS (3), /* dmul */
582 COSTS_N_INSNS (18), /* sdiv */
583 COSTS_N_INSNS (32), /* ddiv */
584 32, /* cache line size */
590 /* Instruction costs on PPC604e processors. */
592 struct processor_costs ppc604e_cost = {
593 COSTS_N_INSNS (2), /* mulsi */
594 COSTS_N_INSNS (2), /* mulsi_const */
595 COSTS_N_INSNS (2), /* mulsi_const9 */
596 COSTS_N_INSNS (2), /* muldi */
597 COSTS_N_INSNS (20), /* divsi */
598 COSTS_N_INSNS (20), /* divdi */
599 COSTS_N_INSNS (3), /* fp */
600 COSTS_N_INSNS (3), /* dmul */
601 COSTS_N_INSNS (18), /* sdiv */
602 COSTS_N_INSNS (32), /* ddiv */
603 32, /* cache line size */
609 /* Instruction costs on PPC620 processors. */
611 struct processor_costs ppc620_cost = {
612 COSTS_N_INSNS (5), /* mulsi */
613 COSTS_N_INSNS (4), /* mulsi_const */
614 COSTS_N_INSNS (3), /* mulsi_const9 */
615 COSTS_N_INSNS (7), /* muldi */
616 COSTS_N_INSNS (21), /* divsi */
617 COSTS_N_INSNS (37), /* divdi */
618 COSTS_N_INSNS (3), /* fp */
619 COSTS_N_INSNS (3), /* dmul */
620 COSTS_N_INSNS (18), /* sdiv */
621 COSTS_N_INSNS (32), /* ddiv */
622 128, /* cache line size */
628 /* Instruction costs on PPC630 processors. */
630 struct processor_costs ppc630_cost = {
631 COSTS_N_INSNS (5), /* mulsi */
632 COSTS_N_INSNS (4), /* mulsi_const */
633 COSTS_N_INSNS (3), /* mulsi_const9 */
634 COSTS_N_INSNS (7), /* muldi */
635 COSTS_N_INSNS (21), /* divsi */
636 COSTS_N_INSNS (37), /* divdi */
637 COSTS_N_INSNS (3), /* fp */
638 COSTS_N_INSNS (3), /* dmul */
639 COSTS_N_INSNS (17), /* sdiv */
640 COSTS_N_INSNS (21), /* ddiv */
641 128, /* cache line size */
647 /* Instruction costs on Cell processor. */
648 /* COSTS_N_INSNS (1) ~ one add. */
650 struct processor_costs ppccell_cost = {
651 COSTS_N_INSNS (9/2)+2, /* mulsi */
652 COSTS_N_INSNS (6/2), /* mulsi_const */
653 COSTS_N_INSNS (6/2), /* mulsi_const9 */
654 COSTS_N_INSNS (15/2)+2, /* muldi */
655 COSTS_N_INSNS (38/2), /* divsi */
656 COSTS_N_INSNS (70/2), /* divdi */
657 COSTS_N_INSNS (10/2), /* fp */
658 COSTS_N_INSNS (10/2), /* dmul */
659 COSTS_N_INSNS (74/2), /* sdiv */
660 COSTS_N_INSNS (74/2), /* ddiv */
661 128, /* cache line size */
667 /* Instruction costs on PPC750 and PPC7400 processors. */
669 struct processor_costs ppc750_cost = {
670 COSTS_N_INSNS (5), /* mulsi */
671 COSTS_N_INSNS (3), /* mulsi_const */
672 COSTS_N_INSNS (2), /* mulsi_const9 */
673 COSTS_N_INSNS (5), /* muldi */
674 COSTS_N_INSNS (17), /* divsi */
675 COSTS_N_INSNS (17), /* divdi */
676 COSTS_N_INSNS (3), /* fp */
677 COSTS_N_INSNS (3), /* dmul */
678 COSTS_N_INSNS (17), /* sdiv */
679 COSTS_N_INSNS (31), /* ddiv */
680 32, /* cache line size */
686 /* Instruction costs on PPC7450 processors. */
688 struct processor_costs ppc7450_cost = {
689 COSTS_N_INSNS (4), /* mulsi */
690 COSTS_N_INSNS (3), /* mulsi_const */
691 COSTS_N_INSNS (3), /* mulsi_const9 */
692 COSTS_N_INSNS (4), /* muldi */
693 COSTS_N_INSNS (23), /* divsi */
694 COSTS_N_INSNS (23), /* divdi */
695 COSTS_N_INSNS (5), /* fp */
696 COSTS_N_INSNS (5), /* dmul */
697 COSTS_N_INSNS (21), /* sdiv */
698 COSTS_N_INSNS (35), /* ddiv */
699 32, /* cache line size */
705 /* Instruction costs on PPC8540 processors. */
707 struct processor_costs ppc8540_cost = {
708 COSTS_N_INSNS (4), /* mulsi */
709 COSTS_N_INSNS (4), /* mulsi_const */
710 COSTS_N_INSNS (4), /* mulsi_const9 */
711 COSTS_N_INSNS (4), /* muldi */
712 COSTS_N_INSNS (19), /* divsi */
713 COSTS_N_INSNS (19), /* divdi */
714 COSTS_N_INSNS (4), /* fp */
715 COSTS_N_INSNS (4), /* dmul */
716 COSTS_N_INSNS (29), /* sdiv */
717 COSTS_N_INSNS (29), /* ddiv */
718 32, /* cache line size */
721 1, /* prefetch streams /*/
724 /* Instruction costs on E300C2 and E300C3 cores. */
726 struct processor_costs ppce300c2c3_cost = {
727 COSTS_N_INSNS (4), /* mulsi */
728 COSTS_N_INSNS (4), /* mulsi_const */
729 COSTS_N_INSNS (4), /* mulsi_const9 */
730 COSTS_N_INSNS (4), /* muldi */
731 COSTS_N_INSNS (19), /* divsi */
732 COSTS_N_INSNS (19), /* divdi */
733 COSTS_N_INSNS (3), /* fp */
734 COSTS_N_INSNS (4), /* dmul */
735 COSTS_N_INSNS (18), /* sdiv */
736 COSTS_N_INSNS (33), /* ddiv */
740 1, /* prefetch streams /*/
743 /* Instruction costs on PPCE500MC processors. */
745 struct processor_costs ppce500mc_cost = {
746 COSTS_N_INSNS (4), /* mulsi */
747 COSTS_N_INSNS (4), /* mulsi_const */
748 COSTS_N_INSNS (4), /* mulsi_const9 */
749 COSTS_N_INSNS (4), /* muldi */
750 COSTS_N_INSNS (14), /* divsi */
751 COSTS_N_INSNS (14), /* divdi */
752 COSTS_N_INSNS (8), /* fp */
753 COSTS_N_INSNS (10), /* dmul */
754 COSTS_N_INSNS (36), /* sdiv */
755 COSTS_N_INSNS (66), /* ddiv */
756 64, /* cache line size */
759 1, /* prefetch streams /*/
762 /* Instruction costs on POWER4 and POWER5 processors. */
764 struct processor_costs power4_cost = {
765 COSTS_N_INSNS (3), /* mulsi */
766 COSTS_N_INSNS (2), /* mulsi_const */
767 COSTS_N_INSNS (2), /* mulsi_const9 */
768 COSTS_N_INSNS (4), /* muldi */
769 COSTS_N_INSNS (18), /* divsi */
770 COSTS_N_INSNS (34), /* divdi */
771 COSTS_N_INSNS (3), /* fp */
772 COSTS_N_INSNS (3), /* dmul */
773 COSTS_N_INSNS (17), /* sdiv */
774 COSTS_N_INSNS (17), /* ddiv */
775 128, /* cache line size */
778 8, /* prefetch streams /*/
781 /* Instruction costs on POWER6 processors. */
783 struct processor_costs power6_cost = {
784 COSTS_N_INSNS (8), /* mulsi */
785 COSTS_N_INSNS (8), /* mulsi_const */
786 COSTS_N_INSNS (8), /* mulsi_const9 */
787 COSTS_N_INSNS (8), /* muldi */
788 COSTS_N_INSNS (22), /* divsi */
789 COSTS_N_INSNS (28), /* divdi */
790 COSTS_N_INSNS (3), /* fp */
791 COSTS_N_INSNS (3), /* dmul */
792 COSTS_N_INSNS (13), /* sdiv */
793 COSTS_N_INSNS (16), /* ddiv */
794 128, /* cache line size */
797 16, /* prefetch streams */
800 /* Instruction costs on POWER7 processors. */
802 struct processor_costs power7_cost = {
803 COSTS_N_INSNS (2), /* mulsi */
804 COSTS_N_INSNS (2), /* mulsi_const */
805 COSTS_N_INSNS (2), /* mulsi_const9 */
806 COSTS_N_INSNS (2), /* muldi */
807 COSTS_N_INSNS (18), /* divsi */
808 COSTS_N_INSNS (34), /* 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 12, /* prefetch streams */
819 /* Instruction costs on POWER A2 processors. */
821 struct processor_costs ppca2_cost = {
822 COSTS_N_INSNS (16), /* mulsi */
823 COSTS_N_INSNS (16), /* mulsi_const */
824 COSTS_N_INSNS (16), /* mulsi_const9 */
825 COSTS_N_INSNS (16), /* muldi */
826 COSTS_N_INSNS (22), /* divsi */
827 COSTS_N_INSNS (28), /* divdi */
828 COSTS_N_INSNS (3), /* fp */
829 COSTS_N_INSNS (3), /* dmul */
830 COSTS_N_INSNS (59), /* sdiv */
831 COSTS_N_INSNS (72), /* ddiv */
835 16, /* prefetch streams */
839 static bool rs6000_function_ok_for_sibcall (tree, tree);
840 static const char *rs6000_invalid_within_doloop (const_rtx);
841 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
842 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
843 static rtx rs6000_generate_compare (rtx, enum machine_mode);
844 static void rs6000_emit_stack_tie (void);
845 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
846 static bool spe_func_has_64bit_regs_p (void);
847 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
849 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
850 static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int, int);
851 static unsigned rs6000_hash_constant (rtx);
852 static unsigned toc_hash_function (const void *);
853 static int toc_hash_eq (const void *, const void *);
854 static bool reg_offset_addressing_ok_p (enum machine_mode);
855 static bool virtual_stack_registers_memory_p (rtx);
856 static bool constant_pool_expr_p (rtx);
857 static bool legitimate_small_data_p (enum machine_mode, rtx);
858 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
859 static struct machine_function * rs6000_init_machine_status (void);
860 static bool rs6000_assemble_integer (rtx, unsigned int, int);
861 static bool no_global_regs_above (int, bool);
862 #ifdef HAVE_GAS_HIDDEN
863 static void rs6000_assemble_visibility (tree, int);
865 static int rs6000_ra_ever_killed (void);
866 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
867 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
868 static bool rs6000_ms_bitfield_layout_p (const_tree);
869 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
870 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
871 static const char *rs6000_mangle_type (const_tree);
872 static void rs6000_set_default_type_attributes (tree);
873 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
874 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
875 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
876 enum machine_mode, bool, bool, bool);
877 static bool rs6000_reg_live_or_pic_offset_p (int);
878 static tree rs6000_builtin_vectorized_function (unsigned int, tree, tree);
879 static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
880 static void rs6000_restore_saved_cr (rtx, int);
881 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
882 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
883 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
885 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
886 static bool rs6000_return_in_memory (const_tree, const_tree);
887 static rtx rs6000_function_value (const_tree, const_tree, bool);
888 static void rs6000_file_start (void);
890 static int rs6000_elf_reloc_rw_mask (void);
891 static void rs6000_elf_asm_out_constructor (rtx, int);
892 static void rs6000_elf_asm_out_destructor (rtx, int);
893 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
894 static void rs6000_elf_asm_init_sections (void);
895 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
896 unsigned HOST_WIDE_INT);
897 static void rs6000_elf_encode_section_info (tree, rtx, int)
900 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
901 static void rs6000_alloc_sdmode_stack_slot (void);
902 static void rs6000_instantiate_decls (void);
904 static void rs6000_xcoff_asm_output_anchor (rtx);
905 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
906 static void rs6000_xcoff_asm_init_sections (void);
907 static int rs6000_xcoff_reloc_rw_mask (void);
908 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
909 static section *rs6000_xcoff_select_section (tree, int,
910 unsigned HOST_WIDE_INT);
911 static void rs6000_xcoff_unique_section (tree, int);
912 static section *rs6000_xcoff_select_rtx_section
913 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
914 static const char * rs6000_xcoff_strip_name_encoding (const char *);
915 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
916 static void rs6000_xcoff_file_start (void);
917 static void rs6000_xcoff_file_end (void);
919 static int rs6000_variable_issue (FILE *, int, rtx, int);
920 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
921 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
922 static int rs6000_debug_address_cost (rtx, bool);
923 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
924 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
925 static void rs6000_sched_init (FILE *, int, int);
926 static bool is_microcoded_insn (rtx);
927 static bool is_nonpipeline_insn (rtx);
928 static bool is_cracked_insn (rtx);
929 static bool is_branch_slot_insn (rtx);
930 static bool is_load_insn (rtx);
931 static rtx get_store_dest (rtx pat);
932 static bool is_store_insn (rtx);
933 static bool set_to_load_agen (rtx,rtx);
934 static bool adjacent_mem_locations (rtx,rtx);
935 static int rs6000_adjust_priority (rtx, int);
936 static int rs6000_issue_rate (void);
937 static bool rs6000_is_costly_dependence (dep_t, int, int);
938 static rtx get_next_active_insn (rtx, rtx);
939 static bool insn_terminates_group_p (rtx , enum group_termination);
940 static bool insn_must_be_first_in_group (rtx);
941 static bool insn_must_be_last_in_group (rtx);
942 static bool is_costly_group (rtx *, rtx);
943 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
944 static int redefine_groups (FILE *, int, rtx, rtx);
945 static int pad_groups (FILE *, int, rtx, rtx);
946 static void rs6000_sched_finish (FILE *, int);
947 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
948 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
949 static int rs6000_use_sched_lookahead (void);
950 static int rs6000_use_sched_lookahead_guard (rtx);
951 static void * rs6000_alloc_sched_context (void);
952 static void rs6000_init_sched_context (void *, bool);
953 static void rs6000_set_sched_context (void *);
954 static void rs6000_free_sched_context (void *);
955 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
956 static tree rs6000_builtin_mask_for_load (void);
957 static tree rs6000_builtin_mul_widen_even (tree);
958 static tree rs6000_builtin_mul_widen_odd (tree);
959 static tree rs6000_builtin_conversion (unsigned int, tree);
960 static tree rs6000_builtin_vec_perm (tree, tree *);
961 static bool rs6000_builtin_support_vector_misalignment (enum
966 static void def_builtin (int, const char *, tree, int);
967 static bool rs6000_vector_alignment_reachable (const_tree, bool);
968 static void rs6000_init_builtins (void);
969 static tree rs6000_builtin_decl (unsigned, bool);
971 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
972 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
973 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
974 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
975 static void altivec_init_builtins (void);
976 static unsigned builtin_hash_function (const void *);
977 static int builtin_hash_eq (const void *, const void *);
978 static tree builtin_function_type (enum machine_mode, enum machine_mode,
979 enum machine_mode, enum machine_mode,
980 enum rs6000_builtins, const char *name);
981 static void rs6000_common_init_builtins (void);
982 static void rs6000_init_libfuncs (void);
984 static void paired_init_builtins (void);
985 static rtx paired_expand_builtin (tree, rtx, bool *);
986 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
987 static rtx paired_expand_stv_builtin (enum insn_code, tree);
988 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
990 static void enable_mask_for_builtins (struct builtin_description *, int,
991 enum rs6000_builtins,
992 enum rs6000_builtins);
993 static void spe_init_builtins (void);
994 static rtx spe_expand_builtin (tree, rtx, bool *);
995 static rtx spe_expand_stv_builtin (enum insn_code, tree);
996 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
997 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
998 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
999 static rs6000_stack_t *rs6000_stack_info (void);
1000 static void debug_stack_info (rs6000_stack_t *);
1002 static rtx altivec_expand_builtin (tree, rtx, bool *);
1003 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1004 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1005 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1006 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1007 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1008 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1009 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1010 static rtx altivec_expand_vec_set_builtin (tree);
1011 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1012 static int get_element_number (tree, tree);
1013 static bool rs6000_handle_option (size_t, const char *, int);
1014 static void rs6000_parse_tls_size_option (void);
1015 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1016 static int first_altivec_reg_to_save (void);
1017 static unsigned int compute_vrsave_mask (void);
1018 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1019 static void is_altivec_return_reg (rtx, void *);
1020 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1021 int easy_vector_constant (rtx, enum machine_mode);
1022 static rtx rs6000_dwarf_register_span (rtx);
1023 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1024 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1025 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1026 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1027 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1028 static rtx rs6000_tls_get_addr (void);
1029 static rtx rs6000_got_sym (void);
1030 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1031 static const char *rs6000_get_some_local_dynamic_name (void);
1032 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1033 static rtx rs6000_complex_function_value (enum machine_mode);
1034 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
1035 enum machine_mode, tree);
1036 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1038 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1039 tree, HOST_WIDE_INT);
1040 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1043 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1044 const_tree, HOST_WIDE_INT,
1046 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
1047 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
1048 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1049 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1050 enum machine_mode, tree,
1052 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1054 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1056 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1058 static void macho_branch_islands (void);
1059 static int no_previous_def (tree function_name);
1060 static tree get_prev_label (tree function_name);
1061 static void rs6000_darwin_file_start (void);
1064 static tree rs6000_build_builtin_va_list (void);
1065 static void rs6000_va_start (tree, rtx);
1066 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1067 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1068 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1069 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1070 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1071 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1073 static tree rs6000_stack_protect_fail (void);
1075 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1078 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1081 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1083 = rs6000_legitimize_reload_address;
1085 static bool rs6000_mode_dependent_address (rtx);
1086 static bool rs6000_debug_mode_dependent_address (rtx);
1087 bool (*rs6000_mode_dependent_address_ptr) (rtx)
1088 = rs6000_mode_dependent_address;
1090 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1091 enum machine_mode, rtx);
1092 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1095 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1096 enum machine_mode, rtx)
1097 = rs6000_secondary_reload_class;
1099 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1100 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1102 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1103 = rs6000_preferred_reload_class;
1105 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1108 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1112 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1114 = rs6000_secondary_memory_needed;
1116 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1119 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1123 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1126 = rs6000_cannot_change_mode_class;
1128 static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class,
1130 struct secondary_reload_info *);
1132 static const enum reg_class *rs6000_ira_cover_classes (void);
1134 const int INSN_NOT_AVAILABLE = -1;
1135 static enum machine_mode rs6000_eh_return_filter_mode (void);
1136 static bool rs6000_can_eliminate (const int, const int);
1137 static void rs6000_trampoline_init (rtx, tree, rtx);
1139 /* Hash table stuff for keeping track of TOC entries. */
1141 struct GTY(()) toc_hash_struct
1143 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1144 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1146 enum machine_mode key_mode;
1150 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1152 /* Hash table to keep track of the argument types for builtin functions. */
1154 struct GTY(()) builtin_hash_struct
1157 enum machine_mode mode[4]; /* return value + 3 arguments. */
1158 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1161 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1163 /* Default register names. */
1164 char rs6000_reg_names[][8] =
1166 "0", "1", "2", "3", "4", "5", "6", "7",
1167 "8", "9", "10", "11", "12", "13", "14", "15",
1168 "16", "17", "18", "19", "20", "21", "22", "23",
1169 "24", "25", "26", "27", "28", "29", "30", "31",
1170 "0", "1", "2", "3", "4", "5", "6", "7",
1171 "8", "9", "10", "11", "12", "13", "14", "15",
1172 "16", "17", "18", "19", "20", "21", "22", "23",
1173 "24", "25", "26", "27", "28", "29", "30", "31",
1174 "mq", "lr", "ctr","ap",
1175 "0", "1", "2", "3", "4", "5", "6", "7",
1177 /* AltiVec registers. */
1178 "0", "1", "2", "3", "4", "5", "6", "7",
1179 "8", "9", "10", "11", "12", "13", "14", "15",
1180 "16", "17", "18", "19", "20", "21", "22", "23",
1181 "24", "25", "26", "27", "28", "29", "30", "31",
1183 /* SPE registers. */
1184 "spe_acc", "spefscr",
1185 /* Soft frame pointer. */
1189 #ifdef TARGET_REGNAMES
1190 static const char alt_reg_names[][8] =
1192 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1193 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1194 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1195 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1196 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1197 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1198 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1199 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1200 "mq", "lr", "ctr", "ap",
1201 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1203 /* AltiVec registers. */
1204 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1205 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1206 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1207 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1209 /* SPE registers. */
1210 "spe_acc", "spefscr",
1211 /* Soft frame pointer. */
1216 /* Table of valid machine attributes. */
1218 static const struct attribute_spec rs6000_attribute_table[] =
1220 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1221 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1222 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1223 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1224 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1225 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1226 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1227 SUBTARGET_ATTRIBUTE_TABLE,
1229 { NULL, 0, 0, false, false, false, NULL }
1232 #ifndef MASK_STRICT_ALIGN
1233 #define MASK_STRICT_ALIGN 0
1235 #ifndef TARGET_PROFILE_KERNEL
1236 #define TARGET_PROFILE_KERNEL 0
1237 #define SET_PROFILE_KERNEL(N)
1239 #define SET_PROFILE_KERNEL(N) TARGET_PROFILE_KERNEL = (N)
1242 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1243 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1245 /* Initialize the GCC target structure. */
1246 #undef TARGET_ATTRIBUTE_TABLE
1247 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1248 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1249 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1251 #undef TARGET_ASM_ALIGNED_DI_OP
1252 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1254 /* Default unaligned ops are only provided for ELF. Find the ops needed
1255 for non-ELF systems. */
1256 #ifndef OBJECT_FORMAT_ELF
1258 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1260 #undef TARGET_ASM_UNALIGNED_HI_OP
1261 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1262 #undef TARGET_ASM_UNALIGNED_SI_OP
1263 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1264 #undef TARGET_ASM_UNALIGNED_DI_OP
1265 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1268 #undef TARGET_ASM_UNALIGNED_HI_OP
1269 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1270 #undef TARGET_ASM_UNALIGNED_SI_OP
1271 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1272 #undef TARGET_ASM_UNALIGNED_DI_OP
1273 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1274 #undef TARGET_ASM_ALIGNED_DI_OP
1275 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1279 /* This hook deals with fixups for relocatable code and DI-mode objects
1281 #undef TARGET_ASM_INTEGER
1282 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1284 #ifdef HAVE_GAS_HIDDEN
1285 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1286 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1289 #undef TARGET_HAVE_TLS
1290 #define TARGET_HAVE_TLS HAVE_AS_TLS
1292 #undef TARGET_CANNOT_FORCE_CONST_MEM
1293 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1295 #undef TARGET_ASM_FUNCTION_PROLOGUE
1296 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1297 #undef TARGET_ASM_FUNCTION_EPILOGUE
1298 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1300 #undef TARGET_LEGITIMIZE_ADDRESS
1301 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1303 #undef TARGET_SCHED_VARIABLE_ISSUE
1304 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1306 #undef TARGET_SCHED_ISSUE_RATE
1307 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1308 #undef TARGET_SCHED_ADJUST_COST
1309 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1310 #undef TARGET_SCHED_ADJUST_PRIORITY
1311 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1312 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1313 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1314 #undef TARGET_SCHED_INIT
1315 #define TARGET_SCHED_INIT rs6000_sched_init
1316 #undef TARGET_SCHED_FINISH
1317 #define TARGET_SCHED_FINISH rs6000_sched_finish
1318 #undef TARGET_SCHED_REORDER
1319 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1320 #undef TARGET_SCHED_REORDER2
1321 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1323 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1324 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1326 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1327 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1329 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1330 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1331 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1332 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1333 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1334 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1335 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1336 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1338 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1339 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1340 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1341 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1342 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1343 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1344 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1345 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1346 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1347 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1348 #undef TARGET_SUPPORT_VECTOR_MISALIGNMENT
1349 #define TARGET_SUPPORT_VECTOR_MISALIGNMENT \
1350 rs6000_builtin_support_vector_misalignment
1351 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1352 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1354 #undef TARGET_INIT_BUILTINS
1355 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1356 #undef TARGET_BUILTIN_DECL
1357 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1359 #undef TARGET_EXPAND_BUILTIN
1360 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1362 #undef TARGET_MANGLE_TYPE
1363 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1365 #undef TARGET_INIT_LIBFUNCS
1366 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1369 #undef TARGET_BINDS_LOCAL_P
1370 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1373 #undef TARGET_MS_BITFIELD_LAYOUT_P
1374 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1376 #undef TARGET_ASM_OUTPUT_MI_THUNK
1377 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1379 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1380 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1382 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1383 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1385 #undef TARGET_INVALID_WITHIN_DOLOOP
1386 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1388 #undef TARGET_RTX_COSTS
1389 #define TARGET_RTX_COSTS rs6000_rtx_costs
1390 #undef TARGET_ADDRESS_COST
1391 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1393 #undef TARGET_DWARF_REGISTER_SPAN
1394 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1396 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1397 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1399 /* On rs6000, function arguments are promoted, as are function return
1401 #undef TARGET_PROMOTE_FUNCTION_MODE
1402 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1404 #undef TARGET_RETURN_IN_MEMORY
1405 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1407 #undef TARGET_SETUP_INCOMING_VARARGS
1408 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1410 /* Always strict argument naming on rs6000. */
1411 #undef TARGET_STRICT_ARGUMENT_NAMING
1412 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1413 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1414 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1415 #undef TARGET_SPLIT_COMPLEX_ARG
1416 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1417 #undef TARGET_MUST_PASS_IN_STACK
1418 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1419 #undef TARGET_PASS_BY_REFERENCE
1420 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1421 #undef TARGET_ARG_PARTIAL_BYTES
1422 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1424 #undef TARGET_BUILD_BUILTIN_VA_LIST
1425 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1427 #undef TARGET_EXPAND_BUILTIN_VA_START
1428 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1430 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1431 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1433 #undef TARGET_EH_RETURN_FILTER_MODE
1434 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1436 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1437 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1439 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1440 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1442 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1443 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1445 #undef TARGET_HANDLE_OPTION
1446 #define TARGET_HANDLE_OPTION rs6000_handle_option
1448 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1449 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1450 rs6000_builtin_vectorized_function
1452 #undef TARGET_DEFAULT_TARGET_FLAGS
1453 #define TARGET_DEFAULT_TARGET_FLAGS \
1456 #undef TARGET_STACK_PROTECT_FAIL
1457 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1459 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1460 The PowerPC architecture requires only weak consistency among
1461 processors--that is, memory accesses between processors need not be
1462 sequentially consistent and memory accesses among processors can occur
1463 in any order. The ability to order memory accesses weakly provides
1464 opportunities for more efficient use of the system bus. Unless a
1465 dependency exists, the 604e allows read operations to precede store
1467 #undef TARGET_RELAXED_ORDERING
1468 #define TARGET_RELAXED_ORDERING true
1471 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1472 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1475 /* Use a 32-bit anchor range. This leads to sequences like:
1477 addis tmp,anchor,high
1480 where tmp itself acts as an anchor, and can be shared between
1481 accesses to the same 64k page. */
1482 #undef TARGET_MIN_ANCHOR_OFFSET
1483 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1484 #undef TARGET_MAX_ANCHOR_OFFSET
1485 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1486 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1487 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1489 #undef TARGET_BUILTIN_RECIPROCAL
1490 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1492 #undef TARGET_EXPAND_TO_RTL_HOOK
1493 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1495 #undef TARGET_INSTANTIATE_DECLS
1496 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1498 #undef TARGET_SECONDARY_RELOAD
1499 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1501 #undef TARGET_IRA_COVER_CLASSES
1502 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1504 #undef TARGET_LEGITIMATE_ADDRESS_P
1505 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1507 #undef TARGET_CAN_ELIMINATE
1508 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1510 #undef TARGET_TRAMPOLINE_INIT
1511 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1513 #undef TARGET_FUNCTION_VALUE
1514 #define TARGET_FUNCTION_VALUE rs6000_function_value
1516 struct gcc_target targetm = TARGET_INITIALIZER;
1518 /* Return number of consecutive hard regs needed starting at reg REGNO
1519 to hold something of mode MODE.
1520 This is ordinarily the length in words of a value of mode MODE
1521 but can be less for certain modes in special long registers.
1523 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1524 scalar instructions. The upper 32 bits are only available to the
1527 POWER and PowerPC GPRs hold 32 bits worth;
1528 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1531 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1533 unsigned HOST_WIDE_INT reg_size;
1535 if (FP_REGNO_P (regno))
1536 reg_size = (VECTOR_MEM_VSX_P (mode)
1537 ? UNITS_PER_VSX_WORD
1538 : UNITS_PER_FP_WORD);
1540 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1541 reg_size = UNITS_PER_SPE_WORD;
1543 else if (ALTIVEC_REGNO_P (regno))
1544 reg_size = UNITS_PER_ALTIVEC_WORD;
1546 /* The value returned for SCmode in the E500 double case is 2 for
1547 ABI compatibility; storing an SCmode value in a single register
1548 would require function_arg and rs6000_spe_function_arg to handle
1549 SCmode so as to pass the value correctly in a pair of
1551 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1552 && !DECIMAL_FLOAT_MODE_P (mode))
1553 reg_size = UNITS_PER_FP_WORD;
1556 reg_size = UNITS_PER_WORD;
1558 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1561 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1564 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1566 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1568 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1569 implementations. Don't allow an item to be split between a FP register
1570 and an Altivec register. */
1571 if (VECTOR_MEM_VSX_P (mode))
1573 if (FP_REGNO_P (regno))
1574 return FP_REGNO_P (last_regno);
1576 if (ALTIVEC_REGNO_P (regno))
1577 return ALTIVEC_REGNO_P (last_regno);
1580 /* The GPRs can hold any mode, but values bigger than one register
1581 cannot go past R31. */
1582 if (INT_REGNO_P (regno))
1583 return INT_REGNO_P (last_regno);
1585 /* The float registers (except for VSX vector modes) can only hold floating
1586 modes and DImode. This excludes the 32-bit decimal float mode for
1588 if (FP_REGNO_P (regno))
1590 if (SCALAR_FLOAT_MODE_P (mode)
1591 && (mode != TDmode || (regno % 2) == 0)
1592 && FP_REGNO_P (last_regno))
1595 if (GET_MODE_CLASS (mode) == MODE_INT
1596 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1599 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1600 && PAIRED_VECTOR_MODE (mode))
1606 /* The CR register can only hold CC modes. */
1607 if (CR_REGNO_P (regno))
1608 return GET_MODE_CLASS (mode) == MODE_CC;
1610 if (XER_REGNO_P (regno))
1611 return mode == PSImode;
1613 /* AltiVec only in AldyVec registers. */
1614 if (ALTIVEC_REGNO_P (regno))
1615 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1617 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1618 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1621 /* We cannot put TImode anywhere except general register and it must be able
1622 to fit within the register set. In the future, allow TImode in the
1623 Altivec or VSX registers. */
1625 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1628 /* Print interesting facts about registers. */
1630 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1634 for (r = first_regno; r <= last_regno; ++r)
1636 const char *comma = "";
1639 if (first_regno == last_regno)
1640 fprintf (stderr, "%s:\t", reg_name);
1642 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1645 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1646 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1650 fprintf (stderr, ",\n\t");
1655 if (rs6000_hard_regno_nregs[m][r] > 1)
1656 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1657 rs6000_hard_regno_nregs[m][r]);
1659 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1664 if (call_used_regs[r])
1668 fprintf (stderr, ",\n\t");
1673 len += fprintf (stderr, "%s%s", comma, "call-used");
1681 fprintf (stderr, ",\n\t");
1686 len += fprintf (stderr, "%s%s", comma, "fixed");
1692 fprintf (stderr, ",\n\t");
1696 fprintf (stderr, "%sregno = %d\n", comma, r);
1700 /* Print various interesting information with -mdebug=reg. */
1702 rs6000_debug_reg_global (void)
1704 const char *nl = (const char *)0;
1706 char costly_num[20];
1708 const char *costly_str;
1709 const char *nop_str;
1711 /* Map enum rs6000_vector to string. */
1712 static const char *rs6000_debug_vector_unit[] = {
1721 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1722 LAST_VIRTUAL_REGISTER);
1723 rs6000_debug_reg_print (0, 31, "gr");
1724 rs6000_debug_reg_print (32, 63, "fp");
1725 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1728 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1729 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1730 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1731 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1732 rs6000_debug_reg_print (XER_REGNO, XER_REGNO, "xer");
1733 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1734 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1735 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1736 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1740 "d reg_class = %s\n"
1741 "f reg_class = %s\n"
1742 "v reg_class = %s\n"
1743 "wa reg_class = %s\n"
1744 "wd reg_class = %s\n"
1745 "wf reg_class = %s\n"
1746 "ws reg_class = %s\n\n",
1747 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1748 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1749 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1750 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1751 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1752 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1753 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1755 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1756 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1759 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1761 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1762 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1768 switch (rs6000_sched_costly_dep)
1770 case max_dep_latency:
1771 costly_str = "max_dep_latency";
1775 costly_str = "no_dep_costly";
1778 case all_deps_costly:
1779 costly_str = "all_deps_costly";
1782 case true_store_to_load_dep_costly:
1783 costly_str = "true_store_to_load_dep_costly";
1786 case store_to_load_dep_costly:
1787 costly_str = "store_to_load_dep_costly";
1791 costly_str = costly_num;
1792 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1796 switch (rs6000_sched_insert_nops)
1798 case sched_finish_regroup_exact:
1799 nop_str = "sched_finish_regroup_exact";
1802 case sched_finish_pad_groups:
1803 nop_str = "sched_finish_pad_groups";
1806 case sched_finish_none:
1807 nop_str = "sched_finish_none";
1812 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1817 "always_hint = %s\n"
1818 "align_branch_targets = %s\n"
1819 "sched_restricted_insns_priority = %d\n"
1820 "sched_costly_dep = %s\n"
1821 "sched_insert_nops = %s\n\n",
1822 rs6000_always_hint ? "true" : "false",
1823 rs6000_align_branch_targets ? "true" : "false",
1824 (int)rs6000_sched_restricted_insns_priority,
1825 costly_str, nop_str);
1828 /* Initialize the various global tables that are based on register size. */
1830 rs6000_init_hard_regno_mode_ok (void)
1836 /* Precalculate REGNO_REG_CLASS. */
1837 rs6000_regno_regclass[0] = GENERAL_REGS;
1838 for (r = 1; r < 32; ++r)
1839 rs6000_regno_regclass[r] = BASE_REGS;
1841 for (r = 32; r < 64; ++r)
1842 rs6000_regno_regclass[r] = FLOAT_REGS;
1844 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1845 rs6000_regno_regclass[r] = NO_REGS;
1847 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
1848 rs6000_regno_regclass[r] = ALTIVEC_REGS;
1850 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
1851 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
1852 rs6000_regno_regclass[r] = CR_REGS;
1854 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
1855 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
1856 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
1857 rs6000_regno_regclass[XER_REGNO] = XER_REGS;
1858 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
1859 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
1860 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
1861 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
1862 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
1863 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
1865 /* Precalculate vector information, this must be set up before the
1866 rs6000_hard_regno_nregs_internal below. */
1867 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1869 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
1870 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
1871 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
1874 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
1875 rs6000_constraints[c] = NO_REGS;
1877 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
1878 believes it can use native alignment or still uses 128-bit alignment. */
1879 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
1890 /* V2DF mode, VSX only. */
1893 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
1894 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
1895 rs6000_vector_align[V2DFmode] = align64;
1898 /* V4SF mode, either VSX or Altivec. */
1901 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
1902 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
1903 rs6000_vector_align[V4SFmode] = align32;
1905 else if (TARGET_ALTIVEC)
1907 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
1908 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
1909 rs6000_vector_align[V4SFmode] = align32;
1912 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
1916 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
1917 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
1918 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
1919 rs6000_vector_align[V4SImode] = align32;
1920 rs6000_vector_align[V8HImode] = align32;
1921 rs6000_vector_align[V16QImode] = align32;
1925 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
1926 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
1927 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
1931 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
1932 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
1933 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
1937 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
1938 Altivec doesn't have 64-bit support. */
1941 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
1942 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
1943 rs6000_vector_align[V2DImode] = align64;
1946 /* DFmode, see if we want to use the VSX unit. */
1947 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
1949 rs6000_vector_unit[DFmode] = VECTOR_VSX;
1950 rs6000_vector_mem[DFmode]
1951 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
1952 rs6000_vector_align[DFmode] = align64;
1955 /* TODO add SPE and paired floating point vector support. */
1957 /* Register class constaints for the constraints that depend on compile
1959 if (TARGET_HARD_FLOAT && TARGET_FPRS)
1960 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
1962 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
1963 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
1967 /* At present, we just use VSX_REGS, but we have different constraints
1968 based on the use, in case we want to fine tune the default register
1969 class used. wa = any VSX register, wf = register class to use for
1970 V4SF, wd = register class to use for V2DF, and ws = register classs to
1971 use for DF scalars. */
1972 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
1973 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
1974 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
1975 if (TARGET_VSX_SCALAR_DOUBLE)
1976 rs6000_constraints[RS6000_CONSTRAINT_ws] = VSX_REGS;
1980 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
1982 /* Set up the reload helper functions. */
1983 if (TARGET_VSX || TARGET_ALTIVEC)
1987 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
1988 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
1989 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
1990 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
1991 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
1992 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
1993 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
1994 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
1995 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
1996 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
1997 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
1998 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2002 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2003 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2004 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2005 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2006 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2007 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2008 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2009 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2010 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2011 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2012 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2013 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2017 /* Precalculate HARD_REGNO_NREGS. */
2018 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2019 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2020 rs6000_hard_regno_nregs[m][r]
2021 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2023 /* Precalculate HARD_REGNO_MODE_OK. */
2024 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2025 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2026 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2027 rs6000_hard_regno_mode_ok_p[m][r] = true;
2029 /* Precalculate CLASS_MAX_NREGS sizes. */
2030 for (c = 0; c < LIM_REG_CLASSES; ++c)
2034 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2035 reg_size = UNITS_PER_VSX_WORD;
2037 else if (c == ALTIVEC_REGS)
2038 reg_size = UNITS_PER_ALTIVEC_WORD;
2040 else if (c == FLOAT_REGS)
2041 reg_size = UNITS_PER_FP_WORD;
2044 reg_size = UNITS_PER_WORD;
2046 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2047 rs6000_class_max_nregs[m][c]
2048 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2051 if (TARGET_E500_DOUBLE)
2052 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2054 if (TARGET_DEBUG_REG)
2055 rs6000_debug_reg_global ();
2059 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2062 darwin_rs6000_override_options (void)
2064 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2066 rs6000_altivec_abi = 1;
2067 TARGET_ALTIVEC_VRSAVE = 1;
2068 if (DEFAULT_ABI == ABI_DARWIN)
2070 if (MACHO_DYNAMIC_NO_PIC_P)
2073 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2076 else if (flag_pic == 1)
2081 if (TARGET_64BIT && ! TARGET_POWERPC64)
2083 target_flags |= MASK_POWERPC64;
2084 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2088 rs6000_default_long_calls = 1;
2089 target_flags |= MASK_SOFT_FLOAT;
2092 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2094 if (!flag_mkernel && !flag_apple_kext
2096 && ! (target_flags_explicit & MASK_ALTIVEC))
2097 target_flags |= MASK_ALTIVEC;
2099 /* Unless the user (not the configurer) has explicitly overridden
2100 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2101 G4 unless targetting the kernel. */
2104 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2105 && ! (target_flags_explicit & MASK_ALTIVEC)
2106 && ! rs6000_select[1].string)
2108 target_flags |= MASK_ALTIVEC;
2113 /* If not otherwise specified by a target, make 'long double' equivalent to
2116 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2117 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2120 /* Override command line options. Mostly we process the processor
2121 type and sometimes adjust other TARGET_ options. */
2124 rs6000_override_options (const char *default_cpu)
2127 struct rs6000_cpu_select *ptr;
2130 /* Simplifications for entries below. */
2133 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2134 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2137 /* This table occasionally claims that a processor does not support
2138 a particular feature even though it does, but the feature is slower
2139 than the alternative. Thus, it shouldn't be relied on as a
2140 complete description of the processor's support.
2142 Please keep this list in order, and don't forget to update the
2143 documentation in invoke.texi when adding a new processor or
2147 const char *const name; /* Canonical processor name. */
2148 const enum processor_type processor; /* Processor type enum value. */
2149 const int target_enable; /* Target flags to enable. */
2150 } const processor_target_table[]
2151 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2152 {"403", PROCESSOR_PPC403,
2153 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2154 {"405", PROCESSOR_PPC405,
2155 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2156 {"405fp", PROCESSOR_PPC405,
2157 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2158 {"440", PROCESSOR_PPC440,
2159 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2160 {"440fp", PROCESSOR_PPC440,
2161 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2162 {"464", PROCESSOR_PPC440,
2163 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2164 {"464fp", PROCESSOR_PPC440,
2165 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2166 {"476", PROCESSOR_PPC476,
2167 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2168 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2169 {"476fp", PROCESSOR_PPC476,
2170 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2171 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2172 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2173 {"601", PROCESSOR_PPC601,
2174 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2175 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2176 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2177 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2178 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2179 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2180 {"620", PROCESSOR_PPC620,
2181 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2182 {"630", PROCESSOR_PPC630,
2183 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2184 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2185 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2186 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2187 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2188 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2189 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2190 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2191 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2193 /* 8548 has a dummy entry for now. */
2194 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2196 {"a2", PROCESSOR_PPCA2,
2197 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2198 | MASK_CMPB | MASK_NO_UPDATE },
2199 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2200 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2201 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2203 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2204 {"970", PROCESSOR_POWER4,
2205 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2206 {"cell", PROCESSOR_CELL,
2207 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2208 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2209 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2210 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2211 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2212 {"G5", PROCESSOR_POWER4,
2213 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2214 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2215 {"power2", PROCESSOR_POWER,
2216 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2217 {"power3", PROCESSOR_PPC630,
2218 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2219 {"power4", PROCESSOR_POWER4,
2220 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2222 {"power5", PROCESSOR_POWER5,
2223 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2224 | MASK_MFCRF | MASK_POPCNTB},
2225 {"power5+", PROCESSOR_POWER5,
2226 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2227 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2228 {"power6", PROCESSOR_POWER6,
2229 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2230 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP},
2231 {"power6x", PROCESSOR_POWER6,
2232 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2233 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2235 {"power7", PROCESSOR_POWER7,
2236 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2237 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2238 | MASK_VSX}, /* Don't add MASK_ISEL by default */
2239 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2240 {"powerpc64", PROCESSOR_POWERPC64,
2241 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2242 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2243 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2244 {"rios2", PROCESSOR_RIOS2,
2245 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2246 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2247 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2248 {"rs64", PROCESSOR_RS64A,
2249 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2252 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2254 /* Some OSs don't support saving the high part of 64-bit registers on
2255 context switch. Other OSs don't support saving Altivec registers.
2256 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2257 settings; if the user wants either, the user must explicitly specify
2258 them and we won't interfere with the user's specification. */
2261 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2262 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2263 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2264 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2265 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2266 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE)
2269 /* Set the pointer size. */
2272 rs6000_pmode = (int)DImode;
2273 rs6000_pointer_size = 64;
2277 rs6000_pmode = (int)SImode;
2278 rs6000_pointer_size = 32;
2281 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2282 #ifdef OS_MISSING_POWERPC64
2283 if (OS_MISSING_POWERPC64)
2284 set_masks &= ~MASK_POWERPC64;
2286 #ifdef OS_MISSING_ALTIVEC
2287 if (OS_MISSING_ALTIVEC)
2288 set_masks &= ~MASK_ALTIVEC;
2291 /* Don't override by the processor default if given explicitly. */
2292 set_masks &= ~target_flags_explicit;
2294 /* Identify the processor type. */
2295 rs6000_select[0].string = default_cpu;
2296 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2298 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2300 ptr = &rs6000_select[i];
2301 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2303 for (j = 0; j < ptt_size; j++)
2304 if (! strcmp (ptr->string, processor_target_table[j].name))
2306 if (ptr->set_tune_p)
2307 rs6000_cpu = processor_target_table[j].processor;
2309 if (ptr->set_arch_p)
2311 target_flags &= ~set_masks;
2312 target_flags |= (processor_target_table[j].target_enable
2319 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2323 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2324 || rs6000_cpu == PROCESSOR_PPCE500MC)
2327 error ("AltiVec not supported in this target");
2329 error ("Spe not supported in this target");
2332 /* Disable Cell microcode if we are optimizing for the Cell
2333 and not optimizing for size. */
2334 if (rs6000_gen_cell_microcode == -1)
2335 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2338 /* If we are optimizing big endian systems for space, use the load/store
2339 multiple and string instructions unless we are not generating
2341 if (BYTES_BIG_ENDIAN && optimize_size && !rs6000_gen_cell_microcode)
2342 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2344 /* Don't allow -mmultiple or -mstring on little endian systems
2345 unless the cpu is a 750, because the hardware doesn't support the
2346 instructions used in little endian mode, and causes an alignment
2347 trap. The 750 does not cause an alignment trap (except when the
2348 target is unaligned). */
2350 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2352 if (TARGET_MULTIPLE)
2354 target_flags &= ~MASK_MULTIPLE;
2355 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2356 warning (0, "-mmultiple is not supported on little endian systems");
2361 target_flags &= ~MASK_STRING;
2362 if ((target_flags_explicit & MASK_STRING) != 0)
2363 warning (0, "-mstring is not supported on little endian systems");
2367 /* Add some warnings for VSX. Enable -maltivec unless the user explicitly
2368 used -mno-altivec */
2371 const char *msg = NULL;
2372 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2373 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2375 if (target_flags_explicit & MASK_VSX)
2376 msg = N_("-mvsx requires hardware floating point");
2378 target_flags &= ~ MASK_VSX;
2380 else if (TARGET_PAIRED_FLOAT)
2381 msg = N_("-mvsx and -mpaired are incompatible");
2382 /* The hardware will allow VSX and little endian, but until we make sure
2383 things like vector select, etc. work don't allow VSX on little endian
2384 systems at this point. */
2385 else if (!BYTES_BIG_ENDIAN)
2386 msg = N_("-mvsx used with little endian code");
2387 else if (TARGET_AVOID_XFORM > 0)
2388 msg = N_("-mvsx needs indexed addressing");
2393 target_flags &= ~ MASK_VSX;
2395 else if (TARGET_VSX && !TARGET_ALTIVEC
2396 && (target_flags_explicit & MASK_ALTIVEC) == 0)
2397 target_flags |= MASK_ALTIVEC;
2400 /* Set debug flags */
2401 if (rs6000_debug_name)
2403 if (! strcmp (rs6000_debug_name, "all"))
2404 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2405 = rs6000_debug_addr = rs6000_debug_cost = 1;
2406 else if (! strcmp (rs6000_debug_name, "stack"))
2407 rs6000_debug_stack = 1;
2408 else if (! strcmp (rs6000_debug_name, "arg"))
2409 rs6000_debug_arg = 1;
2410 else if (! strcmp (rs6000_debug_name, "reg"))
2411 rs6000_debug_reg = 1;
2412 else if (! strcmp (rs6000_debug_name, "addr"))
2413 rs6000_debug_addr = 1;
2414 else if (! strcmp (rs6000_debug_name, "cost"))
2415 rs6000_debug_cost = 1;
2417 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2419 /* If the appropriate debug option is enabled, replace the target hooks
2420 with debug versions that call the real version and then prints
2421 debugging information. */
2422 if (TARGET_DEBUG_COST)
2424 targetm.rtx_costs = rs6000_debug_rtx_costs;
2425 targetm.address_cost = rs6000_debug_address_cost;
2426 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2429 if (TARGET_DEBUG_ADDR)
2431 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2432 targetm.legitimize_address = rs6000_debug_legitimize_address;
2433 rs6000_secondary_reload_class_ptr
2434 = rs6000_debug_secondary_reload_class;
2435 rs6000_secondary_memory_needed_ptr
2436 = rs6000_debug_secondary_memory_needed;
2437 rs6000_cannot_change_mode_class_ptr
2438 = rs6000_debug_cannot_change_mode_class;
2439 rs6000_preferred_reload_class_ptr
2440 = rs6000_debug_preferred_reload_class;
2441 rs6000_legitimize_reload_address_ptr
2442 = rs6000_debug_legitimize_reload_address;
2443 rs6000_mode_dependent_address_ptr
2444 = rs6000_debug_mode_dependent_address;
2448 if (rs6000_traceback_name)
2450 if (! strncmp (rs6000_traceback_name, "full", 4))
2451 rs6000_traceback = traceback_full;
2452 else if (! strncmp (rs6000_traceback_name, "part", 4))
2453 rs6000_traceback = traceback_part;
2454 else if (! strncmp (rs6000_traceback_name, "no", 2))
2455 rs6000_traceback = traceback_none;
2457 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2458 rs6000_traceback_name);
2461 if (!rs6000_explicit_options.long_double)
2462 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2464 #ifndef POWERPC_LINUX
2465 if (!rs6000_explicit_options.ieee)
2466 rs6000_ieeequad = 1;
2469 /* Enable Altivec ABI for AIX -maltivec. */
2470 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2471 rs6000_altivec_abi = 1;
2473 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2474 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2475 be explicitly overridden in either case. */
2478 if (!rs6000_explicit_options.altivec_abi
2479 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2480 rs6000_altivec_abi = 1;
2482 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2483 if (!rs6000_explicit_options.vrsave)
2484 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2487 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2488 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2490 rs6000_darwin64_abi = 1;
2492 darwin_one_byte_bool = 1;
2494 /* Default to natural alignment, for better performance. */
2495 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2498 /* Place FP constants in the constant pool instead of TOC
2499 if section anchors enabled. */
2500 if (flag_section_anchors)
2501 TARGET_NO_FP_IN_TOC = 1;
2503 /* Handle -mtls-size option. */
2504 rs6000_parse_tls_size_option ();
2506 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2507 SUBTARGET_OVERRIDE_OPTIONS;
2509 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2510 SUBSUBTARGET_OVERRIDE_OPTIONS;
2512 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2513 SUB3TARGET_OVERRIDE_OPTIONS;
2516 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC)
2518 /* The e500 and e500mc do not have string instructions, and we set
2519 MASK_STRING above when optimizing for size. */
2520 if ((target_flags & MASK_STRING) != 0)
2521 target_flags = target_flags & ~MASK_STRING;
2523 else if (rs6000_select[1].string != NULL)
2525 /* For the powerpc-eabispe configuration, we set all these by
2526 default, so let's unset them if we manually set another
2527 CPU that is not the E500. */
2528 if (!rs6000_explicit_options.spe_abi)
2530 if (!rs6000_explicit_options.spe)
2532 if (!rs6000_explicit_options.float_gprs)
2533 rs6000_float_gprs = 0;
2534 if (!(target_flags_explicit & MASK_ISEL))
2535 target_flags &= ~MASK_ISEL;
2538 /* Detect invalid option combinations with E500. */
2541 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2542 && rs6000_cpu != PROCESSOR_POWER5
2543 && rs6000_cpu != PROCESSOR_POWER6
2544 && rs6000_cpu != PROCESSOR_POWER7
2545 && rs6000_cpu != PROCESSOR_PPCA2
2546 && rs6000_cpu != PROCESSOR_CELL);
2547 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2548 || rs6000_cpu == PROCESSOR_POWER5
2549 || rs6000_cpu == PROCESSOR_POWER7);
2550 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2551 || rs6000_cpu == PROCESSOR_POWER5
2552 || rs6000_cpu == PROCESSOR_POWER6
2553 || rs6000_cpu == PROCESSOR_POWER7);
2555 /* Allow debug switches to override the above settings. */
2556 if (TARGET_ALWAYS_HINT > 0)
2557 rs6000_always_hint = TARGET_ALWAYS_HINT;
2559 if (TARGET_SCHED_GROUPS > 0)
2560 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2562 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2563 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2565 rs6000_sched_restricted_insns_priority
2566 = (rs6000_sched_groups ? 1 : 0);
2568 /* Handle -msched-costly-dep option. */
2569 rs6000_sched_costly_dep
2570 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2572 if (rs6000_sched_costly_dep_str)
2574 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2575 rs6000_sched_costly_dep = no_dep_costly;
2576 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2577 rs6000_sched_costly_dep = all_deps_costly;
2578 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2579 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2580 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2581 rs6000_sched_costly_dep = store_to_load_dep_costly;
2583 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2584 atoi (rs6000_sched_costly_dep_str));
2587 /* Handle -minsert-sched-nops option. */
2588 rs6000_sched_insert_nops
2589 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2591 if (rs6000_sched_insert_nops_str)
2593 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2594 rs6000_sched_insert_nops = sched_finish_none;
2595 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2596 rs6000_sched_insert_nops = sched_finish_pad_groups;
2597 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2598 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2600 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2601 atoi (rs6000_sched_insert_nops_str));
2604 #ifdef TARGET_REGNAMES
2605 /* If the user desires alternate register names, copy in the
2606 alternate names now. */
2607 if (TARGET_REGNAMES)
2608 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2611 /* Set aix_struct_return last, after the ABI is determined.
2612 If -maix-struct-return or -msvr4-struct-return was explicitly
2613 used, don't override with the ABI default. */
2614 if (!rs6000_explicit_options.aix_struct_ret)
2615 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2617 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2618 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2621 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2623 /* We can only guarantee the availability of DI pseudo-ops when
2624 assembling for 64-bit targets. */
2627 targetm.asm_out.aligned_op.di = NULL;
2628 targetm.asm_out.unaligned_op.di = NULL;
2631 /* Set branch target alignment, if not optimizing for size. */
2634 /* Cell wants to be aligned 8byte for dual issue. */
2635 if (rs6000_cpu == PROCESSOR_CELL)
2637 if (align_functions <= 0)
2638 align_functions = 8;
2639 if (align_jumps <= 0)
2641 if (align_loops <= 0)
2644 if (rs6000_align_branch_targets)
2646 if (align_functions <= 0)
2647 align_functions = 16;
2648 if (align_jumps <= 0)
2650 if (align_loops <= 0)
2653 if (align_jumps_max_skip <= 0)
2654 align_jumps_max_skip = 15;
2655 if (align_loops_max_skip <= 0)
2656 align_loops_max_skip = 15;
2659 /* Arrange to save and restore machine status around nested functions. */
2660 init_machine_status = rs6000_init_machine_status;
2662 /* We should always be splitting complex arguments, but we can't break
2663 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2664 if (DEFAULT_ABI != ABI_AIX)
2665 targetm.calls.split_complex_arg = NULL;
2667 /* Initialize rs6000_cost with the appropriate target costs. */
2669 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2673 case PROCESSOR_RIOS1:
2674 rs6000_cost = &rios1_cost;
2677 case PROCESSOR_RIOS2:
2678 rs6000_cost = &rios2_cost;
2681 case PROCESSOR_RS64A:
2682 rs6000_cost = &rs64a_cost;
2685 case PROCESSOR_MPCCORE:
2686 rs6000_cost = &mpccore_cost;
2689 case PROCESSOR_PPC403:
2690 rs6000_cost = &ppc403_cost;
2693 case PROCESSOR_PPC405:
2694 rs6000_cost = &ppc405_cost;
2697 case PROCESSOR_PPC440:
2698 rs6000_cost = &ppc440_cost;
2701 case PROCESSOR_PPC476:
2702 rs6000_cost = &ppc476_cost;
2705 case PROCESSOR_PPC601:
2706 rs6000_cost = &ppc601_cost;
2709 case PROCESSOR_PPC603:
2710 rs6000_cost = &ppc603_cost;
2713 case PROCESSOR_PPC604:
2714 rs6000_cost = &ppc604_cost;
2717 case PROCESSOR_PPC604e:
2718 rs6000_cost = &ppc604e_cost;
2721 case PROCESSOR_PPC620:
2722 rs6000_cost = &ppc620_cost;
2725 case PROCESSOR_PPC630:
2726 rs6000_cost = &ppc630_cost;
2729 case PROCESSOR_CELL:
2730 rs6000_cost = &ppccell_cost;
2733 case PROCESSOR_PPC750:
2734 case PROCESSOR_PPC7400:
2735 rs6000_cost = &ppc750_cost;
2738 case PROCESSOR_PPC7450:
2739 rs6000_cost = &ppc7450_cost;
2742 case PROCESSOR_PPC8540:
2743 rs6000_cost = &ppc8540_cost;
2746 case PROCESSOR_PPCE300C2:
2747 case PROCESSOR_PPCE300C3:
2748 rs6000_cost = &ppce300c2c3_cost;
2751 case PROCESSOR_PPCE500MC:
2752 rs6000_cost = &ppce500mc_cost;
2755 case PROCESSOR_POWER4:
2756 case PROCESSOR_POWER5:
2757 rs6000_cost = &power4_cost;
2760 case PROCESSOR_POWER6:
2761 rs6000_cost = &power6_cost;
2764 case PROCESSOR_POWER7:
2765 rs6000_cost = &power7_cost;
2768 case PROCESSOR_PPCA2:
2769 rs6000_cost = &ppca2_cost;
2776 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
2777 set_param_value ("simultaneous-prefetches",
2778 rs6000_cost->simultaneous_prefetches);
2779 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
2780 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
2781 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
2782 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
2783 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
2784 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
2786 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
2787 can be optimized to ap = __builtin_next_arg (0). */
2788 if (DEFAULT_ABI != ABI_V4)
2789 targetm.expand_builtin_va_start = NULL;
2791 /* Set up single/double float flags.
2792 If TARGET_HARD_FLOAT is set, but neither single or double is set,
2793 then set both flags. */
2794 if (TARGET_HARD_FLOAT && TARGET_FPRS
2795 && rs6000_single_float == 0 && rs6000_double_float == 0)
2796 rs6000_single_float = rs6000_double_float = 1;
2798 /* Reset single and double FP flags if target is E500. */
2801 rs6000_single_float = rs6000_double_float = 0;
2802 if (TARGET_E500_SINGLE)
2803 rs6000_single_float = 1;
2804 if (TARGET_E500_DOUBLE)
2805 rs6000_single_float = rs6000_double_float = 1;
2808 /* If not explicitly specified via option, decide whether to generate indexed
2809 load/store instructions. */
2810 if (TARGET_AVOID_XFORM == -1)
2811 /* Avoid indexed addressing when targeting Power6 in order to avoid
2812 the DERAT mispredict penalty. */
2813 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
2815 rs6000_init_hard_regno_mode_ok ();
2818 /* Implement targetm.vectorize.builtin_mask_for_load. */
2820 rs6000_builtin_mask_for_load (void)
2822 if (TARGET_ALTIVEC || TARGET_VSX)
2823 return altivec_builtin_mask_for_load;
2828 /* Implement targetm.vectorize.builtin_conversion.
2829 Returns a decl of a function that implements conversion of an integer vector
2830 into a floating-point vector, or vice-versa. TYPE is the type of the integer
2831 side of the conversion.
2832 Return NULL_TREE if it is not available. */
2834 rs6000_builtin_conversion (unsigned int tcode, tree type)
2836 enum tree_code code = (enum tree_code) tcode;
2840 case FIX_TRUNC_EXPR:
2841 switch (TYPE_MODE (type))
2844 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2847 return TYPE_UNSIGNED (type)
2848 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
2849 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
2852 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2855 return TYPE_UNSIGNED (type)
2856 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
2857 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
2864 switch (TYPE_MODE (type))
2867 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2870 return TYPE_UNSIGNED (type)
2871 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
2872 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
2875 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2878 return TYPE_UNSIGNED (type)
2879 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
2880 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
2891 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2893 rs6000_builtin_mul_widen_even (tree type)
2895 if (!TARGET_ALTIVEC)
2898 switch (TYPE_MODE (type))
2901 return TYPE_UNSIGNED (type)
2902 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
2903 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
2906 return TYPE_UNSIGNED (type)
2907 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
2908 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
2914 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2916 rs6000_builtin_mul_widen_odd (tree type)
2918 if (!TARGET_ALTIVEC)
2921 switch (TYPE_MODE (type))
2924 return TYPE_UNSIGNED (type)
2925 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
2926 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
2929 return TYPE_UNSIGNED (type)
2930 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
2931 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
2938 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2939 after applying N number of iterations. This routine does not determine
2940 how may iterations are required to reach desired alignment. */
2943 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
2950 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
2953 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
2963 /* Assuming that all other types are naturally aligned. CHECKME! */
2968 /* Return true if the vector misalignment factor is supported by the
2971 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
2978 /* Return if movmisalign pattern is not supported for this mode. */
2979 if (optab_handler (movmisalign_optab, mode)->insn_code ==
2983 if (misalignment == -1)
2985 /* misalignment factor is unknown at compile time but we know
2986 it's word aligned. */
2987 if (rs6000_vector_alignment_reachable (type, is_packed))
2991 /* VSX supports word-aligned vector. */
2992 if (misalignment % 4 == 0)
2998 /* Implement targetm.vectorize.builtin_vec_perm. */
3000 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3002 tree inner_type = TREE_TYPE (type);
3003 bool uns_p = TYPE_UNSIGNED (inner_type);
3006 *mask_element_type = unsigned_char_type_node;
3008 switch (TYPE_MODE (type))
3012 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3013 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3018 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3019 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3024 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3025 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3029 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3033 if (!TARGET_ALLOW_DF_PERMUTE)
3036 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3040 if (!TARGET_ALLOW_DF_PERMUTE)
3044 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3045 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3056 /* Handle generic options of the form -mfoo=yes/no.
3057 NAME is the option name.
3058 VALUE is the option value.
3059 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3060 whether the option value is 'yes' or 'no' respectively. */
3062 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3066 else if (!strcmp (value, "yes"))
3068 else if (!strcmp (value, "no"))
3071 error ("unknown -m%s= option specified: '%s'", name, value);
3074 /* Validate and record the size specified with the -mtls-size option. */
3077 rs6000_parse_tls_size_option (void)
3079 if (rs6000_tls_size_string == 0)
3081 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3082 rs6000_tls_size = 16;
3083 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3084 rs6000_tls_size = 32;
3085 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3086 rs6000_tls_size = 64;
3088 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3092 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3094 if (DEFAULT_ABI == ABI_DARWIN)
3095 /* The Darwin libraries never set errno, so we might as well
3096 avoid calling them when that's the only reason we would. */
3097 flag_errno_math = 0;
3099 /* Double growth factor to counter reduced min jump length. */
3100 set_param_value ("max-grow-copy-bb-insns", 16);
3102 /* Enable section anchors by default.
3103 Skip section anchors for Objective C and Objective C++
3104 until front-ends fixed. */
3105 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3106 flag_section_anchors = 2;
3109 static enum fpu_type_t
3110 rs6000_parse_fpu_option (const char *option)
3112 if (!strcmp("none", option)) return FPU_NONE;
3113 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3114 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3115 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3116 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3117 error("unknown value %s for -mfpu", option);
3121 /* Returns a function decl for a vectorized version of the builtin function
3122 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3123 if it is not available. */
3126 rs6000_builtin_vectorized_function (unsigned int fn, tree type_out,
3129 enum machine_mode in_mode, out_mode;
3132 if (TREE_CODE (type_out) != VECTOR_TYPE
3133 || TREE_CODE (type_in) != VECTOR_TYPE
3134 || !TARGET_VECTORIZE_BUILTINS)
3137 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3138 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3139 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3140 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3144 case BUILT_IN_COPYSIGN:
3145 if (VECTOR_UNIT_VSX_P (V2DFmode)
3146 && out_mode == DFmode && out_n == 2
3147 && in_mode == DFmode && in_n == 2)
3148 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3150 case BUILT_IN_COPYSIGNF:
3151 if (out_mode != SFmode || out_n != 4
3152 || in_mode != SFmode || in_n != 4)
3154 if (VECTOR_UNIT_VSX_P (V4SFmode))
3155 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3156 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3157 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3160 if (VECTOR_UNIT_VSX_P (V2DFmode)
3161 && out_mode == DFmode && out_n == 2
3162 && in_mode == DFmode && in_n == 2)
3163 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3165 case BUILT_IN_SQRTF:
3166 if (VECTOR_UNIT_VSX_P (V4SFmode)
3167 && out_mode == SFmode && out_n == 4
3168 && in_mode == SFmode && in_n == 4)
3169 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3172 if (VECTOR_UNIT_VSX_P (V2DFmode)
3173 && out_mode == DFmode && out_n == 2
3174 && in_mode == DFmode && in_n == 2)
3175 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3177 case BUILT_IN_CEILF:
3178 if (out_mode != SFmode || out_n != 4
3179 || in_mode != SFmode || in_n != 4)
3181 if (VECTOR_UNIT_VSX_P (V4SFmode))
3182 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3183 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3184 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3186 case BUILT_IN_FLOOR:
3187 if (VECTOR_UNIT_VSX_P (V2DFmode)
3188 && out_mode == DFmode && out_n == 2
3189 && in_mode == DFmode && in_n == 2)
3190 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3192 case BUILT_IN_FLOORF:
3193 if (out_mode != SFmode || out_n != 4
3194 || in_mode != SFmode || in_n != 4)
3196 if (VECTOR_UNIT_VSX_P (V4SFmode))
3197 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3198 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3199 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3201 case BUILT_IN_TRUNC:
3202 if (VECTOR_UNIT_VSX_P (V2DFmode)
3203 && out_mode == DFmode && out_n == 2
3204 && in_mode == DFmode && in_n == 2)
3205 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3207 case BUILT_IN_TRUNCF:
3208 if (out_mode != SFmode || out_n != 4
3209 || in_mode != SFmode || in_n != 4)
3211 if (VECTOR_UNIT_VSX_P (V4SFmode))
3212 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3213 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3214 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3216 case BUILT_IN_NEARBYINT:
3217 if (VECTOR_UNIT_VSX_P (V2DFmode)
3218 && flag_unsafe_math_optimizations
3219 && out_mode == DFmode && out_n == 2
3220 && in_mode == DFmode && in_n == 2)
3221 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3223 case BUILT_IN_NEARBYINTF:
3224 if (VECTOR_UNIT_VSX_P (V4SFmode)
3225 && flag_unsafe_math_optimizations
3226 && out_mode == SFmode && out_n == 4
3227 && in_mode == SFmode && in_n == 4)
3228 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3231 if (VECTOR_UNIT_VSX_P (V2DFmode)
3232 && !flag_trapping_math
3233 && out_mode == DFmode && out_n == 2
3234 && in_mode == DFmode && in_n == 2)
3235 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3237 case BUILT_IN_RINTF:
3238 if (VECTOR_UNIT_VSX_P (V4SFmode)
3239 && !flag_trapping_math
3240 && out_mode == SFmode && out_n == 4
3241 && in_mode == SFmode && in_n == 4)
3242 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3251 /* Implement TARGET_HANDLE_OPTION. */
3254 rs6000_handle_option (size_t code, const char *arg, int value)
3256 enum fpu_type_t fpu_type = FPU_NONE;
3262 target_flags &= ~(MASK_POWER | MASK_POWER2
3263 | MASK_MULTIPLE | MASK_STRING);
3264 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3265 | MASK_MULTIPLE | MASK_STRING);
3267 case OPT_mno_powerpc:
3268 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3269 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3270 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3271 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3274 target_flags &= ~MASK_MINIMAL_TOC;
3275 TARGET_NO_FP_IN_TOC = 0;
3276 TARGET_NO_SUM_IN_TOC = 0;
3277 target_flags_explicit |= MASK_MINIMAL_TOC;
3278 #ifdef TARGET_USES_SYSV4_OPT
3279 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3280 just the same as -mminimal-toc. */
3281 target_flags |= MASK_MINIMAL_TOC;
3282 target_flags_explicit |= MASK_MINIMAL_TOC;
3286 #ifdef TARGET_USES_SYSV4_OPT
3288 /* Make -mtoc behave like -mminimal-toc. */
3289 target_flags |= MASK_MINIMAL_TOC;
3290 target_flags_explicit |= MASK_MINIMAL_TOC;
3294 #ifdef TARGET_USES_AIX64_OPT
3299 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3300 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3301 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3304 #ifdef TARGET_USES_AIX64_OPT
3309 target_flags &= ~MASK_POWERPC64;
3310 target_flags_explicit |= MASK_POWERPC64;
3313 case OPT_minsert_sched_nops_:
3314 rs6000_sched_insert_nops_str = arg;
3317 case OPT_mminimal_toc:
3320 TARGET_NO_FP_IN_TOC = 0;
3321 TARGET_NO_SUM_IN_TOC = 0;
3328 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3329 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3336 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3337 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3341 case OPT_mpowerpc_gpopt:
3342 case OPT_mpowerpc_gfxopt:
3345 target_flags |= MASK_POWERPC;
3346 target_flags_explicit |= MASK_POWERPC;
3350 case OPT_maix_struct_return:
3351 case OPT_msvr4_struct_return:
3352 rs6000_explicit_options.aix_struct_ret = true;
3356 rs6000_explicit_options.vrsave = true;
3357 TARGET_ALTIVEC_VRSAVE = value;
3361 rs6000_explicit_options.vrsave = true;
3362 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3366 target_flags_explicit |= MASK_ISEL;
3368 rs6000_parse_yes_no_option ("isel", arg, &isel);
3370 target_flags |= MASK_ISEL;
3372 target_flags &= ~MASK_ISEL;
3376 rs6000_explicit_options.spe = true;
3381 rs6000_explicit_options.spe = true;
3382 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3386 rs6000_debug_name = arg;
3389 #ifdef TARGET_USES_SYSV4_OPT
3391 rs6000_abi_name = arg;
3395 rs6000_sdata_name = arg;
3398 case OPT_mtls_size_:
3399 rs6000_tls_size_string = arg;
3402 case OPT_mrelocatable:
3405 target_flags |= MASK_MINIMAL_TOC;
3406 target_flags_explicit |= MASK_MINIMAL_TOC;
3407 TARGET_NO_FP_IN_TOC = 1;
3411 case OPT_mrelocatable_lib:
3414 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3415 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3416 TARGET_NO_FP_IN_TOC = 1;
3420 target_flags &= ~MASK_RELOCATABLE;
3421 target_flags_explicit |= MASK_RELOCATABLE;
3427 if (!strcmp (arg, "altivec"))
3429 rs6000_explicit_options.altivec_abi = true;
3430 rs6000_altivec_abi = 1;
3432 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3435 else if (! strcmp (arg, "no-altivec"))
3437 rs6000_explicit_options.altivec_abi = true;
3438 rs6000_altivec_abi = 0;
3440 else if (! strcmp (arg, "spe"))
3442 rs6000_explicit_options.spe_abi = true;
3444 rs6000_altivec_abi = 0;
3445 if (!TARGET_SPE_ABI)
3446 error ("not configured for ABI: '%s'", arg);
3448 else if (! strcmp (arg, "no-spe"))
3450 rs6000_explicit_options.spe_abi = true;
3454 /* These are here for testing during development only, do not
3455 document in the manual please. */
3456 else if (! strcmp (arg, "d64"))
3458 rs6000_darwin64_abi = 1;
3459 warning (0, "Using darwin64 ABI");
3461 else if (! strcmp (arg, "d32"))
3463 rs6000_darwin64_abi = 0;
3464 warning (0, "Using old darwin ABI");
3467 else if (! strcmp (arg, "ibmlongdouble"))
3469 rs6000_explicit_options.ieee = true;
3470 rs6000_ieeequad = 0;
3471 warning (0, "Using IBM extended precision long double");
3473 else if (! strcmp (arg, "ieeelongdouble"))
3475 rs6000_explicit_options.ieee = true;
3476 rs6000_ieeequad = 1;
3477 warning (0, "Using IEEE extended precision long double");
3482 error ("unknown ABI specified: '%s'", arg);
3488 rs6000_select[1].string = arg;
3492 rs6000_select[2].string = arg;
3495 case OPT_mtraceback_:
3496 rs6000_traceback_name = arg;
3499 case OPT_mfloat_gprs_:
3500 rs6000_explicit_options.float_gprs = true;
3501 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3502 rs6000_float_gprs = 1;
3503 else if (! strcmp (arg, "double"))
3504 rs6000_float_gprs = 2;
3505 else if (! strcmp (arg, "no"))
3506 rs6000_float_gprs = 0;
3509 error ("invalid option for -mfloat-gprs: '%s'", arg);
3514 case OPT_mlong_double_:
3515 rs6000_explicit_options.long_double = true;
3516 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3517 if (value != 64 && value != 128)
3519 error ("Unknown switch -mlong-double-%s", arg);
3520 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3524 rs6000_long_double_type_size = value;
3527 case OPT_msched_costly_dep_:
3528 rs6000_sched_costly_dep_str = arg;
3532 rs6000_explicit_options.alignment = true;
3533 if (! strcmp (arg, "power"))
3535 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3536 some C library functions, so warn about it. The flag may be
3537 useful for performance studies from time to time though, so
3538 don't disable it entirely. */
3539 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3540 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3541 " it is incompatible with the installed C and C++ libraries");
3542 rs6000_alignment_flags = MASK_ALIGN_POWER;
3544 else if (! strcmp (arg, "natural"))
3545 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3548 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3553 case OPT_msingle_float:
3554 if (!TARGET_SINGLE_FPU)
3555 warning (0, "-msingle-float option equivalent to -mhard-float");
3556 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3557 rs6000_double_float = 0;
3558 target_flags &= ~MASK_SOFT_FLOAT;
3559 target_flags_explicit |= MASK_SOFT_FLOAT;
3562 case OPT_mdouble_float:
3563 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3564 rs6000_single_float = 1;
3565 target_flags &= ~MASK_SOFT_FLOAT;
3566 target_flags_explicit |= MASK_SOFT_FLOAT;
3569 case OPT_msimple_fpu:
3570 if (!TARGET_SINGLE_FPU)
3571 warning (0, "-msimple-fpu option ignored");
3574 case OPT_mhard_float:
3575 /* -mhard_float implies -msingle-float and -mdouble-float. */
3576 rs6000_single_float = rs6000_double_float = 1;
3579 case OPT_msoft_float:
3580 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3581 rs6000_single_float = rs6000_double_float = 0;
3585 fpu_type = rs6000_parse_fpu_option(arg);
3586 if (fpu_type != FPU_NONE)
3587 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3589 target_flags &= ~MASK_SOFT_FLOAT;
3590 target_flags_explicit |= MASK_SOFT_FLOAT;
3591 rs6000_xilinx_fpu = 1;
3592 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3593 rs6000_single_float = 1;
3594 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3595 rs6000_single_float = rs6000_double_float = 1;
3596 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3597 rs6000_simple_fpu = 1;
3601 /* -mfpu=none is equivalent to -msoft-float */
3602 target_flags |= MASK_SOFT_FLOAT;
3603 target_flags_explicit |= MASK_SOFT_FLOAT;
3604 rs6000_single_float = rs6000_double_float = 0;
3611 /* Do anything needed at the start of the asm file. */
3614 rs6000_file_start (void)
3618 const char *start = buffer;
3619 struct rs6000_cpu_select *ptr;
3620 const char *default_cpu = TARGET_CPU_DEFAULT;
3621 FILE *file = asm_out_file;
3623 default_file_start ();
3625 #ifdef TARGET_BI_ARCH
3626 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3630 if (flag_verbose_asm)
3632 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3633 rs6000_select[0].string = default_cpu;
3635 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3637 ptr = &rs6000_select[i];
3638 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
3640 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
3645 if (PPC405_ERRATUM77)
3647 fprintf (file, "%s PPC405CR_ERRATUM77", start);
3651 #ifdef USING_ELFOS_H
3652 switch (rs6000_sdata)
3654 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
3655 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
3656 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
3657 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
3660 if (rs6000_sdata && g_switch_value)
3662 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
3672 #ifdef HAVE_AS_GNU_ATTRIBUTE
3673 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
3675 fprintf (file, "\t.gnu_attribute 4, %d\n",
3676 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
3677 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
3679 fprintf (file, "\t.gnu_attribute 8, %d\n",
3680 (TARGET_ALTIVEC_ABI ? 2
3681 : TARGET_SPE_ABI ? 3
3683 fprintf (file, "\t.gnu_attribute 12, %d\n",
3684 aix_struct_return ? 2 : 1);
3689 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
3691 switch_to_section (toc_section);
3692 switch_to_section (text_section);
3697 /* Return nonzero if this function is known to have a null epilogue. */
3700 direct_return (void)
3702 if (reload_completed)
3704 rs6000_stack_t *info = rs6000_stack_info ();
3706 if (info->first_gp_reg_save == 32
3707 && info->first_fp_reg_save == 64
3708 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
3709 && ! info->lr_save_p
3710 && ! info->cr_save_p
3711 && info->vrsave_mask == 0
3719 /* Return the number of instructions it takes to form a constant in an
3720 integer register. */
3723 num_insns_constant_wide (HOST_WIDE_INT value)
3725 /* signed constant loadable with {cal|addi} */
3726 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
3729 /* constant loadable with {cau|addis} */
3730 else if ((value & 0xffff) == 0
3731 && (value >> 31 == -1 || value >> 31 == 0))
3734 #if HOST_BITS_PER_WIDE_INT == 64
3735 else if (TARGET_POWERPC64)
3737 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
3738 HOST_WIDE_INT high = value >> 31;
3740 if (high == 0 || high == -1)
3746 return num_insns_constant_wide (high) + 1;
3748 return (num_insns_constant_wide (high)
3749 + num_insns_constant_wide (low) + 1);
3758 num_insns_constant (rtx op, enum machine_mode mode)
3760 HOST_WIDE_INT low, high;
3762 switch (GET_CODE (op))
3765 #if HOST_BITS_PER_WIDE_INT == 64
3766 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
3767 && mask64_operand (op, mode))
3771 return num_insns_constant_wide (INTVAL (op));
3774 if (mode == SFmode || mode == SDmode)
3779 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3780 if (DECIMAL_FLOAT_MODE_P (mode))
3781 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
3783 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
3784 return num_insns_constant_wide ((HOST_WIDE_INT) l);
3787 if (mode == VOIDmode || mode == DImode)
3789 high = CONST_DOUBLE_HIGH (op);
3790 low = CONST_DOUBLE_LOW (op);
3797 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3798 if (DECIMAL_FLOAT_MODE_P (mode))
3799 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
3801 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
3802 high = l[WORDS_BIG_ENDIAN == 0];
3803 low = l[WORDS_BIG_ENDIAN != 0];
3807 return (num_insns_constant_wide (low)
3808 + num_insns_constant_wide (high));
3811 if ((high == 0 && low >= 0)
3812 || (high == -1 && low < 0))
3813 return num_insns_constant_wide (low);
3815 else if (mask64_operand (op, mode))
3819 return num_insns_constant_wide (high) + 1;
3822 return (num_insns_constant_wide (high)
3823 + num_insns_constant_wide (low) + 1);
3831 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
3832 If the mode of OP is MODE_VECTOR_INT, this simply returns the
3833 corresponding element of the vector, but for V4SFmode and V2SFmode,
3834 the corresponding "float" is interpreted as an SImode integer. */
3837 const_vector_elt_as_int (rtx op, unsigned int elt)
3839 rtx tmp = CONST_VECTOR_ELT (op, elt);
3840 if (GET_MODE (op) == V4SFmode
3841 || GET_MODE (op) == V2SFmode)
3842 tmp = gen_lowpart (SImode, tmp);
3843 return INTVAL (tmp);
3846 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
3847 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
3848 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
3849 all items are set to the same value and contain COPIES replicas of the
3850 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
3851 operand and the others are set to the value of the operand's msb. */
3854 vspltis_constant (rtx op, unsigned step, unsigned copies)
3856 enum machine_mode mode = GET_MODE (op);
3857 enum machine_mode inner = GET_MODE_INNER (mode);
3860 unsigned nunits = GET_MODE_NUNITS (mode);
3861 unsigned bitsize = GET_MODE_BITSIZE (inner);
3862 unsigned mask = GET_MODE_MASK (inner);
3864 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
3865 HOST_WIDE_INT splat_val = val;
3866 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
3868 /* Construct the value to be splatted, if possible. If not, return 0. */
3869 for (i = 2; i <= copies; i *= 2)
3871 HOST_WIDE_INT small_val;
3873 small_val = splat_val >> bitsize;
3875 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
3877 splat_val = small_val;
3880 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
3881 if (EASY_VECTOR_15 (splat_val))
3884 /* Also check if we can splat, and then add the result to itself. Do so if
3885 the value is positive, of if the splat instruction is using OP's mode;
3886 for splat_val < 0, the splat and the add should use the same mode. */
3887 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
3888 && (splat_val >= 0 || (step == 1 && copies == 1)))
3891 /* Also check if are loading up the most significant bit which can be done by
3892 loading up -1 and shifting the value left by -1. */
3893 else if (EASY_VECTOR_MSB (splat_val, inner))
3899 /* Check if VAL is present in every STEP-th element, and the
3900 other elements are filled with its most significant bit. */
3901 for (i = 0; i < nunits - 1; ++i)
3903 HOST_WIDE_INT desired_val;
3904 if (((i + 1) & (step - 1)) == 0)
3907 desired_val = msb_val;
3909 if (desired_val != const_vector_elt_as_int (op, i))
3917 /* Return true if OP is of the given MODE and can be synthesized
3918 with a vspltisb, vspltish or vspltisw. */
3921 easy_altivec_constant (rtx op, enum machine_mode mode)
3923 unsigned step, copies;
3925 if (mode == VOIDmode)
3926 mode = GET_MODE (op);
3927 else if (mode != GET_MODE (op))
3930 /* Start with a vspltisw. */
3931 step = GET_MODE_NUNITS (mode) / 4;
3934 if (vspltis_constant (op, step, copies))
3937 /* Then try with a vspltish. */
3943 if (vspltis_constant (op, step, copies))
3946 /* And finally a vspltisb. */
3952 if (vspltis_constant (op, step, copies))
3958 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
3959 result is OP. Abort if it is not possible. */
3962 gen_easy_altivec_constant (rtx op)
3964 enum machine_mode mode = GET_MODE (op);
3965 int nunits = GET_MODE_NUNITS (mode);
3966 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
3967 unsigned step = nunits / 4;
3968 unsigned copies = 1;
3970 /* Start with a vspltisw. */
3971 if (vspltis_constant (op, step, copies))
3972 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
3974 /* Then try with a vspltish. */
3980 if (vspltis_constant (op, step, copies))
3981 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
3983 /* And finally a vspltisb. */
3989 if (vspltis_constant (op, step, copies))
3990 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
3996 output_vec_const_move (rtx *operands)
3999 enum machine_mode mode;
4004 mode = GET_MODE (dest);
4006 if (TARGET_VSX && zero_constant (vec, mode))
4007 return "xxlxor %x0,%x0,%x0";
4012 if (zero_constant (vec, mode))
4013 return "vxor %0,%0,%0";
4015 splat_vec = gen_easy_altivec_constant (vec);
4016 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4017 operands[1] = XEXP (splat_vec, 0);
4018 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4021 switch (GET_MODE (splat_vec))
4024 return "vspltisw %0,%1";
4027 return "vspltish %0,%1";
4030 return "vspltisb %0,%1";
4037 gcc_assert (TARGET_SPE);
4039 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4040 pattern of V1DI, V4HI, and V2SF.
4042 FIXME: We should probably return # and add post reload
4043 splitters for these, but this way is so easy ;-). */
4044 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4045 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4046 operands[1] = CONST_VECTOR_ELT (vec, 0);
4047 operands[2] = CONST_VECTOR_ELT (vec, 1);
4049 return "li %0,%1\n\tevmergelo %0,%0,%0";
4051 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4054 /* Initialize TARGET of vector PAIRED to VALS. */
4057 paired_expand_vector_init (rtx target, rtx vals)
4059 enum machine_mode mode = GET_MODE (target);
4060 int n_elts = GET_MODE_NUNITS (mode);
4062 rtx x, new_rtx, tmp, constant_op, op1, op2;
4065 for (i = 0; i < n_elts; ++i)
4067 x = XVECEXP (vals, 0, i);
4068 if (!CONSTANT_P (x))
4073 /* Load from constant pool. */
4074 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4080 /* The vector is initialized only with non-constants. */
4081 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4082 XVECEXP (vals, 0, 1));
4084 emit_move_insn (target, new_rtx);
4088 /* One field is non-constant and the other one is a constant. Load the
4089 constant from the constant pool and use ps_merge instruction to
4090 construct the whole vector. */
4091 op1 = XVECEXP (vals, 0, 0);
4092 op2 = XVECEXP (vals, 0, 1);
4094 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4096 tmp = gen_reg_rtx (GET_MODE (constant_op));
4097 emit_move_insn (tmp, constant_op);
4099 if (CONSTANT_P (op1))
4100 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4102 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4104 emit_move_insn (target, new_rtx);
4108 paired_expand_vector_move (rtx operands[])
4110 rtx op0 = operands[0], op1 = operands[1];
4112 emit_move_insn (op0, op1);
4115 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4116 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4117 operands for the relation operation COND. This is a recursive
4121 paired_emit_vector_compare (enum rtx_code rcode,
4122 rtx dest, rtx op0, rtx op1,
4123 rtx cc_op0, rtx cc_op1)
4125 rtx tmp = gen_reg_rtx (V2SFmode);
4126 rtx tmp1, max, min, equal_zero;
4128 gcc_assert (TARGET_PAIRED_FLOAT);
4129 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4135 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4139 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4140 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4144 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4147 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4150 tmp1 = gen_reg_rtx (V2SFmode);
4151 max = gen_reg_rtx (V2SFmode);
4152 min = gen_reg_rtx (V2SFmode);
4153 equal_zero = gen_reg_rtx (V2SFmode);
4155 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4156 emit_insn (gen_selv2sf4
4157 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4158 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4159 emit_insn (gen_selv2sf4
4160 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4161 emit_insn (gen_subv2sf3 (tmp1, min, max));
4162 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4165 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4168 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4171 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4174 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4177 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4186 /* Emit vector conditional expression.
4187 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4188 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4191 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4192 rtx cond, rtx cc_op0, rtx cc_op1)
4194 enum rtx_code rcode = GET_CODE (cond);
4196 if (!TARGET_PAIRED_FLOAT)
4199 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4204 /* Initialize vector TARGET to VALS. */
4207 rs6000_expand_vector_init (rtx target, rtx vals)
4209 enum machine_mode mode = GET_MODE (target);
4210 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4211 int n_elts = GET_MODE_NUNITS (mode);
4212 int n_var = 0, one_var = -1;
4213 bool all_same = true, all_const_zero = true;
4217 for (i = 0; i < n_elts; ++i)
4219 x = XVECEXP (vals, 0, i);
4220 if (!CONSTANT_P (x))
4221 ++n_var, one_var = i;
4222 else if (x != CONST0_RTX (inner_mode))
4223 all_const_zero = false;
4225 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4231 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4232 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4233 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4235 /* Zero register. */
4236 emit_insn (gen_rtx_SET (VOIDmode, target,
4237 gen_rtx_XOR (mode, target, target)));
4240 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4242 /* Splat immediate. */
4243 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4248 /* Load from constant pool. */
4249 emit_move_insn (target, const_vec);
4254 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4255 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4259 rtx element = XVECEXP (vals, 0, 0);
4260 if (mode == V2DFmode)
4261 emit_insn (gen_vsx_splat_v2df (target, element));
4263 emit_insn (gen_vsx_splat_v2di (target, element));
4267 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4268 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4269 if (mode == V2DFmode)
4270 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4272 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4277 /* With single precision floating point on VSX, know that internally single
4278 precision is actually represented as a double, and either make 2 V2DF
4279 vectors, and convert these vectors to single precision, or do one
4280 conversion, and splat the result to the other elements. */
4281 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4285 rtx freg = gen_reg_rtx (V4SFmode);
4286 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4288 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4289 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4293 rtx dbl_even = gen_reg_rtx (V2DFmode);
4294 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4295 rtx flt_even = gen_reg_rtx (V4SFmode);
4296 rtx flt_odd = gen_reg_rtx (V4SFmode);
4298 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4299 copy_to_reg (XVECEXP (vals, 0, 0)),
4300 copy_to_reg (XVECEXP (vals, 0, 1))));
4301 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4302 copy_to_reg (XVECEXP (vals, 0, 2)),
4303 copy_to_reg (XVECEXP (vals, 0, 3))));
4304 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4305 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4306 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4311 /* Store value to stack temp. Load vector element. Splat. However, splat
4312 of 64-bit items is not supported on Altivec. */
4313 if (all_same && GET_MODE_SIZE (mode) <= 4)
4315 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4316 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4317 XVECEXP (vals, 0, 0));
4318 x = gen_rtx_UNSPEC (VOIDmode,
4319 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4320 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4322 gen_rtx_SET (VOIDmode,
4325 x = gen_rtx_VEC_SELECT (inner_mode, target,
4326 gen_rtx_PARALLEL (VOIDmode,
4327 gen_rtvec (1, const0_rtx)));
4328 emit_insn (gen_rtx_SET (VOIDmode, target,
4329 gen_rtx_VEC_DUPLICATE (mode, x)));
4333 /* One field is non-constant. Load constant then overwrite
4337 rtx copy = copy_rtx (vals);
4339 /* Load constant part of vector, substitute neighboring value for
4341 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4342 rs6000_expand_vector_init (target, copy);
4344 /* Insert variable. */
4345 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4349 /* Construct the vector in memory one field at a time
4350 and load the whole vector. */
4351 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4352 for (i = 0; i < n_elts; i++)
4353 emit_move_insn (adjust_address_nv (mem, inner_mode,
4354 i * GET_MODE_SIZE (inner_mode)),
4355 XVECEXP (vals, 0, i));
4356 emit_move_insn (target, mem);
4359 /* Set field ELT of TARGET to VAL. */
4362 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4364 enum machine_mode mode = GET_MODE (target);
4365 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4366 rtx reg = gen_reg_rtx (mode);
4368 int width = GET_MODE_SIZE (inner_mode);
4371 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4373 rtx (*set_func) (rtx, rtx, rtx, rtx)
4374 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4375 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4379 /* Load single variable value. */
4380 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4381 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4382 x = gen_rtx_UNSPEC (VOIDmode,
4383 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4384 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4386 gen_rtx_SET (VOIDmode,
4390 /* Linear sequence. */
4391 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4392 for (i = 0; i < 16; ++i)
4393 XVECEXP (mask, 0, i) = GEN_INT (i);
4395 /* Set permute mask to insert element into target. */
4396 for (i = 0; i < width; ++i)
4397 XVECEXP (mask, 0, elt*width + i)
4398 = GEN_INT (i + 0x10);
4399 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4400 x = gen_rtx_UNSPEC (mode,
4401 gen_rtvec (3, target, reg,
4402 force_reg (V16QImode, x)),
4404 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4407 /* Extract field ELT from VEC into TARGET. */
4410 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4412 enum machine_mode mode = GET_MODE (vec);
4413 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4416 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4418 rtx (*extract_func) (rtx, rtx, rtx)
4419 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4420 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4424 /* Allocate mode-sized buffer. */
4425 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4427 /* Add offset to field within buffer matching vector element. */
4428 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4430 /* Store single field into mode-sized buffer. */
4431 x = gen_rtx_UNSPEC (VOIDmode,
4432 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4433 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4435 gen_rtx_SET (VOIDmode,
4438 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4441 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4442 implement ANDing by the mask IN. */
4444 build_mask64_2_operands (rtx in, rtx *out)
4446 #if HOST_BITS_PER_WIDE_INT >= 64
4447 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4450 gcc_assert (GET_CODE (in) == CONST_INT);
4455 /* Assume c initially something like 0x00fff000000fffff. The idea
4456 is to rotate the word so that the middle ^^^^^^ group of zeros
4457 is at the MS end and can be cleared with an rldicl mask. We then
4458 rotate back and clear off the MS ^^ group of zeros with a
4460 c = ~c; /* c == 0xff000ffffff00000 */
4461 lsb = c & -c; /* lsb == 0x0000000000100000 */
4462 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4463 c = ~c; /* c == 0x00fff000000fffff */
4464 c &= -lsb; /* c == 0x00fff00000000000 */
4465 lsb = c & -c; /* lsb == 0x0000100000000000 */
4466 c = ~c; /* c == 0xff000fffffffffff */
4467 c &= -lsb; /* c == 0xff00000000000000 */
4469 while ((lsb >>= 1) != 0)
4470 shift++; /* shift == 44 on exit from loop */
4471 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4472 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4473 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4477 /* Assume c initially something like 0xff000f0000000000. The idea
4478 is to rotate the word so that the ^^^ middle group of zeros
4479 is at the LS end and can be cleared with an rldicr mask. We then
4480 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4482 lsb = c & -c; /* lsb == 0x0000010000000000 */
4483 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4484 c = ~c; /* c == 0x00fff0ffffffffff */
4485 c &= -lsb; /* c == 0x00fff00000000000 */
4486 lsb = c & -c; /* lsb == 0x0000100000000000 */
4487 c = ~c; /* c == 0xff000fffffffffff */
4488 c &= -lsb; /* c == 0xff00000000000000 */
4490 while ((lsb >>= 1) != 0)
4491 shift++; /* shift == 44 on exit from loop */
4492 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4493 m1 >>= shift; /* m1 == 0x0000000000000fff */
4494 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4497 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4498 masks will be all 1's. We are guaranteed more than one transition. */
4499 out[0] = GEN_INT (64 - shift);
4500 out[1] = GEN_INT (m1);
4501 out[2] = GEN_INT (shift);
4502 out[3] = GEN_INT (m2);
4510 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4513 invalid_e500_subreg (rtx op, enum machine_mode mode)
4515 if (TARGET_E500_DOUBLE)
4517 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4518 subreg:TI and reg:TF. Decimal float modes are like integer
4519 modes (only low part of each register used) for this
4521 if (GET_CODE (op) == SUBREG
4522 && (mode == SImode || mode == DImode || mode == TImode
4523 || mode == DDmode || mode == TDmode)
4524 && REG_P (SUBREG_REG (op))
4525 && (GET_MODE (SUBREG_REG (op)) == DFmode
4526 || GET_MODE (SUBREG_REG (op)) == TFmode))
4529 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4531 if (GET_CODE (op) == SUBREG
4532 && (mode == DFmode || mode == TFmode)
4533 && REG_P (SUBREG_REG (op))
4534 && (GET_MODE (SUBREG_REG (op)) == DImode
4535 || GET_MODE (SUBREG_REG (op)) == TImode
4536 || GET_MODE (SUBREG_REG (op)) == DDmode
4537 || GET_MODE (SUBREG_REG (op)) == TDmode))
4542 && GET_CODE (op) == SUBREG
4544 && REG_P (SUBREG_REG (op))
4545 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4551 /* AIX increases natural record alignment to doubleword if the first
4552 field is an FP double while the FP fields remain word aligned. */
4555 rs6000_special_round_type_align (tree type, unsigned int computed,
4556 unsigned int specified)
4558 unsigned int align = MAX (computed, specified);
4559 tree field = TYPE_FIELDS (type);
4561 /* Skip all non field decls */
4562 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4563 field = TREE_CHAIN (field);
4565 if (field != NULL && field != type)
4567 type = TREE_TYPE (field);
4568 while (TREE_CODE (type) == ARRAY_TYPE)
4569 type = TREE_TYPE (type);
4571 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4572 align = MAX (align, 64);
4578 /* Darwin increases record alignment to the natural alignment of
4582 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4583 unsigned int specified)
4585 unsigned int align = MAX (computed, specified);
4587 if (TYPE_PACKED (type))
4590 /* Find the first field, looking down into aggregates. */
4592 tree field = TYPE_FIELDS (type);
4593 /* Skip all non field decls */
4594 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4595 field = TREE_CHAIN (field);
4598 type = TREE_TYPE (field);
4599 while (TREE_CODE (type) == ARRAY_TYPE)
4600 type = TREE_TYPE (type);
4601 } while (AGGREGATE_TYPE_P (type));
4603 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
4604 align = MAX (align, TYPE_ALIGN (type));
4609 /* Return 1 for an operand in small memory on V.4/eabi. */
4612 small_data_operand (rtx op ATTRIBUTE_UNUSED,
4613 enum machine_mode mode ATTRIBUTE_UNUSED)
4618 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
4621 if (DEFAULT_ABI != ABI_V4)
4624 /* Vector and float memory instructions have a limited offset on the
4625 SPE, so using a vector or float variable directly as an operand is
4628 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
4631 if (GET_CODE (op) == SYMBOL_REF)
4634 else if (GET_CODE (op) != CONST
4635 || GET_CODE (XEXP (op, 0)) != PLUS
4636 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
4637 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
4642 rtx sum = XEXP (op, 0);
4643 HOST_WIDE_INT summand;
4645 /* We have to be careful here, because it is the referenced address
4646 that must be 32k from _SDA_BASE_, not just the symbol. */
4647 summand = INTVAL (XEXP (sum, 1));
4648 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
4651 sym_ref = XEXP (sum, 0);
4654 return SYMBOL_REF_SMALL_P (sym_ref);
4660 /* Return true if either operand is a general purpose register. */
4663 gpr_or_gpr_p (rtx op0, rtx op1)
4665 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
4666 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
4670 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
4673 reg_offset_addressing_ok_p (enum machine_mode mode)
4683 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
4684 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
4692 /* Paired vector modes. Only reg+reg addressing is valid. */
4693 if (TARGET_PAIRED_FLOAT)
4705 virtual_stack_registers_memory_p (rtx op)
4709 if (GET_CODE (op) == REG)
4710 regnum = REGNO (op);
4712 else if (GET_CODE (op) == PLUS
4713 && GET_CODE (XEXP (op, 0)) == REG
4714 && GET_CODE (XEXP (op, 1)) == CONST_INT)
4715 regnum = REGNO (XEXP (op, 0));
4720 return (regnum >= FIRST_VIRTUAL_REGISTER
4721 && regnum <= LAST_VIRTUAL_REGISTER);
4725 constant_pool_expr_p (rtx op)
4729 split_const (op, &base, &offset);
4730 return (GET_CODE (base) == SYMBOL_REF
4731 && CONSTANT_POOL_ADDRESS_P (base)
4732 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
4736 toc_relative_expr_p (rtx op)
4740 if (GET_CODE (op) != CONST)
4743 split_const (op, &base, &offset);
4744 return (GET_CODE (base) == UNSPEC
4745 && XINT (base, 1) == UNSPEC_TOCREL);
4749 legitimate_constant_pool_address_p (rtx x)
4752 && GET_CODE (x) == PLUS
4753 && GET_CODE (XEXP (x, 0)) == REG
4754 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
4755 && toc_relative_expr_p (XEXP (x, 1)));
4759 legitimate_small_data_p (enum machine_mode mode, rtx x)
4761 return (DEFAULT_ABI == ABI_V4
4762 && !flag_pic && !TARGET_TOC
4763 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
4764 && small_data_operand (x, mode));
4767 /* SPE offset addressing is limited to 5-bits worth of double words. */
4768 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
4771 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
4773 unsigned HOST_WIDE_INT offset, extra;
4775 if (GET_CODE (x) != PLUS)
4777 if (GET_CODE (XEXP (x, 0)) != REG)
4779 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4781 if (!reg_offset_addressing_ok_p (mode))
4782 return virtual_stack_registers_memory_p (x);
4783 if (legitimate_constant_pool_address_p (x))
4785 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4788 offset = INTVAL (XEXP (x, 1));
4796 /* SPE vector modes. */
4797 return SPE_CONST_OFFSET_OK (offset);
4800 if (TARGET_E500_DOUBLE)
4801 return SPE_CONST_OFFSET_OK (offset);
4803 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
4805 if (VECTOR_MEM_VSX_P (DFmode))
4810 /* On e500v2, we may have:
4812 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
4814 Which gets addressed with evldd instructions. */
4815 if (TARGET_E500_DOUBLE)
4816 return SPE_CONST_OFFSET_OK (offset);
4818 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
4820 else if (offset & 3)
4825 if (TARGET_E500_DOUBLE)
4826 return (SPE_CONST_OFFSET_OK (offset)
4827 && SPE_CONST_OFFSET_OK (offset + 8));
4831 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
4833 else if (offset & 3)
4844 return (offset < 0x10000) && (offset + extra < 0x10000);
4848 legitimate_indexed_address_p (rtx x, int strict)
4852 if (GET_CODE (x) != PLUS)
4858 /* Recognize the rtl generated by reload which we know will later be
4859 replaced with proper base and index regs. */
4861 && reload_in_progress
4862 && (REG_P (op0) || GET_CODE (op0) == PLUS)
4866 return (REG_P (op0) && REG_P (op1)
4867 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
4868 && INT_REG_OK_FOR_INDEX_P (op1, strict))
4869 || (INT_REG_OK_FOR_BASE_P (op1, strict)
4870 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
4874 avoiding_indexed_address_p (enum machine_mode mode)
4876 /* Avoid indexed addressing for modes that have non-indexed
4877 load/store instruction forms. */
4878 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
4882 legitimate_indirect_address_p (rtx x, int strict)
4884 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
4888 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
4890 if (!TARGET_MACHO || !flag_pic
4891 || mode != SImode || GET_CODE (x) != MEM)
4895 if (GET_CODE (x) != LO_SUM)
4897 if (GET_CODE (XEXP (x, 0)) != REG)
4899 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
4903 return CONSTANT_P (x);
4907 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
4909 if (GET_CODE (x) != LO_SUM)
4911 if (GET_CODE (XEXP (x, 0)) != REG)
4913 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4915 /* Restrict addressing for DI because of our SUBREG hackery. */
4916 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4917 || mode == DDmode || mode == TDmode
4922 if (TARGET_ELF || TARGET_MACHO)
4924 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
4928 if (GET_MODE_NUNITS (mode) != 1)
4930 if (GET_MODE_BITSIZE (mode) > 64
4931 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
4932 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4933 && (mode == DFmode || mode == DDmode))))
4936 return CONSTANT_P (x);
4943 /* Try machine-dependent ways of modifying an illegitimate address
4944 to be legitimate. If we find one, return the new, valid address.
4945 This is used from only one place: `memory_address' in explow.c.
4947 OLDX is the address as it was before break_out_memory_refs was
4948 called. In some cases it is useful to look at this to decide what
4951 It is always safe for this function to do nothing. It exists to
4952 recognize opportunities to optimize the output.
4954 On RS/6000, first check for the sum of a register with a constant
4955 integer that is out of range. If so, generate code to add the
4956 constant with the low-order 16 bits masked to the register and force
4957 this result into another register (this can be done with `cau').
4958 Then generate an address of REG+(CONST&0xffff), allowing for the
4959 possibility of bit 16 being a one.
4961 Then check for the sum of a register and something not constant, try to
4962 load the other things into a register and return the sum. */
4965 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
4966 enum machine_mode mode)
4968 unsigned int extra = 0;
4970 if (!reg_offset_addressing_ok_p (mode))
4972 if (virtual_stack_registers_memory_p (x))
4975 /* In theory we should not be seeing addresses of the form reg+0,
4976 but just in case it is generated, optimize it away. */
4977 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
4978 return force_reg (Pmode, XEXP (x, 0));
4980 /* Make sure both operands are registers. */
4981 else if (GET_CODE (x) == PLUS)
4982 return gen_rtx_PLUS (Pmode,
4983 force_reg (Pmode, XEXP (x, 0)),
4984 force_reg (Pmode, XEXP (x, 1)));
4986 return force_reg (Pmode, x);
4988 if (GET_CODE (x) == SYMBOL_REF)
4990 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
4992 return rs6000_legitimize_tls_address (x, model);
5002 if (!TARGET_POWERPC64)
5010 extra = TARGET_POWERPC64 ? 8 : 12;
5016 if (GET_CODE (x) == PLUS
5017 && GET_CODE (XEXP (x, 0)) == REG
5018 && GET_CODE (XEXP (x, 1)) == CONST_INT
5019 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5021 && !((TARGET_POWERPC64
5022 && (mode == DImode || mode == TImode)
5023 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5024 || SPE_VECTOR_MODE (mode)
5025 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5026 || mode == DImode || mode == DDmode
5027 || mode == TDmode))))
5029 HOST_WIDE_INT high_int, low_int;
5031 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5032 if (low_int >= 0x8000 - extra)
5034 high_int = INTVAL (XEXP (x, 1)) - low_int;
5035 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5036 GEN_INT (high_int)), 0);
5037 return plus_constant (sum, low_int);
5039 else if (GET_CODE (x) == PLUS
5040 && GET_CODE (XEXP (x, 0)) == REG
5041 && GET_CODE (XEXP (x, 1)) != CONST_INT
5042 && GET_MODE_NUNITS (mode) == 1
5043 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5045 || ((mode != DImode && mode != DFmode && mode != DDmode)
5046 || (TARGET_E500_DOUBLE && mode != DDmode)))
5047 && (TARGET_POWERPC64 || mode != DImode)
5048 && !avoiding_indexed_address_p (mode)
5053 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5054 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5056 else if (SPE_VECTOR_MODE (mode)
5057 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5058 || mode == DDmode || mode == TDmode
5059 || mode == DImode)))
5063 /* We accept [reg + reg] and [reg + OFFSET]. */
5065 if (GET_CODE (x) == PLUS)
5067 rtx op1 = XEXP (x, 0);
5068 rtx op2 = XEXP (x, 1);
5071 op1 = force_reg (Pmode, op1);
5073 if (GET_CODE (op2) != REG
5074 && (GET_CODE (op2) != CONST_INT
5075 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5076 || (GET_MODE_SIZE (mode) > 8
5077 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5078 op2 = force_reg (Pmode, op2);
5080 /* We can't always do [reg + reg] for these, because [reg +
5081 reg + offset] is not a legitimate addressing mode. */
5082 y = gen_rtx_PLUS (Pmode, op1, op2);
5084 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5085 return force_reg (Pmode, y);
5090 return force_reg (Pmode, x);
5096 && GET_CODE (x) != CONST_INT
5097 && GET_CODE (x) != CONST_DOUBLE
5099 && GET_MODE_NUNITS (mode) == 1
5100 && (GET_MODE_BITSIZE (mode) <= 32
5101 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5102 && (mode == DFmode || mode == DDmode))))
5104 rtx reg = gen_reg_rtx (Pmode);
5105 emit_insn (gen_elf_high (reg, x));
5106 return gen_rtx_LO_SUM (Pmode, reg, x);
5108 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5111 && ! MACHO_DYNAMIC_NO_PIC_P
5113 && GET_CODE (x) != CONST_INT
5114 && GET_CODE (x) != CONST_DOUBLE
5116 && GET_MODE_NUNITS (mode) == 1
5117 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5118 || (mode != DFmode && mode != DDmode))
5122 rtx reg = gen_reg_rtx (Pmode);
5123 emit_insn (gen_macho_high (reg, x));
5124 return gen_rtx_LO_SUM (Pmode, reg, x);
5127 && GET_CODE (x) == SYMBOL_REF
5128 && constant_pool_expr_p (x)
5129 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5131 return create_TOC_reference (x);
5137 /* Debug version of rs6000_legitimize_address. */
5139 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5145 ret = rs6000_legitimize_address (x, oldx, mode);
5146 insns = get_insns ();
5152 "\nrs6000_legitimize_address: mode %s, old code %s, "
5153 "new code %s, modified\n",
5154 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5155 GET_RTX_NAME (GET_CODE (ret)));
5157 fprintf (stderr, "Original address:\n");
5160 fprintf (stderr, "oldx:\n");
5163 fprintf (stderr, "New address:\n");
5168 fprintf (stderr, "Insns added:\n");
5169 debug_rtx_list (insns, 20);
5175 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5176 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5187 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5188 We need to emit DTP-relative relocations. */
5191 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5196 fputs ("\t.long\t", file);
5199 fputs (DOUBLE_INT_ASM_OP, file);
5204 output_addr_const (file, x);
5205 fputs ("@dtprel+0x8000", file);
5208 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5210 static GTY(()) rtx rs6000_tls_symbol;
5212 rs6000_tls_get_addr (void)
5214 if (!rs6000_tls_symbol)
5215 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5217 return rs6000_tls_symbol;
5220 /* Construct the SYMBOL_REF for TLS GOT references. */
5222 static GTY(()) rtx rs6000_got_symbol;
5224 rs6000_got_sym (void)
5226 if (!rs6000_got_symbol)
5228 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5229 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5230 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5233 return rs6000_got_symbol;
5236 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5237 this (thread-local) address. */
5240 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5244 dest = gen_reg_rtx (Pmode);
5245 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5251 tlsreg = gen_rtx_REG (Pmode, 13);
5252 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5256 tlsreg = gen_rtx_REG (Pmode, 2);
5257 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5261 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5265 tmp = gen_reg_rtx (Pmode);
5268 tlsreg = gen_rtx_REG (Pmode, 13);
5269 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5273 tlsreg = gen_rtx_REG (Pmode, 2);
5274 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5278 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5280 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5285 rtx r3, got, tga, tmp1, tmp2, eqv;
5287 /* We currently use relocations like @got@tlsgd for tls, which
5288 means the linker will handle allocation of tls entries, placing
5289 them in the .got section. So use a pointer to the .got section,
5290 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5291 or to secondary GOT sections used by 32-bit -fPIC. */
5293 got = gen_rtx_REG (Pmode, 2);
5297 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5300 rtx gsym = rs6000_got_sym ();
5301 got = gen_reg_rtx (Pmode);
5303 rs6000_emit_move (got, gsym, Pmode);
5309 tmp1 = gen_reg_rtx (Pmode);
5310 tmp2 = gen_reg_rtx (Pmode);
5311 tmp3 = gen_reg_rtx (Pmode);
5312 mem = gen_const_mem (Pmode, tmp1);
5314 first = emit_insn (gen_load_toc_v4_PIC_1b (gsym));
5315 emit_move_insn (tmp1,
5316 gen_rtx_REG (Pmode, LR_REGNO));
5317 emit_move_insn (tmp2, mem);
5318 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
5319 last = emit_move_insn (got, tmp3);
5320 set_unique_reg_note (last, REG_EQUAL, gsym);
5325 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5327 r3 = gen_rtx_REG (Pmode, 3);
5328 tga = rs6000_tls_get_addr ();
5330 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5331 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5332 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5333 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5334 else if (DEFAULT_ABI == ABI_V4)
5335 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5340 insn = emit_call_insn (insn);
5341 RTL_CONST_CALL_P (insn) = 1;
5342 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5343 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5344 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5345 insn = get_insns ();
5347 emit_libcall_block (insn, dest, r3, addr);
5349 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5351 r3 = gen_rtx_REG (Pmode, 3);
5352 tga = rs6000_tls_get_addr ();
5354 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5355 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5356 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5357 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5358 else if (DEFAULT_ABI == ABI_V4)
5359 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5364 insn = emit_call_insn (insn);
5365 RTL_CONST_CALL_P (insn) = 1;
5366 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5367 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5368 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5369 insn = get_insns ();
5371 tmp1 = gen_reg_rtx (Pmode);
5372 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
5374 emit_libcall_block (insn, tmp1, r3, eqv);
5375 if (rs6000_tls_size == 16)
5378 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5380 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5382 else if (rs6000_tls_size == 32)
5384 tmp2 = gen_reg_rtx (Pmode);
5386 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5388 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5391 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5393 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5397 tmp2 = gen_reg_rtx (Pmode);
5399 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5401 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5403 insn = gen_rtx_SET (Pmode, dest,
5404 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5410 /* IE, or 64-bit offset LE. */
5411 tmp2 = gen_reg_rtx (Pmode);
5413 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5415 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5418 insn = gen_tls_tls_64 (dest, tmp2, addr);
5420 insn = gen_tls_tls_32 (dest, tmp2, addr);
5428 /* Return 1 if X contains a thread-local symbol. */
5431 rs6000_tls_referenced_p (rtx x)
5433 if (! TARGET_HAVE_TLS)
5436 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5439 /* Return 1 if *X is a thread-local symbol. This is the same as
5440 rs6000_tls_symbol_ref except for the type of the unused argument. */
5443 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5445 return RS6000_SYMBOL_REF_TLS_P (*x);
5448 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5449 replace the input X, or the original X if no replacement is called for.
5450 The output parameter *WIN is 1 if the calling macro should goto WIN,
5453 For RS/6000, we wish to handle large displacements off a base
5454 register by splitting the addend across an addiu/addis and the mem insn.
5455 This cuts number of extra insns needed from 3 to 1.
5457 On Darwin, we use this to generate code for floating point constants.
5458 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5459 The Darwin code is inside #if TARGET_MACHO because only then are the
5460 machopic_* functions defined. */
5462 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5463 int opnum, int type,
5464 int ind_levels ATTRIBUTE_UNUSED, int *win)
5466 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5468 /* We must recognize output that we have already generated ourselves. */
5469 if (GET_CODE (x) == PLUS
5470 && GET_CODE (XEXP (x, 0)) == PLUS
5471 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5472 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5473 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5475 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5476 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5477 opnum, (enum reload_type)type);
5483 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5484 && GET_CODE (x) == LO_SUM
5485 && GET_CODE (XEXP (x, 0)) == PLUS
5486 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5487 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5488 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5489 && machopic_operand_p (XEXP (x, 1)))
5491 /* Result of previous invocation of this function on Darwin
5492 floating point constant. */
5493 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5494 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5495 opnum, (enum reload_type)type);
5501 /* Force ld/std non-word aligned offset into base register by wrapping
5503 if (GET_CODE (x) == PLUS
5504 && GET_CODE (XEXP (x, 0)) == REG
5505 && REGNO (XEXP (x, 0)) < 32
5506 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5507 && GET_CODE (XEXP (x, 1)) == CONST_INT
5509 && (INTVAL (XEXP (x, 1)) & 3) != 0
5510 && VECTOR_MEM_NONE_P (mode)
5511 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5512 && TARGET_POWERPC64)
5514 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5515 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5516 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5517 opnum, (enum reload_type) type);
5522 if (GET_CODE (x) == PLUS
5523 && GET_CODE (XEXP (x, 0)) == REG
5524 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5525 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5526 && GET_CODE (XEXP (x, 1)) == CONST_INT
5528 && !SPE_VECTOR_MODE (mode)
5529 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5530 || mode == DDmode || mode == TDmode
5532 && VECTOR_MEM_NONE_P (mode))
5534 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5535 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5537 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5539 /* Check for 32-bit overflow. */
5540 if (high + low != val)
5546 /* Reload the high part into a base reg; leave the low part
5547 in the mem directly. */
5549 x = gen_rtx_PLUS (GET_MODE (x),
5550 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5554 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5555 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5556 opnum, (enum reload_type)type);
5561 if (GET_CODE (x) == SYMBOL_REF
5563 && VECTOR_MEM_NONE_P (mode)
5564 && !SPE_VECTOR_MODE (mode)
5566 && DEFAULT_ABI == ABI_DARWIN
5567 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
5569 && DEFAULT_ABI == ABI_V4
5572 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
5573 The same goes for DImode without 64-bit gprs and DFmode and DDmode
5577 && (mode != DImode || TARGET_POWERPC64)
5578 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
5579 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
5584 rtx offset = machopic_gen_offset (x);
5585 x = gen_rtx_LO_SUM (GET_MODE (x),
5586 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
5587 gen_rtx_HIGH (Pmode, offset)), offset);
5591 x = gen_rtx_LO_SUM (GET_MODE (x),
5592 gen_rtx_HIGH (Pmode, x), x);
5594 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5595 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5596 opnum, (enum reload_type)type);
5601 /* Reload an offset address wrapped by an AND that represents the
5602 masking of the lower bits. Strip the outer AND and let reload
5603 convert the offset address into an indirect address. For VSX,
5604 force reload to create the address with an AND in a separate
5605 register, because we can't guarantee an altivec register will
5607 if (VECTOR_MEM_ALTIVEC_P (mode)
5608 && GET_CODE (x) == AND
5609 && GET_CODE (XEXP (x, 0)) == PLUS
5610 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5611 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5612 && GET_CODE (XEXP (x, 1)) == CONST_INT
5613 && INTVAL (XEXP (x, 1)) == -16)
5622 && GET_CODE (x) == SYMBOL_REF
5623 && constant_pool_expr_p (x)
5624 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
5626 x = create_TOC_reference (x);
5634 /* Debug version of rs6000_legitimize_reload_address. */
5636 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
5637 int opnum, int type,
5638 int ind_levels, int *win)
5640 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
5643 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
5644 "type = %d, ind_levels = %d, win = %d, original addr:\n",
5645 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
5649 fprintf (stderr, "Same address returned\n");
5651 fprintf (stderr, "NULL returned\n");
5654 fprintf (stderr, "New address:\n");
5661 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
5662 that is a valid memory address for an instruction.
5663 The MODE argument is the machine mode for the MEM expression
5664 that wants to use this address.
5666 On the RS/6000, there are four valid address: a SYMBOL_REF that
5667 refers to a constant pool entry of an address (or the sum of it
5668 plus a constant), a short (16-bit signed) constant plus a register,
5669 the sum of two registers, or a register indirect, possibly with an
5670 auto-increment. For DFmode, DDmode and DImode with a constant plus
5671 register, we must ensure that both words are addressable or PowerPC64
5672 with offset word aligned.
5674 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
5675 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
5676 because adjacent memory cells are accessed by adding word-sized offsets
5677 during assembly output. */
5679 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
5681 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5683 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
5684 if (VECTOR_MEM_ALTIVEC_P (mode)
5685 && GET_CODE (x) == AND
5686 && GET_CODE (XEXP (x, 1)) == CONST_INT
5687 && INTVAL (XEXP (x, 1)) == -16)
5690 if (RS6000_SYMBOL_REF_TLS_P (x))
5692 if (legitimate_indirect_address_p (x, reg_ok_strict))
5694 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
5695 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5696 && !SPE_VECTOR_MODE (mode)
5699 /* Restrict addressing for DI because of our SUBREG hackery. */
5700 && !(TARGET_E500_DOUBLE
5701 && (mode == DFmode || mode == DDmode || mode == DImode))
5703 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
5705 if (virtual_stack_registers_memory_p (x))
5707 if (reg_offset_p && legitimate_small_data_p (mode, x))
5709 if (reg_offset_p && legitimate_constant_pool_address_p (x))
5711 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
5714 && GET_CODE (x) == PLUS
5715 && GET_CODE (XEXP (x, 0)) == REG
5716 && (XEXP (x, 0) == virtual_stack_vars_rtx
5717 || XEXP (x, 0) == arg_pointer_rtx)
5718 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5720 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
5725 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5727 || (mode != DFmode && mode != DDmode)
5728 || (TARGET_E500_DOUBLE && mode != DDmode))
5729 && (TARGET_POWERPC64 || mode != DImode)
5730 && !avoiding_indexed_address_p (mode)
5731 && legitimate_indexed_address_p (x, reg_ok_strict))
5733 if (GET_CODE (x) == PRE_MODIFY
5737 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5739 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
5740 && (TARGET_POWERPC64 || mode != DImode)
5741 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5742 && !SPE_VECTOR_MODE (mode)
5743 /* Restrict addressing for DI because of our SUBREG hackery. */
5744 && !(TARGET_E500_DOUBLE
5745 && (mode == DFmode || mode == DDmode || mode == DImode))
5747 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
5748 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
5749 || (!avoiding_indexed_address_p (mode)
5750 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
5751 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5753 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
5758 /* Debug version of rs6000_legitimate_address_p. */
5760 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
5763 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
5765 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
5766 "strict = %d, code = %s\n",
5767 ret ? "true" : "false",
5768 GET_MODE_NAME (mode),
5770 GET_RTX_NAME (GET_CODE (x)));
5776 /* Go to LABEL if ADDR (a legitimate address expression)
5777 has an effect that depends on the machine mode it is used for.
5779 On the RS/6000 this is true of all integral offsets (since AltiVec
5780 and VSX modes don't allow them) or is a pre-increment or decrement.
5782 ??? Except that due to conceptual problems in offsettable_address_p
5783 we can't really report the problems of integral offsets. So leave
5784 this assuming that the adjustable offset must be valid for the
5785 sub-words of a TFmode operand, which is what we had before. */
5788 rs6000_mode_dependent_address (rtx addr)
5790 switch (GET_CODE (addr))
5793 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
5794 is considered a legitimate address before reload, so there
5795 are no offset restrictions in that case. Note that this
5796 condition is safe in strict mode because any address involving
5797 virtual_stack_vars_rtx or arg_pointer_rtx would already have
5798 been rejected as illegitimate. */
5799 if (XEXP (addr, 0) != virtual_stack_vars_rtx
5800 && XEXP (addr, 0) != arg_pointer_rtx
5801 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5803 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
5804 return val + 12 + 0x8000 >= 0x10000;
5811 /* Auto-increment cases are now treated generically in recog.c. */
5813 return TARGET_UPDATE;
5815 /* AND is only allowed in Altivec loads. */
5826 /* Debug version of rs6000_mode_dependent_address. */
5828 rs6000_debug_mode_dependent_address (rtx addr)
5830 bool ret = rs6000_mode_dependent_address (addr);
5832 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
5833 ret ? "true" : "false");
5839 /* Implement FIND_BASE_TERM. */
5842 rs6000_find_base_term (rtx op)
5846 split_const (op, &base, &offset);
5847 if (GET_CODE (base) == UNSPEC)
5848 switch (XINT (base, 1))
5851 case UNSPEC_MACHOPIC_OFFSET:
5852 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
5853 for aliasing purposes. */
5854 return XVECEXP (base, 0, 0);
5860 /* More elaborate version of recog's offsettable_memref_p predicate
5861 that works around the ??? note of rs6000_mode_dependent_address.
5862 In particular it accepts
5864 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
5866 in 32-bit mode, that the recog predicate rejects. */
5869 rs6000_offsettable_memref_p (rtx op)
5874 /* First mimic offsettable_memref_p. */
5875 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
5878 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
5879 the latter predicate knows nothing about the mode of the memory
5880 reference and, therefore, assumes that it is the largest supported
5881 mode (TFmode). As a consequence, legitimate offsettable memory
5882 references are rejected. rs6000_legitimate_offset_address_p contains
5883 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
5884 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
5887 /* Change register usage conditional on target flags. */
5889 rs6000_conditional_register_usage (void)
5893 /* Set MQ register fixed (already call_used) if not POWER
5894 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
5899 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
5901 fixed_regs[13] = call_used_regs[13]
5902 = call_really_used_regs[13] = 1;
5904 /* Conditionally disable FPRs. */
5905 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
5906 for (i = 32; i < 64; i++)
5907 fixed_regs[i] = call_used_regs[i]
5908 = call_really_used_regs[i] = 1;
5910 /* The TOC register is not killed across calls in a way that is
5911 visible to the compiler. */
5912 if (DEFAULT_ABI == ABI_AIX)
5913 call_really_used_regs[2] = 0;
5915 if (DEFAULT_ABI == ABI_V4
5916 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
5918 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5920 if (DEFAULT_ABI == ABI_V4
5921 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
5923 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5924 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5925 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5927 if (DEFAULT_ABI == ABI_DARWIN
5928 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
5929 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5930 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5931 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5933 if (TARGET_TOC && TARGET_MINIMAL_TOC)
5934 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5935 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5939 global_regs[SPEFSCR_REGNO] = 1;
5940 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
5941 registers in prologues and epilogues. We no longer use r14
5942 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
5943 pool for link-compatibility with older versions of GCC. Once
5944 "old" code has died out, we can return r14 to the allocation
5947 = call_used_regs[14]
5948 = call_really_used_regs[14] = 1;
5951 if (!TARGET_ALTIVEC && !TARGET_VSX)
5953 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
5954 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
5955 call_really_used_regs[VRSAVE_REGNO] = 1;
5958 if (TARGET_ALTIVEC || TARGET_VSX)
5959 global_regs[VSCR_REGNO] = 1;
5961 if (TARGET_ALTIVEC_ABI)
5963 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
5964 call_used_regs[i] = call_really_used_regs[i] = 1;
5966 /* AIX reserves VR20:31 in non-extended ABI mode. */
5968 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
5969 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
5973 /* Try to output insns to set TARGET equal to the constant C if it can
5974 be done in less than N insns. Do all computations in MODE.
5975 Returns the place where the output has been placed if it can be
5976 done and the insns have been emitted. If it would take more than N
5977 insns, zero is returned and no insns and emitted. */
5980 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
5981 rtx source, int n ATTRIBUTE_UNUSED)
5983 rtx result, insn, set;
5984 HOST_WIDE_INT c0, c1;
5991 dest = gen_reg_rtx (mode);
5992 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
5996 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
5998 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
5999 GEN_INT (INTVAL (source)
6000 & (~ (HOST_WIDE_INT) 0xffff))));
6001 emit_insn (gen_rtx_SET (VOIDmode, dest,
6002 gen_rtx_IOR (SImode, copy_rtx (result),
6003 GEN_INT (INTVAL (source) & 0xffff))));
6008 switch (GET_CODE (source))
6011 c0 = INTVAL (source);
6016 #if HOST_BITS_PER_WIDE_INT >= 64
6017 c0 = CONST_DOUBLE_LOW (source);
6020 c0 = CONST_DOUBLE_LOW (source);
6021 c1 = CONST_DOUBLE_HIGH (source);
6029 result = rs6000_emit_set_long_const (dest, c0, c1);
6036 insn = get_last_insn ();
6037 set = single_set (insn);
6038 if (! CONSTANT_P (SET_SRC (set)))
6039 set_unique_reg_note (insn, REG_EQUAL, source);
6044 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6045 fall back to a straight forward decomposition. We do this to avoid
6046 exponential run times encountered when looking for longer sequences
6047 with rs6000_emit_set_const. */
6049 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6051 if (!TARGET_POWERPC64)
6053 rtx operand1, operand2;
6055 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6057 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6059 emit_move_insn (operand1, GEN_INT (c1));
6060 emit_move_insn (operand2, GEN_INT (c2));
6064 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6067 ud2 = (c1 & 0xffff0000) >> 16;
6068 #if HOST_BITS_PER_WIDE_INT >= 64
6072 ud4 = (c2 & 0xffff0000) >> 16;
6074 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6075 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6078 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6080 emit_move_insn (dest, GEN_INT (ud1));
6083 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6084 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6087 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6090 emit_move_insn (dest, GEN_INT (ud2 << 16));
6092 emit_move_insn (copy_rtx (dest),
6093 gen_rtx_IOR (DImode, copy_rtx (dest),
6096 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6097 || (ud4 == 0 && ! (ud3 & 0x8000)))
6100 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6103 emit_move_insn (dest, GEN_INT (ud3 << 16));
6106 emit_move_insn (copy_rtx (dest),
6107 gen_rtx_IOR (DImode, copy_rtx (dest),
6109 emit_move_insn (copy_rtx (dest),
6110 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6113 emit_move_insn (copy_rtx (dest),
6114 gen_rtx_IOR (DImode, copy_rtx (dest),
6120 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6123 emit_move_insn (dest, GEN_INT (ud4 << 16));
6126 emit_move_insn (copy_rtx (dest),
6127 gen_rtx_IOR (DImode, copy_rtx (dest),
6130 emit_move_insn (copy_rtx (dest),
6131 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6134 emit_move_insn (copy_rtx (dest),
6135 gen_rtx_IOR (DImode, copy_rtx (dest),
6136 GEN_INT (ud2 << 16)));
6138 emit_move_insn (copy_rtx (dest),
6139 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6145 /* Helper for the following. Get rid of [r+r] memory refs
6146 in cases where it won't work (TImode, TFmode, TDmode). */
6149 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6151 if (GET_CODE (operands[0]) == MEM
6152 && GET_CODE (XEXP (operands[0], 0)) != REG
6153 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
6154 && ! reload_in_progress)
6156 = replace_equiv_address (operands[0],
6157 copy_addr_to_reg (XEXP (operands[0], 0)));
6159 if (GET_CODE (operands[1]) == MEM
6160 && GET_CODE (XEXP (operands[1], 0)) != REG
6161 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
6162 && ! reload_in_progress)
6164 = replace_equiv_address (operands[1],
6165 copy_addr_to_reg (XEXP (operands[1], 0)));
6168 /* Emit a move from SOURCE to DEST in mode MODE. */
6170 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6174 operands[1] = source;
6176 if (TARGET_DEBUG_ADDR)
6179 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6180 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6181 GET_MODE_NAME (mode),
6184 can_create_pseudo_p ());
6186 fprintf (stderr, "source:\n");
6190 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6191 if (GET_CODE (operands[1]) == CONST_DOUBLE
6192 && ! FLOAT_MODE_P (mode)
6193 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6195 /* FIXME. This should never happen. */
6196 /* Since it seems that it does, do the safe thing and convert
6198 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6200 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6201 || FLOAT_MODE_P (mode)
6202 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6203 || CONST_DOUBLE_LOW (operands[1]) < 0)
6204 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6205 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6207 /* Check if GCC is setting up a block move that will end up using FP
6208 registers as temporaries. We must make sure this is acceptable. */
6209 if (GET_CODE (operands[0]) == MEM
6210 && GET_CODE (operands[1]) == MEM
6212 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6213 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6214 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6215 ? 32 : MEM_ALIGN (operands[0])))
6216 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6218 : MEM_ALIGN (operands[1]))))
6219 && ! MEM_VOLATILE_P (operands [0])
6220 && ! MEM_VOLATILE_P (operands [1]))
6222 emit_move_insn (adjust_address (operands[0], SImode, 0),
6223 adjust_address (operands[1], SImode, 0));
6224 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6225 adjust_address (copy_rtx (operands[1]), SImode, 4));
6229 /* Fix up invalid (const (plus (symbol_ref) (reg))) that seems to be created
6230 in the secondary_reload phase, which evidently overwrites the CONST_INT
6232 if (GET_CODE (source) == CONST && GET_CODE (XEXP (source, 0)) == PLUS
6235 rtx add_op0 = XEXP (XEXP (source, 0), 0);
6236 rtx add_op1 = XEXP (XEXP (source, 0), 1);
6238 if (GET_CODE (add_op0) == SYMBOL_REF && GET_CODE (add_op1) == REG)
6240 rtx tmp = (can_create_pseudo_p ()) ? gen_reg_rtx (Pmode) : dest;
6242 if (TARGET_DEBUG_ADDR)
6244 fprintf (stderr, "\nrs6000_emit_move: bad source\n");
6248 rs6000_emit_move (tmp, add_op0, Pmode);
6249 emit_insn (gen_rtx_SET (VOIDmode, dest,
6250 gen_rtx_PLUS (Pmode, tmp, add_op1)));
6255 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6256 && !gpc_reg_operand (operands[1], mode))
6257 operands[1] = force_reg (mode, operands[1]);
6259 if (mode == SFmode && ! TARGET_POWERPC
6260 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6261 && GET_CODE (operands[0]) == MEM)
6265 if (reload_in_progress || reload_completed)
6266 regnum = true_regnum (operands[1]);
6267 else if (GET_CODE (operands[1]) == REG)
6268 regnum = REGNO (operands[1]);
6272 /* If operands[1] is a register, on POWER it may have
6273 double-precision data in it, so truncate it to single
6275 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6278 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6279 : gen_reg_rtx (mode));
6280 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6281 operands[1] = newreg;
6285 /* Recognize the case where operand[1] is a reference to thread-local
6286 data and load its address to a register. */
6287 if (rs6000_tls_referenced_p (operands[1]))
6289 enum tls_model model;
6290 rtx tmp = operands[1];
6293 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6295 addend = XEXP (XEXP (tmp, 0), 1);
6296 tmp = XEXP (XEXP (tmp, 0), 0);
6299 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6300 model = SYMBOL_REF_TLS_MODEL (tmp);
6301 gcc_assert (model != 0);
6303 tmp = rs6000_legitimize_tls_address (tmp, model);
6306 tmp = gen_rtx_PLUS (mode, tmp, addend);
6307 tmp = force_operand (tmp, operands[0]);
6312 /* Handle the case where reload calls us with an invalid address. */
6313 if (reload_in_progress && mode == Pmode
6314 && (! general_operand (operands[1], mode)
6315 || ! nonimmediate_operand (operands[0], mode)))
6318 /* 128-bit constant floating-point values on Darwin should really be
6319 loaded as two parts. */
6320 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6321 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6323 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6324 know how to get a DFmode SUBREG of a TFmode. */
6325 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6326 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6327 simplify_gen_subreg (imode, operands[1], mode, 0),
6329 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6330 GET_MODE_SIZE (imode)),
6331 simplify_gen_subreg (imode, operands[1], mode,
6332 GET_MODE_SIZE (imode)),
6337 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6338 cfun->machine->sdmode_stack_slot =
6339 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6341 if (reload_in_progress
6343 && MEM_P (operands[0])
6344 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6345 && REG_P (operands[1]))
6347 if (FP_REGNO_P (REGNO (operands[1])))
6349 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6350 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6351 emit_insn (gen_movsd_store (mem, operands[1]));
6353 else if (INT_REGNO_P (REGNO (operands[1])))
6355 rtx mem = adjust_address_nv (operands[0], mode, 4);
6356 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6357 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6363 if (reload_in_progress
6365 && REG_P (operands[0])
6366 && MEM_P (operands[1])
6367 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6369 if (FP_REGNO_P (REGNO (operands[0])))
6371 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6372 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6373 emit_insn (gen_movsd_load (operands[0], mem));
6375 else if (INT_REGNO_P (REGNO (operands[0])))
6377 rtx mem = adjust_address_nv (operands[1], mode, 4);
6378 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6379 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6386 /* FIXME: In the long term, this switch statement should go away
6387 and be replaced by a sequence of tests based on things like
6393 if (CONSTANT_P (operands[1])
6394 && GET_CODE (operands[1]) != CONST_INT)
6395 operands[1] = force_const_mem (mode, operands[1]);
6400 rs6000_eliminate_indexed_memrefs (operands);
6407 if (CONSTANT_P (operands[1])
6408 && ! easy_fp_constant (operands[1], mode))
6409 operands[1] = force_const_mem (mode, operands[1]);
6422 if (CONSTANT_P (operands[1])
6423 && !easy_vector_constant (operands[1], mode))
6424 operands[1] = force_const_mem (mode, operands[1]);
6429 /* Use default pattern for address of ELF small data */
6432 && DEFAULT_ABI == ABI_V4
6433 && (GET_CODE (operands[1]) == SYMBOL_REF
6434 || GET_CODE (operands[1]) == CONST)
6435 && small_data_operand (operands[1], mode))
6437 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6441 if (DEFAULT_ABI == ABI_V4
6442 && mode == Pmode && mode == SImode
6443 && flag_pic == 1 && got_operand (operands[1], mode))
6445 emit_insn (gen_movsi_got (operands[0], operands[1]));
6449 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6453 && CONSTANT_P (operands[1])
6454 && GET_CODE (operands[1]) != HIGH
6455 && GET_CODE (operands[1]) != CONST_INT)
6457 rtx target = (!can_create_pseudo_p ()
6459 : gen_reg_rtx (mode));
6461 /* If this is a function address on -mcall-aixdesc,
6462 convert it to the address of the descriptor. */
6463 if (DEFAULT_ABI == ABI_AIX
6464 && GET_CODE (operands[1]) == SYMBOL_REF
6465 && XSTR (operands[1], 0)[0] == '.')
6467 const char *name = XSTR (operands[1], 0);
6469 while (*name == '.')
6471 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6472 CONSTANT_POOL_ADDRESS_P (new_ref)
6473 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6474 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6475 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6476 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6477 operands[1] = new_ref;
6480 if (DEFAULT_ABI == ABI_DARWIN)
6483 if (MACHO_DYNAMIC_NO_PIC_P)
6485 /* Take care of any required data indirection. */
6486 operands[1] = rs6000_machopic_legitimize_pic_address (
6487 operands[1], mode, operands[0]);
6488 if (operands[0] != operands[1])
6489 emit_insn (gen_rtx_SET (VOIDmode,
6490 operands[0], operands[1]));
6494 emit_insn (gen_macho_high (target, operands[1]));
6495 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6499 emit_insn (gen_elf_high (target, operands[1]));
6500 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6504 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6505 and we have put it in the TOC, we just need to make a TOC-relative
6508 && GET_CODE (operands[1]) == SYMBOL_REF
6509 && constant_pool_expr_p (operands[1])
6510 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6511 get_pool_mode (operands[1])))
6513 operands[1] = create_TOC_reference (operands[1]);
6515 else if (mode == Pmode
6516 && CONSTANT_P (operands[1])
6517 && ((GET_CODE (operands[1]) != CONST_INT
6518 && ! easy_fp_constant (operands[1], mode))
6519 || (GET_CODE (operands[1]) == CONST_INT
6520 && num_insns_constant (operands[1], mode) > 2)
6521 || (GET_CODE (operands[0]) == REG
6522 && FP_REGNO_P (REGNO (operands[0]))))
6523 && GET_CODE (operands[1]) != HIGH
6524 && ! legitimate_constant_pool_address_p (operands[1])
6525 && ! toc_relative_expr_p (operands[1]))
6529 /* Darwin uses a special PIC legitimizer. */
6530 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
6533 rs6000_machopic_legitimize_pic_address (operands[1], mode,
6535 if (operands[0] != operands[1])
6536 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6541 /* If we are to limit the number of things we put in the TOC and
6542 this is a symbol plus a constant we can add in one insn,
6543 just put the symbol in the TOC and add the constant. Don't do
6544 this if reload is in progress. */
6545 if (GET_CODE (operands[1]) == CONST
6546 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
6547 && GET_CODE (XEXP (operands[1], 0)) == PLUS
6548 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
6549 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
6550 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
6551 && ! side_effects_p (operands[0]))
6554 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
6555 rtx other = XEXP (XEXP (operands[1], 0), 1);
6557 sym = force_reg (mode, sym);
6558 emit_insn (gen_add3_insn (operands[0], sym, other));
6562 operands[1] = force_const_mem (mode, operands[1]);
6565 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6566 && constant_pool_expr_p (XEXP (operands[1], 0))
6567 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
6568 get_pool_constant (XEXP (operands[1], 0)),
6569 get_pool_mode (XEXP (operands[1], 0))))
6572 = gen_const_mem (mode,
6573 create_TOC_reference (XEXP (operands[1], 0)));
6574 set_mem_alias_set (operands[1], get_TOC_alias_set ());
6580 rs6000_eliminate_indexed_memrefs (operands);
6584 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6586 gen_rtx_SET (VOIDmode,
6587 operands[0], operands[1]),
6588 gen_rtx_CLOBBER (VOIDmode,
6589 gen_rtx_SCRATCH (SImode)))));
6595 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
6598 /* Above, we may have called force_const_mem which may have returned
6599 an invalid address. If we can, fix this up; otherwise, reload will
6600 have to deal with it. */
6601 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
6602 operands[1] = validize_mem (operands[1]);
6605 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6608 /* Nonzero if we can use a floating-point register to pass this arg. */
6609 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
6610 (SCALAR_FLOAT_MODE_P (MODE) \
6611 && (CUM)->fregno <= FP_ARG_MAX_REG \
6612 && TARGET_HARD_FLOAT && TARGET_FPRS)
6614 /* Nonzero if we can use an AltiVec register to pass this arg. */
6615 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
6616 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
6617 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
6618 && TARGET_ALTIVEC_ABI \
6621 /* Return a nonzero value to say to return the function value in
6622 memory, just as large structures are always returned. TYPE will be
6623 the data type of the value, and FNTYPE will be the type of the
6624 function doing the returning, or @code{NULL} for libcalls.
6626 The AIX ABI for the RS/6000 specifies that all structures are
6627 returned in memory. The Darwin ABI does the same. The SVR4 ABI
6628 specifies that structures <= 8 bytes are returned in r3/r4, but a
6629 draft put them in memory, and GCC used to implement the draft
6630 instead of the final standard. Therefore, aix_struct_return
6631 controls this instead of DEFAULT_ABI; V.4 targets needing backward
6632 compatibility can change DRAFT_V4_STRUCT_RET to override the
6633 default, and -m switches get the final word. See
6634 rs6000_override_options for more details.
6636 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
6637 long double support is enabled. These values are returned in memory.
6639 int_size_in_bytes returns -1 for variable size objects, which go in
6640 memory always. The cast to unsigned makes -1 > 8. */
6643 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6645 /* In the darwin64 abi, try to use registers for larger structs
6647 if (rs6000_darwin64_abi
6648 && TREE_CODE (type) == RECORD_TYPE
6649 && int_size_in_bytes (type) > 0)
6651 CUMULATIVE_ARGS valcum;
6655 valcum.fregno = FP_ARG_MIN_REG;
6656 valcum.vregno = ALTIVEC_ARG_MIN_REG;
6657 /* Do a trial code generation as if this were going to be passed
6658 as an argument; if any part goes in memory, we return NULL. */
6659 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
6662 /* Otherwise fall through to more conventional ABI rules. */
6665 if (AGGREGATE_TYPE_P (type)
6666 && (aix_struct_return
6667 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
6670 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6671 modes only exist for GCC vector types if -maltivec. */
6672 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
6673 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6676 /* Return synthetic vectors in memory. */
6677 if (TREE_CODE (type) == VECTOR_TYPE
6678 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
6680 static bool warned_for_return_big_vectors = false;
6681 if (!warned_for_return_big_vectors)
6683 warning (0, "GCC vector returned by reference: "
6684 "non-standard ABI extension with no compatibility guarantee");
6685 warned_for_return_big_vectors = true;
6690 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
6696 /* Initialize a variable CUM of type CUMULATIVE_ARGS
6697 for a call to a function whose data type is FNTYPE.
6698 For a library call, FNTYPE is 0.
6700 For incoming args we set the number of arguments in the prototype large
6701 so we never return a PARALLEL. */
6704 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
6705 rtx libname ATTRIBUTE_UNUSED, int incoming,
6706 int libcall, int n_named_args)
6708 static CUMULATIVE_ARGS zero_cumulative;
6710 *cum = zero_cumulative;
6712 cum->fregno = FP_ARG_MIN_REG;
6713 cum->vregno = ALTIVEC_ARG_MIN_REG;
6714 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
6715 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
6716 ? CALL_LIBCALL : CALL_NORMAL);
6717 cum->sysv_gregno = GP_ARG_MIN_REG;
6718 cum->stdarg = fntype
6719 && (TYPE_ARG_TYPES (fntype) != 0
6720 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
6721 != void_type_node));
6723 cum->nargs_prototype = 0;
6724 if (incoming || cum->prototype)
6725 cum->nargs_prototype = n_named_args;
6727 /* Check for a longcall attribute. */
6728 if ((!fntype && rs6000_default_long_calls)
6730 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
6731 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
6732 cum->call_cookie |= CALL_LONG;
6734 if (TARGET_DEBUG_ARG)
6736 fprintf (stderr, "\ninit_cumulative_args:");
6739 tree ret_type = TREE_TYPE (fntype);
6740 fprintf (stderr, " ret code = %s,",
6741 tree_code_name[ (int)TREE_CODE (ret_type) ]);
6744 if (cum->call_cookie & CALL_LONG)
6745 fprintf (stderr, " longcall,");
6747 fprintf (stderr, " proto = %d, nargs = %d\n",
6748 cum->prototype, cum->nargs_prototype);
6753 && TARGET_ALTIVEC_ABI
6754 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
6756 error ("cannot return value in vector register because"
6757 " altivec instructions are disabled, use -maltivec"
6762 /* Return true if TYPE must be passed on the stack and not in registers. */
6765 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
6767 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
6768 return must_pass_in_stack_var_size (mode, type);
6770 return must_pass_in_stack_var_size_or_pad (mode, type);
6773 /* If defined, a C expression which determines whether, and in which
6774 direction, to pad out an argument with extra space. The value
6775 should be of type `enum direction': either `upward' to pad above
6776 the argument, `downward' to pad below, or `none' to inhibit
6779 For the AIX ABI structs are always stored left shifted in their
6783 function_arg_padding (enum machine_mode mode, const_tree type)
6785 #ifndef AGGREGATE_PADDING_FIXED
6786 #define AGGREGATE_PADDING_FIXED 0
6788 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
6789 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
6792 if (!AGGREGATE_PADDING_FIXED)
6794 /* GCC used to pass structures of the same size as integer types as
6795 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
6796 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6797 passed padded downward, except that -mstrict-align further
6798 muddied the water in that multi-component structures of 2 and 4
6799 bytes in size were passed padded upward.
6801 The following arranges for best compatibility with previous
6802 versions of gcc, but removes the -mstrict-align dependency. */
6803 if (BYTES_BIG_ENDIAN)
6805 HOST_WIDE_INT size = 0;
6807 if (mode == BLKmode)
6809 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
6810 size = int_size_in_bytes (type);
6813 size = GET_MODE_SIZE (mode);
6815 if (size == 1 || size == 2 || size == 4)
6821 if (AGGREGATES_PAD_UPWARD_ALWAYS)
6823 if (type != 0 && AGGREGATE_TYPE_P (type))
6827 /* Fall back to the default. */
6828 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
6831 /* If defined, a C expression that gives the alignment boundary, in bits,
6832 of an argument with the specified mode and type. If it is not defined,
6833 PARM_BOUNDARY is used for all arguments.
6835 V.4 wants long longs and doubles to be double word aligned. Just
6836 testing the mode size is a boneheaded way to do this as it means
6837 that other types such as complex int are also double word aligned.
6838 However, we're stuck with this because changing the ABI might break
6839 existing library interfaces.
6841 Doubleword align SPE vectors.
6842 Quadword align Altivec vectors.
6843 Quadword align large synthetic vector types. */
6846 function_arg_boundary (enum machine_mode mode, tree type)
6848 if (DEFAULT_ABI == ABI_V4
6849 && (GET_MODE_SIZE (mode) == 8
6850 || (TARGET_HARD_FLOAT
6852 && (mode == TFmode || mode == TDmode))))
6854 else if (SPE_VECTOR_MODE (mode)
6855 || (type && TREE_CODE (type) == VECTOR_TYPE
6856 && int_size_in_bytes (type) >= 8
6857 && int_size_in_bytes (type) < 16))
6859 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
6860 || (type && TREE_CODE (type) == VECTOR_TYPE
6861 && int_size_in_bytes (type) >= 16))
6863 else if (rs6000_darwin64_abi && mode == BLKmode
6864 && type && TYPE_ALIGN (type) > 64)
6867 return PARM_BOUNDARY;
6870 /* For a function parm of MODE and TYPE, return the starting word in
6871 the parameter area. NWORDS of the parameter area are already used. */
6874 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
6877 unsigned int parm_offset;
6879 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
6880 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
6881 return nwords + (-(parm_offset + nwords) & align);
6884 /* Compute the size (in words) of a function argument. */
6886 static unsigned long
6887 rs6000_arg_size (enum machine_mode mode, tree type)
6891 if (mode != BLKmode)
6892 size = GET_MODE_SIZE (mode);
6894 size = int_size_in_bytes (type);
6897 return (size + 3) >> 2;
6899 return (size + 7) >> 3;
6902 /* Use this to flush pending int fields. */
6905 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
6906 HOST_WIDE_INT bitpos)
6908 unsigned int startbit, endbit;
6909 int intregs, intoffset;
6910 enum machine_mode mode;
6912 if (cum->intoffset == -1)
6915 intoffset = cum->intoffset;
6916 cum->intoffset = -1;
6918 if (intoffset % BITS_PER_WORD != 0)
6920 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
6922 if (mode == BLKmode)
6924 /* We couldn't find an appropriate mode, which happens,
6925 e.g., in packed structs when there are 3 bytes to load.
6926 Back intoffset back to the beginning of the word in this
6928 intoffset = intoffset & -BITS_PER_WORD;
6932 startbit = intoffset & -BITS_PER_WORD;
6933 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
6934 intregs = (endbit - startbit) / BITS_PER_WORD;
6935 cum->words += intregs;
6938 /* The darwin64 ABI calls for us to recurse down through structs,
6939 looking for elements passed in registers. Unfortunately, we have
6940 to track int register count here also because of misalignments
6941 in powerpc alignment mode. */
6944 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
6946 HOST_WIDE_INT startbitpos)
6950 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
6951 if (TREE_CODE (f) == FIELD_DECL)
6953 HOST_WIDE_INT bitpos = startbitpos;
6954 tree ftype = TREE_TYPE (f);
6955 enum machine_mode mode;
6956 if (ftype == error_mark_node)
6958 mode = TYPE_MODE (ftype);
6960 if (DECL_SIZE (f) != 0
6961 && host_integerp (bit_position (f), 1))
6962 bitpos += int_bit_position (f);
6964 /* ??? FIXME: else assume zero offset. */
6966 if (TREE_CODE (ftype) == RECORD_TYPE)
6967 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
6968 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
6970 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
6971 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
6972 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
6974 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
6976 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
6980 else if (cum->intoffset == -1)
6981 cum->intoffset = bitpos;
6985 /* Update the data in CUM to advance over an argument
6986 of mode MODE and data type TYPE.
6987 (TYPE is null for libcalls where that information may not be available.)
6989 Note that for args passed by reference, function_arg will be called
6990 with MODE and TYPE set to that of the pointer to the arg, not the arg
6994 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
6995 tree type, int named, int depth)
6999 /* Only tick off an argument if we're not recursing. */
7001 cum->nargs_prototype--;
7003 if (TARGET_ALTIVEC_ABI
7004 && (ALTIVEC_VECTOR_MODE (mode)
7005 || VSX_VECTOR_MODE (mode)
7006 || (type && TREE_CODE (type) == VECTOR_TYPE
7007 && int_size_in_bytes (type) == 16)))
7011 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7014 if (!TARGET_ALTIVEC)
7015 error ("cannot pass argument in vector register because"
7016 " altivec instructions are disabled, use -maltivec"
7019 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7020 even if it is going to be passed in a vector register.
7021 Darwin does the same for variable-argument functions. */
7022 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7023 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7033 /* Vector parameters must be 16-byte aligned. This places
7034 them at 2 mod 4 in terms of words in 32-bit mode, since
7035 the parameter save area starts at offset 24 from the
7036 stack. In 64-bit mode, they just have to start on an
7037 even word, since the parameter save area is 16-byte
7038 aligned. Space for GPRs is reserved even if the argument
7039 will be passed in memory. */
7041 align = (2 - cum->words) & 3;
7043 align = cum->words & 1;
7044 cum->words += align + rs6000_arg_size (mode, type);
7046 if (TARGET_DEBUG_ARG)
7048 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7050 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7051 cum->nargs_prototype, cum->prototype,
7052 GET_MODE_NAME (mode));
7056 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7058 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7061 else if (rs6000_darwin64_abi
7063 && TREE_CODE (type) == RECORD_TYPE
7064 && (size = int_size_in_bytes (type)) > 0)
7066 /* Variable sized types have size == -1 and are
7067 treated as if consisting entirely of ints.
7068 Pad to 16 byte boundary if needed. */
7069 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7070 && (cum->words % 2) != 0)
7072 /* For varargs, we can just go up by the size of the struct. */
7074 cum->words += (size + 7) / 8;
7077 /* It is tempting to say int register count just goes up by
7078 sizeof(type)/8, but this is wrong in a case such as
7079 { int; double; int; } [powerpc alignment]. We have to
7080 grovel through the fields for these too. */
7082 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7083 rs6000_darwin64_record_arg_advance_flush (cum,
7084 size * BITS_PER_UNIT);
7087 else if (DEFAULT_ABI == ABI_V4)
7089 if (TARGET_HARD_FLOAT && TARGET_FPRS
7090 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7091 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7092 || (mode == TFmode && !TARGET_IEEEQUAD)
7093 || mode == SDmode || mode == DDmode || mode == TDmode))
7095 /* _Decimal128 must use an even/odd register pair. This assumes
7096 that the register number is odd when fregno is odd. */
7097 if (mode == TDmode && (cum->fregno % 2) == 1)
7100 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7101 <= FP_ARG_V4_MAX_REG)
7102 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7105 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7106 if (mode == DFmode || mode == TFmode
7107 || mode == DDmode || mode == TDmode)
7108 cum->words += cum->words & 1;
7109 cum->words += rs6000_arg_size (mode, type);
7114 int n_words = rs6000_arg_size (mode, type);
7115 int gregno = cum->sysv_gregno;
7117 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7118 (r7,r8) or (r9,r10). As does any other 2 word item such
7119 as complex int due to a historical mistake. */
7121 gregno += (1 - gregno) & 1;
7123 /* Multi-reg args are not split between registers and stack. */
7124 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7126 /* Long long and SPE vectors are aligned on the stack.
7127 So are other 2 word items such as complex int due to
7128 a historical mistake. */
7130 cum->words += cum->words & 1;
7131 cum->words += n_words;
7134 /* Note: continuing to accumulate gregno past when we've started
7135 spilling to the stack indicates the fact that we've started
7136 spilling to the stack to expand_builtin_saveregs. */
7137 cum->sysv_gregno = gregno + n_words;
7140 if (TARGET_DEBUG_ARG)
7142 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7143 cum->words, cum->fregno);
7144 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7145 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7146 fprintf (stderr, "mode = %4s, named = %d\n",
7147 GET_MODE_NAME (mode), named);
7152 int n_words = rs6000_arg_size (mode, type);
7153 int start_words = cum->words;
7154 int align_words = rs6000_parm_start (mode, type, start_words);
7156 cum->words = align_words + n_words;
7158 if (SCALAR_FLOAT_MODE_P (mode)
7159 && TARGET_HARD_FLOAT && TARGET_FPRS)
7161 /* _Decimal128 must be passed in an even/odd float register pair.
7162 This assumes that the register number is odd when fregno is
7164 if (mode == TDmode && (cum->fregno % 2) == 1)
7166 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7169 if (TARGET_DEBUG_ARG)
7171 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7172 cum->words, cum->fregno);
7173 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7174 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7175 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7176 named, align_words - start_words, depth);
7182 spe_build_register_parallel (enum machine_mode mode, int gregno)
7189 r1 = gen_rtx_REG (DImode, gregno);
7190 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7191 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7195 r1 = gen_rtx_REG (DImode, gregno);
7196 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7197 r3 = gen_rtx_REG (DImode, gregno + 2);
7198 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7199 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7202 r1 = gen_rtx_REG (DImode, gregno);
7203 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7204 r3 = gen_rtx_REG (DImode, gregno + 2);
7205 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7206 r5 = gen_rtx_REG (DImode, gregno + 4);
7207 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7208 r7 = gen_rtx_REG (DImode, gregno + 6);
7209 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7210 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7217 /* Determine where to put a SIMD argument on the SPE. */
7219 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7222 int gregno = cum->sysv_gregno;
7224 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7225 are passed and returned in a pair of GPRs for ABI compatibility. */
7226 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7227 || mode == DCmode || mode == TCmode))
7229 int n_words = rs6000_arg_size (mode, type);
7231 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7233 gregno += (1 - gregno) & 1;
7235 /* Multi-reg args are not split between registers and stack. */
7236 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7239 return spe_build_register_parallel (mode, gregno);
7243 int n_words = rs6000_arg_size (mode, type);
7245 /* SPE vectors are put in odd registers. */
7246 if (n_words == 2 && (gregno & 1) == 0)
7249 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7252 enum machine_mode m = SImode;
7254 r1 = gen_rtx_REG (m, gregno);
7255 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7256 r2 = gen_rtx_REG (m, gregno + 1);
7257 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7258 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7265 if (gregno <= GP_ARG_MAX_REG)
7266 return gen_rtx_REG (mode, gregno);
7272 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7273 structure between cum->intoffset and bitpos to integer registers. */
7276 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7277 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7279 enum machine_mode mode;
7281 unsigned int startbit, endbit;
7282 int this_regno, intregs, intoffset;
7285 if (cum->intoffset == -1)
7288 intoffset = cum->intoffset;
7289 cum->intoffset = -1;
7291 /* If this is the trailing part of a word, try to only load that
7292 much into the register. Otherwise load the whole register. Note
7293 that in the latter case we may pick up unwanted bits. It's not a
7294 problem at the moment but may wish to revisit. */
7296 if (intoffset % BITS_PER_WORD != 0)
7298 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7300 if (mode == BLKmode)
7302 /* We couldn't find an appropriate mode, which happens,
7303 e.g., in packed structs when there are 3 bytes to load.
7304 Back intoffset back to the beginning of the word in this
7306 intoffset = intoffset & -BITS_PER_WORD;
7313 startbit = intoffset & -BITS_PER_WORD;
7314 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7315 intregs = (endbit - startbit) / BITS_PER_WORD;
7316 this_regno = cum->words + intoffset / BITS_PER_WORD;
7318 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7321 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7325 intoffset /= BITS_PER_UNIT;
7328 regno = GP_ARG_MIN_REG + this_regno;
7329 reg = gen_rtx_REG (mode, regno);
7331 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7334 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7338 while (intregs > 0);
7341 /* Recursive workhorse for the following. */
7344 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7345 HOST_WIDE_INT startbitpos, rtx rvec[],
7350 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7351 if (TREE_CODE (f) == FIELD_DECL)
7353 HOST_WIDE_INT bitpos = startbitpos;
7354 tree ftype = TREE_TYPE (f);
7355 enum machine_mode mode;
7356 if (ftype == error_mark_node)
7358 mode = TYPE_MODE (ftype);
7360 if (DECL_SIZE (f) != 0
7361 && host_integerp (bit_position (f), 1))
7362 bitpos += int_bit_position (f);
7364 /* ??? FIXME: else assume zero offset. */
7366 if (TREE_CODE (ftype) == RECORD_TYPE)
7367 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7368 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7373 case SCmode: mode = SFmode; break;
7374 case DCmode: mode = DFmode; break;
7375 case TCmode: mode = TFmode; break;
7379 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7381 = gen_rtx_EXPR_LIST (VOIDmode,
7382 gen_rtx_REG (mode, cum->fregno++),
7383 GEN_INT (bitpos / BITS_PER_UNIT));
7384 if (mode == TFmode || mode == TDmode)
7387 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7389 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7391 = gen_rtx_EXPR_LIST (VOIDmode,
7392 gen_rtx_REG (mode, cum->vregno++),
7393 GEN_INT (bitpos / BITS_PER_UNIT));
7395 else if (cum->intoffset == -1)
7396 cum->intoffset = bitpos;
7400 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7401 the register(s) to be used for each field and subfield of a struct
7402 being passed by value, along with the offset of where the
7403 register's value may be found in the block. FP fields go in FP
7404 register, vector fields go in vector registers, and everything
7405 else goes in int registers, packed as in memory.
7407 This code is also used for function return values. RETVAL indicates
7408 whether this is the case.
7410 Much of this is taken from the SPARC V9 port, which has a similar
7411 calling convention. */
7414 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7415 int named, bool retval)
7417 rtx rvec[FIRST_PSEUDO_REGISTER];
7418 int k = 1, kbase = 1;
7419 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7420 /* This is a copy; modifications are not visible to our caller. */
7421 CUMULATIVE_ARGS copy_cum = *orig_cum;
7422 CUMULATIVE_ARGS *cum = ©_cum;
7424 /* Pad to 16 byte boundary if needed. */
7425 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7426 && (cum->words % 2) != 0)
7433 /* Put entries into rvec[] for individual FP and vector fields, and
7434 for the chunks of memory that go in int regs. Note we start at
7435 element 1; 0 is reserved for an indication of using memory, and
7436 may or may not be filled in below. */
7437 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7438 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7440 /* If any part of the struct went on the stack put all of it there.
7441 This hack is because the generic code for
7442 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7443 parts of the struct are not at the beginning. */
7447 return NULL_RTX; /* doesn't go in registers at all */
7449 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7451 if (k > 1 || cum->use_stack)
7452 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7457 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7460 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7464 rtx rvec[GP_ARG_NUM_REG + 1];
7466 if (align_words >= GP_ARG_NUM_REG)
7469 n_units = rs6000_arg_size (mode, type);
7471 /* Optimize the simple case where the arg fits in one gpr, except in
7472 the case of BLKmode due to assign_parms assuming that registers are
7473 BITS_PER_WORD wide. */
7475 || (n_units == 1 && mode != BLKmode))
7476 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7479 if (align_words + n_units > GP_ARG_NUM_REG)
7480 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7481 using a magic NULL_RTX component.
7482 This is not strictly correct. Only some of the arg belongs in
7483 memory, not all of it. However, the normal scheme using
7484 function_arg_partial_nregs can result in unusual subregs, eg.
7485 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7486 store the whole arg to memory is often more efficient than code
7487 to store pieces, and we know that space is available in the right
7488 place for the whole arg. */
7489 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7494 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7495 rtx off = GEN_INT (i++ * 4);
7496 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7498 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7500 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7503 /* Determine where to put an argument to a function.
7504 Value is zero to push the argument on the stack,
7505 or a hard register in which to store the argument.
7507 MODE is the argument's machine mode.
7508 TYPE is the data type of the argument (as a tree).
7509 This is null for libcalls where that information may
7511 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7512 the preceding args and about the function being called. It is
7513 not modified in this routine.
7514 NAMED is nonzero if this argument is a named parameter
7515 (otherwise it is an extra parameter matching an ellipsis).
7517 On RS/6000 the first eight words of non-FP are normally in registers
7518 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7519 Under V.4, the first 8 FP args are in registers.
7521 If this is floating-point and no prototype is specified, we use
7522 both an FP and integer register (or possibly FP reg and stack). Library
7523 functions (when CALL_LIBCALL is set) always have the proper types for args,
7524 so we can pass the FP value just in one register. emit_library_function
7525 doesn't support PARALLEL anyway.
7527 Note that for args passed by reference, function_arg will be called
7528 with MODE and TYPE set to that of the pointer to the arg, not the arg
7532 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7533 tree type, int named)
7535 enum rs6000_abi abi = DEFAULT_ABI;
7537 /* Return a marker to indicate whether CR1 needs to set or clear the
7538 bit that V.4 uses to say fp args were passed in registers.
7539 Assume that we don't need the marker for software floating point,
7540 or compiler generated library calls. */
7541 if (mode == VOIDmode)
7544 && (cum->call_cookie & CALL_LIBCALL) == 0
7546 || (cum->nargs_prototype < 0
7547 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7549 /* For the SPE, we need to crxor CR6 always. */
7551 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
7552 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
7553 return GEN_INT (cum->call_cookie
7554 | ((cum->fregno == FP_ARG_MIN_REG)
7555 ? CALL_V4_SET_FP_ARGS
7556 : CALL_V4_CLEAR_FP_ARGS));
7559 return GEN_INT (cum->call_cookie);
7562 if (rs6000_darwin64_abi && mode == BLKmode
7563 && TREE_CODE (type) == RECORD_TYPE)
7565 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
7566 if (rslt != NULL_RTX)
7568 /* Else fall through to usual handling. */
7571 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7572 if (TARGET_64BIT && ! cum->prototype)
7574 /* Vector parameters get passed in vector register
7575 and also in GPRs or memory, in absence of prototype. */
7578 align_words = (cum->words + 1) & ~1;
7580 if (align_words >= GP_ARG_NUM_REG)
7586 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7588 return gen_rtx_PARALLEL (mode,
7590 gen_rtx_EXPR_LIST (VOIDmode,
7592 gen_rtx_EXPR_LIST (VOIDmode,
7593 gen_rtx_REG (mode, cum->vregno),
7597 return gen_rtx_REG (mode, cum->vregno);
7598 else if (TARGET_ALTIVEC_ABI
7599 && (ALTIVEC_VECTOR_MODE (mode)
7600 || VSX_VECTOR_MODE (mode)
7601 || (type && TREE_CODE (type) == VECTOR_TYPE
7602 && int_size_in_bytes (type) == 16)))
7604 if (named || abi == ABI_V4)
7608 /* Vector parameters to varargs functions under AIX or Darwin
7609 get passed in memory and possibly also in GPRs. */
7610 int align, align_words, n_words;
7611 enum machine_mode part_mode;
7613 /* Vector parameters must be 16-byte aligned. This places them at
7614 2 mod 4 in terms of words in 32-bit mode, since the parameter
7615 save area starts at offset 24 from the stack. In 64-bit mode,
7616 they just have to start on an even word, since the parameter
7617 save area is 16-byte aligned. */
7619 align = (2 - cum->words) & 3;
7621 align = cum->words & 1;
7622 align_words = cum->words + align;
7624 /* Out of registers? Memory, then. */
7625 if (align_words >= GP_ARG_NUM_REG)
7628 if (TARGET_32BIT && TARGET_POWERPC64)
7629 return rs6000_mixed_function_arg (mode, type, align_words);
7631 /* The vector value goes in GPRs. Only the part of the
7632 value in GPRs is reported here. */
7634 n_words = rs6000_arg_size (mode, type);
7635 if (align_words + n_words > GP_ARG_NUM_REG)
7636 /* Fortunately, there are only two possibilities, the value
7637 is either wholly in GPRs or half in GPRs and half not. */
7640 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
7643 else if (TARGET_SPE_ABI && TARGET_SPE
7644 && (SPE_VECTOR_MODE (mode)
7645 || (TARGET_E500_DOUBLE && (mode == DFmode
7648 || mode == TCmode))))
7649 return rs6000_spe_function_arg (cum, mode, type);
7651 else if (abi == ABI_V4)
7653 if (TARGET_HARD_FLOAT && TARGET_FPRS
7654 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7655 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7656 || (mode == TFmode && !TARGET_IEEEQUAD)
7657 || mode == SDmode || mode == DDmode || mode == TDmode))
7659 /* _Decimal128 must use an even/odd register pair. This assumes
7660 that the register number is odd when fregno is odd. */
7661 if (mode == TDmode && (cum->fregno % 2) == 1)
7664 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7665 <= FP_ARG_V4_MAX_REG)
7666 return gen_rtx_REG (mode, cum->fregno);
7672 int n_words = rs6000_arg_size (mode, type);
7673 int gregno = cum->sysv_gregno;
7675 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7676 (r7,r8) or (r9,r10). As does any other 2 word item such
7677 as complex int due to a historical mistake. */
7679 gregno += (1 - gregno) & 1;
7681 /* Multi-reg args are not split between registers and stack. */
7682 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7685 if (TARGET_32BIT && TARGET_POWERPC64)
7686 return rs6000_mixed_function_arg (mode, type,
7687 gregno - GP_ARG_MIN_REG);
7688 return gen_rtx_REG (mode, gregno);
7693 int align_words = rs6000_parm_start (mode, type, cum->words);
7695 /* _Decimal128 must be passed in an even/odd float register pair.
7696 This assumes that the register number is odd when fregno is odd. */
7697 if (mode == TDmode && (cum->fregno % 2) == 1)
7700 if (USE_FP_FOR_ARG_P (cum, mode, type))
7702 rtx rvec[GP_ARG_NUM_REG + 1];
7706 enum machine_mode fmode = mode;
7707 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
7709 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
7711 /* Currently, we only ever need one reg here because complex
7712 doubles are split. */
7713 gcc_assert (cum->fregno == FP_ARG_MAX_REG
7714 && (fmode == TFmode || fmode == TDmode));
7716 /* Long double or _Decimal128 split over regs and memory. */
7717 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
7720 /* Do we also need to pass this arg in the parameter save
7723 && (cum->nargs_prototype <= 0
7724 || (DEFAULT_ABI == ABI_AIX
7726 && align_words >= GP_ARG_NUM_REG)));
7728 if (!needs_psave && mode == fmode)
7729 return gen_rtx_REG (fmode, cum->fregno);
7734 /* Describe the part that goes in gprs or the stack.
7735 This piece must come first, before the fprs. */
7736 if (align_words < GP_ARG_NUM_REG)
7738 unsigned long n_words = rs6000_arg_size (mode, type);
7740 if (align_words + n_words > GP_ARG_NUM_REG
7741 || (TARGET_32BIT && TARGET_POWERPC64))
7743 /* If this is partially on the stack, then we only
7744 include the portion actually in registers here. */
7745 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
7748 if (align_words + n_words > GP_ARG_NUM_REG)
7749 /* Not all of the arg fits in gprs. Say that it
7750 goes in memory too, using a magic NULL_RTX
7751 component. Also see comment in
7752 rs6000_mixed_function_arg for why the normal
7753 function_arg_partial_nregs scheme doesn't work
7755 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
7759 r = gen_rtx_REG (rmode,
7760 GP_ARG_MIN_REG + align_words);
7761 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
7762 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7764 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
7768 /* The whole arg fits in gprs. */
7769 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7770 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7774 /* It's entirely in memory. */
7775 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7778 /* Describe where this piece goes in the fprs. */
7779 r = gen_rtx_REG (fmode, cum->fregno);
7780 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7782 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7784 else if (align_words < GP_ARG_NUM_REG)
7786 if (TARGET_32BIT && TARGET_POWERPC64)
7787 return rs6000_mixed_function_arg (mode, type, align_words);
7789 if (mode == BLKmode)
7792 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7799 /* For an arg passed partly in registers and partly in memory, this is
7800 the number of bytes passed in registers. For args passed entirely in
7801 registers or entirely in memory, zero. When an arg is described by a
7802 PARALLEL, perhaps using more than one register type, this function
7803 returns the number of bytes used by the first element of the PARALLEL. */
7806 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7807 tree type, bool named)
7812 if (DEFAULT_ABI == ABI_V4)
7815 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
7816 && cum->nargs_prototype >= 0)
7819 /* In this complicated case we just disable the partial_nregs code. */
7820 if (rs6000_darwin64_abi && mode == BLKmode
7821 && TREE_CODE (type) == RECORD_TYPE
7822 && int_size_in_bytes (type) > 0)
7825 align_words = rs6000_parm_start (mode, type, cum->words);
7827 if (USE_FP_FOR_ARG_P (cum, mode, type))
7829 /* If we are passing this arg in the fixed parameter save area
7830 (gprs or memory) as well as fprs, then this function should
7831 return the number of partial bytes passed in the parameter
7832 save area rather than partial bytes passed in fprs. */
7834 && (cum->nargs_prototype <= 0
7835 || (DEFAULT_ABI == ABI_AIX
7837 && align_words >= GP_ARG_NUM_REG)))
7839 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
7840 > FP_ARG_MAX_REG + 1)
7841 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
7842 else if (cum->nargs_prototype >= 0)
7846 if (align_words < GP_ARG_NUM_REG
7847 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
7848 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
7850 if (ret != 0 && TARGET_DEBUG_ARG)
7851 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
7856 /* A C expression that indicates when an argument must be passed by
7857 reference. If nonzero for an argument, a copy of that argument is
7858 made in memory and a pointer to the argument is passed instead of
7859 the argument itself. The pointer is passed in whatever way is
7860 appropriate for passing a pointer to that type.
7862 Under V.4, aggregates and long double are passed by reference.
7864 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
7865 reference unless the AltiVec vector extension ABI is in force.
7867 As an extension to all ABIs, variable sized types are passed by
7871 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
7872 enum machine_mode mode, const_tree type,
7873 bool named ATTRIBUTE_UNUSED)
7875 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
7877 if (TARGET_DEBUG_ARG)
7878 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
7885 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
7887 if (TARGET_DEBUG_ARG)
7888 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
7892 if (int_size_in_bytes (type) < 0)
7894 if (TARGET_DEBUG_ARG)
7895 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
7899 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7900 modes only exist for GCC vector types if -maltivec. */
7901 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
7903 if (TARGET_DEBUG_ARG)
7904 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
7908 /* Pass synthetic vectors in memory. */
7909 if (TREE_CODE (type) == VECTOR_TYPE
7910 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7912 static bool warned_for_pass_big_vectors = false;
7913 if (TARGET_DEBUG_ARG)
7914 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
7915 if (!warned_for_pass_big_vectors)
7917 warning (0, "GCC vector passed by reference: "
7918 "non-standard ABI extension with no compatibility guarantee");
7919 warned_for_pass_big_vectors = true;
7928 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
7931 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
7936 for (i = 0; i < nregs; i++)
7938 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
7939 if (reload_completed)
7941 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
7944 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
7945 i * GET_MODE_SIZE (reg_mode));
7948 tem = replace_equiv_address (tem, XEXP (tem, 0));
7952 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
7956 /* Perform any needed actions needed for a function that is receiving a
7957 variable number of arguments.
7961 MODE and TYPE are the mode and type of the current parameter.
7963 PRETEND_SIZE is a variable that should be set to the amount of stack
7964 that must be pushed by the prolog to pretend that our caller pushed
7967 Normally, this macro will push all remaining incoming registers on the
7968 stack and set PRETEND_SIZE to the length of the registers pushed. */
7971 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7972 tree type, int *pretend_size ATTRIBUTE_UNUSED,
7975 CUMULATIVE_ARGS next_cum;
7976 int reg_size = TARGET_32BIT ? 4 : 8;
7977 rtx save_area = NULL_RTX, mem;
7978 int first_reg_offset;
7981 /* Skip the last named argument. */
7983 function_arg_advance (&next_cum, mode, type, 1, 0);
7985 if (DEFAULT_ABI == ABI_V4)
7987 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
7991 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
7992 HOST_WIDE_INT offset = 0;
7994 /* Try to optimize the size of the varargs save area.
7995 The ABI requires that ap.reg_save_area is doubleword
7996 aligned, but we don't need to allocate space for all
7997 the bytes, only those to which we actually will save
7999 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8000 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8001 if (TARGET_HARD_FLOAT && TARGET_FPRS
8002 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8003 && cfun->va_list_fpr_size)
8006 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8007 * UNITS_PER_FP_WORD;
8008 if (cfun->va_list_fpr_size
8009 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8010 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8012 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8013 * UNITS_PER_FP_WORD;
8017 offset = -((first_reg_offset * reg_size) & ~7);
8018 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8020 gpr_reg_num = cfun->va_list_gpr_size;
8021 if (reg_size == 4 && (first_reg_offset & 1))
8024 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8027 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8029 - (int) (GP_ARG_NUM_REG * reg_size);
8031 if (gpr_size + fpr_size)
8034 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8035 gcc_assert (GET_CODE (reg_save_area) == MEM);
8036 reg_save_area = XEXP (reg_save_area, 0);
8037 if (GET_CODE (reg_save_area) == PLUS)
8039 gcc_assert (XEXP (reg_save_area, 0)
8040 == virtual_stack_vars_rtx);
8041 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8042 offset += INTVAL (XEXP (reg_save_area, 1));
8045 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8048 cfun->machine->varargs_save_offset = offset;
8049 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8054 first_reg_offset = next_cum.words;
8055 save_area = virtual_incoming_args_rtx;
8057 if (targetm.calls.must_pass_in_stack (mode, type))
8058 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8061 set = get_varargs_alias_set ();
8062 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8063 && cfun->va_list_gpr_size)
8065 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8067 if (va_list_gpr_counter_field)
8069 /* V4 va_list_gpr_size counts number of registers needed. */
8070 if (nregs > cfun->va_list_gpr_size)
8071 nregs = cfun->va_list_gpr_size;
8075 /* char * va_list instead counts number of bytes needed. */
8076 if (nregs > cfun->va_list_gpr_size / reg_size)
8077 nregs = cfun->va_list_gpr_size / reg_size;
8080 mem = gen_rtx_MEM (BLKmode,
8081 plus_constant (save_area,
8082 first_reg_offset * reg_size));
8083 MEM_NOTRAP_P (mem) = 1;
8084 set_mem_alias_set (mem, set);
8085 set_mem_align (mem, BITS_PER_WORD);
8087 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8091 /* Save FP registers if needed. */
8092 if (DEFAULT_ABI == ABI_V4
8093 && TARGET_HARD_FLOAT && TARGET_FPRS
8095 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8096 && cfun->va_list_fpr_size)
8098 int fregno = next_cum.fregno, nregs;
8099 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8100 rtx lab = gen_label_rtx ();
8101 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8102 * UNITS_PER_FP_WORD);
8105 (gen_rtx_SET (VOIDmode,
8107 gen_rtx_IF_THEN_ELSE (VOIDmode,
8108 gen_rtx_NE (VOIDmode, cr1,
8110 gen_rtx_LABEL_REF (VOIDmode, lab),
8114 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8115 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8117 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8119 plus_constant (save_area, off));
8120 MEM_NOTRAP_P (mem) = 1;
8121 set_mem_alias_set (mem, set);
8122 set_mem_align (mem, GET_MODE_ALIGNMENT (
8123 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8124 ? DFmode : SFmode));
8125 emit_move_insn (mem, gen_rtx_REG (
8126 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8127 ? DFmode : SFmode, fregno));
8134 /* Create the va_list data type. */
8137 rs6000_build_builtin_va_list (void)
8139 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8141 /* For AIX, prefer 'char *' because that's what the system
8142 header files like. */
8143 if (DEFAULT_ABI != ABI_V4)
8144 return build_pointer_type (char_type_node);
8146 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8147 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8148 get_identifier ("__va_list_tag"), record);
8150 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8151 unsigned_char_type_node);
8152 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8153 unsigned_char_type_node);
8154 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8156 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8157 get_identifier ("reserved"), short_unsigned_type_node);
8158 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8159 get_identifier ("overflow_arg_area"),
8161 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8162 get_identifier ("reg_save_area"),
8165 va_list_gpr_counter_field = f_gpr;
8166 va_list_fpr_counter_field = f_fpr;
8168 DECL_FIELD_CONTEXT (f_gpr) = record;
8169 DECL_FIELD_CONTEXT (f_fpr) = record;
8170 DECL_FIELD_CONTEXT (f_res) = record;
8171 DECL_FIELD_CONTEXT (f_ovf) = record;
8172 DECL_FIELD_CONTEXT (f_sav) = record;
8174 TREE_CHAIN (record) = type_decl;
8175 TYPE_NAME (record) = type_decl;
8176 TYPE_FIELDS (record) = f_gpr;
8177 TREE_CHAIN (f_gpr) = f_fpr;
8178 TREE_CHAIN (f_fpr) = f_res;
8179 TREE_CHAIN (f_res) = f_ovf;
8180 TREE_CHAIN (f_ovf) = f_sav;
8182 layout_type (record);
8184 /* The correct type is an array type of one element. */
8185 return build_array_type (record, build_index_type (size_zero_node));
8188 /* Implement va_start. */
8191 rs6000_va_start (tree valist, rtx nextarg)
8193 HOST_WIDE_INT words, n_gpr, n_fpr;
8194 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8195 tree gpr, fpr, ovf, sav, t;
8197 /* Only SVR4 needs something special. */
8198 if (DEFAULT_ABI != ABI_V4)
8200 std_expand_builtin_va_start (valist, nextarg);
8204 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8205 f_fpr = TREE_CHAIN (f_gpr);
8206 f_res = TREE_CHAIN (f_fpr);
8207 f_ovf = TREE_CHAIN (f_res);
8208 f_sav = TREE_CHAIN (f_ovf);
8210 valist = build_va_arg_indirect_ref (valist);
8211 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8212 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8214 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8216 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8219 /* Count number of gp and fp argument registers used. */
8220 words = crtl->args.info.words;
8221 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8223 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8226 if (TARGET_DEBUG_ARG)
8227 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8228 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8229 words, n_gpr, n_fpr);
8231 if (cfun->va_list_gpr_size)
8233 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8234 build_int_cst (NULL_TREE, n_gpr));
8235 TREE_SIDE_EFFECTS (t) = 1;
8236 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8239 if (cfun->va_list_fpr_size)
8241 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8242 build_int_cst (NULL_TREE, n_fpr));
8243 TREE_SIDE_EFFECTS (t) = 1;
8244 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8247 /* Find the overflow area. */
8248 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8250 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8251 size_int (words * UNITS_PER_WORD));
8252 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8253 TREE_SIDE_EFFECTS (t) = 1;
8254 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8256 /* If there were no va_arg invocations, don't set up the register
8258 if (!cfun->va_list_gpr_size
8259 && !cfun->va_list_fpr_size
8260 && n_gpr < GP_ARG_NUM_REG
8261 && n_fpr < FP_ARG_V4_MAX_REG)
8264 /* Find the register save area. */
8265 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8266 if (cfun->machine->varargs_save_offset)
8267 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8268 size_int (cfun->machine->varargs_save_offset));
8269 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8270 TREE_SIDE_EFFECTS (t) = 1;
8271 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8274 /* Implement va_arg. */
8277 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8280 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8281 tree gpr, fpr, ovf, sav, reg, t, u;
8282 int size, rsize, n_reg, sav_ofs, sav_scale;
8283 tree lab_false, lab_over, addr;
8285 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8289 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8291 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8292 return build_va_arg_indirect_ref (t);
8295 if (DEFAULT_ABI != ABI_V4)
8297 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8299 tree elem_type = TREE_TYPE (type);
8300 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8301 int elem_size = GET_MODE_SIZE (elem_mode);
8303 if (elem_size < UNITS_PER_WORD)
8305 tree real_part, imag_part;
8306 gimple_seq post = NULL;
8308 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8310 /* Copy the value into a temporary, lest the formal temporary
8311 be reused out from under us. */
8312 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8313 gimple_seq_add_seq (pre_p, post);
8315 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8318 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8322 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8325 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8326 f_fpr = TREE_CHAIN (f_gpr);
8327 f_res = TREE_CHAIN (f_fpr);
8328 f_ovf = TREE_CHAIN (f_res);
8329 f_sav = TREE_CHAIN (f_ovf);
8331 valist = build_va_arg_indirect_ref (valist);
8332 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8333 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8335 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8337 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8340 size = int_size_in_bytes (type);
8341 rsize = (size + 3) / 4;
8344 if (TARGET_HARD_FLOAT && TARGET_FPRS
8345 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8346 || (TARGET_DOUBLE_FLOAT
8347 && (TYPE_MODE (type) == DFmode
8348 || TYPE_MODE (type) == TFmode
8349 || TYPE_MODE (type) == SDmode
8350 || TYPE_MODE (type) == DDmode
8351 || TYPE_MODE (type) == TDmode))))
8353 /* FP args go in FP registers, if present. */
8355 n_reg = (size + 7) / 8;
8356 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8357 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8358 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8363 /* Otherwise into GP registers. */
8372 /* Pull the value out of the saved registers.... */
8375 addr = create_tmp_var (ptr_type_node, "addr");
8377 /* AltiVec vectors never go in registers when -mabi=altivec. */
8378 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8382 lab_false = create_artificial_label (input_location);
8383 lab_over = create_artificial_label (input_location);
8385 /* Long long and SPE vectors are aligned in the registers.
8386 As are any other 2 gpr item such as complex int due to a
8387 historical mistake. */
8389 if (n_reg == 2 && reg == gpr)
8392 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8393 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8394 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8395 unshare_expr (reg), u);
8397 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8398 reg number is 0 for f1, so we want to make it odd. */
8399 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8401 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8402 build_int_cst (TREE_TYPE (reg), 1));
8403 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8406 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8407 t = build2 (GE_EXPR, boolean_type_node, u, t);
8408 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8409 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8410 gimplify_and_add (t, pre_p);
8414 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8416 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8417 build_int_cst (TREE_TYPE (reg), n_reg));
8418 u = fold_convert (sizetype, u);
8419 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8420 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8422 /* _Decimal32 varargs are located in the second word of the 64-bit
8423 FP register for 32-bit binaries. */
8424 if (!TARGET_POWERPC64
8425 && TARGET_HARD_FLOAT && TARGET_FPRS
8426 && TYPE_MODE (type) == SDmode)
8427 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8429 gimplify_assign (addr, t, pre_p);
8431 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8433 stmt = gimple_build_label (lab_false);
8434 gimple_seq_add_stmt (pre_p, stmt);
8436 if ((n_reg == 2 && !regalign) || n_reg > 2)
8438 /* Ensure that we don't find any more args in regs.
8439 Alignment has taken care of for special cases. */
8440 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8444 /* ... otherwise out of the overflow area. */
8446 /* Care for on-stack alignment if needed. */
8450 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8451 t = fold_convert (sizetype, t);
8452 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8454 t = fold_convert (TREE_TYPE (ovf), t);
8456 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8458 gimplify_assign (unshare_expr (addr), t, pre_p);
8460 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8461 gimplify_assign (unshare_expr (ovf), t, pre_p);
8465 stmt = gimple_build_label (lab_over);
8466 gimple_seq_add_stmt (pre_p, stmt);
8469 if (STRICT_ALIGNMENT
8470 && (TYPE_ALIGN (type)
8471 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8473 /* The value (of type complex double, for example) may not be
8474 aligned in memory in the saved registers, so copy via a
8475 temporary. (This is the same code as used for SPARC.) */
8476 tree tmp = create_tmp_var (type, "va_arg_tmp");
8477 tree dest_addr = build_fold_addr_expr (tmp);
8479 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8480 3, dest_addr, addr, size_int (rsize * 4));
8482 gimplify_and_add (copy, pre_p);
8486 addr = fold_convert (ptrtype, addr);
8487 return build_va_arg_indirect_ref (addr);
8493 def_builtin (int mask, const char *name, tree type, int code)
8495 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8497 if (rs6000_builtin_decls[code])
8498 fatal_error ("internal error: builtin function to %s already processed.",
8501 rs6000_builtin_decls[code] =
8502 add_builtin_function (name, type, code, BUILT_IN_MD,
8507 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
8509 static const struct builtin_description bdesc_3arg[] =
8511 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
8512 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
8513 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
8514 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
8515 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
8516 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
8517 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
8518 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
8519 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
8520 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
8521 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
8522 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
8523 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
8524 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
8525 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
8526 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
8527 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
8528 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
8529 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
8530 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
8531 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
8532 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
8533 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
8534 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
8535 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
8536 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
8537 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
8538 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
8539 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
8540 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
8541 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
8542 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
8543 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
8544 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
8545 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
8547 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
8548 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
8549 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
8550 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
8551 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
8552 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
8553 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
8554 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
8555 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
8556 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
8557 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
8558 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
8559 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
8560 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
8561 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
8563 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
8564 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
8565 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
8566 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
8568 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
8569 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
8570 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
8571 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
8573 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
8574 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
8576 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
8577 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
8578 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
8579 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
8580 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
8581 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
8582 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
8583 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
8584 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
8585 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
8587 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
8588 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
8589 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
8590 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
8591 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
8592 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
8593 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
8594 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
8595 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
8596 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
8598 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
8599 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
8600 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
8601 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
8602 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
8603 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
8604 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
8605 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
8606 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
8608 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
8609 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
8610 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
8611 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
8612 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
8613 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
8614 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
8616 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
8617 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
8618 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
8619 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
8620 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
8621 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
8622 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
8623 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
8624 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
8627 /* DST operations: void foo (void *, const int, const char). */
8629 static const struct builtin_description bdesc_dst[] =
8631 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
8632 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
8633 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
8634 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
8636 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
8637 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
8638 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
8639 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
8642 /* Simple binary operations: VECc = foo (VECa, VECb). */
8644 static struct builtin_description bdesc_2arg[] =
8646 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
8647 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
8648 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
8649 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
8650 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
8651 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
8652 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
8653 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
8654 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
8655 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
8656 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
8657 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
8658 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
8659 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
8660 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
8661 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
8662 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
8663 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
8664 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
8665 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
8666 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
8667 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
8668 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
8669 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
8670 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
8671 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
8672 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
8673 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
8674 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
8675 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
8676 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
8677 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
8678 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
8679 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
8680 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
8681 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
8682 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
8683 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
8684 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
8685 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
8686 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
8687 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
8688 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
8689 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
8690 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
8691 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
8692 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
8693 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
8694 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
8695 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
8696 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
8697 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
8698 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
8699 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
8700 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
8701 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
8702 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
8703 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
8704 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
8705 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
8706 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
8707 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
8708 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
8709 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
8710 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
8711 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
8712 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
8713 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
8714 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
8715 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
8716 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
8717 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
8718 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
8719 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
8720 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
8721 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
8722 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
8723 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
8724 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
8725 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
8726 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
8727 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
8728 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
8729 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
8730 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
8731 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
8732 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
8733 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
8734 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
8735 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
8736 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
8737 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
8738 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
8739 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
8740 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
8741 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
8742 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
8743 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
8744 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
8745 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
8746 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
8747 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
8748 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
8749 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
8750 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
8751 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
8752 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
8753 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
8754 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
8755 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
8756 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
8757 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
8758 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
8759 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
8760 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
8761 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
8763 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
8764 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
8765 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
8766 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
8767 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
8768 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
8769 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
8770 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
8771 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
8772 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
8773 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
8775 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
8776 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
8777 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
8778 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
8779 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
8780 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
8781 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
8782 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
8783 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
8784 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
8785 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
8787 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
8788 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
8789 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
8790 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
8791 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
8792 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
8794 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
8795 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
8796 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
8797 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
8798 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
8799 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
8800 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
8801 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
8803 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
8804 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
8805 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
8806 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
8807 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
8808 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
8809 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
8810 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
8811 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
8812 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
8813 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
8814 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
8815 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
8816 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
8817 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
8818 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
8819 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
8820 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
8821 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
8822 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
8823 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
8824 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
8825 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
8826 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
8827 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
8828 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
8829 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
8830 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
8831 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
8832 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
8833 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
8834 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
8835 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
8836 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
8837 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
8838 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
8839 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
8840 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
8841 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
8842 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
8843 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
8844 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
8845 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
8846 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
8847 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
8848 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
8849 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
8850 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
8851 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
8852 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
8853 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
8854 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
8855 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
8856 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
8857 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
8858 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
8859 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
8860 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
8861 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
8862 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
8863 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
8864 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
8865 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
8866 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
8867 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
8868 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
8869 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
8870 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
8871 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
8872 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
8873 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
8874 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
8875 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
8876 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
8877 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
8878 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
8879 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
8880 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
8881 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
8882 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
8883 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
8884 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
8885 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
8886 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
8887 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
8888 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
8889 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
8890 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
8891 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
8892 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
8893 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
8894 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
8895 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
8896 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
8897 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
8898 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
8899 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
8900 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
8901 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
8902 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
8903 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
8904 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
8905 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
8906 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
8907 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
8908 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
8909 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
8910 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
8911 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
8912 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
8913 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
8914 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
8915 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
8916 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
8917 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
8918 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
8919 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
8920 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
8921 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
8922 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
8923 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
8924 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
8925 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
8926 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
8927 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
8928 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
8929 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
8930 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
8932 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
8933 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
8935 { 0, CODE_FOR_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
8936 { 0, CODE_FOR_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
8937 { 0, CODE_FOR_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
8938 { 0, CODE_FOR_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
8939 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
8940 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
8941 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
8942 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
8943 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
8944 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
8946 /* Place holder, leave as first spe builtin. */
8947 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
8948 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
8949 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
8950 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
8951 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
8952 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
8953 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
8954 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
8955 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
8956 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
8957 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
8958 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
8959 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
8960 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
8961 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
8962 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
8963 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
8964 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
8965 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
8966 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
8967 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
8968 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
8969 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
8970 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
8971 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
8972 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
8973 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
8974 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
8975 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
8976 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
8977 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
8978 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
8979 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
8980 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
8981 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
8982 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
8983 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
8984 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
8985 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
8986 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
8987 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
8988 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
8989 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
8990 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
8991 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
8992 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
8993 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
8994 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
8995 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
8996 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
8997 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
8998 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
8999 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9000 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9001 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9002 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9003 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9004 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9005 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9006 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9007 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9008 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9009 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9010 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9011 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9012 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9013 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9014 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9015 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9016 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9017 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9018 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9019 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9020 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9021 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9022 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9023 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9024 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9025 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9026 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9027 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9028 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9029 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9030 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9031 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9032 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9033 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9034 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9035 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9036 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9037 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9038 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9039 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9040 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9041 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9042 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9043 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9044 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9045 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9046 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9047 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9048 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9049 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9050 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9051 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9052 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9053 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9054 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9055 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9057 /* SPE binary operations expecting a 5-bit unsigned literal. */
9058 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9060 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9061 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9062 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9063 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9064 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9065 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9066 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9067 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9068 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9069 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9070 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9071 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9072 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9073 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9074 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9075 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9076 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9077 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9078 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9079 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9080 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9081 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9082 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9083 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9084 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9085 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9087 /* Place-holder. Leave as last binary SPE builtin. */
9088 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9091 /* AltiVec predicates. */
9093 struct builtin_description_predicates
9095 const unsigned int mask;
9096 const enum insn_code icode;
9097 const char *const name;
9098 const enum rs6000_builtins code;
9101 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9103 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9104 ALTIVEC_BUILTIN_VCMPBFP_P },
9105 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9106 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9107 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9108 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9109 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9110 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9111 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9112 ALTIVEC_BUILTIN_VCMPEQUW_P },
9113 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9114 ALTIVEC_BUILTIN_VCMPGTSW_P },
9115 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9116 ALTIVEC_BUILTIN_VCMPGTUW_P },
9117 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9118 ALTIVEC_BUILTIN_VCMPEQUH_P },
9119 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9120 ALTIVEC_BUILTIN_VCMPGTSH_P },
9121 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9122 ALTIVEC_BUILTIN_VCMPGTUH_P },
9123 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9124 ALTIVEC_BUILTIN_VCMPEQUB_P },
9125 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9126 ALTIVEC_BUILTIN_VCMPGTSB_P },
9127 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9128 ALTIVEC_BUILTIN_VCMPGTUB_P },
9130 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9131 VSX_BUILTIN_XVCMPEQSP_P },
9132 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9133 VSX_BUILTIN_XVCMPGESP_P },
9134 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9135 VSX_BUILTIN_XVCMPGTSP_P },
9136 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9137 VSX_BUILTIN_XVCMPEQDP_P },
9138 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9139 VSX_BUILTIN_XVCMPGEDP_P },
9140 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9141 VSX_BUILTIN_XVCMPGTDP_P },
9143 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9144 ALTIVEC_BUILTIN_VCMPEQ_P },
9145 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9146 ALTIVEC_BUILTIN_VCMPGT_P },
9147 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9148 ALTIVEC_BUILTIN_VCMPGE_P }
9151 /* SPE predicates. */
9152 static struct builtin_description bdesc_spe_predicates[] =
9154 /* Place-holder. Leave as first. */
9155 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9156 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9157 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9158 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9159 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9160 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9161 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9162 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9163 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9164 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9165 /* Place-holder. Leave as last. */
9166 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9169 /* SPE evsel predicates. */
9170 static struct builtin_description bdesc_spe_evsel[] =
9172 /* Place-holder. Leave as first. */
9173 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9174 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9175 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9176 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9177 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9178 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9179 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9180 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9181 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9182 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9183 /* Place-holder. Leave as last. */
9184 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9187 /* PAIRED predicates. */
9188 static const struct builtin_description bdesc_paired_preds[] =
9190 /* Place-holder. Leave as first. */
9191 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9192 /* Place-holder. Leave as last. */
9193 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9196 /* ABS* operations. */
9198 static const struct builtin_description bdesc_abs[] =
9200 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9201 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9202 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9203 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9204 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9205 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9206 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9207 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9208 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9209 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9210 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9213 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9216 static struct builtin_description bdesc_1arg[] =
9218 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9219 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9220 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9221 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9222 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9223 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9224 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9225 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9226 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9227 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9228 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9229 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9230 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9231 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9232 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9233 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9234 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9236 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9237 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9238 { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9239 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9240 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9241 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9243 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9244 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9245 { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9246 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9247 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9248 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9250 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9251 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9252 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9253 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9254 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9255 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9257 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9258 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9259 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9260 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9261 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9262 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9264 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9265 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9266 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9267 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9269 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9270 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9271 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9272 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9273 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9274 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9275 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9276 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9277 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9279 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9280 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9281 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9282 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9283 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9284 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9285 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9286 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9287 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9289 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9290 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9291 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9292 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9293 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9295 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9296 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9297 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9298 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9299 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9300 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9301 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9302 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9303 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9304 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9305 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9306 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9307 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9308 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9309 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9310 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9311 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9312 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9313 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9315 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9316 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9317 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9319 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9320 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9321 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9322 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9324 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9325 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9326 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9327 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9328 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9329 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9330 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9331 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9332 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9333 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9334 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9335 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9336 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9337 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9338 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9339 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9340 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9341 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9342 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9343 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9344 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9345 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9346 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9347 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9348 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9349 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9350 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9351 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9352 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9353 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9355 /* Place-holder. Leave as last unary SPE builtin. */
9356 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9358 { 0, CODE_FOR_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9359 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9360 { 0, CODE_FOR_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9361 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9362 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9366 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9369 tree arg0 = CALL_EXPR_ARG (exp, 0);
9370 rtx op0 = expand_normal (arg0);
9371 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9372 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9374 if (icode == CODE_FOR_nothing)
9375 /* Builtin not supported on this processor. */
9378 /* If we got invalid arguments bail out before generating bad rtl. */
9379 if (arg0 == error_mark_node)
9382 if (icode == CODE_FOR_altivec_vspltisb
9383 || icode == CODE_FOR_altivec_vspltish
9384 || icode == CODE_FOR_altivec_vspltisw
9385 || icode == CODE_FOR_spe_evsplatfi
9386 || icode == CODE_FOR_spe_evsplati)
9388 /* Only allow 5-bit *signed* literals. */
9389 if (GET_CODE (op0) != CONST_INT
9390 || INTVAL (op0) > 15
9391 || INTVAL (op0) < -16)
9393 error ("argument 1 must be a 5-bit signed literal");
9399 || GET_MODE (target) != tmode
9400 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9401 target = gen_reg_rtx (tmode);
9403 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9404 op0 = copy_to_mode_reg (mode0, op0);
9406 pat = GEN_FCN (icode) (target, op0);
9415 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9417 rtx pat, scratch1, scratch2;
9418 tree arg0 = CALL_EXPR_ARG (exp, 0);
9419 rtx op0 = expand_normal (arg0);
9420 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9421 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9423 /* If we have invalid arguments, bail out before generating bad rtl. */
9424 if (arg0 == error_mark_node)
9428 || GET_MODE (target) != tmode
9429 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9430 target = gen_reg_rtx (tmode);
9432 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9433 op0 = copy_to_mode_reg (mode0, op0);
9435 scratch1 = gen_reg_rtx (mode0);
9436 scratch2 = gen_reg_rtx (mode0);
9438 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9447 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
9450 tree arg0 = CALL_EXPR_ARG (exp, 0);
9451 tree arg1 = CALL_EXPR_ARG (exp, 1);
9452 rtx op0 = expand_normal (arg0);
9453 rtx op1 = expand_normal (arg1);
9454 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9455 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9456 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9458 if (icode == CODE_FOR_nothing)
9459 /* Builtin not supported on this processor. */
9462 /* If we got invalid arguments bail out before generating bad rtl. */
9463 if (arg0 == error_mark_node || arg1 == error_mark_node)
9466 if (icode == CODE_FOR_altivec_vcfux
9467 || icode == CODE_FOR_altivec_vcfsx
9468 || icode == CODE_FOR_altivec_vctsxs
9469 || icode == CODE_FOR_altivec_vctuxs
9470 || icode == CODE_FOR_altivec_vspltb
9471 || icode == CODE_FOR_altivec_vsplth
9472 || icode == CODE_FOR_altivec_vspltw
9473 || icode == CODE_FOR_spe_evaddiw
9474 || icode == CODE_FOR_spe_evldd
9475 || icode == CODE_FOR_spe_evldh
9476 || icode == CODE_FOR_spe_evldw
9477 || icode == CODE_FOR_spe_evlhhesplat
9478 || icode == CODE_FOR_spe_evlhhossplat
9479 || icode == CODE_FOR_spe_evlhhousplat
9480 || icode == CODE_FOR_spe_evlwhe
9481 || icode == CODE_FOR_spe_evlwhos
9482 || icode == CODE_FOR_spe_evlwhou
9483 || icode == CODE_FOR_spe_evlwhsplat
9484 || icode == CODE_FOR_spe_evlwwsplat
9485 || icode == CODE_FOR_spe_evrlwi
9486 || icode == CODE_FOR_spe_evslwi
9487 || icode == CODE_FOR_spe_evsrwis
9488 || icode == CODE_FOR_spe_evsubifw
9489 || icode == CODE_FOR_spe_evsrwiu)
9491 /* Only allow 5-bit unsigned literals. */
9493 if (TREE_CODE (arg1) != INTEGER_CST
9494 || TREE_INT_CST_LOW (arg1) & ~0x1f)
9496 error ("argument 2 must be a 5-bit unsigned literal");
9502 || GET_MODE (target) != tmode
9503 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9504 target = gen_reg_rtx (tmode);
9506 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9507 op0 = copy_to_mode_reg (mode0, op0);
9508 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9509 op1 = copy_to_mode_reg (mode1, op1);
9511 pat = GEN_FCN (icode) (target, op0, op1);
9520 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
9523 tree cr6_form = CALL_EXPR_ARG (exp, 0);
9524 tree arg0 = CALL_EXPR_ARG (exp, 1);
9525 tree arg1 = CALL_EXPR_ARG (exp, 2);
9526 rtx op0 = expand_normal (arg0);
9527 rtx op1 = expand_normal (arg1);
9528 enum machine_mode tmode = SImode;
9529 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9530 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9533 if (TREE_CODE (cr6_form) != INTEGER_CST)
9535 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9539 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
9541 gcc_assert (mode0 == mode1);
9543 /* If we have invalid arguments, bail out before generating bad rtl. */
9544 if (arg0 == error_mark_node || arg1 == error_mark_node)
9548 || GET_MODE (target) != tmode
9549 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9550 target = gen_reg_rtx (tmode);
9552 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9553 op0 = copy_to_mode_reg (mode0, op0);
9554 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9555 op1 = copy_to_mode_reg (mode1, op1);
9557 scratch = gen_reg_rtx (mode0);
9559 pat = GEN_FCN (icode) (scratch, op0, op1);
9564 /* The vec_any* and vec_all* predicates use the same opcodes for two
9565 different operations, but the bits in CR6 will be different
9566 depending on what information we want. So we have to play tricks
9567 with CR6 to get the right bits out.
9569 If you think this is disgusting, look at the specs for the
9570 AltiVec predicates. */
9572 switch (cr6_form_int)
9575 emit_insn (gen_cr6_test_for_zero (target));
9578 emit_insn (gen_cr6_test_for_zero_reverse (target));
9581 emit_insn (gen_cr6_test_for_lt (target));
9584 emit_insn (gen_cr6_test_for_lt_reverse (target));
9587 error ("argument 1 of __builtin_altivec_predicate is out of range");
9595 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
9598 tree arg0 = CALL_EXPR_ARG (exp, 0);
9599 tree arg1 = CALL_EXPR_ARG (exp, 1);
9600 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9601 enum machine_mode mode0 = Pmode;
9602 enum machine_mode mode1 = Pmode;
9603 rtx op0 = expand_normal (arg0);
9604 rtx op1 = expand_normal (arg1);
9606 if (icode == CODE_FOR_nothing)
9607 /* Builtin not supported on this processor. */
9610 /* If we got invalid arguments bail out before generating bad rtl. */
9611 if (arg0 == error_mark_node || arg1 == error_mark_node)
9615 || GET_MODE (target) != tmode
9616 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9617 target = gen_reg_rtx (tmode);
9619 op1 = copy_to_mode_reg (mode1, op1);
9621 if (op0 == const0_rtx)
9623 addr = gen_rtx_MEM (tmode, op1);
9627 op0 = copy_to_mode_reg (mode0, op0);
9628 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
9631 pat = GEN_FCN (icode) (target, addr);
9641 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
9644 tree arg0 = CALL_EXPR_ARG (exp, 0);
9645 tree arg1 = CALL_EXPR_ARG (exp, 1);
9646 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9647 enum machine_mode mode0 = Pmode;
9648 enum machine_mode mode1 = Pmode;
9649 rtx op0 = expand_normal (arg0);
9650 rtx op1 = expand_normal (arg1);
9652 if (icode == CODE_FOR_nothing)
9653 /* Builtin not supported on this processor. */
9656 /* If we got invalid arguments bail out before generating bad rtl. */
9657 if (arg0 == error_mark_node || arg1 == error_mark_node)
9661 || GET_MODE (target) != tmode
9662 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9663 target = gen_reg_rtx (tmode);
9665 op1 = copy_to_mode_reg (mode1, op1);
9667 if (op0 == const0_rtx)
9669 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
9673 op0 = copy_to_mode_reg (mode0, op0);
9674 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
9677 pat = GEN_FCN (icode) (target, addr);
9687 spe_expand_stv_builtin (enum insn_code icode, tree exp)
9689 tree arg0 = CALL_EXPR_ARG (exp, 0);
9690 tree arg1 = CALL_EXPR_ARG (exp, 1);
9691 tree arg2 = CALL_EXPR_ARG (exp, 2);
9692 rtx op0 = expand_normal (arg0);
9693 rtx op1 = expand_normal (arg1);
9694 rtx op2 = expand_normal (arg2);
9696 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
9697 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
9698 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
9700 /* Invalid arguments. Bail before doing anything stoopid! */
9701 if (arg0 == error_mark_node
9702 || arg1 == error_mark_node
9703 || arg2 == error_mark_node)
9706 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
9707 op0 = copy_to_mode_reg (mode2, op0);
9708 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
9709 op1 = copy_to_mode_reg (mode0, op1);
9710 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
9711 op2 = copy_to_mode_reg (mode1, op2);
9713 pat = GEN_FCN (icode) (op1, op2, op0);
9720 paired_expand_stv_builtin (enum insn_code icode, tree exp)
9722 tree arg0 = CALL_EXPR_ARG (exp, 0);
9723 tree arg1 = CALL_EXPR_ARG (exp, 1);
9724 tree arg2 = CALL_EXPR_ARG (exp, 2);
9725 rtx op0 = expand_normal (arg0);
9726 rtx op1 = expand_normal (arg1);
9727 rtx op2 = expand_normal (arg2);
9729 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9730 enum machine_mode mode1 = Pmode;
9731 enum machine_mode mode2 = Pmode;
9733 /* Invalid arguments. Bail before doing anything stoopid! */
9734 if (arg0 == error_mark_node
9735 || arg1 == error_mark_node
9736 || arg2 == error_mark_node)
9739 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9740 op0 = copy_to_mode_reg (tmode, op0);
9742 op2 = copy_to_mode_reg (mode2, op2);
9744 if (op1 == const0_rtx)
9746 addr = gen_rtx_MEM (tmode, op2);
9750 op1 = copy_to_mode_reg (mode1, op1);
9751 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9754 pat = GEN_FCN (icode) (addr, op0);
9761 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
9763 tree arg0 = CALL_EXPR_ARG (exp, 0);
9764 tree arg1 = CALL_EXPR_ARG (exp, 1);
9765 tree arg2 = CALL_EXPR_ARG (exp, 2);
9766 rtx op0 = expand_normal (arg0);
9767 rtx op1 = expand_normal (arg1);
9768 rtx op2 = expand_normal (arg2);
9770 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9771 enum machine_mode mode1 = Pmode;
9772 enum machine_mode mode2 = Pmode;
9774 /* Invalid arguments. Bail before doing anything stoopid! */
9775 if (arg0 == error_mark_node
9776 || arg1 == error_mark_node
9777 || arg2 == error_mark_node)
9780 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9781 op0 = copy_to_mode_reg (tmode, op0);
9783 op2 = copy_to_mode_reg (mode2, op2);
9785 if (op1 == const0_rtx)
9787 addr = gen_rtx_MEM (tmode, op2);
9791 op1 = copy_to_mode_reg (mode1, op1);
9792 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9795 pat = GEN_FCN (icode) (addr, op0);
9802 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
9805 tree arg0 = CALL_EXPR_ARG (exp, 0);
9806 tree arg1 = CALL_EXPR_ARG (exp, 1);
9807 tree arg2 = CALL_EXPR_ARG (exp, 2);
9808 rtx op0 = expand_normal (arg0);
9809 rtx op1 = expand_normal (arg1);
9810 rtx op2 = expand_normal (arg2);
9811 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9812 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9813 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9814 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
9816 if (icode == CODE_FOR_nothing)
9817 /* Builtin not supported on this processor. */
9820 /* If we got invalid arguments bail out before generating bad rtl. */
9821 if (arg0 == error_mark_node
9822 || arg1 == error_mark_node
9823 || arg2 == error_mark_node)
9828 case CODE_FOR_altivec_vsldoi_v4sf:
9829 case CODE_FOR_altivec_vsldoi_v4si:
9830 case CODE_FOR_altivec_vsldoi_v8hi:
9831 case CODE_FOR_altivec_vsldoi_v16qi:
9832 /* Only allow 4-bit unsigned literals. */
9834 if (TREE_CODE (arg2) != INTEGER_CST
9835 || TREE_INT_CST_LOW (arg2) & ~0xf)
9837 error ("argument 3 must be a 4-bit unsigned literal");
9842 case CODE_FOR_vsx_xxpermdi_v2df:
9843 case CODE_FOR_vsx_xxpermdi_v2di:
9844 case CODE_FOR_vsx_xxsldwi_v16qi:
9845 case CODE_FOR_vsx_xxsldwi_v8hi:
9846 case CODE_FOR_vsx_xxsldwi_v4si:
9847 case CODE_FOR_vsx_xxsldwi_v4sf:
9848 case CODE_FOR_vsx_xxsldwi_v2di:
9849 case CODE_FOR_vsx_xxsldwi_v2df:
9850 /* Only allow 2-bit unsigned literals. */
9852 if (TREE_CODE (arg2) != INTEGER_CST
9853 || TREE_INT_CST_LOW (arg2) & ~0x3)
9855 error ("argument 3 must be a 2-bit unsigned literal");
9860 case CODE_FOR_vsx_set_v2df:
9861 case CODE_FOR_vsx_set_v2di:
9862 /* Only allow 1-bit unsigned literals. */
9864 if (TREE_CODE (arg2) != INTEGER_CST
9865 || TREE_INT_CST_LOW (arg2) & ~0x1)
9867 error ("argument 3 must be a 1-bit unsigned literal");
9877 || GET_MODE (target) != tmode
9878 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9879 target = gen_reg_rtx (tmode);
9881 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9882 op0 = copy_to_mode_reg (mode0, op0);
9883 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9884 op1 = copy_to_mode_reg (mode1, op1);
9885 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
9886 op2 = copy_to_mode_reg (mode2, op2);
9888 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
9889 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
9891 pat = GEN_FCN (icode) (target, op0, op1, op2);
9899 /* Expand the lvx builtins. */
9901 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
9903 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9904 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9906 enum machine_mode tmode, mode0;
9908 enum insn_code icode;
9912 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
9913 icode = CODE_FOR_vector_load_v16qi;
9915 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
9916 icode = CODE_FOR_vector_load_v8hi;
9918 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
9919 icode = CODE_FOR_vector_load_v4si;
9921 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
9922 icode = CODE_FOR_vector_load_v4sf;
9931 arg0 = CALL_EXPR_ARG (exp, 0);
9932 op0 = expand_normal (arg0);
9933 tmode = insn_data[icode].operand[0].mode;
9934 mode0 = insn_data[icode].operand[1].mode;
9937 || GET_MODE (target) != tmode
9938 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9939 target = gen_reg_rtx (tmode);
9941 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9942 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
9944 pat = GEN_FCN (icode) (target, op0);
9951 /* Expand the stvx builtins. */
9953 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
9956 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9957 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9959 enum machine_mode mode0, mode1;
9961 enum insn_code icode;
9965 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
9966 icode = CODE_FOR_vector_store_v16qi;
9968 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
9969 icode = CODE_FOR_vector_store_v8hi;
9971 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
9972 icode = CODE_FOR_vector_store_v4si;
9974 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
9975 icode = CODE_FOR_vector_store_v4sf;
9982 arg0 = CALL_EXPR_ARG (exp, 0);
9983 arg1 = CALL_EXPR_ARG (exp, 1);
9984 op0 = expand_normal (arg0);
9985 op1 = expand_normal (arg1);
9986 mode0 = insn_data[icode].operand[0].mode;
9987 mode1 = insn_data[icode].operand[1].mode;
9989 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
9990 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
9991 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
9992 op1 = copy_to_mode_reg (mode1, op1);
9994 pat = GEN_FCN (icode) (op0, op1);
10002 /* Expand the dst builtins. */
10004 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10007 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10008 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10009 tree arg0, arg1, arg2;
10010 enum machine_mode mode0, mode1, mode2;
10011 rtx pat, op0, op1, op2;
10012 const struct builtin_description *d;
10015 *expandedp = false;
10017 /* Handle DST variants. */
10019 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10020 if (d->code == fcode)
10022 arg0 = CALL_EXPR_ARG (exp, 0);
10023 arg1 = CALL_EXPR_ARG (exp, 1);
10024 arg2 = CALL_EXPR_ARG (exp, 2);
10025 op0 = expand_normal (arg0);
10026 op1 = expand_normal (arg1);
10027 op2 = expand_normal (arg2);
10028 mode0 = insn_data[d->icode].operand[0].mode;
10029 mode1 = insn_data[d->icode].operand[1].mode;
10030 mode2 = insn_data[d->icode].operand[2].mode;
10032 /* Invalid arguments, bail out before generating bad rtl. */
10033 if (arg0 == error_mark_node
10034 || arg1 == error_mark_node
10035 || arg2 == error_mark_node)
10040 if (TREE_CODE (arg2) != INTEGER_CST
10041 || TREE_INT_CST_LOW (arg2) & ~0x3)
10043 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10047 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10048 op0 = copy_to_mode_reg (Pmode, op0);
10049 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10050 op1 = copy_to_mode_reg (mode1, op1);
10052 pat = GEN_FCN (d->icode) (op0, op1, op2);
10062 /* Expand vec_init builtin. */
10064 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10066 enum machine_mode tmode = TYPE_MODE (type);
10067 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10068 int i, n_elt = GET_MODE_NUNITS (tmode);
10069 rtvec v = rtvec_alloc (n_elt);
10071 gcc_assert (VECTOR_MODE_P (tmode));
10072 gcc_assert (n_elt == call_expr_nargs (exp));
10074 for (i = 0; i < n_elt; ++i)
10076 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10077 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10080 if (!target || !register_operand (target, tmode))
10081 target = gen_reg_rtx (tmode);
10083 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10087 /* Return the integer constant in ARG. Constrain it to be in the range
10088 of the subparts of VEC_TYPE; issue an error if not. */
10091 get_element_number (tree vec_type, tree arg)
10093 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10095 if (!host_integerp (arg, 1)
10096 || (elt = tree_low_cst (arg, 1), elt > max))
10098 error ("selector must be an integer constant in the range 0..%wi", max);
10105 /* Expand vec_set builtin. */
10107 altivec_expand_vec_set_builtin (tree exp)
10109 enum machine_mode tmode, mode1;
10110 tree arg0, arg1, arg2;
10114 arg0 = CALL_EXPR_ARG (exp, 0);
10115 arg1 = CALL_EXPR_ARG (exp, 1);
10116 arg2 = CALL_EXPR_ARG (exp, 2);
10118 tmode = TYPE_MODE (TREE_TYPE (arg0));
10119 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10120 gcc_assert (VECTOR_MODE_P (tmode));
10122 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10123 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10124 elt = get_element_number (TREE_TYPE (arg0), arg2);
10126 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10127 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10129 op0 = force_reg (tmode, op0);
10130 op1 = force_reg (mode1, op1);
10132 rs6000_expand_vector_set (op0, op1, elt);
10137 /* Expand vec_ext builtin. */
10139 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10141 enum machine_mode tmode, mode0;
10146 arg0 = CALL_EXPR_ARG (exp, 0);
10147 arg1 = CALL_EXPR_ARG (exp, 1);
10149 op0 = expand_normal (arg0);
10150 elt = get_element_number (TREE_TYPE (arg0), arg1);
10152 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10153 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10154 gcc_assert (VECTOR_MODE_P (mode0));
10156 op0 = force_reg (mode0, op0);
10158 if (optimize || !target || !register_operand (target, tmode))
10159 target = gen_reg_rtx (tmode);
10161 rs6000_expand_vector_extract (target, op0, elt);
10166 /* Expand the builtin in EXP and store the result in TARGET. Store
10167 true in *EXPANDEDP if we found a builtin to expand. */
10169 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10171 const struct builtin_description *d;
10172 const struct builtin_description_predicates *dp;
10174 enum insn_code icode;
10175 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10178 enum machine_mode tmode, mode0;
10179 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10181 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10182 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10183 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10184 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10187 error ("unresolved overload for Altivec builtin %qF", fndecl);
10191 target = altivec_expand_ld_builtin (exp, target, expandedp);
10195 target = altivec_expand_st_builtin (exp, target, expandedp);
10199 target = altivec_expand_dst_builtin (exp, target, expandedp);
10207 case ALTIVEC_BUILTIN_STVX:
10208 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10209 case ALTIVEC_BUILTIN_STVEBX:
10210 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10211 case ALTIVEC_BUILTIN_STVEHX:
10212 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10213 case ALTIVEC_BUILTIN_STVEWX:
10214 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10215 case ALTIVEC_BUILTIN_STVXL:
10216 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10218 case ALTIVEC_BUILTIN_STVLX:
10219 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10220 case ALTIVEC_BUILTIN_STVLXL:
10221 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10222 case ALTIVEC_BUILTIN_STVRX:
10223 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10224 case ALTIVEC_BUILTIN_STVRXL:
10225 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10227 case ALTIVEC_BUILTIN_MFVSCR:
10228 icode = CODE_FOR_altivec_mfvscr;
10229 tmode = insn_data[icode].operand[0].mode;
10232 || GET_MODE (target) != tmode
10233 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10234 target = gen_reg_rtx (tmode);
10236 pat = GEN_FCN (icode) (target);
10242 case ALTIVEC_BUILTIN_MTVSCR:
10243 icode = CODE_FOR_altivec_mtvscr;
10244 arg0 = CALL_EXPR_ARG (exp, 0);
10245 op0 = expand_normal (arg0);
10246 mode0 = insn_data[icode].operand[0].mode;
10248 /* If we got invalid arguments bail out before generating bad rtl. */
10249 if (arg0 == error_mark_node)
10252 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10253 op0 = copy_to_mode_reg (mode0, op0);
10255 pat = GEN_FCN (icode) (op0);
10260 case ALTIVEC_BUILTIN_DSSALL:
10261 emit_insn (gen_altivec_dssall ());
10264 case ALTIVEC_BUILTIN_DSS:
10265 icode = CODE_FOR_altivec_dss;
10266 arg0 = CALL_EXPR_ARG (exp, 0);
10268 op0 = expand_normal (arg0);
10269 mode0 = insn_data[icode].operand[0].mode;
10271 /* If we got invalid arguments bail out before generating bad rtl. */
10272 if (arg0 == error_mark_node)
10275 if (TREE_CODE (arg0) != INTEGER_CST
10276 || TREE_INT_CST_LOW (arg0) & ~0x3)
10278 error ("argument to dss must be a 2-bit unsigned literal");
10282 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10283 op0 = copy_to_mode_reg (mode0, op0);
10285 emit_insn (gen_altivec_dss (op0));
10288 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10289 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10290 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10291 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10292 case VSX_BUILTIN_VEC_INIT_V2DF:
10293 case VSX_BUILTIN_VEC_INIT_V2DI:
10294 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10296 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10297 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10298 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10299 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10300 case VSX_BUILTIN_VEC_SET_V2DF:
10301 case VSX_BUILTIN_VEC_SET_V2DI:
10302 return altivec_expand_vec_set_builtin (exp);
10304 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10305 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10306 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10307 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10308 case VSX_BUILTIN_VEC_EXT_V2DF:
10309 case VSX_BUILTIN_VEC_EXT_V2DI:
10310 return altivec_expand_vec_ext_builtin (exp, target);
10314 /* Fall through. */
10317 /* Expand abs* operations. */
10319 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10320 if (d->code == fcode)
10321 return altivec_expand_abs_builtin (d->icode, exp, target);
10323 /* Expand the AltiVec predicates. */
10324 dp = bdesc_altivec_preds;
10325 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10326 if (dp->code == fcode)
10327 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10329 /* LV* are funky. We initialized them differently. */
10332 case ALTIVEC_BUILTIN_LVSL:
10333 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10334 exp, target, false);
10335 case ALTIVEC_BUILTIN_LVSR:
10336 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10337 exp, target, false);
10338 case ALTIVEC_BUILTIN_LVEBX:
10339 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10340 exp, target, false);
10341 case ALTIVEC_BUILTIN_LVEHX:
10342 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10343 exp, target, false);
10344 case ALTIVEC_BUILTIN_LVEWX:
10345 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10346 exp, target, false);
10347 case ALTIVEC_BUILTIN_LVXL:
10348 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10349 exp, target, false);
10350 case ALTIVEC_BUILTIN_LVX:
10351 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10352 exp, target, false);
10353 case ALTIVEC_BUILTIN_LVLX:
10354 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10355 exp, target, true);
10356 case ALTIVEC_BUILTIN_LVLXL:
10357 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10358 exp, target, true);
10359 case ALTIVEC_BUILTIN_LVRX:
10360 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10361 exp, target, true);
10362 case ALTIVEC_BUILTIN_LVRXL:
10363 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10364 exp, target, true);
10367 /* Fall through. */
10370 *expandedp = false;
10374 /* Expand the builtin in EXP and store the result in TARGET. Store
10375 true in *EXPANDEDP if we found a builtin to expand. */
10377 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10379 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10380 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10381 const struct builtin_description *d;
10388 case PAIRED_BUILTIN_STX:
10389 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10390 case PAIRED_BUILTIN_LX:
10391 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10394 /* Fall through. */
10397 /* Expand the paired predicates. */
10398 d = bdesc_paired_preds;
10399 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10400 if (d->code == fcode)
10401 return paired_expand_predicate_builtin (d->icode, exp, target);
10403 *expandedp = false;
10407 /* Binops that need to be initialized manually, but can be expanded
10408 automagically by rs6000_expand_binop_builtin. */
10409 static struct builtin_description bdesc_2arg_spe[] =
10411 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10412 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10413 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10414 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10415 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10416 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10417 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10418 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10419 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10420 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10421 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10422 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10423 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10424 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10425 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10426 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10427 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10428 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10429 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10430 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10431 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10432 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10435 /* Expand the builtin in EXP and store the result in TARGET. Store
10436 true in *EXPANDEDP if we found a builtin to expand.
10438 This expands the SPE builtins that are not simple unary and binary
10441 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10443 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10445 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10446 enum insn_code icode;
10447 enum machine_mode tmode, mode0;
10449 struct builtin_description *d;
10454 /* Syntax check for a 5-bit unsigned immediate. */
10457 case SPE_BUILTIN_EVSTDD:
10458 case SPE_BUILTIN_EVSTDH:
10459 case SPE_BUILTIN_EVSTDW:
10460 case SPE_BUILTIN_EVSTWHE:
10461 case SPE_BUILTIN_EVSTWHO:
10462 case SPE_BUILTIN_EVSTWWE:
10463 case SPE_BUILTIN_EVSTWWO:
10464 arg1 = CALL_EXPR_ARG (exp, 2);
10465 if (TREE_CODE (arg1) != INTEGER_CST
10466 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10468 error ("argument 2 must be a 5-bit unsigned literal");
10476 /* The evsplat*i instructions are not quite generic. */
10479 case SPE_BUILTIN_EVSPLATFI:
10480 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
10482 case SPE_BUILTIN_EVSPLATI:
10483 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
10489 d = (struct builtin_description *) bdesc_2arg_spe;
10490 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
10491 if (d->code == fcode)
10492 return rs6000_expand_binop_builtin (d->icode, exp, target);
10494 d = (struct builtin_description *) bdesc_spe_predicates;
10495 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
10496 if (d->code == fcode)
10497 return spe_expand_predicate_builtin (d->icode, exp, target);
10499 d = (struct builtin_description *) bdesc_spe_evsel;
10500 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
10501 if (d->code == fcode)
10502 return spe_expand_evsel_builtin (d->icode, exp, target);
10506 case SPE_BUILTIN_EVSTDDX:
10507 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
10508 case SPE_BUILTIN_EVSTDHX:
10509 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
10510 case SPE_BUILTIN_EVSTDWX:
10511 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
10512 case SPE_BUILTIN_EVSTWHEX:
10513 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
10514 case SPE_BUILTIN_EVSTWHOX:
10515 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
10516 case SPE_BUILTIN_EVSTWWEX:
10517 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
10518 case SPE_BUILTIN_EVSTWWOX:
10519 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
10520 case SPE_BUILTIN_EVSTDD:
10521 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
10522 case SPE_BUILTIN_EVSTDH:
10523 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
10524 case SPE_BUILTIN_EVSTDW:
10525 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
10526 case SPE_BUILTIN_EVSTWHE:
10527 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
10528 case SPE_BUILTIN_EVSTWHO:
10529 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
10530 case SPE_BUILTIN_EVSTWWE:
10531 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
10532 case SPE_BUILTIN_EVSTWWO:
10533 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
10534 case SPE_BUILTIN_MFSPEFSCR:
10535 icode = CODE_FOR_spe_mfspefscr;
10536 tmode = insn_data[icode].operand[0].mode;
10539 || GET_MODE (target) != tmode
10540 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10541 target = gen_reg_rtx (tmode);
10543 pat = GEN_FCN (icode) (target);
10548 case SPE_BUILTIN_MTSPEFSCR:
10549 icode = CODE_FOR_spe_mtspefscr;
10550 arg0 = CALL_EXPR_ARG (exp, 0);
10551 op0 = expand_normal (arg0);
10552 mode0 = insn_data[icode].operand[0].mode;
10554 if (arg0 == error_mark_node)
10557 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10558 op0 = copy_to_mode_reg (mode0, op0);
10560 pat = GEN_FCN (icode) (op0);
10568 *expandedp = false;
10573 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10575 rtx pat, scratch, tmp;
10576 tree form = CALL_EXPR_ARG (exp, 0);
10577 tree arg0 = CALL_EXPR_ARG (exp, 1);
10578 tree arg1 = CALL_EXPR_ARG (exp, 2);
10579 rtx op0 = expand_normal (arg0);
10580 rtx op1 = expand_normal (arg1);
10581 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10582 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10584 enum rtx_code code;
10586 if (TREE_CODE (form) != INTEGER_CST)
10588 error ("argument 1 of __builtin_paired_predicate must be a constant");
10592 form_int = TREE_INT_CST_LOW (form);
10594 gcc_assert (mode0 == mode1);
10596 if (arg0 == error_mark_node || arg1 == error_mark_node)
10600 || GET_MODE (target) != SImode
10601 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
10602 target = gen_reg_rtx (SImode);
10603 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10604 op0 = copy_to_mode_reg (mode0, op0);
10605 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10606 op1 = copy_to_mode_reg (mode1, op1);
10608 scratch = gen_reg_rtx (CCFPmode);
10610 pat = GEN_FCN (icode) (scratch, op0, op1);
10632 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10635 error ("argument 1 of __builtin_paired_predicate is out of range");
10639 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10640 emit_move_insn (target, tmp);
10645 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10647 rtx pat, scratch, tmp;
10648 tree form = CALL_EXPR_ARG (exp, 0);
10649 tree arg0 = CALL_EXPR_ARG (exp, 1);
10650 tree arg1 = CALL_EXPR_ARG (exp, 2);
10651 rtx op0 = expand_normal (arg0);
10652 rtx op1 = expand_normal (arg1);
10653 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10654 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10656 enum rtx_code code;
10658 if (TREE_CODE (form) != INTEGER_CST)
10660 error ("argument 1 of __builtin_spe_predicate must be a constant");
10664 form_int = TREE_INT_CST_LOW (form);
10666 gcc_assert (mode0 == mode1);
10668 if (arg0 == error_mark_node || arg1 == error_mark_node)
10672 || GET_MODE (target) != SImode
10673 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
10674 target = gen_reg_rtx (SImode);
10676 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10677 op0 = copy_to_mode_reg (mode0, op0);
10678 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10679 op1 = copy_to_mode_reg (mode1, op1);
10681 scratch = gen_reg_rtx (CCmode);
10683 pat = GEN_FCN (icode) (scratch, op0, op1);
10688 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
10689 _lower_. We use one compare, but look in different bits of the
10690 CR for each variant.
10692 There are 2 elements in each SPE simd type (upper/lower). The CR
10693 bits are set as follows:
10695 BIT0 | BIT 1 | BIT 2 | BIT 3
10696 U | L | (U | L) | (U & L)
10698 So, for an "all" relationship, BIT 3 would be set.
10699 For an "any" relationship, BIT 2 would be set. Etc.
10701 Following traditional nomenclature, these bits map to:
10703 BIT0 | BIT 1 | BIT 2 | BIT 3
10706 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
10711 /* All variant. OV bit. */
10713 /* We need to get to the OV bit, which is the ORDERED bit. We
10714 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
10715 that's ugly and will make validate_condition_mode die.
10716 So let's just use another pattern. */
10717 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10719 /* Any variant. EQ bit. */
10723 /* Upper variant. LT bit. */
10727 /* Lower variant. GT bit. */
10732 error ("argument 1 of __builtin_spe_predicate is out of range");
10736 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10737 emit_move_insn (target, tmp);
10742 /* The evsel builtins look like this:
10744 e = __builtin_spe_evsel_OP (a, b, c, d);
10746 and work like this:
10748 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
10749 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
10753 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
10756 tree arg0 = CALL_EXPR_ARG (exp, 0);
10757 tree arg1 = CALL_EXPR_ARG (exp, 1);
10758 tree arg2 = CALL_EXPR_ARG (exp, 2);
10759 tree arg3 = CALL_EXPR_ARG (exp, 3);
10760 rtx op0 = expand_normal (arg0);
10761 rtx op1 = expand_normal (arg1);
10762 rtx op2 = expand_normal (arg2);
10763 rtx op3 = expand_normal (arg3);
10764 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10765 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10767 gcc_assert (mode0 == mode1);
10769 if (arg0 == error_mark_node || arg1 == error_mark_node
10770 || arg2 == error_mark_node || arg3 == error_mark_node)
10774 || GET_MODE (target) != mode0
10775 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
10776 target = gen_reg_rtx (mode0);
10778 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10779 op0 = copy_to_mode_reg (mode0, op0);
10780 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10781 op1 = copy_to_mode_reg (mode0, op1);
10782 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10783 op2 = copy_to_mode_reg (mode0, op2);
10784 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
10785 op3 = copy_to_mode_reg (mode0, op3);
10787 /* Generate the compare. */
10788 scratch = gen_reg_rtx (CCmode);
10789 pat = GEN_FCN (icode) (scratch, op0, op1);
10794 if (mode0 == V2SImode)
10795 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
10797 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
10802 /* Expand an expression EXP that calls a built-in function,
10803 with result going to TARGET if that's convenient
10804 (and in mode MODE if that's convenient).
10805 SUBTARGET may be used as the target for computing one of EXP's operands.
10806 IGNORE is nonzero if the value is to be ignored. */
10809 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10810 enum machine_mode mode ATTRIBUTE_UNUSED,
10811 int ignore ATTRIBUTE_UNUSED)
10813 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10814 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10815 const struct builtin_description *d;
10820 if (fcode == RS6000_BUILTIN_RECIP)
10821 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
10823 if (fcode == RS6000_BUILTIN_RECIPF)
10824 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
10826 if (fcode == RS6000_BUILTIN_RSQRTF)
10827 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
10829 if (fcode == RS6000_BUILTIN_BSWAP_HI)
10830 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
10832 if (fcode == POWER7_BUILTIN_BPERMD)
10833 return rs6000_expand_binop_builtin (((TARGET_64BIT)
10834 ? CODE_FOR_bpermd_di
10835 : CODE_FOR_bpermd_si), exp, target);
10837 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
10838 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10840 int icode = (int) CODE_FOR_altivec_lvsr;
10841 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10842 enum machine_mode mode = insn_data[icode].operand[1].mode;
10846 gcc_assert (TARGET_ALTIVEC);
10848 arg = CALL_EXPR_ARG (exp, 0);
10849 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
10850 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
10851 addr = memory_address (mode, op);
10852 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10856 /* For the load case need to negate the address. */
10857 op = gen_reg_rtx (GET_MODE (addr));
10858 emit_insn (gen_rtx_SET (VOIDmode, op,
10859 gen_rtx_NEG (GET_MODE (addr), addr)));
10861 op = gen_rtx_MEM (mode, op);
10864 || GET_MODE (target) != tmode
10865 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10866 target = gen_reg_rtx (tmode);
10868 /*pat = gen_altivec_lvsr (target, op);*/
10869 pat = GEN_FCN (icode) (target, op);
10877 /* FIXME: There's got to be a nicer way to handle this case than
10878 constructing a new CALL_EXPR. */
10879 if (fcode == ALTIVEC_BUILTIN_VCFUX
10880 || fcode == ALTIVEC_BUILTIN_VCFSX
10881 || fcode == ALTIVEC_BUILTIN_VCTUXS
10882 || fcode == ALTIVEC_BUILTIN_VCTSXS)
10884 if (call_expr_nargs (exp) == 1)
10885 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
10886 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
10889 if (TARGET_ALTIVEC)
10891 ret = altivec_expand_builtin (exp, target, &success);
10898 ret = spe_expand_builtin (exp, target, &success);
10903 if (TARGET_PAIRED_FLOAT)
10905 ret = paired_expand_builtin (exp, target, &success);
10911 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
10913 /* Handle simple unary operations. */
10914 d = (struct builtin_description *) bdesc_1arg;
10915 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
10916 if (d->code == fcode)
10917 return rs6000_expand_unop_builtin (d->icode, exp, target);
10919 /* Handle simple binary operations. */
10920 d = (struct builtin_description *) bdesc_2arg;
10921 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
10922 if (d->code == fcode)
10923 return rs6000_expand_binop_builtin (d->icode, exp, target);
10925 /* Handle simple ternary operations. */
10927 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
10928 if (d->code == fcode)
10929 return rs6000_expand_ternop_builtin (d->icode, exp, target);
10931 gcc_unreachable ();
10935 rs6000_init_builtins (void)
10939 V2SI_type_node = build_vector_type (intSI_type_node, 2);
10940 V2SF_type_node = build_vector_type (float_type_node, 2);
10941 V2DI_type_node = build_vector_type (intDI_type_node, 2);
10942 V2DF_type_node = build_vector_type (double_type_node, 2);
10943 V4HI_type_node = build_vector_type (intHI_type_node, 4);
10944 V4SI_type_node = build_vector_type (intSI_type_node, 4);
10945 V4SF_type_node = build_vector_type (float_type_node, 4);
10946 V8HI_type_node = build_vector_type (intHI_type_node, 8);
10947 V16QI_type_node = build_vector_type (intQI_type_node, 16);
10949 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
10950 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
10951 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
10952 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
10954 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
10955 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
10956 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
10957 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
10959 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
10960 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
10961 'vector unsigned short'. */
10963 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
10964 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
10965 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
10966 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
10967 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
10969 long_integer_type_internal_node = long_integer_type_node;
10970 long_unsigned_type_internal_node = long_unsigned_type_node;
10971 intQI_type_internal_node = intQI_type_node;
10972 uintQI_type_internal_node = unsigned_intQI_type_node;
10973 intHI_type_internal_node = intHI_type_node;
10974 uintHI_type_internal_node = unsigned_intHI_type_node;
10975 intSI_type_internal_node = intSI_type_node;
10976 uintSI_type_internal_node = unsigned_intSI_type_node;
10977 intDI_type_internal_node = intDI_type_node;
10978 uintDI_type_internal_node = unsigned_intDI_type_node;
10979 float_type_internal_node = float_type_node;
10980 double_type_internal_node = float_type_node;
10981 void_type_internal_node = void_type_node;
10983 /* Initialize the modes for builtin_function_type, mapping a machine mode to
10985 builtin_mode_to_type[QImode][0] = integer_type_node;
10986 builtin_mode_to_type[HImode][0] = integer_type_node;
10987 builtin_mode_to_type[SImode][0] = intSI_type_node;
10988 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
10989 builtin_mode_to_type[DImode][0] = intDI_type_node;
10990 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
10991 builtin_mode_to_type[SFmode][0] = float_type_node;
10992 builtin_mode_to_type[DFmode][0] = double_type_node;
10993 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
10994 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
10995 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
10996 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
10997 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
10998 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
10999 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11000 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11001 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11002 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11003 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11004 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11005 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11007 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11008 get_identifier ("__bool char"),
11009 bool_char_type_node);
11010 TYPE_NAME (bool_char_type_node) = tdecl;
11011 (*lang_hooks.decls.pushdecl) (tdecl);
11012 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11013 get_identifier ("__bool short"),
11014 bool_short_type_node);
11015 TYPE_NAME (bool_short_type_node) = tdecl;
11016 (*lang_hooks.decls.pushdecl) (tdecl);
11017 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11018 get_identifier ("__bool int"),
11019 bool_int_type_node);
11020 TYPE_NAME (bool_int_type_node) = tdecl;
11021 (*lang_hooks.decls.pushdecl) (tdecl);
11022 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
11024 TYPE_NAME (pixel_type_node) = tdecl;
11025 (*lang_hooks.decls.pushdecl) (tdecl);
11027 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
11028 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11029 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11030 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11031 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11033 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11034 get_identifier ("__vector unsigned char"),
11035 unsigned_V16QI_type_node);
11036 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11037 (*lang_hooks.decls.pushdecl) (tdecl);
11038 tdecl = build_decl (BUILTINS_LOCATION,
11039 TYPE_DECL, get_identifier ("__vector signed char"),
11041 TYPE_NAME (V16QI_type_node) = tdecl;
11042 (*lang_hooks.decls.pushdecl) (tdecl);
11043 tdecl = build_decl (BUILTINS_LOCATION,
11044 TYPE_DECL, get_identifier ("__vector __bool char"),
11045 bool_V16QI_type_node);
11046 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11047 (*lang_hooks.decls.pushdecl) (tdecl);
11049 tdecl = build_decl (BUILTINS_LOCATION,
11050 TYPE_DECL, get_identifier ("__vector unsigned short"),
11051 unsigned_V8HI_type_node);
11052 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11053 (*lang_hooks.decls.pushdecl) (tdecl);
11054 tdecl = build_decl (BUILTINS_LOCATION,
11055 TYPE_DECL, get_identifier ("__vector signed short"),
11057 TYPE_NAME (V8HI_type_node) = tdecl;
11058 (*lang_hooks.decls.pushdecl) (tdecl);
11059 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11060 get_identifier ("__vector __bool short"),
11061 bool_V8HI_type_node);
11062 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11063 (*lang_hooks.decls.pushdecl) (tdecl);
11065 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11066 get_identifier ("__vector unsigned int"),
11067 unsigned_V4SI_type_node);
11068 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11069 (*lang_hooks.decls.pushdecl) (tdecl);
11070 tdecl = build_decl (BUILTINS_LOCATION,
11071 TYPE_DECL, get_identifier ("__vector signed int"),
11073 TYPE_NAME (V4SI_type_node) = tdecl;
11074 (*lang_hooks.decls.pushdecl) (tdecl);
11075 tdecl = build_decl (BUILTINS_LOCATION,
11076 TYPE_DECL, get_identifier ("__vector __bool int"),
11077 bool_V4SI_type_node);
11078 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11079 (*lang_hooks.decls.pushdecl) (tdecl);
11081 tdecl = build_decl (BUILTINS_LOCATION,
11082 TYPE_DECL, get_identifier ("__vector float"),
11084 TYPE_NAME (V4SF_type_node) = tdecl;
11085 (*lang_hooks.decls.pushdecl) (tdecl);
11086 tdecl = build_decl (BUILTINS_LOCATION,
11087 TYPE_DECL, get_identifier ("__vector __pixel"),
11088 pixel_V8HI_type_node);
11089 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11090 (*lang_hooks.decls.pushdecl) (tdecl);
11094 tdecl = build_decl (BUILTINS_LOCATION,
11095 TYPE_DECL, get_identifier ("__vector double"),
11097 TYPE_NAME (V2DF_type_node) = tdecl;
11098 (*lang_hooks.decls.pushdecl) (tdecl);
11100 tdecl = build_decl (BUILTINS_LOCATION,
11101 TYPE_DECL, get_identifier ("__vector long"),
11103 TYPE_NAME (V2DI_type_node) = tdecl;
11104 (*lang_hooks.decls.pushdecl) (tdecl);
11106 tdecl = build_decl (BUILTINS_LOCATION,
11107 TYPE_DECL, get_identifier ("__vector unsigned long"),
11108 unsigned_V2DI_type_node);
11109 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11110 (*lang_hooks.decls.pushdecl) (tdecl);
11112 tdecl = build_decl (BUILTINS_LOCATION,
11113 TYPE_DECL, get_identifier ("__vector __bool long"),
11114 bool_V2DI_type_node);
11115 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11116 (*lang_hooks.decls.pushdecl) (tdecl);
11119 if (TARGET_PAIRED_FLOAT)
11120 paired_init_builtins ();
11122 spe_init_builtins ();
11123 if (TARGET_ALTIVEC)
11124 altivec_init_builtins ();
11125 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11126 rs6000_common_init_builtins ();
11127 if (TARGET_PPC_GFXOPT)
11129 tree ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11130 RS6000_BUILTIN_RECIPF,
11131 "__builtin_recipdivf");
11132 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11133 RS6000_BUILTIN_RECIPF);
11135 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11136 RS6000_BUILTIN_RSQRTF,
11137 "__builtin_rsqrtf");
11138 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11139 RS6000_BUILTIN_RSQRTF);
11141 if (TARGET_POPCNTB)
11143 tree ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11144 RS6000_BUILTIN_RECIP,
11145 "__builtin_recipdiv");
11146 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11147 RS6000_BUILTIN_RECIP);
11150 if (TARGET_POPCNTD)
11152 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11153 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11154 POWER7_BUILTIN_BPERMD,
11155 "__builtin_bpermd");
11156 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11157 POWER7_BUILTIN_BPERMD);
11159 if (TARGET_POWERPC)
11161 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11162 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11163 unsigned_intHI_type_node,
11165 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11166 RS6000_BUILTIN_BSWAP_HI);
11170 /* AIX libm provides clog as __clog. */
11171 if (built_in_decls [BUILT_IN_CLOG])
11172 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11175 #ifdef SUBTARGET_INIT_BUILTINS
11176 SUBTARGET_INIT_BUILTINS;
11180 /* Returns the rs6000 builtin decl for CODE. */
11183 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
11185 if (code >= RS6000_BUILTIN_COUNT)
11186 return error_mark_node;
11188 return rs6000_builtin_decls[code];
11191 /* Search through a set of builtins and enable the mask bits.
11192 DESC is an array of builtins.
11193 SIZE is the total number of builtins.
11194 START is the builtin enum at which to start.
11195 END is the builtin enum at which to end. */
11197 enable_mask_for_builtins (struct builtin_description *desc, int size,
11198 enum rs6000_builtins start,
11199 enum rs6000_builtins end)
11203 for (i = 0; i < size; ++i)
11204 if (desc[i].code == start)
11210 for (; i < size; ++i)
11212 /* Flip all the bits on. */
11213 desc[i].mask = target_flags;
11214 if (desc[i].code == end)
11220 spe_init_builtins (void)
11222 tree endlink = void_list_node;
11223 tree puint_type_node = build_pointer_type (unsigned_type_node);
11224 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11225 struct builtin_description *d;
11228 tree v2si_ftype_4_v2si
11229 = build_function_type
11230 (opaque_V2SI_type_node,
11231 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11232 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11233 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11234 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11237 tree v2sf_ftype_4_v2sf
11238 = build_function_type
11239 (opaque_V2SF_type_node,
11240 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11241 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11242 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11243 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11246 tree int_ftype_int_v2si_v2si
11247 = build_function_type
11248 (integer_type_node,
11249 tree_cons (NULL_TREE, integer_type_node,
11250 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11251 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11254 tree int_ftype_int_v2sf_v2sf
11255 = build_function_type
11256 (integer_type_node,
11257 tree_cons (NULL_TREE, integer_type_node,
11258 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11259 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11262 tree void_ftype_v2si_puint_int
11263 = build_function_type (void_type_node,
11264 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11265 tree_cons (NULL_TREE, puint_type_node,
11266 tree_cons (NULL_TREE,
11270 tree void_ftype_v2si_puint_char
11271 = build_function_type (void_type_node,
11272 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11273 tree_cons (NULL_TREE, puint_type_node,
11274 tree_cons (NULL_TREE,
11278 tree void_ftype_v2si_pv2si_int
11279 = build_function_type (void_type_node,
11280 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11281 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11282 tree_cons (NULL_TREE,
11286 tree void_ftype_v2si_pv2si_char
11287 = build_function_type (void_type_node,
11288 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11289 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11290 tree_cons (NULL_TREE,
11294 tree void_ftype_int
11295 = build_function_type (void_type_node,
11296 tree_cons (NULL_TREE, integer_type_node, endlink));
11298 tree int_ftype_void
11299 = build_function_type (integer_type_node, endlink);
11301 tree v2si_ftype_pv2si_int
11302 = build_function_type (opaque_V2SI_type_node,
11303 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11304 tree_cons (NULL_TREE, integer_type_node,
11307 tree v2si_ftype_puint_int
11308 = build_function_type (opaque_V2SI_type_node,
11309 tree_cons (NULL_TREE, puint_type_node,
11310 tree_cons (NULL_TREE, integer_type_node,
11313 tree v2si_ftype_pushort_int
11314 = build_function_type (opaque_V2SI_type_node,
11315 tree_cons (NULL_TREE, pushort_type_node,
11316 tree_cons (NULL_TREE, integer_type_node,
11319 tree v2si_ftype_signed_char
11320 = build_function_type (opaque_V2SI_type_node,
11321 tree_cons (NULL_TREE, signed_char_type_node,
11324 /* The initialization of the simple binary and unary builtins is
11325 done in rs6000_common_init_builtins, but we have to enable the
11326 mask bits here manually because we have run out of `target_flags'
11327 bits. We really need to redesign this mask business. */
11329 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11330 ARRAY_SIZE (bdesc_2arg),
11331 SPE_BUILTIN_EVADDW,
11332 SPE_BUILTIN_EVXOR);
11333 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11334 ARRAY_SIZE (bdesc_1arg),
11336 SPE_BUILTIN_EVSUBFUSIAAW);
11337 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11338 ARRAY_SIZE (bdesc_spe_predicates),
11339 SPE_BUILTIN_EVCMPEQ,
11340 SPE_BUILTIN_EVFSTSTLT);
11341 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11342 ARRAY_SIZE (bdesc_spe_evsel),
11343 SPE_BUILTIN_EVSEL_CMPGTS,
11344 SPE_BUILTIN_EVSEL_FSTSTEQ);
11346 (*lang_hooks.decls.pushdecl)
11347 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11348 get_identifier ("__ev64_opaque__"),
11349 opaque_V2SI_type_node));
11351 /* Initialize irregular SPE builtins. */
11353 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11354 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11355 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11356 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11357 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11358 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11359 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11360 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11361 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11362 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11363 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11364 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11365 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11366 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11367 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11368 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11369 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11370 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11373 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11374 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11375 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11376 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11377 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11378 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11379 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11380 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11381 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11382 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11383 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11384 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11385 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11386 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11387 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11388 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11389 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11390 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11391 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11392 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11393 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11394 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11397 d = (struct builtin_description *) bdesc_spe_predicates;
11398 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11402 switch (insn_data[d->icode].operand[1].mode)
11405 type = int_ftype_int_v2si_v2si;
11408 type = int_ftype_int_v2sf_v2sf;
11411 gcc_unreachable ();
11414 def_builtin (d->mask, d->name, type, d->code);
11417 /* Evsel predicates. */
11418 d = (struct builtin_description *) bdesc_spe_evsel;
11419 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11423 switch (insn_data[d->icode].operand[1].mode)
11426 type = v2si_ftype_4_v2si;
11429 type = v2sf_ftype_4_v2sf;
11432 gcc_unreachable ();
11435 def_builtin (d->mask, d->name, type, d->code);
11440 paired_init_builtins (void)
11442 const struct builtin_description *d;
11444 tree endlink = void_list_node;
11446 tree int_ftype_int_v2sf_v2sf
11447 = build_function_type
11448 (integer_type_node,
11449 tree_cons (NULL_TREE, integer_type_node,
11450 tree_cons (NULL_TREE, V2SF_type_node,
11451 tree_cons (NULL_TREE, V2SF_type_node,
11453 tree pcfloat_type_node =
11454 build_pointer_type (build_qualified_type
11455 (float_type_node, TYPE_QUAL_CONST));
11457 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
11458 long_integer_type_node,
11461 tree void_ftype_v2sf_long_pcfloat =
11462 build_function_type_list (void_type_node,
11464 long_integer_type_node,
11469 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
11470 PAIRED_BUILTIN_LX);
11473 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
11474 PAIRED_BUILTIN_STX);
11477 d = bdesc_paired_preds;
11478 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
11482 switch (insn_data[d->icode].operand[1].mode)
11485 type = int_ftype_int_v2sf_v2sf;
11488 gcc_unreachable ();
11491 def_builtin (d->mask, d->name, type, d->code);
11496 altivec_init_builtins (void)
11498 const struct builtin_description *d;
11499 const struct builtin_description_predicates *dp;
11503 tree pfloat_type_node = build_pointer_type (float_type_node);
11504 tree pint_type_node = build_pointer_type (integer_type_node);
11505 tree pshort_type_node = build_pointer_type (short_integer_type_node);
11506 tree pchar_type_node = build_pointer_type (char_type_node);
11508 tree pvoid_type_node = build_pointer_type (void_type_node);
11510 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
11511 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
11512 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
11513 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
11515 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
11517 tree int_ftype_opaque
11518 = build_function_type_list (integer_type_node,
11519 opaque_V4SI_type_node, NULL_TREE);
11520 tree opaque_ftype_opaque
11521 = build_function_type (integer_type_node,
11523 tree opaque_ftype_opaque_int
11524 = build_function_type_list (opaque_V4SI_type_node,
11525 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
11526 tree opaque_ftype_opaque_opaque_int
11527 = build_function_type_list (opaque_V4SI_type_node,
11528 opaque_V4SI_type_node, opaque_V4SI_type_node,
11529 integer_type_node, NULL_TREE);
11530 tree int_ftype_int_opaque_opaque
11531 = build_function_type_list (integer_type_node,
11532 integer_type_node, opaque_V4SI_type_node,
11533 opaque_V4SI_type_node, NULL_TREE);
11534 tree int_ftype_int_v4si_v4si
11535 = build_function_type_list (integer_type_node,
11536 integer_type_node, V4SI_type_node,
11537 V4SI_type_node, NULL_TREE);
11538 tree v4sf_ftype_pcfloat
11539 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
11540 tree void_ftype_pfloat_v4sf
11541 = build_function_type_list (void_type_node,
11542 pfloat_type_node, V4SF_type_node, NULL_TREE);
11543 tree v4si_ftype_pcint
11544 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
11545 tree void_ftype_pint_v4si
11546 = build_function_type_list (void_type_node,
11547 pint_type_node, V4SI_type_node, NULL_TREE);
11548 tree v8hi_ftype_pcshort
11549 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
11550 tree void_ftype_pshort_v8hi
11551 = build_function_type_list (void_type_node,
11552 pshort_type_node, V8HI_type_node, NULL_TREE);
11553 tree v16qi_ftype_pcchar
11554 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
11555 tree void_ftype_pchar_v16qi
11556 = build_function_type_list (void_type_node,
11557 pchar_type_node, V16QI_type_node, NULL_TREE);
11558 tree void_ftype_v4si
11559 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
11560 tree v8hi_ftype_void
11561 = build_function_type (V8HI_type_node, void_list_node);
11562 tree void_ftype_void
11563 = build_function_type (void_type_node, void_list_node);
11564 tree void_ftype_int
11565 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
11567 tree opaque_ftype_long_pcvoid
11568 = build_function_type_list (opaque_V4SI_type_node,
11569 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11570 tree v16qi_ftype_long_pcvoid
11571 = build_function_type_list (V16QI_type_node,
11572 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11573 tree v8hi_ftype_long_pcvoid
11574 = build_function_type_list (V8HI_type_node,
11575 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11576 tree v4si_ftype_long_pcvoid
11577 = build_function_type_list (V4SI_type_node,
11578 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11580 tree void_ftype_opaque_long_pvoid
11581 = build_function_type_list (void_type_node,
11582 opaque_V4SI_type_node, long_integer_type_node,
11583 pvoid_type_node, NULL_TREE);
11584 tree void_ftype_v4si_long_pvoid
11585 = build_function_type_list (void_type_node,
11586 V4SI_type_node, long_integer_type_node,
11587 pvoid_type_node, NULL_TREE);
11588 tree void_ftype_v16qi_long_pvoid
11589 = build_function_type_list (void_type_node,
11590 V16QI_type_node, long_integer_type_node,
11591 pvoid_type_node, NULL_TREE);
11592 tree void_ftype_v8hi_long_pvoid
11593 = build_function_type_list (void_type_node,
11594 V8HI_type_node, long_integer_type_node,
11595 pvoid_type_node, NULL_TREE);
11596 tree int_ftype_int_v8hi_v8hi
11597 = build_function_type_list (integer_type_node,
11598 integer_type_node, V8HI_type_node,
11599 V8HI_type_node, NULL_TREE);
11600 tree int_ftype_int_v16qi_v16qi
11601 = build_function_type_list (integer_type_node,
11602 integer_type_node, V16QI_type_node,
11603 V16QI_type_node, NULL_TREE);
11604 tree int_ftype_int_v4sf_v4sf
11605 = build_function_type_list (integer_type_node,
11606 integer_type_node, V4SF_type_node,
11607 V4SF_type_node, NULL_TREE);
11608 tree int_ftype_int_v2df_v2df
11609 = build_function_type_list (integer_type_node,
11610 integer_type_node, V2DF_type_node,
11611 V2DF_type_node, NULL_TREE);
11612 tree v4si_ftype_v4si
11613 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
11614 tree v8hi_ftype_v8hi
11615 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
11616 tree v16qi_ftype_v16qi
11617 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
11618 tree v4sf_ftype_v4sf
11619 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
11620 tree v2df_ftype_v2df
11621 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
11622 tree void_ftype_pcvoid_int_int
11623 = build_function_type_list (void_type_node,
11624 pcvoid_type_node, integer_type_node,
11625 integer_type_node, NULL_TREE);
11627 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
11628 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
11629 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
11630 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
11631 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
11632 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
11633 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
11634 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
11635 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
11636 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
11637 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
11638 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
11639 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
11640 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
11641 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
11642 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
11643 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
11644 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
11645 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
11646 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
11647 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
11648 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
11649 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
11650 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
11651 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
11652 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
11653 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
11654 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
11655 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
11656 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
11657 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
11658 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
11659 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
11660 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
11661 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
11662 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
11663 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
11664 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
11665 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
11666 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
11667 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
11668 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
11669 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
11670 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
11671 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
11672 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
11674 if (rs6000_cpu == PROCESSOR_CELL)
11676 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
11677 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
11678 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
11679 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
11681 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
11682 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
11683 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
11684 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
11686 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
11687 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
11688 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
11689 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
11691 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
11692 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
11693 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
11694 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
11696 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
11697 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
11698 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
11700 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
11701 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
11702 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
11703 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
11704 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
11705 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
11706 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
11707 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
11708 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
11709 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
11710 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
11711 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
11713 /* Add the DST variants. */
11715 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11716 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
11718 /* Initialize the predicates. */
11719 dp = bdesc_altivec_preds;
11720 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11722 enum machine_mode mode1;
11724 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11725 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11726 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
11727 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
11732 mode1 = insn_data[dp->icode].operand[1].mode;
11737 type = int_ftype_int_opaque_opaque;
11740 type = int_ftype_int_v4si_v4si;
11743 type = int_ftype_int_v8hi_v8hi;
11746 type = int_ftype_int_v16qi_v16qi;
11749 type = int_ftype_int_v4sf_v4sf;
11752 type = int_ftype_int_v2df_v2df;
11755 gcc_unreachable ();
11758 def_builtin (dp->mask, dp->name, type, dp->code);
11761 /* Initialize the abs* operators. */
11763 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11765 enum machine_mode mode0;
11768 mode0 = insn_data[d->icode].operand[0].mode;
11773 type = v4si_ftype_v4si;
11776 type = v8hi_ftype_v8hi;
11779 type = v16qi_ftype_v16qi;
11782 type = v4sf_ftype_v4sf;
11785 type = v2df_ftype_v2df;
11788 gcc_unreachable ();
11791 def_builtin (d->mask, d->name, type, d->code);
11794 if (TARGET_ALTIVEC)
11798 /* Initialize target builtin that implements
11799 targetm.vectorize.builtin_mask_for_load. */
11801 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
11802 v16qi_ftype_long_pcvoid,
11803 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
11804 BUILT_IN_MD, NULL, NULL_TREE);
11805 TREE_READONLY (decl) = 1;
11806 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
11807 altivec_builtin_mask_for_load = decl;
11810 /* Access to the vec_init patterns. */
11811 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
11812 integer_type_node, integer_type_node,
11813 integer_type_node, NULL_TREE);
11814 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
11815 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
11817 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
11818 short_integer_type_node,
11819 short_integer_type_node,
11820 short_integer_type_node,
11821 short_integer_type_node,
11822 short_integer_type_node,
11823 short_integer_type_node,
11824 short_integer_type_node, NULL_TREE);
11825 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
11826 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
11828 ftype = build_function_type_list (V16QI_type_node, char_type_node,
11829 char_type_node, char_type_node,
11830 char_type_node, char_type_node,
11831 char_type_node, char_type_node,
11832 char_type_node, char_type_node,
11833 char_type_node, char_type_node,
11834 char_type_node, char_type_node,
11835 char_type_node, char_type_node,
11836 char_type_node, NULL_TREE);
11837 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
11838 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
11840 ftype = build_function_type_list (V4SF_type_node, float_type_node,
11841 float_type_node, float_type_node,
11842 float_type_node, NULL_TREE);
11843 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
11844 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
11848 ftype = build_function_type_list (V2DF_type_node, double_type_node,
11849 double_type_node, NULL_TREE);
11850 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
11851 VSX_BUILTIN_VEC_INIT_V2DF);
11853 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
11854 intDI_type_node, NULL_TREE);
11855 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
11856 VSX_BUILTIN_VEC_INIT_V2DI);
11859 /* Access to the vec_set patterns. */
11860 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
11862 integer_type_node, NULL_TREE);
11863 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
11864 ALTIVEC_BUILTIN_VEC_SET_V4SI);
11866 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
11868 integer_type_node, NULL_TREE);
11869 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
11870 ALTIVEC_BUILTIN_VEC_SET_V8HI);
11872 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
11874 integer_type_node, NULL_TREE);
11875 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
11876 ALTIVEC_BUILTIN_VEC_SET_V16QI);
11878 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
11880 integer_type_node, NULL_TREE);
11881 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
11882 ALTIVEC_BUILTIN_VEC_SET_V4SF);
11886 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
11888 integer_type_node, NULL_TREE);
11889 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
11890 VSX_BUILTIN_VEC_SET_V2DF);
11892 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
11894 integer_type_node, NULL_TREE);
11895 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
11896 VSX_BUILTIN_VEC_SET_V2DI);
11899 /* Access to the vec_extract patterns. */
11900 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
11901 integer_type_node, NULL_TREE);
11902 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
11903 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
11905 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
11906 integer_type_node, NULL_TREE);
11907 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
11908 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
11910 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
11911 integer_type_node, NULL_TREE);
11912 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
11913 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
11915 ftype = build_function_type_list (float_type_node, V4SF_type_node,
11916 integer_type_node, NULL_TREE);
11917 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
11918 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
11922 ftype = build_function_type_list (double_type_node, V2DF_type_node,
11923 integer_type_node, NULL_TREE);
11924 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
11925 VSX_BUILTIN_VEC_EXT_V2DF);
11927 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
11928 integer_type_node, NULL_TREE);
11929 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
11930 VSX_BUILTIN_VEC_EXT_V2DI);
11934 /* Hash function for builtin functions with up to 3 arguments and a return
11937 builtin_hash_function (const void *hash_entry)
11941 const struct builtin_hash_struct *bh =
11942 (const struct builtin_hash_struct *) hash_entry;
11944 for (i = 0; i < 4; i++)
11946 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
11947 ret = (ret * 2) + bh->uns_p[i];
11953 /* Compare builtin hash entries H1 and H2 for equivalence. */
11955 builtin_hash_eq (const void *h1, const void *h2)
11957 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
11958 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
11960 return ((p1->mode[0] == p2->mode[0])
11961 && (p1->mode[1] == p2->mode[1])
11962 && (p1->mode[2] == p2->mode[2])
11963 && (p1->mode[3] == p2->mode[3])
11964 && (p1->uns_p[0] == p2->uns_p[0])
11965 && (p1->uns_p[1] == p2->uns_p[1])
11966 && (p1->uns_p[2] == p2->uns_p[2])
11967 && (p1->uns_p[3] == p2->uns_p[3]));
11970 /* Map types for builtin functions with an explicit return type and up to 3
11971 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
11972 of the argument. */
11974 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
11975 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
11976 enum rs6000_builtins builtin, const char *name)
11978 struct builtin_hash_struct h;
11979 struct builtin_hash_struct *h2;
11983 tree ret_type = NULL_TREE;
11984 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
11987 /* Create builtin_hash_table. */
11988 if (builtin_hash_table == NULL)
11989 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
11990 builtin_hash_eq, NULL);
11992 h.type = NULL_TREE;
11993 h.mode[0] = mode_ret;
11994 h.mode[1] = mode_arg0;
11995 h.mode[2] = mode_arg1;
11996 h.mode[3] = mode_arg2;
12002 /* If the builtin is a type that produces unsigned results or takes unsigned
12003 arguments, and it is returned as a decl for the vectorizer (such as
12004 widening multiplies, permute), make sure the arguments and return value
12005 are type correct. */
12008 /* unsigned 2 argument functions. */
12009 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12010 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12011 case ALTIVEC_BUILTIN_VMULOUB_UNS:
12012 case ALTIVEC_BUILTIN_VMULOUH_UNS:
12018 /* unsigned 3 argument functions. */
12019 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
12020 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
12021 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
12022 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
12023 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
12024 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
12025 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
12026 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
12027 case VSX_BUILTIN_VPERM_16QI_UNS:
12028 case VSX_BUILTIN_VPERM_8HI_UNS:
12029 case VSX_BUILTIN_VPERM_4SI_UNS:
12030 case VSX_BUILTIN_VPERM_2DI_UNS:
12031 case VSX_BUILTIN_XXSEL_16QI_UNS:
12032 case VSX_BUILTIN_XXSEL_8HI_UNS:
12033 case VSX_BUILTIN_XXSEL_4SI_UNS:
12034 case VSX_BUILTIN_XXSEL_2DI_UNS:
12041 /* signed permute functions with unsigned char mask. */
12042 case ALTIVEC_BUILTIN_VPERM_16QI:
12043 case ALTIVEC_BUILTIN_VPERM_8HI:
12044 case ALTIVEC_BUILTIN_VPERM_4SI:
12045 case ALTIVEC_BUILTIN_VPERM_4SF:
12046 case ALTIVEC_BUILTIN_VPERM_2DI:
12047 case ALTIVEC_BUILTIN_VPERM_2DF:
12048 case VSX_BUILTIN_VPERM_16QI:
12049 case VSX_BUILTIN_VPERM_8HI:
12050 case VSX_BUILTIN_VPERM_4SI:
12051 case VSX_BUILTIN_VPERM_4SF:
12052 case VSX_BUILTIN_VPERM_2DI:
12053 case VSX_BUILTIN_VPERM_2DF:
12057 /* unsigned args, signed return. */
12058 case VSX_BUILTIN_XVCVUXDDP_UNS:
12059 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12063 /* signed args, unsigned return. */
12064 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12065 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12073 /* Figure out how many args are present. */
12074 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12078 fatal_error ("internal error: builtin function %s had no type", name);
12080 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12081 if (!ret_type && h.uns_p[0])
12082 ret_type = builtin_mode_to_type[h.mode[0]][0];
12085 fatal_error ("internal error: builtin function %s had an unexpected "
12086 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12088 for (i = 0; i < num_args; i++)
12090 int m = (int) h.mode[i+1];
12091 int uns_p = h.uns_p[i+1];
12093 arg_type[i] = builtin_mode_to_type[m][uns_p];
12094 if (!arg_type[i] && uns_p)
12095 arg_type[i] = builtin_mode_to_type[m][0];
12098 fatal_error ("internal error: builtin function %s, argument %d "
12099 "had unexpected argument type %s", name, i,
12100 GET_MODE_NAME (m));
12103 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12104 if (*found == NULL)
12106 h2 = GGC_NEW (struct builtin_hash_struct);
12108 *found = (void *)h2;
12109 args = void_list_node;
12111 for (i = num_args - 1; i >= 0; i--)
12112 args = tree_cons (NULL_TREE, arg_type[i], args);
12114 h2->type = build_function_type (ret_type, args);
12117 return ((struct builtin_hash_struct *)(*found))->type;
12121 rs6000_common_init_builtins (void)
12123 const struct builtin_description *d;
12126 tree opaque_ftype_opaque = NULL_TREE;
12127 tree opaque_ftype_opaque_opaque = NULL_TREE;
12128 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12129 tree v2si_ftype_qi = NULL_TREE;
12130 tree v2si_ftype_v2si_qi = NULL_TREE;
12131 tree v2si_ftype_int_qi = NULL_TREE;
12133 if (!TARGET_PAIRED_FLOAT)
12135 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12136 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12139 /* Add the ternary operators. */
12141 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12144 int mask = d->mask;
12146 if ((mask != 0 && (mask & target_flags) == 0)
12147 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12150 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12151 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12152 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12153 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12155 if (! (type = opaque_ftype_opaque_opaque_opaque))
12156 type = opaque_ftype_opaque_opaque_opaque
12157 = build_function_type_list (opaque_V4SI_type_node,
12158 opaque_V4SI_type_node,
12159 opaque_V4SI_type_node,
12160 opaque_V4SI_type_node,
12165 enum insn_code icode = d->icode;
12166 if (d->name == 0 || icode == CODE_FOR_nothing)
12169 type = builtin_function_type (insn_data[icode].operand[0].mode,
12170 insn_data[icode].operand[1].mode,
12171 insn_data[icode].operand[2].mode,
12172 insn_data[icode].operand[3].mode,
12176 def_builtin (d->mask, d->name, type, d->code);
12179 /* Add the binary operators. */
12181 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12183 enum machine_mode mode0, mode1, mode2;
12185 int mask = d->mask;
12187 if ((mask != 0 && (mask & target_flags) == 0)
12188 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12191 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12192 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12193 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12194 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12196 if (! (type = opaque_ftype_opaque_opaque))
12197 type = opaque_ftype_opaque_opaque
12198 = build_function_type_list (opaque_V4SI_type_node,
12199 opaque_V4SI_type_node,
12200 opaque_V4SI_type_node,
12205 enum insn_code icode = d->icode;
12206 if (d->name == 0 || icode == CODE_FOR_nothing)
12209 mode0 = insn_data[icode].operand[0].mode;
12210 mode1 = insn_data[icode].operand[1].mode;
12211 mode2 = insn_data[icode].operand[2].mode;
12213 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12215 if (! (type = v2si_ftype_v2si_qi))
12216 type = v2si_ftype_v2si_qi
12217 = build_function_type_list (opaque_V2SI_type_node,
12218 opaque_V2SI_type_node,
12223 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12224 && mode2 == QImode)
12226 if (! (type = v2si_ftype_int_qi))
12227 type = v2si_ftype_int_qi
12228 = build_function_type_list (opaque_V2SI_type_node,
12235 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12239 def_builtin (d->mask, d->name, type, d->code);
12242 /* Add the simple unary operators. */
12243 d = (struct builtin_description *) bdesc_1arg;
12244 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12246 enum machine_mode mode0, mode1;
12248 int mask = d->mask;
12250 if ((mask != 0 && (mask & target_flags) == 0)
12251 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12254 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12255 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12256 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12257 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12259 if (! (type = opaque_ftype_opaque))
12260 type = opaque_ftype_opaque
12261 = build_function_type_list (opaque_V4SI_type_node,
12262 opaque_V4SI_type_node,
12267 enum insn_code icode = d->icode;
12268 if (d->name == 0 || icode == CODE_FOR_nothing)
12271 mode0 = insn_data[icode].operand[0].mode;
12272 mode1 = insn_data[icode].operand[1].mode;
12274 if (mode0 == V2SImode && mode1 == QImode)
12276 if (! (type = v2si_ftype_qi))
12277 type = v2si_ftype_qi
12278 = build_function_type_list (opaque_V2SI_type_node,
12284 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12288 def_builtin (d->mask, d->name, type, d->code);
12293 rs6000_init_libfuncs (void)
12295 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12296 && !TARGET_POWER2 && !TARGET_POWERPC)
12298 /* AIX library routines for float->int conversion. */
12299 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12300 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12301 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12302 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12305 if (!TARGET_IEEEQUAD)
12306 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12307 if (!TARGET_XL_COMPAT)
12309 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12310 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12311 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12312 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12314 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12316 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12317 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12318 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12319 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12320 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12321 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12322 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12324 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12325 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12326 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12327 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12328 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12329 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12330 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12331 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12334 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12335 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12339 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12340 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12341 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12342 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12346 /* 32-bit SVR4 quad floating point routines. */
12348 set_optab_libfunc (add_optab, TFmode, "_q_add");
12349 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12350 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12351 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12352 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12353 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12354 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12356 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12357 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12358 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12359 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12360 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12361 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12363 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12364 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12365 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12366 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12367 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12368 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12369 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12370 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12375 /* Expand a block clear operation, and return 1 if successful. Return 0
12376 if we should let the compiler generate normal code.
12378 operands[0] is the destination
12379 operands[1] is the length
12380 operands[3] is the alignment */
12383 expand_block_clear (rtx operands[])
12385 rtx orig_dest = operands[0];
12386 rtx bytes_rtx = operands[1];
12387 rtx align_rtx = operands[3];
12388 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12389 HOST_WIDE_INT align;
12390 HOST_WIDE_INT bytes;
12395 /* If this is not a fixed size move, just call memcpy */
12399 /* This must be a fixed size alignment */
12400 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12401 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12403 /* Anything to clear? */
12404 bytes = INTVAL (bytes_rtx);
12408 /* Use the builtin memset after a point, to avoid huge code bloat.
12409 When optimize_size, avoid any significant code bloat; calling
12410 memset is about 4 instructions, so allow for one instruction to
12411 load zero and three to do clearing. */
12412 if (TARGET_ALTIVEC && align >= 128)
12414 else if (TARGET_POWERPC64 && align >= 32)
12416 else if (TARGET_SPE && align >= 64)
12421 if (optimize_size && bytes > 3 * clear_step)
12423 if (! optimize_size && bytes > 8 * clear_step)
12426 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12428 enum machine_mode mode = BLKmode;
12431 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
12436 else if (bytes >= 8 && TARGET_SPE && align >= 64)
12441 else if (bytes >= 8 && TARGET_POWERPC64
12442 /* 64-bit loads and stores require word-aligned
12444 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12449 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12450 { /* move 4 bytes */
12454 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12455 { /* move 2 bytes */
12459 else /* move 1 byte at a time */
12465 dest = adjust_address (orig_dest, mode, offset);
12467 emit_move_insn (dest, CONST0_RTX (mode));
12474 /* Expand a block move operation, and return 1 if successful. Return 0
12475 if we should let the compiler generate normal code.
12477 operands[0] is the destination
12478 operands[1] is the source
12479 operands[2] is the length
12480 operands[3] is the alignment */
12482 #define MAX_MOVE_REG 4
12485 expand_block_move (rtx operands[])
12487 rtx orig_dest = operands[0];
12488 rtx orig_src = operands[1];
12489 rtx bytes_rtx = operands[2];
12490 rtx align_rtx = operands[3];
12491 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
12496 rtx stores[MAX_MOVE_REG];
12499 /* If this is not a fixed size move, just call memcpy */
12503 /* This must be a fixed size alignment */
12504 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12505 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12507 /* Anything to move? */
12508 bytes = INTVAL (bytes_rtx);
12512 /* store_one_arg depends on expand_block_move to handle at least the size of
12513 reg_parm_stack_space. */
12514 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
12517 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
12520 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
12521 rtx (*mov) (rtx, rtx);
12523 enum machine_mode mode = BLKmode;
12526 /* Altivec first, since it will be faster than a string move
12527 when it applies, and usually not significantly larger. */
12528 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
12532 gen_func.mov = gen_movv4si;
12534 else if (TARGET_SPE && bytes >= 8 && align >= 64)
12538 gen_func.mov = gen_movv2si;
12540 else if (TARGET_STRING
12541 && bytes > 24 /* move up to 32 bytes at a time */
12547 && ! fixed_regs[10]
12548 && ! fixed_regs[11]
12549 && ! fixed_regs[12])
12551 move_bytes = (bytes > 32) ? 32 : bytes;
12552 gen_func.movmemsi = gen_movmemsi_8reg;
12554 else if (TARGET_STRING
12555 && bytes > 16 /* move up to 24 bytes at a time */
12561 && ! fixed_regs[10])
12563 move_bytes = (bytes > 24) ? 24 : bytes;
12564 gen_func.movmemsi = gen_movmemsi_6reg;
12566 else if (TARGET_STRING
12567 && bytes > 8 /* move up to 16 bytes at a time */
12571 && ! fixed_regs[8])
12573 move_bytes = (bytes > 16) ? 16 : bytes;
12574 gen_func.movmemsi = gen_movmemsi_4reg;
12576 else if (bytes >= 8 && TARGET_POWERPC64
12577 /* 64-bit loads and stores require word-aligned
12579 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12583 gen_func.mov = gen_movdi;
12585 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
12586 { /* move up to 8 bytes at a time */
12587 move_bytes = (bytes > 8) ? 8 : bytes;
12588 gen_func.movmemsi = gen_movmemsi_2reg;
12590 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12591 { /* move 4 bytes */
12594 gen_func.mov = gen_movsi;
12596 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12597 { /* move 2 bytes */
12600 gen_func.mov = gen_movhi;
12602 else if (TARGET_STRING && bytes > 1)
12603 { /* move up to 4 bytes at a time */
12604 move_bytes = (bytes > 4) ? 4 : bytes;
12605 gen_func.movmemsi = gen_movmemsi_1reg;
12607 else /* move 1 byte at a time */
12611 gen_func.mov = gen_movqi;
12614 src = adjust_address (orig_src, mode, offset);
12615 dest = adjust_address (orig_dest, mode, offset);
12617 if (mode != BLKmode)
12619 rtx tmp_reg = gen_reg_rtx (mode);
12621 emit_insn ((*gen_func.mov) (tmp_reg, src));
12622 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
12625 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
12628 for (i = 0; i < num_reg; i++)
12629 emit_insn (stores[i]);
12633 if (mode == BLKmode)
12635 /* Move the address into scratch registers. The movmemsi
12636 patterns require zero offset. */
12637 if (!REG_P (XEXP (src, 0)))
12639 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
12640 src = replace_equiv_address (src, src_reg);
12642 set_mem_size (src, GEN_INT (move_bytes));
12644 if (!REG_P (XEXP (dest, 0)))
12646 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
12647 dest = replace_equiv_address (dest, dest_reg);
12649 set_mem_size (dest, GEN_INT (move_bytes));
12651 emit_insn ((*gen_func.movmemsi) (dest, src,
12652 GEN_INT (move_bytes & 31),
12661 /* Return a string to perform a load_multiple operation.
12662 operands[0] is the vector.
12663 operands[1] is the source address.
12664 operands[2] is the first destination register. */
12667 rs6000_output_load_multiple (rtx operands[3])
12669 /* We have to handle the case where the pseudo used to contain the address
12670 is assigned to one of the output registers. */
12672 int words = XVECLEN (operands[0], 0);
12675 if (XVECLEN (operands[0], 0) == 1)
12676 return "{l|lwz} %2,0(%1)";
12678 for (i = 0; i < words; i++)
12679 if (refers_to_regno_p (REGNO (operands[2]) + i,
12680 REGNO (operands[2]) + i + 1, operands[1], 0))
12684 xop[0] = GEN_INT (4 * (words-1));
12685 xop[1] = operands[1];
12686 xop[2] = operands[2];
12687 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
12692 xop[0] = GEN_INT (4 * (words-1));
12693 xop[1] = operands[1];
12694 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
12695 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);
12700 for (j = 0; j < words; j++)
12703 xop[0] = GEN_INT (j * 4);
12704 xop[1] = operands[1];
12705 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
12706 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
12708 xop[0] = GEN_INT (i * 4);
12709 xop[1] = operands[1];
12710 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
12715 return "{lsi|lswi} %2,%1,%N0";
12719 /* A validation routine: say whether CODE, a condition code, and MODE
12720 match. The other alternatives either don't make sense or should
12721 never be generated. */
12724 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
12726 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
12727 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
12728 && GET_MODE_CLASS (mode) == MODE_CC);
12730 /* These don't make sense. */
12731 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
12732 || mode != CCUNSmode);
12734 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
12735 || mode == CCUNSmode);
12737 gcc_assert (mode == CCFPmode
12738 || (code != ORDERED && code != UNORDERED
12739 && code != UNEQ && code != LTGT
12740 && code != UNGT && code != UNLT
12741 && code != UNGE && code != UNLE));
12743 /* These should never be generated except for
12744 flag_finite_math_only. */
12745 gcc_assert (mode != CCFPmode
12746 || flag_finite_math_only
12747 || (code != LE && code != GE
12748 && code != UNEQ && code != LTGT
12749 && code != UNGT && code != UNLT));
12751 /* These are invalid; the information is not there. */
12752 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
12756 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
12757 mask required to convert the result of a rotate insn into a shift
12758 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
12761 includes_lshift_p (rtx shiftop, rtx andop)
12763 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12765 shift_mask <<= INTVAL (shiftop);
12767 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12770 /* Similar, but for right shift. */
12773 includes_rshift_p (rtx shiftop, rtx andop)
12775 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12777 shift_mask >>= INTVAL (shiftop);
12779 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12782 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
12783 to perform a left shift. It must have exactly SHIFTOP least
12784 significant 0's, then one or more 1's, then zero or more 0's. */
12787 includes_rldic_lshift_p (rtx shiftop, rtx andop)
12789 if (GET_CODE (andop) == CONST_INT)
12791 HOST_WIDE_INT c, lsb, shift_mask;
12793 c = INTVAL (andop);
12794 if (c == 0 || c == ~0)
12798 shift_mask <<= INTVAL (shiftop);
12800 /* Find the least significant one bit. */
12803 /* It must coincide with the LSB of the shift mask. */
12804 if (-lsb != shift_mask)
12807 /* Invert to look for the next transition (if any). */
12810 /* Remove the low group of ones (originally low group of zeros). */
12813 /* Again find the lsb, and check we have all 1's above. */
12817 else if (GET_CODE (andop) == CONST_DOUBLE
12818 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12820 HOST_WIDE_INT low, high, lsb;
12821 HOST_WIDE_INT shift_mask_low, shift_mask_high;
12823 low = CONST_DOUBLE_LOW (andop);
12824 if (HOST_BITS_PER_WIDE_INT < 64)
12825 high = CONST_DOUBLE_HIGH (andop);
12827 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
12828 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
12831 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12833 shift_mask_high = ~0;
12834 if (INTVAL (shiftop) > 32)
12835 shift_mask_high <<= INTVAL (shiftop) - 32;
12837 lsb = high & -high;
12839 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
12845 lsb = high & -high;
12846 return high == -lsb;
12849 shift_mask_low = ~0;
12850 shift_mask_low <<= INTVAL (shiftop);
12854 if (-lsb != shift_mask_low)
12857 if (HOST_BITS_PER_WIDE_INT < 64)
12862 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12864 lsb = high & -high;
12865 return high == -lsb;
12869 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
12875 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
12876 to perform a left shift. It must have SHIFTOP or more least
12877 significant 0's, with the remainder of the word 1's. */
12880 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
12882 if (GET_CODE (andop) == CONST_INT)
12884 HOST_WIDE_INT c, lsb, shift_mask;
12887 shift_mask <<= INTVAL (shiftop);
12888 c = INTVAL (andop);
12890 /* Find the least significant one bit. */
12893 /* It must be covered by the shift mask.
12894 This test also rejects c == 0. */
12895 if ((lsb & shift_mask) == 0)
12898 /* Check we have all 1's above the transition, and reject all 1's. */
12899 return c == -lsb && lsb != 1;
12901 else if (GET_CODE (andop) == CONST_DOUBLE
12902 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12904 HOST_WIDE_INT low, lsb, shift_mask_low;
12906 low = CONST_DOUBLE_LOW (andop);
12908 if (HOST_BITS_PER_WIDE_INT < 64)
12910 HOST_WIDE_INT high, shift_mask_high;
12912 high = CONST_DOUBLE_HIGH (andop);
12916 shift_mask_high = ~0;
12917 if (INTVAL (shiftop) > 32)
12918 shift_mask_high <<= INTVAL (shiftop) - 32;
12920 lsb = high & -high;
12922 if ((lsb & shift_mask_high) == 0)
12925 return high == -lsb;
12931 shift_mask_low = ~0;
12932 shift_mask_low <<= INTVAL (shiftop);
12936 if ((lsb & shift_mask_low) == 0)
12939 return low == -lsb && lsb != 1;
12945 /* Return 1 if operands will generate a valid arguments to rlwimi
12946 instruction for insert with right shift in 64-bit mode. The mask may
12947 not start on the first bit or stop on the last bit because wrap-around
12948 effects of instruction do not correspond to semantics of RTL insn. */
12951 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
12953 if (INTVAL (startop) > 32
12954 && INTVAL (startop) < 64
12955 && INTVAL (sizeop) > 1
12956 && INTVAL (sizeop) + INTVAL (startop) < 64
12957 && INTVAL (shiftop) > 0
12958 && INTVAL (sizeop) + INTVAL (shiftop) < 32
12959 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
12965 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
12966 for lfq and stfq insns iff the registers are hard registers. */
12969 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
12971 /* We might have been passed a SUBREG. */
12972 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
12975 /* We might have been passed non floating point registers. */
12976 if (!FP_REGNO_P (REGNO (reg1))
12977 || !FP_REGNO_P (REGNO (reg2)))
12980 return (REGNO (reg1) == REGNO (reg2) - 1);
12983 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
12984 addr1 and addr2 must be in consecutive memory locations
12985 (addr2 == addr1 + 8). */
12988 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
12991 unsigned int reg1, reg2;
12992 int offset1, offset2;
12994 /* The mems cannot be volatile. */
12995 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
12998 addr1 = XEXP (mem1, 0);
12999 addr2 = XEXP (mem2, 0);
13001 /* Extract an offset (if used) from the first addr. */
13002 if (GET_CODE (addr1) == PLUS)
13004 /* If not a REG, return zero. */
13005 if (GET_CODE (XEXP (addr1, 0)) != REG)
13009 reg1 = REGNO (XEXP (addr1, 0));
13010 /* The offset must be constant! */
13011 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13013 offset1 = INTVAL (XEXP (addr1, 1));
13016 else if (GET_CODE (addr1) != REG)
13020 reg1 = REGNO (addr1);
13021 /* This was a simple (mem (reg)) expression. Offset is 0. */
13025 /* And now for the second addr. */
13026 if (GET_CODE (addr2) == PLUS)
13028 /* If not a REG, return zero. */
13029 if (GET_CODE (XEXP (addr2, 0)) != REG)
13033 reg2 = REGNO (XEXP (addr2, 0));
13034 /* The offset must be constant. */
13035 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
13037 offset2 = INTVAL (XEXP (addr2, 1));
13040 else if (GET_CODE (addr2) != REG)
13044 reg2 = REGNO (addr2);
13045 /* This was a simple (mem (reg)) expression. Offset is 0. */
13049 /* Both of these must have the same base register. */
13053 /* The offset for the second addr must be 8 more than the first addr. */
13054 if (offset2 != offset1 + 8)
13057 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13064 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13066 static bool eliminated = false;
13069 if (mode != SDmode)
13070 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13073 rtx mem = cfun->machine->sdmode_stack_slot;
13074 gcc_assert (mem != NULL_RTX);
13078 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13079 cfun->machine->sdmode_stack_slot = mem;
13085 if (TARGET_DEBUG_ADDR)
13087 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13088 GET_MODE_NAME (mode));
13090 fprintf (stderr, "\tNULL_RTX\n");
13099 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13101 /* Don't walk into types. */
13102 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13104 *walk_subtrees = 0;
13108 switch (TREE_CODE (*tp))
13117 case ALIGN_INDIRECT_REF:
13118 case MISALIGNED_INDIRECT_REF:
13119 case VIEW_CONVERT_EXPR:
13120 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13130 enum reload_reg_type {
13132 VECTOR_REGISTER_TYPE,
13133 OTHER_REGISTER_TYPE
13136 static enum reload_reg_type
13137 rs6000_reload_register_type (enum reg_class rclass)
13143 return GPR_REGISTER_TYPE;
13148 return VECTOR_REGISTER_TYPE;
13151 return OTHER_REGISTER_TYPE;
13155 /* Inform reload about cases where moving X with a mode MODE to a register in
13156 RCLASS requires an extra scratch or immediate register. Return the class
13157 needed for the immediate register.
13159 For VSX and Altivec, we may need a register to convert sp+offset into
13162 static enum reg_class
13163 rs6000_secondary_reload (bool in_p,
13165 enum reg_class rclass,
13166 enum machine_mode mode,
13167 secondary_reload_info *sri)
13169 enum reg_class ret = ALL_REGS;
13170 enum insn_code icode;
13171 bool default_p = false;
13173 sri->icode = CODE_FOR_nothing;
13175 /* Convert vector loads and stores into gprs to use an additional base
13177 icode = rs6000_vector_reload[mode][in_p != false];
13178 if (icode != CODE_FOR_nothing)
13181 sri->icode = CODE_FOR_nothing;
13182 sri->extra_cost = 0;
13184 if (GET_CODE (x) == MEM)
13186 rtx addr = XEXP (x, 0);
13188 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13189 an extra register in that case, but it would need an extra
13190 register if the addressing is reg+reg or (reg+reg)&(-16). */
13191 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13193 if (!legitimate_indirect_address_p (addr, false)
13194 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13196 sri->icode = icode;
13197 /* account for splitting the loads, and converting the
13198 address from reg+reg to reg. */
13199 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13200 + ((GET_CODE (addr) == AND) ? 1 : 0));
13203 /* Loads to and stores from vector registers can only do reg+reg
13204 addressing. Altivec registers can also do (reg+reg)&(-16). */
13205 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13206 || rclass == FLOAT_REGS || rclass == NO_REGS)
13208 if (!VECTOR_MEM_ALTIVEC_P (mode)
13209 && GET_CODE (addr) == AND
13210 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13211 && INTVAL (XEXP (addr, 1)) == -16
13212 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13213 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13215 sri->icode = icode;
13216 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13219 else if (!legitimate_indirect_address_p (addr, false)
13220 && (rclass == NO_REGS
13221 || !legitimate_indexed_address_p (addr, false)))
13223 sri->icode = icode;
13224 sri->extra_cost = 1;
13227 icode = CODE_FOR_nothing;
13229 /* Any other loads, including to pseudo registers which haven't been
13230 assigned to a register yet, default to require a scratch
13234 sri->icode = icode;
13235 sri->extra_cost = 2;
13238 else if (REG_P (x))
13240 int regno = true_regnum (x);
13242 icode = CODE_FOR_nothing;
13243 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13247 enum reg_class xclass = REGNO_REG_CLASS (regno);
13248 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13249 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13251 /* If memory is needed, use default_secondary_reload to create the
13253 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13266 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13268 gcc_assert (ret != ALL_REGS);
13270 if (TARGET_DEBUG_ADDR)
13273 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13275 reg_class_names[ret],
13276 in_p ? "true" : "false",
13277 reg_class_names[rclass],
13278 GET_MODE_NAME (mode));
13281 fprintf (stderr, ", default secondary reload");
13283 if (sri->icode != CODE_FOR_nothing)
13284 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13285 insn_data[sri->icode].name, sri->extra_cost);
13287 fprintf (stderr, "\n");
13295 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13296 to SP+reg addressing. */
13299 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13301 int regno = true_regnum (reg);
13302 enum machine_mode mode = GET_MODE (reg);
13303 enum reg_class rclass;
13305 rtx and_op2 = NULL_RTX;
13308 rtx scratch_or_premodify = scratch;
13312 if (TARGET_DEBUG_ADDR)
13314 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13315 store_p ? "store" : "load");
13316 fprintf (stderr, "reg:\n");
13318 fprintf (stderr, "mem:\n");
13320 fprintf (stderr, "scratch:\n");
13321 debug_rtx (scratch);
13324 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13325 gcc_assert (GET_CODE (mem) == MEM);
13326 rclass = REGNO_REG_CLASS (regno);
13327 addr = XEXP (mem, 0);
13331 /* GPRs can handle reg + small constant, all other addresses need to use
13332 the scratch register. */
13335 if (GET_CODE (addr) == AND)
13337 and_op2 = XEXP (addr, 1);
13338 addr = XEXP (addr, 0);
13341 if (GET_CODE (addr) == PRE_MODIFY)
13343 scratch_or_premodify = XEXP (addr, 0);
13344 gcc_assert (REG_P (scratch_or_premodify));
13345 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13346 addr = XEXP (addr, 1);
13349 if (GET_CODE (addr) == PLUS
13350 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13351 || and_op2 != NULL_RTX))
13353 addr_op1 = XEXP (addr, 0);
13354 addr_op2 = XEXP (addr, 1);
13355 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13357 if (!REG_P (addr_op2)
13358 && (GET_CODE (addr_op2) != CONST_INT
13359 || !satisfies_constraint_I (addr_op2)))
13361 if (TARGET_DEBUG_ADDR)
13364 "\nMove plus addr to register %s, mode = %s: ",
13365 rs6000_reg_names[REGNO (scratch)],
13366 GET_MODE_NAME (mode));
13367 debug_rtx (addr_op2);
13369 rs6000_emit_move (scratch, addr_op2, Pmode);
13370 addr_op2 = scratch;
13373 emit_insn (gen_rtx_SET (VOIDmode,
13374 scratch_or_premodify,
13375 gen_rtx_PLUS (Pmode,
13379 addr = scratch_or_premodify;
13380 scratch_or_premodify = scratch;
13382 else if (!legitimate_indirect_address_p (addr, false)
13383 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13385 if (TARGET_DEBUG_ADDR)
13387 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13388 rs6000_reg_names[REGNO (scratch_or_premodify)],
13389 GET_MODE_NAME (mode));
13392 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13393 addr = scratch_or_premodify;
13394 scratch_or_premodify = scratch;
13398 /* Float/Altivec registers can only handle reg+reg addressing. Move
13399 other addresses into a scratch register. */
13404 /* With float regs, we need to handle the AND ourselves, since we can't
13405 use the Altivec instruction with an implicit AND -16. Allow scalar
13406 loads to float registers to use reg+offset even if VSX. */
13407 if (GET_CODE (addr) == AND
13408 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13409 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13410 || INTVAL (XEXP (addr, 1)) != -16
13411 || !VECTOR_MEM_ALTIVEC_P (mode)))
13413 and_op2 = XEXP (addr, 1);
13414 addr = XEXP (addr, 0);
13417 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13418 as the address later. */
13419 if (GET_CODE (addr) == PRE_MODIFY
13420 && (!VECTOR_MEM_VSX_P (mode)
13421 || and_op2 != NULL_RTX
13422 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13424 scratch_or_premodify = XEXP (addr, 0);
13425 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13427 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13428 addr = XEXP (addr, 1);
13431 if (legitimate_indirect_address_p (addr, false) /* reg */
13432 || legitimate_indexed_address_p (addr, false) /* reg+reg */
13433 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
13434 || (GET_CODE (addr) == AND /* Altivec memory */
13435 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13436 && INTVAL (XEXP (addr, 1)) == -16
13437 && VECTOR_MEM_ALTIVEC_P (mode))
13438 || (rclass == FLOAT_REGS /* legacy float mem */
13439 && GET_MODE_SIZE (mode) == 8
13440 && and_op2 == NULL_RTX
13441 && scratch_or_premodify == scratch
13442 && rs6000_legitimate_offset_address_p (mode, addr, false)))
13445 else if (GET_CODE (addr) == PLUS)
13447 addr_op1 = XEXP (addr, 0);
13448 addr_op2 = XEXP (addr, 1);
13449 gcc_assert (REG_P (addr_op1));
13451 if (TARGET_DEBUG_ADDR)
13453 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
13454 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13455 debug_rtx (addr_op2);
13457 rs6000_emit_move (scratch, addr_op2, Pmode);
13458 emit_insn (gen_rtx_SET (VOIDmode,
13459 scratch_or_premodify,
13460 gen_rtx_PLUS (Pmode,
13463 addr = scratch_or_premodify;
13464 scratch_or_premodify = scratch;
13467 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
13468 || GET_CODE (addr) == CONST_INT || REG_P (addr))
13470 if (TARGET_DEBUG_ADDR)
13472 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13473 rs6000_reg_names[REGNO (scratch_or_premodify)],
13474 GET_MODE_NAME (mode));
13478 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13479 addr = scratch_or_premodify;
13480 scratch_or_premodify = scratch;
13484 gcc_unreachable ();
13489 gcc_unreachable ();
13492 /* If the original address involved a pre-modify that we couldn't use the VSX
13493 memory instruction with update, and we haven't taken care of already,
13494 store the address in the pre-modify register and use that as the
13496 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
13498 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
13499 addr = scratch_or_premodify;
13502 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
13503 memory instruction, recreate the AND now, including the clobber which is
13504 generated by the general ANDSI3/ANDDI3 patterns for the
13505 andi. instruction. */
13506 if (and_op2 != NULL_RTX)
13508 if (! legitimate_indirect_address_p (addr, false))
13510 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
13514 if (TARGET_DEBUG_ADDR)
13516 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
13517 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13518 debug_rtx (and_op2);
13521 and_rtx = gen_rtx_SET (VOIDmode,
13523 gen_rtx_AND (Pmode,
13527 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
13528 emit_insn (gen_rtx_PARALLEL (VOIDmode,
13529 gen_rtvec (2, and_rtx, cc_clobber)));
13533 /* Adjust the address if it changed. */
13534 if (addr != XEXP (mem, 0))
13536 mem = change_address (mem, mode, addr);
13537 if (TARGET_DEBUG_ADDR)
13538 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
13541 /* Now create the move. */
13543 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
13545 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
13550 /* Target hook to return the cover classes for Integrated Register Allocator.
13551 Cover classes is a set of non-intersected register classes covering all hard
13552 registers used for register allocation purpose. Any move between two
13553 registers of a cover class should be cheaper than load or store of the
13554 registers. The value is array of register classes with LIM_REG_CLASSES used
13557 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
13558 account for the Altivec and Floating registers being subsets of the VSX
13559 register set under VSX, but distinct register sets on pre-VSX machines. */
13561 static const enum reg_class *
13562 rs6000_ira_cover_classes (void)
13564 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
13565 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
13567 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
13570 /* Allocate a 64-bit stack slot to be used for copying SDmode
13571 values through if this function has any SDmode references. */
13574 rs6000_alloc_sdmode_stack_slot (void)
13578 gimple_stmt_iterator gsi;
13580 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
13583 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
13585 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
13588 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13589 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13595 /* Check for any SDmode parameters of the function. */
13596 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
13598 if (TREE_TYPE (t) == error_mark_node)
13601 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
13602 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
13604 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13605 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13613 rs6000_instantiate_decls (void)
13615 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
13616 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
13619 /* Given an rtx X being reloaded into a reg required to be
13620 in class CLASS, return the class of reg to actually use.
13621 In general this is just CLASS; but on some machines
13622 in some cases it is preferable to use a more restrictive class.
13624 On the RS/6000, we have to return NO_REGS when we want to reload a
13625 floating-point CONST_DOUBLE to force it to be copied to memory.
13627 We also don't want to reload integer values into floating-point
13628 registers if we can at all help it. In fact, this can
13629 cause reload to die, if it tries to generate a reload of CTR
13630 into a FP register and discovers it doesn't have the memory location
13633 ??? Would it be a good idea to have reload do the converse, that is
13634 try to reload floating modes into FP registers if possible?
13637 static enum reg_class
13638 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
13640 enum machine_mode mode = GET_MODE (x);
13642 if (VECTOR_UNIT_VSX_P (mode)
13643 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
13646 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
13647 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
13648 && easy_vector_constant (x, mode))
13649 return ALTIVEC_REGS;
13651 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
13654 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
13655 return GENERAL_REGS;
13657 /* For VSX, prefer the traditional registers for DF if the address is of the
13658 form reg+offset because we can use the non-VSX loads. Prefer the Altivec
13659 registers if Altivec is handling the vector operations (i.e. V16QI, V8HI,
13661 if (rclass == VSX_REGS && VECTOR_MEM_VSX_P (mode))
13663 if (mode == DFmode && GET_CODE (x) == MEM)
13665 rtx addr = XEXP (x, 0);
13667 if (legitimate_indirect_address_p (addr, false)) /* reg */
13670 if (legitimate_indexed_address_p (addr, false)) /* reg+reg */
13673 if (GET_CODE (addr) == PRE_MODIFY
13674 && legitimate_indexed_address_p (XEXP (addr, 0), false))
13680 if (VECTOR_UNIT_ALTIVEC_P (mode))
13681 return ALTIVEC_REGS;
13689 /* Debug version of rs6000_preferred_reload_class. */
13690 static enum reg_class
13691 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
13693 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
13696 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
13698 reg_class_names[ret], reg_class_names[rclass],
13699 GET_MODE_NAME (GET_MODE (x)));
13705 /* If we are copying between FP or AltiVec registers and anything else, we need
13706 a memory location. The exception is when we are targeting ppc64 and the
13707 move to/from fpr to gpr instructions are available. Also, under VSX, you
13708 can copy vector registers from the FP register set to the Altivec register
13709 set and vice versa. */
13712 rs6000_secondary_memory_needed (enum reg_class class1,
13713 enum reg_class class2,
13714 enum machine_mode mode)
13716 if (class1 == class2)
13719 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
13720 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
13721 between these classes. But we need memory for other things that can go in
13722 FLOAT_REGS like SFmode. */
13724 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
13725 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
13726 || class1 == FLOAT_REGS))
13727 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
13728 && class2 != FLOAT_REGS);
13730 if (class1 == VSX_REGS || class2 == VSX_REGS)
13733 if (class1 == FLOAT_REGS
13734 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13735 || ((mode != DFmode)
13736 && (mode != DDmode)
13737 && (mode != DImode))))
13740 if (class2 == FLOAT_REGS
13741 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13742 || ((mode != DFmode)
13743 && (mode != DDmode)
13744 && (mode != DImode))))
13747 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
13753 /* Debug version of rs6000_secondary_memory_needed. */
13755 rs6000_debug_secondary_memory_needed (enum reg_class class1,
13756 enum reg_class class2,
13757 enum machine_mode mode)
13759 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
13762 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
13763 "class2 = %s, mode = %s\n",
13764 ret ? "true" : "false", reg_class_names[class1],
13765 reg_class_names[class2], GET_MODE_NAME (mode));
13770 /* Return the register class of a scratch register needed to copy IN into
13771 or out of a register in RCLASS in MODE. If it can be done directly,
13772 NO_REGS is returned. */
13774 static enum reg_class
13775 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
13780 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
13782 && MACHOPIC_INDIRECT
13786 /* We cannot copy a symbolic operand directly into anything
13787 other than BASE_REGS for TARGET_ELF. So indicate that a
13788 register from BASE_REGS is needed as an intermediate
13791 On Darwin, pic addresses require a load from memory, which
13792 needs a base register. */
13793 if (rclass != BASE_REGS
13794 && (GET_CODE (in) == SYMBOL_REF
13795 || GET_CODE (in) == HIGH
13796 || GET_CODE (in) == LABEL_REF
13797 || GET_CODE (in) == CONST))
13801 if (GET_CODE (in) == REG)
13803 regno = REGNO (in);
13804 if (regno >= FIRST_PSEUDO_REGISTER)
13806 regno = true_regnum (in);
13807 if (regno >= FIRST_PSEUDO_REGISTER)
13811 else if (GET_CODE (in) == SUBREG)
13813 regno = true_regnum (in);
13814 if (regno >= FIRST_PSEUDO_REGISTER)
13820 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
13822 if (rclass == GENERAL_REGS || rclass == BASE_REGS
13823 || (regno >= 0 && INT_REGNO_P (regno)))
13826 /* Constants, memory, and FP registers can go into FP registers. */
13827 if ((regno == -1 || FP_REGNO_P (regno))
13828 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
13829 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
13831 /* Memory, and FP/altivec registers can go into fp/altivec registers under
13834 && (regno == -1 || VSX_REGNO_P (regno))
13835 && VSX_REG_CLASS_P (rclass))
13838 /* Memory, and AltiVec registers can go into AltiVec registers. */
13839 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
13840 && rclass == ALTIVEC_REGS)
13843 /* We can copy among the CR registers. */
13844 if ((rclass == CR_REGS || rclass == CR0_REGS)
13845 && regno >= 0 && CR_REGNO_P (regno))
13848 /* Otherwise, we need GENERAL_REGS. */
13849 return GENERAL_REGS;
13852 /* Debug version of rs6000_secondary_reload_class. */
13853 static enum reg_class
13854 rs6000_debug_secondary_reload_class (enum reg_class rclass,
13855 enum machine_mode mode, rtx in)
13857 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
13859 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
13860 "mode = %s, input rtx:\n",
13861 reg_class_names[ret], reg_class_names[rclass],
13862 GET_MODE_NAME (mode));
13868 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
13871 rs6000_cannot_change_mode_class (enum machine_mode from,
13872 enum machine_mode to,
13873 enum reg_class rclass)
13875 unsigned from_size = GET_MODE_SIZE (from);
13876 unsigned to_size = GET_MODE_SIZE (to);
13878 if (from_size != to_size)
13880 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
13881 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
13882 && reg_classes_intersect_p (xclass, rclass));
13885 if (TARGET_E500_DOUBLE
13886 && ((((to) == DFmode) + ((from) == DFmode)) == 1
13887 || (((to) == TFmode) + ((from) == TFmode)) == 1
13888 || (((to) == DDmode) + ((from) == DDmode)) == 1
13889 || (((to) == TDmode) + ((from) == TDmode)) == 1
13890 || (((to) == DImode) + ((from) == DImode)) == 1))
13893 /* Since the VSX register set includes traditional floating point registers
13894 and altivec registers, just check for the size being different instead of
13895 trying to check whether the modes are vector modes. Otherwise it won't
13896 allow say DF and DI to change classes. */
13897 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
13898 return (from_size != 8 && from_size != 16);
13900 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
13901 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
13904 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
13905 && reg_classes_intersect_p (GENERAL_REGS, rclass))
13911 /* Debug version of rs6000_cannot_change_mode_class. */
13913 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
13914 enum machine_mode to,
13915 enum reg_class rclass)
13917 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
13920 "rs6000_cannot_change_mode_class, return %s, from = %s, "
13921 "to = %s, rclass = %s\n",
13922 ret ? "true" : "false",
13923 GET_MODE_NAME (from), GET_MODE_NAME (to),
13924 reg_class_names[rclass]);
13929 /* Given a comparison operation, return the bit number in CCR to test. We
13930 know this is a valid comparison.
13932 SCC_P is 1 if this is for an scc. That means that %D will have been
13933 used instead of %C, so the bits will be in different places.
13935 Return -1 if OP isn't a valid comparison for some reason. */
13938 ccr_bit (rtx op, int scc_p)
13940 enum rtx_code code = GET_CODE (op);
13941 enum machine_mode cc_mode;
13946 if (!COMPARISON_P (op))
13949 reg = XEXP (op, 0);
13951 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
13953 cc_mode = GET_MODE (reg);
13954 cc_regnum = REGNO (reg);
13955 base_bit = 4 * (cc_regnum - CR0_REGNO);
13957 validate_condition_mode (code, cc_mode);
13959 /* When generating a sCOND operation, only positive conditions are
13962 || code == EQ || code == GT || code == LT || code == UNORDERED
13963 || code == GTU || code == LTU);
13968 return scc_p ? base_bit + 3 : base_bit + 2;
13970 return base_bit + 2;
13971 case GT: case GTU: case UNLE:
13972 return base_bit + 1;
13973 case LT: case LTU: case UNGE:
13975 case ORDERED: case UNORDERED:
13976 return base_bit + 3;
13979 /* If scc, we will have done a cror to put the bit in the
13980 unordered position. So test that bit. For integer, this is ! LT
13981 unless this is an scc insn. */
13982 return scc_p ? base_bit + 3 : base_bit;
13985 return scc_p ? base_bit + 3 : base_bit + 1;
13988 gcc_unreachable ();
13992 /* Return the GOT register. */
13995 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
13997 /* The second flow pass currently (June 1999) can't update
13998 regs_ever_live without disturbing other parts of the compiler, so
13999 update it here to make the prolog/epilogue code happy. */
14000 if (!can_create_pseudo_p ()
14001 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
14002 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
14004 crtl->uses_pic_offset_table = 1;
14006 return pic_offset_table_rtx;
14009 /* Function to init struct machine_function.
14010 This will be called, via a pointer variable,
14011 from push_function_context. */
14013 static struct machine_function *
14014 rs6000_init_machine_status (void)
14016 return GGC_CNEW (machine_function);
14019 /* These macros test for integers and extract the low-order bits. */
14021 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
14022 && GET_MODE (X) == VOIDmode)
14024 #define INT_LOWPART(X) \
14025 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
14028 extract_MB (rtx op)
14031 unsigned long val = INT_LOWPART (op);
14033 /* If the high bit is zero, the value is the first 1 bit we find
14035 if ((val & 0x80000000) == 0)
14037 gcc_assert (val & 0xffffffff);
14040 while (((val <<= 1) & 0x80000000) == 0)
14045 /* If the high bit is set and the low bit is not, or the mask is all
14046 1's, the value is zero. */
14047 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14050 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14053 while (((val >>= 1) & 1) != 0)
14060 extract_ME (rtx op)
14063 unsigned long val = INT_LOWPART (op);
14065 /* If the low bit is zero, the value is the first 1 bit we find from
14067 if ((val & 1) == 0)
14069 gcc_assert (val & 0xffffffff);
14072 while (((val >>= 1) & 1) == 0)
14078 /* If the low bit is set and the high bit is not, or the mask is all
14079 1's, the value is 31. */
14080 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14083 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14086 while (((val <<= 1) & 0x80000000) != 0)
14092 /* Locate some local-dynamic symbol still in use by this function
14093 so that we can print its name in some tls_ld pattern. */
14095 static const char *
14096 rs6000_get_some_local_dynamic_name (void)
14100 if (cfun->machine->some_ld_name)
14101 return cfun->machine->some_ld_name;
14103 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14105 && for_each_rtx (&PATTERN (insn),
14106 rs6000_get_some_local_dynamic_name_1, 0))
14107 return cfun->machine->some_ld_name;
14109 gcc_unreachable ();
14112 /* Helper function for rs6000_get_some_local_dynamic_name. */
14115 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14119 if (GET_CODE (x) == SYMBOL_REF)
14121 const char *str = XSTR (x, 0);
14122 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14124 cfun->machine->some_ld_name = str;
14132 /* Write out a function code label. */
14135 rs6000_output_function_entry (FILE *file, const char *fname)
14137 if (fname[0] != '.')
14139 switch (DEFAULT_ABI)
14142 gcc_unreachable ();
14148 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14157 RS6000_OUTPUT_BASENAME (file, fname);
14159 assemble_name (file, fname);
14162 /* Print an operand. Recognize special options, documented below. */
14165 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14166 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14168 #define SMALL_DATA_RELOC "sda21"
14169 #define SMALL_DATA_REG 0
14173 print_operand (FILE *file, rtx x, int code)
14177 unsigned HOST_WIDE_INT uval;
14182 /* Write out an instruction after the call which may be replaced
14183 with glue code by the loader. This depends on the AIX version. */
14184 asm_fprintf (file, RS6000_CALL_GLUE);
14187 /* %a is output_address. */
14190 /* If X is a constant integer whose low-order 5 bits are zero,
14191 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14192 in the AIX assembler where "sri" with a zero shift count
14193 writes a trash instruction. */
14194 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14201 /* If constant, low-order 16 bits of constant, unsigned.
14202 Otherwise, write normally. */
14204 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14206 print_operand (file, x, 0);
14210 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14211 for 64-bit mask direction. */
14212 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14215 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14219 /* X is a CR register. Print the number of the GT bit of the CR. */
14220 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14221 output_operand_lossage ("invalid %%c value");
14223 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14227 /* Like 'J' but get to the GT bit only. */
14228 gcc_assert (GET_CODE (x) == REG);
14230 /* Bit 1 is GT bit. */
14231 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14233 /* Add one for shift count in rlinm for scc. */
14234 fprintf (file, "%d", i + 1);
14238 /* X is a CR register. Print the number of the EQ bit of the CR */
14239 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14240 output_operand_lossage ("invalid %%E value");
14242 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14246 /* X is a CR register. Print the shift count needed to move it
14247 to the high-order four bits. */
14248 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14249 output_operand_lossage ("invalid %%f value");
14251 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14255 /* Similar, but print the count for the rotate in the opposite
14257 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14258 output_operand_lossage ("invalid %%F value");
14260 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14264 /* X is a constant integer. If it is negative, print "m",
14265 otherwise print "z". This is to make an aze or ame insn. */
14266 if (GET_CODE (x) != CONST_INT)
14267 output_operand_lossage ("invalid %%G value");
14268 else if (INTVAL (x) >= 0)
14275 /* If constant, output low-order five bits. Otherwise, write
14278 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14280 print_operand (file, x, 0);
14284 /* If constant, output low-order six bits. Otherwise, write
14287 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14289 print_operand (file, x, 0);
14293 /* Print `i' if this is a constant, else nothing. */
14299 /* Write the bit number in CCR for jump. */
14300 i = ccr_bit (x, 0);
14302 output_operand_lossage ("invalid %%j code");
14304 fprintf (file, "%d", i);
14308 /* Similar, but add one for shift count in rlinm for scc and pass
14309 scc flag to `ccr_bit'. */
14310 i = ccr_bit (x, 1);
14312 output_operand_lossage ("invalid %%J code");
14314 /* If we want bit 31, write a shift count of zero, not 32. */
14315 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14319 /* X must be a constant. Write the 1's complement of the
14322 output_operand_lossage ("invalid %%k value");
14324 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14328 /* X must be a symbolic constant on ELF. Write an
14329 expression suitable for an 'addi' that adds in the low 16
14330 bits of the MEM. */
14331 if (GET_CODE (x) != CONST)
14333 print_operand_address (file, x);
14334 fputs ("@l", file);
14338 if (GET_CODE (XEXP (x, 0)) != PLUS
14339 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14340 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14341 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14342 output_operand_lossage ("invalid %%K value");
14343 print_operand_address (file, XEXP (XEXP (x, 0), 0));
14344 fputs ("@l", file);
14345 /* For GNU as, there must be a non-alphanumeric character
14346 between 'l' and the number. The '-' is added by
14347 print_operand() already. */
14348 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
14350 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
14354 /* %l is output_asm_label. */
14357 /* Write second word of DImode or DFmode reference. Works on register
14358 or non-indexed memory only. */
14359 if (GET_CODE (x) == REG)
14360 fputs (reg_names[REGNO (x) + 1], file);
14361 else if (GET_CODE (x) == MEM)
14363 /* Handle possible auto-increment. Since it is pre-increment and
14364 we have already done it, we can just use an offset of word. */
14365 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14366 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14367 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14369 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14370 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14373 output_address (XEXP (adjust_address_nv (x, SImode,
14377 if (small_data_operand (x, GET_MODE (x)))
14378 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14379 reg_names[SMALL_DATA_REG]);
14384 /* MB value for a mask operand. */
14385 if (! mask_operand (x, SImode))
14386 output_operand_lossage ("invalid %%m value");
14388 fprintf (file, "%d", extract_MB (x));
14392 /* ME value for a mask operand. */
14393 if (! mask_operand (x, SImode))
14394 output_operand_lossage ("invalid %%M value");
14396 fprintf (file, "%d", extract_ME (x));
14399 /* %n outputs the negative of its operand. */
14402 /* Write the number of elements in the vector times 4. */
14403 if (GET_CODE (x) != PARALLEL)
14404 output_operand_lossage ("invalid %%N value");
14406 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14410 /* Similar, but subtract 1 first. */
14411 if (GET_CODE (x) != PARALLEL)
14412 output_operand_lossage ("invalid %%O value");
14414 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14418 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14420 || INT_LOWPART (x) < 0
14421 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14422 output_operand_lossage ("invalid %%p value");
14424 fprintf (file, "%d", i);
14428 /* The operand must be an indirect memory reference. The result
14429 is the register name. */
14430 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14431 || REGNO (XEXP (x, 0)) >= 32)
14432 output_operand_lossage ("invalid %%P value");
14434 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14438 /* This outputs the logical code corresponding to a boolean
14439 expression. The expression may have one or both operands
14440 negated (if one, only the first one). For condition register
14441 logical operations, it will also treat the negated
14442 CR codes as NOTs, but not handle NOTs of them. */
14444 const char *const *t = 0;
14446 enum rtx_code code = GET_CODE (x);
14447 static const char * const tbl[3][3] = {
14448 { "and", "andc", "nor" },
14449 { "or", "orc", "nand" },
14450 { "xor", "eqv", "xor" } };
14454 else if (code == IOR)
14456 else if (code == XOR)
14459 output_operand_lossage ("invalid %%q value");
14461 if (GET_CODE (XEXP (x, 0)) != NOT)
14465 if (GET_CODE (XEXP (x, 1)) == NOT)
14483 /* X is a CR register. Print the mask for `mtcrf'. */
14484 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14485 output_operand_lossage ("invalid %%R value");
14487 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
14491 /* Low 5 bits of 32 - value */
14493 output_operand_lossage ("invalid %%s value");
14495 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
14499 /* PowerPC64 mask position. All 0's is excluded.
14500 CONST_INT 32-bit mask is considered sign-extended so any
14501 transition must occur within the CONST_INT, not on the boundary. */
14502 if (! mask64_operand (x, DImode))
14503 output_operand_lossage ("invalid %%S value");
14505 uval = INT_LOWPART (x);
14507 if (uval & 1) /* Clear Left */
14509 #if HOST_BITS_PER_WIDE_INT > 64
14510 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14514 else /* Clear Right */
14517 #if HOST_BITS_PER_WIDE_INT > 64
14518 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14524 gcc_assert (i >= 0);
14525 fprintf (file, "%d", i);
14529 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
14530 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
14532 /* Bit 3 is OV bit. */
14533 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
14535 /* If we want bit 31, write a shift count of zero, not 32. */
14536 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14540 /* Print the symbolic name of a branch target register. */
14541 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
14542 && REGNO (x) != CTR_REGNO))
14543 output_operand_lossage ("invalid %%T value");
14544 else if (REGNO (x) == LR_REGNO)
14545 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
14547 fputs ("ctr", file);
14551 /* High-order 16 bits of constant for use in unsigned operand. */
14553 output_operand_lossage ("invalid %%u value");
14555 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14556 (INT_LOWPART (x) >> 16) & 0xffff);
14560 /* High-order 16 bits of constant for use in signed operand. */
14562 output_operand_lossage ("invalid %%v value");
14564 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14565 (INT_LOWPART (x) >> 16) & 0xffff);
14569 /* Print `u' if this has an auto-increment or auto-decrement. */
14570 if (GET_CODE (x) == MEM
14571 && (GET_CODE (XEXP (x, 0)) == PRE_INC
14572 || GET_CODE (XEXP (x, 0)) == PRE_DEC
14573 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
14578 /* Print the trap code for this operand. */
14579 switch (GET_CODE (x))
14582 fputs ("eq", file); /* 4 */
14585 fputs ("ne", file); /* 24 */
14588 fputs ("lt", file); /* 16 */
14591 fputs ("le", file); /* 20 */
14594 fputs ("gt", file); /* 8 */
14597 fputs ("ge", file); /* 12 */
14600 fputs ("llt", file); /* 2 */
14603 fputs ("lle", file); /* 6 */
14606 fputs ("lgt", file); /* 1 */
14609 fputs ("lge", file); /* 5 */
14612 gcc_unreachable ();
14617 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
14620 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
14621 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
14623 print_operand (file, x, 0);
14627 /* MB value for a PowerPC64 rldic operand. */
14628 val = (GET_CODE (x) == CONST_INT
14629 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
14634 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
14635 if ((val <<= 1) < 0)
14638 #if HOST_BITS_PER_WIDE_INT == 32
14639 if (GET_CODE (x) == CONST_INT && i >= 0)
14640 i += 32; /* zero-extend high-part was all 0's */
14641 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
14643 val = CONST_DOUBLE_LOW (x);
14649 for ( ; i < 64; i++)
14650 if ((val <<= 1) < 0)
14655 fprintf (file, "%d", i + 1);
14659 /* X is a FPR or Altivec register used in a VSX context. */
14660 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
14661 output_operand_lossage ("invalid %%x value");
14664 int reg = REGNO (x);
14665 int vsx_reg = (FP_REGNO_P (reg)
14667 : reg - FIRST_ALTIVEC_REGNO + 32);
14669 #ifdef TARGET_REGNAMES
14670 if (TARGET_REGNAMES)
14671 fprintf (file, "%%vs%d", vsx_reg);
14674 fprintf (file, "%d", vsx_reg);
14679 if (GET_CODE (x) == MEM
14680 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
14681 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
14682 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
14687 /* Like 'L', for third word of TImode */
14688 if (GET_CODE (x) == REG)
14689 fputs (reg_names[REGNO (x) + 2], file);
14690 else if (GET_CODE (x) == MEM)
14692 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14693 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14694 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14695 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14696 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14698 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
14699 if (small_data_operand (x, GET_MODE (x)))
14700 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14701 reg_names[SMALL_DATA_REG]);
14706 /* X is a SYMBOL_REF. Write out the name preceded by a
14707 period and without any trailing data in brackets. Used for function
14708 names. If we are configured for System V (or the embedded ABI) on
14709 the PowerPC, do not emit the period, since those systems do not use
14710 TOCs and the like. */
14711 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14713 /* Mark the decl as referenced so that cgraph will output the
14715 if (SYMBOL_REF_DECL (x))
14716 mark_decl_referenced (SYMBOL_REF_DECL (x));
14718 /* For macho, check to see if we need a stub. */
14721 const char *name = XSTR (x, 0);
14723 if (MACHOPIC_INDIRECT
14724 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
14725 name = machopic_indirection_name (x, /*stub_p=*/true);
14727 assemble_name (file, name);
14729 else if (!DOT_SYMBOLS)
14730 assemble_name (file, XSTR (x, 0));
14732 rs6000_output_function_entry (file, XSTR (x, 0));
14736 /* Like 'L', for last word of TImode. */
14737 if (GET_CODE (x) == REG)
14738 fputs (reg_names[REGNO (x) + 3], file);
14739 else if (GET_CODE (x) == MEM)
14741 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14742 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14743 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14744 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14745 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14747 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
14748 if (small_data_operand (x, GET_MODE (x)))
14749 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14750 reg_names[SMALL_DATA_REG]);
14754 /* Print AltiVec or SPE memory operand. */
14759 gcc_assert (GET_CODE (x) == MEM);
14763 /* Ugly hack because %y is overloaded. */
14764 if ((TARGET_SPE || TARGET_E500_DOUBLE)
14765 && (GET_MODE_SIZE (GET_MODE (x)) == 8
14766 || GET_MODE (x) == TFmode
14767 || GET_MODE (x) == TImode))
14769 /* Handle [reg]. */
14770 if (GET_CODE (tmp) == REG)
14772 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
14775 /* Handle [reg+UIMM]. */
14776 else if (GET_CODE (tmp) == PLUS &&
14777 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
14781 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
14783 x = INTVAL (XEXP (tmp, 1));
14784 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
14788 /* Fall through. Must be [reg+reg]. */
14790 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
14791 && GET_CODE (tmp) == AND
14792 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
14793 && INTVAL (XEXP (tmp, 1)) == -16)
14794 tmp = XEXP (tmp, 0);
14795 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
14796 && GET_CODE (tmp) == PRE_MODIFY)
14797 tmp = XEXP (tmp, 1);
14798 if (GET_CODE (tmp) == REG)
14799 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
14802 if (!GET_CODE (tmp) == PLUS
14803 || !REG_P (XEXP (tmp, 0))
14804 || !REG_P (XEXP (tmp, 1)))
14806 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
14810 if (REGNO (XEXP (tmp, 0)) == 0)
14811 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
14812 reg_names[ REGNO (XEXP (tmp, 0)) ]);
14814 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
14815 reg_names[ REGNO (XEXP (tmp, 1)) ]);
14821 if (GET_CODE (x) == REG)
14822 fprintf (file, "%s", reg_names[REGNO (x)]);
14823 else if (GET_CODE (x) == MEM)
14825 /* We need to handle PRE_INC and PRE_DEC here, since we need to
14826 know the width from the mode. */
14827 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
14828 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
14829 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14830 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
14831 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
14832 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14833 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14834 output_address (XEXP (XEXP (x, 0), 1));
14836 output_address (XEXP (x, 0));
14839 output_addr_const (file, x);
14843 assemble_name (file, rs6000_get_some_local_dynamic_name ());
14847 output_operand_lossage ("invalid %%xn code");
14851 /* Print the address of an operand. */
14854 print_operand_address (FILE *file, rtx x)
14856 if (GET_CODE (x) == REG)
14857 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
14858 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
14859 || GET_CODE (x) == LABEL_REF)
14861 output_addr_const (file, x);
14862 if (small_data_operand (x, GET_MODE (x)))
14863 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14864 reg_names[SMALL_DATA_REG]);
14866 gcc_assert (!TARGET_TOC);
14868 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
14870 gcc_assert (REG_P (XEXP (x, 0)));
14871 if (REGNO (XEXP (x, 0)) == 0)
14872 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
14873 reg_names[ REGNO (XEXP (x, 0)) ]);
14875 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
14876 reg_names[ REGNO (XEXP (x, 1)) ]);
14878 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
14879 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
14880 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
14882 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
14883 && CONSTANT_P (XEXP (x, 1)))
14885 output_addr_const (file, XEXP (x, 1));
14886 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
14890 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
14891 && CONSTANT_P (XEXP (x, 1)))
14893 fprintf (file, "lo16(");
14894 output_addr_const (file, XEXP (x, 1));
14895 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
14898 else if (legitimate_constant_pool_address_p (x))
14900 output_addr_const (file, XEXP (x, 1));
14901 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
14904 gcc_unreachable ();
14907 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
14910 rs6000_output_addr_const_extra (FILE *file, rtx x)
14912 if (GET_CODE (x) == UNSPEC)
14913 switch (XINT (x, 1))
14915 case UNSPEC_TOCREL:
14916 x = XVECEXP (x, 0, 0);
14917 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14918 output_addr_const (file, x);
14919 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
14922 assemble_name (file, toc_label_name);
14924 else if (TARGET_ELF)
14925 fputs ("@toc", file);
14929 case UNSPEC_MACHOPIC_OFFSET:
14930 output_addr_const (file, XVECEXP (x, 0, 0));
14932 machopic_output_function_base_name (file);
14939 /* Target hook for assembling integer objects. The PowerPC version has
14940 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
14941 is defined. It also needs to handle DI-mode objects on 64-bit
14945 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
14947 #ifdef RELOCATABLE_NEEDS_FIXUP
14948 /* Special handling for SI values. */
14949 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
14951 static int recurse = 0;
14953 /* For -mrelocatable, we mark all addresses that need to be fixed up
14954 in the .fixup section. */
14955 if (TARGET_RELOCATABLE
14956 && in_section != toc_section
14957 && in_section != text_section
14958 && !unlikely_text_section_p (in_section)
14960 && GET_CODE (x) != CONST_INT
14961 && GET_CODE (x) != CONST_DOUBLE
14967 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
14969 ASM_OUTPUT_LABEL (asm_out_file, buf);
14970 fprintf (asm_out_file, "\t.long\t(");
14971 output_addr_const (asm_out_file, x);
14972 fprintf (asm_out_file, ")@fixup\n");
14973 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
14974 ASM_OUTPUT_ALIGN (asm_out_file, 2);
14975 fprintf (asm_out_file, "\t.long\t");
14976 assemble_name (asm_out_file, buf);
14977 fprintf (asm_out_file, "\n\t.previous\n");
14981 /* Remove initial .'s to turn a -mcall-aixdesc function
14982 address into the address of the descriptor, not the function
14984 else if (GET_CODE (x) == SYMBOL_REF
14985 && XSTR (x, 0)[0] == '.'
14986 && DEFAULT_ABI == ABI_AIX)
14988 const char *name = XSTR (x, 0);
14989 while (*name == '.')
14992 fprintf (asm_out_file, "\t.long\t%s\n", name);
14996 #endif /* RELOCATABLE_NEEDS_FIXUP */
14997 return default_assemble_integer (x, size, aligned_p);
15000 #ifdef HAVE_GAS_HIDDEN
15001 /* Emit an assembler directive to set symbol visibility for DECL to
15002 VISIBILITY_TYPE. */
15005 rs6000_assemble_visibility (tree decl, int vis)
15007 /* Functions need to have their entry point symbol visibility set as
15008 well as their descriptor symbol visibility. */
15009 if (DEFAULT_ABI == ABI_AIX
15011 && TREE_CODE (decl) == FUNCTION_DECL)
15013 static const char * const visibility_types[] = {
15014 NULL, "internal", "hidden", "protected"
15017 const char *name, *type;
15019 name = ((* targetm.strip_name_encoding)
15020 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
15021 type = visibility_types[vis];
15023 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
15024 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
15027 default_assemble_visibility (decl, vis);
15032 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15034 /* Reversal of FP compares takes care -- an ordered compare
15035 becomes an unordered compare and vice versa. */
15036 if (mode == CCFPmode
15037 && (!flag_finite_math_only
15038 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15039 || code == UNEQ || code == LTGT))
15040 return reverse_condition_maybe_unordered (code);
15042 return reverse_condition (code);
15045 /* Generate a compare for CODE. Return a brand-new rtx that
15046 represents the result of the compare. */
15049 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15051 enum machine_mode comp_mode;
15052 rtx compare_result;
15053 enum rtx_code code = GET_CODE (cmp);
15054 rtx op0 = XEXP (cmp, 0);
15055 rtx op1 = XEXP (cmp, 1);
15057 if (FLOAT_MODE_P (mode))
15058 comp_mode = CCFPmode;
15059 else if (code == GTU || code == LTU
15060 || code == GEU || code == LEU)
15061 comp_mode = CCUNSmode;
15062 else if ((code == EQ || code == NE)
15063 && GET_CODE (op0) == SUBREG
15064 && GET_CODE (op1) == SUBREG
15065 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15066 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15067 /* These are unsigned values, perhaps there will be a later
15068 ordering compare that can be shared with this one.
15069 Unfortunately we cannot detect the signedness of the operands
15070 for non-subregs. */
15071 comp_mode = CCUNSmode;
15073 comp_mode = CCmode;
15075 /* First, the compare. */
15076 compare_result = gen_reg_rtx (comp_mode);
15078 /* E500 FP compare instructions on the GPRs. Yuck! */
15079 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15080 && FLOAT_MODE_P (mode))
15082 rtx cmp, or_result, compare_result2;
15083 enum machine_mode op_mode = GET_MODE (op0);
15085 if (op_mode == VOIDmode)
15086 op_mode = GET_MODE (op1);
15088 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15089 This explains the following mess. */
15093 case EQ: case UNEQ: case NE: case LTGT:
15097 cmp = (flag_finite_math_only && !flag_trapping_math)
15098 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15099 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15103 cmp = (flag_finite_math_only && !flag_trapping_math)
15104 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15105 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15109 cmp = (flag_finite_math_only && !flag_trapping_math)
15110 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15111 : gen_cmptfeq_gpr (compare_result, op0, op1);
15115 gcc_unreachable ();
15119 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15123 cmp = (flag_finite_math_only && !flag_trapping_math)
15124 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15125 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15129 cmp = (flag_finite_math_only && !flag_trapping_math)
15130 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15131 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15135 cmp = (flag_finite_math_only && !flag_trapping_math)
15136 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15137 : gen_cmptfgt_gpr (compare_result, op0, op1);
15141 gcc_unreachable ();
15145 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15149 cmp = (flag_finite_math_only && !flag_trapping_math)
15150 ? gen_tstsflt_gpr (compare_result, op0, op1)
15151 : gen_cmpsflt_gpr (compare_result, op0, op1);
15155 cmp = (flag_finite_math_only && !flag_trapping_math)
15156 ? gen_tstdflt_gpr (compare_result, op0, op1)
15157 : gen_cmpdflt_gpr (compare_result, op0, op1);
15161 cmp = (flag_finite_math_only && !flag_trapping_math)
15162 ? gen_tsttflt_gpr (compare_result, op0, op1)
15163 : gen_cmptflt_gpr (compare_result, op0, op1);
15167 gcc_unreachable ();
15171 gcc_unreachable ();
15174 /* Synthesize LE and GE from LT/GT || EQ. */
15175 if (code == LE || code == GE || code == LEU || code == GEU)
15181 case LE: code = LT; break;
15182 case GE: code = GT; break;
15183 case LEU: code = LT; break;
15184 case GEU: code = GT; break;
15185 default: gcc_unreachable ();
15188 compare_result2 = gen_reg_rtx (CCFPmode);
15194 cmp = (flag_finite_math_only && !flag_trapping_math)
15195 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15196 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15200 cmp = (flag_finite_math_only && !flag_trapping_math)
15201 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15202 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15206 cmp = (flag_finite_math_only && !flag_trapping_math)
15207 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15208 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15212 gcc_unreachable ();
15216 /* OR them together. */
15217 or_result = gen_reg_rtx (CCFPmode);
15218 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15220 compare_result = or_result;
15225 if (code == NE || code == LTGT)
15235 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15236 CLOBBERs to match cmptf_internal2 pattern. */
15237 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15238 && GET_MODE (op0) == TFmode
15239 && !TARGET_IEEEQUAD
15240 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15241 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15243 gen_rtx_SET (VOIDmode,
15245 gen_rtx_COMPARE (comp_mode, op0, op1)),
15246 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15247 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15248 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15249 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15250 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15251 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15252 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15253 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
15254 else if (GET_CODE (op1) == UNSPEC
15255 && XINT (op1, 1) == UNSPEC_SP_TEST)
15257 rtx op1b = XVECEXP (op1, 0, 0);
15258 comp_mode = CCEQmode;
15259 compare_result = gen_reg_rtx (CCEQmode);
15261 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15263 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15266 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15267 gen_rtx_COMPARE (comp_mode, op0, op1)));
15270 /* Some kinds of FP comparisons need an OR operation;
15271 under flag_finite_math_only we don't bother. */
15272 if (FLOAT_MODE_P (mode)
15273 && !flag_finite_math_only
15274 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15275 && (code == LE || code == GE
15276 || code == UNEQ || code == LTGT
15277 || code == UNGT || code == UNLT))
15279 enum rtx_code or1, or2;
15280 rtx or1_rtx, or2_rtx, compare2_rtx;
15281 rtx or_result = gen_reg_rtx (CCEQmode);
15285 case LE: or1 = LT; or2 = EQ; break;
15286 case GE: or1 = GT; or2 = EQ; break;
15287 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15288 case LTGT: or1 = LT; or2 = GT; break;
15289 case UNGT: or1 = UNORDERED; or2 = GT; break;
15290 case UNLT: or1 = UNORDERED; or2 = LT; break;
15291 default: gcc_unreachable ();
15293 validate_condition_mode (or1, comp_mode);
15294 validate_condition_mode (or2, comp_mode);
15295 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15296 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15297 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15298 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15300 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15302 compare_result = or_result;
15306 validate_condition_mode (code, GET_MODE (compare_result));
15308 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15312 /* Emit the RTL for an sCOND pattern. */
15315 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15318 enum machine_mode op_mode;
15319 enum rtx_code cond_code;
15320 rtx result = operands[0];
15322 condition_rtx = rs6000_generate_compare (operands[1], mode);
15323 cond_code = GET_CODE (condition_rtx);
15325 if (FLOAT_MODE_P (mode)
15326 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15330 PUT_MODE (condition_rtx, SImode);
15331 t = XEXP (condition_rtx, 0);
15333 gcc_assert (cond_code == NE || cond_code == EQ);
15335 if (cond_code == NE)
15336 emit_insn (gen_e500_flip_gt_bit (t, t));
15338 emit_insn (gen_move_from_CR_gt_bit (result, t));
15342 if (cond_code == NE
15343 || cond_code == GE || cond_code == LE
15344 || cond_code == GEU || cond_code == LEU
15345 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15347 rtx not_result = gen_reg_rtx (CCEQmode);
15348 rtx not_op, rev_cond_rtx;
15349 enum machine_mode cc_mode;
15351 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15353 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15354 SImode, XEXP (condition_rtx, 0), const0_rtx);
15355 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15356 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15357 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15360 op_mode = GET_MODE (XEXP (operands[1], 0));
15361 if (op_mode == VOIDmode)
15362 op_mode = GET_MODE (XEXP (operands[1], 1));
15364 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15366 PUT_MODE (condition_rtx, DImode);
15367 convert_move (result, condition_rtx, 0);
15371 PUT_MODE (condition_rtx, SImode);
15372 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15376 /* Emit a branch of kind CODE to location LOC. */
15379 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15381 rtx condition_rtx, loc_ref;
15383 condition_rtx = rs6000_generate_compare (operands[0], mode);
15384 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15385 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15386 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15387 loc_ref, pc_rtx)));
15390 /* Return the string to output a conditional branch to LABEL, which is
15391 the operand number of the label, or -1 if the branch is really a
15392 conditional return.
15394 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15395 condition code register and its mode specifies what kind of
15396 comparison we made.
15398 REVERSED is nonzero if we should reverse the sense of the comparison.
15400 INSN is the insn. */
15403 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
15405 static char string[64];
15406 enum rtx_code code = GET_CODE (op);
15407 rtx cc_reg = XEXP (op, 0);
15408 enum machine_mode mode = GET_MODE (cc_reg);
15409 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
15410 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
15411 int really_reversed = reversed ^ need_longbranch;
15417 validate_condition_mode (code, mode);
15419 /* Work out which way this really branches. We could use
15420 reverse_condition_maybe_unordered here always but this
15421 makes the resulting assembler clearer. */
15422 if (really_reversed)
15424 /* Reversal of FP compares takes care -- an ordered compare
15425 becomes an unordered compare and vice versa. */
15426 if (mode == CCFPmode)
15427 code = reverse_condition_maybe_unordered (code);
15429 code = reverse_condition (code);
15432 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
15434 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
15439 /* Opposite of GT. */
15448 gcc_unreachable ();
15454 /* Not all of these are actually distinct opcodes, but
15455 we distinguish them for clarity of the resulting assembler. */
15456 case NE: case LTGT:
15457 ccode = "ne"; break;
15458 case EQ: case UNEQ:
15459 ccode = "eq"; break;
15461 ccode = "ge"; break;
15462 case GT: case GTU: case UNGT:
15463 ccode = "gt"; break;
15465 ccode = "le"; break;
15466 case LT: case LTU: case UNLT:
15467 ccode = "lt"; break;
15468 case UNORDERED: ccode = "un"; break;
15469 case ORDERED: ccode = "nu"; break;
15470 case UNGE: ccode = "nl"; break;
15471 case UNLE: ccode = "ng"; break;
15473 gcc_unreachable ();
15476 /* Maybe we have a guess as to how likely the branch is.
15477 The old mnemonics don't have a way to specify this information. */
15479 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
15480 if (note != NULL_RTX)
15482 /* PROB is the difference from 50%. */
15483 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
15485 /* Only hint for highly probable/improbable branches on newer
15486 cpus as static prediction overrides processor dynamic
15487 prediction. For older cpus we may as well always hint, but
15488 assume not taken for branches that are very close to 50% as a
15489 mispredicted taken branch is more expensive than a
15490 mispredicted not-taken branch. */
15491 if (rs6000_always_hint
15492 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
15493 && br_prob_note_reliable_p (note)))
15495 if (abs (prob) > REG_BR_PROB_BASE / 20
15496 && ((prob > 0) ^ need_longbranch))
15504 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
15506 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
15508 /* We need to escape any '%' characters in the reg_names string.
15509 Assume they'd only be the first character.... */
15510 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
15512 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
15516 /* If the branch distance was too far, we may have to use an
15517 unconditional branch to go the distance. */
15518 if (need_longbranch)
15519 s += sprintf (s, ",$+8\n\tb %s", label);
15521 s += sprintf (s, ",%s", label);
15527 /* Return the string to flip the GT bit on a CR. */
15529 output_e500_flip_gt_bit (rtx dst, rtx src)
15531 static char string[64];
15534 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
15535 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
15538 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
15539 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
15541 sprintf (string, "crnot %d,%d", a, b);
15545 /* Return insn for VSX or Altivec comparisons. */
15548 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
15551 enum machine_mode mode = GET_MODE (op0);
15559 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
15565 mask = gen_reg_rtx (mode);
15566 emit_insn (gen_rtx_SET (VOIDmode,
15568 gen_rtx_fmt_ee (code, mode, op0, op1)));
15575 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
15576 DMODE is expected destination mode. This is a recursive function. */
15579 rs6000_emit_vector_compare (enum rtx_code rcode,
15581 enum machine_mode dmode)
15584 bool swap_operands = false;
15585 bool try_again = false;
15587 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
15588 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
15590 /* See if the comparison works as is. */
15591 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15599 swap_operands = true;
15604 swap_operands = true;
15612 /* Invert condition and try again.
15613 e.g., A != B becomes ~(A==B). */
15615 enum rtx_code rev_code;
15616 enum insn_code nor_code;
15619 rev_code = reverse_condition_maybe_unordered (rcode);
15620 if (rev_code == UNKNOWN)
15623 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
15624 if (nor_code == CODE_FOR_nothing)
15627 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
15631 mask = gen_reg_rtx (dmode);
15632 emit_insn (GEN_FCN (nor_code) (mask, mask2));
15640 /* Try GT/GTU/LT/LTU OR EQ */
15643 enum insn_code ior_code;
15644 enum rtx_code new_code;
15665 gcc_unreachable ();
15668 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
15669 if (ior_code == CODE_FOR_nothing)
15672 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
15676 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
15680 mask = gen_reg_rtx (dmode);
15681 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
15699 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15704 /* You only get two chances. */
15708 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
15709 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
15710 operands for the relation operation COND. */
15713 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
15714 rtx cond, rtx cc_op0, rtx cc_op1)
15716 enum machine_mode dest_mode = GET_MODE (dest);
15717 enum rtx_code rcode = GET_CODE (cond);
15718 enum machine_mode cc_mode = CCmode;
15722 bool invert_move = false;
15724 if (VECTOR_UNIT_NONE_P (dest_mode))
15729 /* Swap operands if we can, and fall back to doing the operation as
15730 specified, and doing a NOR to invert the test. */
15736 /* Invert condition and try again.
15737 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
15738 invert_move = true;
15739 rcode = reverse_condition_maybe_unordered (rcode);
15740 if (rcode == UNKNOWN)
15744 /* Mark unsigned tests with CCUNSmode. */
15749 cc_mode = CCUNSmode;
15756 /* Get the vector mask for the given relational operations. */
15757 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
15765 op_true = op_false;
15769 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
15770 emit_insn (gen_rtx_SET (VOIDmode,
15772 gen_rtx_IF_THEN_ELSE (dest_mode,
15779 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
15780 operands of the last comparison is nonzero/true, FALSE_COND if it
15781 is zero/false. Return 0 if the hardware has no such operation. */
15784 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15786 enum rtx_code code = GET_CODE (op);
15787 rtx op0 = XEXP (op, 0);
15788 rtx op1 = XEXP (op, 1);
15789 REAL_VALUE_TYPE c1;
15790 enum machine_mode compare_mode = GET_MODE (op0);
15791 enum machine_mode result_mode = GET_MODE (dest);
15793 bool is_against_zero;
15795 /* These modes should always match. */
15796 if (GET_MODE (op1) != compare_mode
15797 /* In the isel case however, we can use a compare immediate, so
15798 op1 may be a small constant. */
15799 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
15801 if (GET_MODE (true_cond) != result_mode)
15803 if (GET_MODE (false_cond) != result_mode)
15806 /* First, work out if the hardware can do this at all, or
15807 if it's too slow.... */
15808 if (!FLOAT_MODE_P (compare_mode))
15811 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
15814 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
15815 && SCALAR_FLOAT_MODE_P (compare_mode))
15818 is_against_zero = op1 == CONST0_RTX (compare_mode);
15820 /* A floating-point subtract might overflow, underflow, or produce
15821 an inexact result, thus changing the floating-point flags, so it
15822 can't be generated if we care about that. It's safe if one side
15823 of the construct is zero, since then no subtract will be
15825 if (SCALAR_FLOAT_MODE_P (compare_mode)
15826 && flag_trapping_math && ! is_against_zero)
15829 /* Eliminate half of the comparisons by switching operands, this
15830 makes the remaining code simpler. */
15831 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
15832 || code == LTGT || code == LT || code == UNLE)
15834 code = reverse_condition_maybe_unordered (code);
15836 true_cond = false_cond;
15840 /* UNEQ and LTGT take four instructions for a comparison with zero,
15841 it'll probably be faster to use a branch here too. */
15842 if (code == UNEQ && HONOR_NANS (compare_mode))
15845 if (GET_CODE (op1) == CONST_DOUBLE)
15846 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
15848 /* We're going to try to implement comparisons by performing
15849 a subtract, then comparing against zero. Unfortunately,
15850 Inf - Inf is NaN which is not zero, and so if we don't
15851 know that the operand is finite and the comparison
15852 would treat EQ different to UNORDERED, we can't do it. */
15853 if (HONOR_INFINITIES (compare_mode)
15854 && code != GT && code != UNGE
15855 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
15856 /* Constructs of the form (a OP b ? a : b) are safe. */
15857 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
15858 || (! rtx_equal_p (op0, true_cond)
15859 && ! rtx_equal_p (op1, true_cond))))
15862 /* At this point we know we can use fsel. */
15864 /* Reduce the comparison to a comparison against zero. */
15865 if (! is_against_zero)
15867 temp = gen_reg_rtx (compare_mode);
15868 emit_insn (gen_rtx_SET (VOIDmode, temp,
15869 gen_rtx_MINUS (compare_mode, op0, op1)));
15871 op1 = CONST0_RTX (compare_mode);
15874 /* If we don't care about NaNs we can reduce some of the comparisons
15875 down to faster ones. */
15876 if (! HONOR_NANS (compare_mode))
15882 true_cond = false_cond;
15895 /* Now, reduce everything down to a GE. */
15902 temp = gen_reg_rtx (compare_mode);
15903 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15908 temp = gen_reg_rtx (compare_mode);
15909 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
15914 temp = gen_reg_rtx (compare_mode);
15915 emit_insn (gen_rtx_SET (VOIDmode, temp,
15916 gen_rtx_NEG (compare_mode,
15917 gen_rtx_ABS (compare_mode, op0))));
15922 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
15923 temp = gen_reg_rtx (result_mode);
15924 emit_insn (gen_rtx_SET (VOIDmode, temp,
15925 gen_rtx_IF_THEN_ELSE (result_mode,
15926 gen_rtx_GE (VOIDmode,
15928 true_cond, false_cond)));
15929 false_cond = true_cond;
15932 temp = gen_reg_rtx (compare_mode);
15933 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15938 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
15939 temp = gen_reg_rtx (result_mode);
15940 emit_insn (gen_rtx_SET (VOIDmode, temp,
15941 gen_rtx_IF_THEN_ELSE (result_mode,
15942 gen_rtx_GE (VOIDmode,
15944 true_cond, false_cond)));
15945 true_cond = false_cond;
15948 temp = gen_reg_rtx (compare_mode);
15949 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15954 gcc_unreachable ();
15957 emit_insn (gen_rtx_SET (VOIDmode, dest,
15958 gen_rtx_IF_THEN_ELSE (result_mode,
15959 gen_rtx_GE (VOIDmode,
15961 true_cond, false_cond)));
15965 /* Same as above, but for ints (isel). */
15968 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15970 rtx condition_rtx, cr;
15971 enum machine_mode mode = GET_MODE (XEXP (op, 0));
15973 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
15976 /* We still have to do the compare, because isel doesn't do a
15977 compare, it just looks at the CRx bits set by a previous compare
15979 condition_rtx = rs6000_generate_compare (op, SImode);
15980 cr = XEXP (condition_rtx, 0);
15982 if (mode == SImode)
15984 if (GET_MODE (cr) == CCmode)
15985 emit_insn (gen_isel_signed_si (dest, condition_rtx,
15986 true_cond, false_cond, cr));
15988 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
15989 true_cond, false_cond, cr));
15993 if (GET_MODE (cr) == CCmode)
15994 emit_insn (gen_isel_signed_di (dest, condition_rtx,
15995 true_cond, false_cond, cr));
15997 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
15998 true_cond, false_cond, cr));
16005 output_isel (rtx *operands)
16007 enum rtx_code code;
16009 code = GET_CODE (operands[1]);
16010 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
16012 PUT_CODE (operands[1], reverse_condition (code));
16013 return "isel %0,%3,%2,%j1";
16016 return "isel %0,%2,%3,%j1";
16020 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
16022 enum machine_mode mode = GET_MODE (op0);
16026 /* VSX/altivec have direct min/max insns. */
16027 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
16029 emit_insn (gen_rtx_SET (VOIDmode,
16031 gen_rtx_fmt_ee (code, mode, op0, op1)));
16035 if (code == SMAX || code == SMIN)
16040 if (code == SMAX || code == UMAX)
16041 target = emit_conditional_move (dest, c, op0, op1, mode,
16042 op0, op1, mode, 0);
16044 target = emit_conditional_move (dest, c, op0, op1, mode,
16045 op1, op0, mode, 0);
16046 gcc_assert (target);
16047 if (target != dest)
16048 emit_move_insn (dest, target);
16051 /* Emit instructions to perform a load-reserved/store-conditional operation.
16052 The operation performed is an atomic
16053 (set M (CODE:MODE M OP))
16054 If not NULL, BEFORE is atomically set to M before the operation, and
16055 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16056 If SYNC_P then a memory barrier is emitted before the operation.
16057 Either OP or M may be wrapped in a NOT operation. */
16060 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16061 rtx m, rtx op, rtx before_param, rtx after_param,
16064 enum machine_mode used_mode;
16065 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16068 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16069 rtx shift = NULL_RTX;
16072 emit_insn (gen_lwsync ());
16076 /* If this is smaller than SImode, we'll have to use SImode with
16078 if (mode == QImode || mode == HImode)
16082 if (MEM_ALIGN (used_m) >= 32)
16085 if (BYTES_BIG_ENDIAN)
16086 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16088 shift = GEN_INT (ishift);
16089 used_m = change_address (used_m, SImode, 0);
16093 rtx addrSI, aligned_addr;
16094 int shift_mask = mode == QImode ? 0x18 : 0x10;
16096 addrSI = gen_lowpart_common (SImode,
16097 force_reg (Pmode, XEXP (used_m, 0)));
16098 addrSI = force_reg (SImode, addrSI);
16099 shift = gen_reg_rtx (SImode);
16101 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16102 GEN_INT (shift_mask)));
16103 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16105 aligned_addr = expand_binop (Pmode, and_optab,
16107 GEN_INT (-4), NULL_RTX,
16108 1, OPTAB_LIB_WIDEN);
16109 used_m = change_address (used_m, SImode, aligned_addr);
16110 set_mem_align (used_m, 32);
16112 /* It's safe to keep the old alias set of USED_M, because
16113 the operation is atomic and only affects the original
16117 if (GET_CODE (op) == NOT)
16119 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16120 oldop = gen_rtx_NOT (SImode, oldop);
16123 oldop = lowpart_subreg (SImode, op, mode);
16129 newop = expand_binop (SImode, and_optab,
16130 oldop, GEN_INT (imask), NULL_RTX,
16131 1, OPTAB_LIB_WIDEN);
16132 emit_insn (gen_ashlsi3 (newop, newop, shift));
16135 case NOT: /* NAND */
16136 newop = expand_binop (SImode, ior_optab,
16137 oldop, GEN_INT (~imask), NULL_RTX,
16138 1, OPTAB_LIB_WIDEN);
16139 emit_insn (gen_rotlsi3 (newop, newop, shift));
16143 newop = expand_binop (SImode, ior_optab,
16144 oldop, GEN_INT (~imask), NULL_RTX,
16145 1, OPTAB_LIB_WIDEN);
16146 emit_insn (gen_rotlsi3 (newop, newop, shift));
16154 newop = expand_binop (SImode, and_optab,
16155 oldop, GEN_INT (imask), NULL_RTX,
16156 1, OPTAB_LIB_WIDEN);
16157 emit_insn (gen_ashlsi3 (newop, newop, shift));
16159 mask = gen_reg_rtx (SImode);
16160 emit_move_insn (mask, GEN_INT (imask));
16161 emit_insn (gen_ashlsi3 (mask, mask, shift));
16164 newop = gen_rtx_PLUS (SImode, m, newop);
16166 newop = gen_rtx_MINUS (SImode, m, newop);
16167 newop = gen_rtx_AND (SImode, newop, mask);
16168 newop = gen_rtx_IOR (SImode, newop,
16169 gen_rtx_AND (SImode,
16170 gen_rtx_NOT (SImode, mask),
16176 gcc_unreachable ();
16180 used_mode = SImode;
16181 before = gen_reg_rtx (used_mode);
16182 after = gen_reg_rtx (used_mode);
16187 before = before_param;
16188 after = after_param;
16190 if (before == NULL_RTX)
16191 before = gen_reg_rtx (used_mode);
16192 if (after == NULL_RTX)
16193 after = gen_reg_rtx (used_mode);
16196 if ((code == PLUS || code == MINUS)
16197 && used_mode != mode)
16198 the_op = op; /* Computed above. */
16199 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16200 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16201 else if (code == NOT)
16202 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16203 gen_rtx_NOT (used_mode, m),
16204 gen_rtx_NOT (used_mode, op));
16206 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16208 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16209 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16210 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16211 gen_rtx_UNSPEC (used_mode,
16212 gen_rtvec (1, the_op),
16214 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16216 if ((code == PLUS || code == MINUS) && used_mode != mode)
16217 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16218 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16220 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16221 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16223 /* Shift and mask the return values properly. */
16224 if (used_mode != mode && before_param)
16226 emit_insn (gen_lshrsi3 (before, before, shift));
16227 convert_move (before_param, before, 1);
16230 if (used_mode != mode && after_param)
16232 emit_insn (gen_lshrsi3 (after, after, shift));
16233 convert_move (after_param, after, 1);
16236 /* The previous sequence will end with a branch that's dependent on
16237 the conditional store, so placing an isync will ensure that no
16238 other instructions (especially, no load or store instructions)
16239 can start before the atomic operation completes. */
16241 emit_insn (gen_isync ());
16244 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16245 COND is true. Mark the jump as unlikely to be taken. */
16248 emit_unlikely_jump (rtx cond, rtx label)
16250 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16253 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16254 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16255 add_reg_note (x, REG_BR_PROB, very_unlikely);
16258 /* A subroutine of the atomic operation splitters. Emit a load-locked
16259 instruction in MODE. */
16262 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16264 rtx (*fn) (rtx, rtx) = NULL;
16265 if (mode == SImode)
16266 fn = gen_load_locked_si;
16267 else if (mode == DImode)
16268 fn = gen_load_locked_di;
16269 emit_insn (fn (reg, mem));
16272 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16273 instruction in MODE. */
16276 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16278 rtx (*fn) (rtx, rtx, rtx) = NULL;
16279 if (mode == SImode)
16280 fn = gen_store_conditional_si;
16281 else if (mode == DImode)
16282 fn = gen_store_conditional_di;
16284 /* Emit sync before stwcx. to address PPC405 Erratum. */
16285 if (PPC405_ERRATUM77)
16286 emit_insn (gen_memory_barrier ());
16288 emit_insn (fn (res, mem, val));
16291 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16292 to perform. MEM is the memory on which to operate. VAL is the second
16293 operand of the binary operator. BEFORE and AFTER are optional locations to
16294 return the value of MEM either before of after the operation. SCRATCH is
16295 a scratch register. */
16298 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16299 rtx before, rtx after, rtx scratch)
16301 enum machine_mode mode = GET_MODE (mem);
16302 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16304 emit_insn (gen_lwsync ());
16306 label = gen_label_rtx ();
16307 emit_label (label);
16308 label = gen_rtx_LABEL_REF (VOIDmode, label);
16310 if (before == NULL_RTX)
16312 emit_load_locked (mode, before, mem);
16315 x = gen_rtx_IOR (mode,
16316 gen_rtx_NOT (mode, before),
16317 gen_rtx_NOT (mode, val));
16318 else if (code == AND)
16319 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16321 x = gen_rtx_fmt_ee (code, mode, before, val);
16323 if (after != NULL_RTX)
16324 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16325 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16327 emit_store_conditional (mode, cond, mem, scratch);
16329 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16330 emit_unlikely_jump (x, label);
16332 emit_insn (gen_isync ());
16335 /* Expand an atomic compare and swap operation. MEM is the memory on which
16336 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16337 value to be stored. SCRATCH is a scratch GPR. */
16340 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16343 enum machine_mode mode = GET_MODE (mem);
16344 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16346 emit_insn (gen_lwsync ());
16348 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16349 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16350 emit_label (XEXP (label1, 0));
16352 emit_load_locked (mode, retval, mem);
16354 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16355 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16357 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16358 emit_unlikely_jump (x, label2);
16360 emit_move_insn (scratch, newval);
16361 emit_store_conditional (mode, cond, mem, scratch);
16363 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16364 emit_unlikely_jump (x, label1);
16366 emit_insn (gen_isync ());
16367 emit_label (XEXP (label2, 0));
16370 /* Expand an atomic test and set operation. MEM is the memory on which
16371 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16374 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16376 enum machine_mode mode = GET_MODE (mem);
16377 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16379 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16380 emit_label (XEXP (label, 0));
16382 emit_load_locked (mode, retval, mem);
16383 emit_move_insn (scratch, val);
16384 emit_store_conditional (mode, cond, mem, scratch);
16386 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16387 emit_unlikely_jump (x, label);
16389 emit_insn (gen_isync ());
16393 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
16395 enum machine_mode mode = GET_MODE (mem);
16396 rtx addrSI, align, wdst, shift, mask;
16397 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
16398 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16400 /* Shift amount for subword relative to aligned word. */
16401 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
16402 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
16403 shift = gen_reg_rtx (SImode);
16404 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16405 GEN_INT (shift_mask)));
16406 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16408 /* Shift and mask old value into position within word. */
16409 oldval = convert_modes (SImode, mode, oldval, 1);
16410 oldval = expand_binop (SImode, and_optab,
16411 oldval, GEN_INT (imask), NULL_RTX,
16412 1, OPTAB_LIB_WIDEN);
16413 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
16415 /* Shift and mask new value into position within word. */
16416 newval = convert_modes (SImode, mode, newval, 1);
16417 newval = expand_binop (SImode, and_optab,
16418 newval, GEN_INT (imask), NULL_RTX,
16419 1, OPTAB_LIB_WIDEN);
16420 emit_insn (gen_ashlsi3 (newval, newval, shift));
16422 /* Mask for insertion. */
16423 mask = gen_reg_rtx (SImode);
16424 emit_move_insn (mask, GEN_INT (imask));
16425 emit_insn (gen_ashlsi3 (mask, mask, shift));
16427 /* Address of aligned word containing subword. */
16428 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
16429 NULL_RTX, 1, OPTAB_LIB_WIDEN);
16430 mem = change_address (mem, SImode, align);
16431 set_mem_align (mem, 32);
16432 MEM_VOLATILE_P (mem) = 1;
16434 wdst = gen_reg_rtx (SImode);
16435 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
16436 oldval, newval, mem));
16438 /* Shift the result back. */
16439 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
16441 emit_move_insn (dst, gen_lowpart (mode, wdst));
16445 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
16446 rtx oldval, rtx newval, rtx mem,
16449 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16451 emit_insn (gen_lwsync ());
16452 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16453 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16454 emit_label (XEXP (label1, 0));
16456 emit_load_locked (SImode, scratch, mem);
16458 /* Mask subword within loaded value for comparison with oldval.
16459 Use UNSPEC_AND to avoid clobber.*/
16460 emit_insn (gen_rtx_SET (SImode, dest,
16461 gen_rtx_UNSPEC (SImode,
16462 gen_rtvec (2, scratch, mask),
16465 x = gen_rtx_COMPARE (CCmode, dest, oldval);
16466 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16468 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16469 emit_unlikely_jump (x, label2);
16471 /* Clear subword within loaded value for insertion of new value. */
16472 emit_insn (gen_rtx_SET (SImode, scratch,
16473 gen_rtx_AND (SImode,
16474 gen_rtx_NOT (SImode, mask), scratch)));
16475 emit_insn (gen_iorsi3 (scratch, scratch, newval));
16476 emit_store_conditional (SImode, cond, mem, scratch);
16478 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16479 emit_unlikely_jump (x, label1);
16481 emit_insn (gen_isync ());
16482 emit_label (XEXP (label2, 0));
16486 /* Emit instructions to move SRC to DST. Called by splitters for
16487 multi-register moves. It will emit at most one instruction for
16488 each register that is accessed; that is, it won't emit li/lis pairs
16489 (or equivalent for 64-bit code). One of SRC or DST must be a hard
16493 rs6000_split_multireg_move (rtx dst, rtx src)
16495 /* The register number of the first register being moved. */
16497 /* The mode that is to be moved. */
16498 enum machine_mode mode;
16499 /* The mode that the move is being done in, and its size. */
16500 enum machine_mode reg_mode;
16502 /* The number of registers that will be moved. */
16505 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
16506 mode = GET_MODE (dst);
16507 nregs = hard_regno_nregs[reg][mode];
16508 if (FP_REGNO_P (reg))
16509 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
16510 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
16511 else if (ALTIVEC_REGNO_P (reg))
16512 reg_mode = V16QImode;
16513 else if (TARGET_E500_DOUBLE && mode == TFmode)
16516 reg_mode = word_mode;
16517 reg_mode_size = GET_MODE_SIZE (reg_mode);
16519 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
16521 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
16523 /* Move register range backwards, if we might have destructive
16526 for (i = nregs - 1; i >= 0; i--)
16527 emit_insn (gen_rtx_SET (VOIDmode,
16528 simplify_gen_subreg (reg_mode, dst, mode,
16529 i * reg_mode_size),
16530 simplify_gen_subreg (reg_mode, src, mode,
16531 i * reg_mode_size)));
16537 bool used_update = false;
16539 if (MEM_P (src) && INT_REGNO_P (reg))
16543 if (GET_CODE (XEXP (src, 0)) == PRE_INC
16544 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
16547 breg = XEXP (XEXP (src, 0), 0);
16548 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
16549 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
16550 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
16551 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16552 src = replace_equiv_address (src, breg);
16554 else if (! rs6000_offsettable_memref_p (src))
16557 basereg = gen_rtx_REG (Pmode, reg);
16558 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
16559 src = replace_equiv_address (src, basereg);
16562 breg = XEXP (src, 0);
16563 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
16564 breg = XEXP (breg, 0);
16566 /* If the base register we are using to address memory is
16567 also a destination reg, then change that register last. */
16569 && REGNO (breg) >= REGNO (dst)
16570 && REGNO (breg) < REGNO (dst) + nregs)
16571 j = REGNO (breg) - REGNO (dst);
16574 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
16578 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
16579 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
16582 breg = XEXP (XEXP (dst, 0), 0);
16583 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
16584 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
16585 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
16587 /* We have to update the breg before doing the store.
16588 Use store with update, if available. */
16592 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16593 emit_insn (TARGET_32BIT
16594 ? (TARGET_POWERPC64
16595 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
16596 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
16597 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
16598 used_update = true;
16601 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16602 dst = replace_equiv_address (dst, breg);
16605 gcc_assert (rs6000_offsettable_memref_p (dst));
16608 for (i = 0; i < nregs; i++)
16610 /* Calculate index to next subword. */
16615 /* If compiler already emitted move of first word by
16616 store with update, no need to do anything. */
16617 if (j == 0 && used_update)
16620 emit_insn (gen_rtx_SET (VOIDmode,
16621 simplify_gen_subreg (reg_mode, dst, mode,
16622 j * reg_mode_size),
16623 simplify_gen_subreg (reg_mode, src, mode,
16624 j * reg_mode_size)));
16630 /* This page contains routines that are used to determine what the
16631 function prologue and epilogue code will do and write them out. */
16633 /* Return the first fixed-point register that is required to be
16634 saved. 32 if none. */
16637 first_reg_to_save (void)
16641 /* Find lowest numbered live register. */
16642 for (first_reg = 13; first_reg <= 31; first_reg++)
16643 if (df_regs_ever_live_p (first_reg)
16644 && (! call_used_regs[first_reg]
16645 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
16646 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
16647 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
16648 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
16653 && crtl->uses_pic_offset_table
16654 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
16655 return RS6000_PIC_OFFSET_TABLE_REGNUM;
16661 /* Similar, for FP regs. */
16664 first_fp_reg_to_save (void)
16668 /* Find lowest numbered live register. */
16669 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
16670 if (df_regs_ever_live_p (first_reg))
16676 /* Similar, for AltiVec regs. */
16679 first_altivec_reg_to_save (void)
16683 /* Stack frame remains as is unless we are in AltiVec ABI. */
16684 if (! TARGET_ALTIVEC_ABI)
16685 return LAST_ALTIVEC_REGNO + 1;
16687 /* On Darwin, the unwind routines are compiled without
16688 TARGET_ALTIVEC, and use save_world to save/restore the
16689 altivec registers when necessary. */
16690 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16691 && ! TARGET_ALTIVEC)
16692 return FIRST_ALTIVEC_REGNO + 20;
16694 /* Find lowest numbered live register. */
16695 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
16696 if (df_regs_ever_live_p (i))
16702 /* Return a 32-bit mask of the AltiVec registers we need to set in
16703 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
16704 the 32-bit word is 0. */
16706 static unsigned int
16707 compute_vrsave_mask (void)
16709 unsigned int i, mask = 0;
16711 /* On Darwin, the unwind routines are compiled without
16712 TARGET_ALTIVEC, and use save_world to save/restore the
16713 call-saved altivec registers when necessary. */
16714 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16715 && ! TARGET_ALTIVEC)
16718 /* First, find out if we use _any_ altivec registers. */
16719 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
16720 if (df_regs_ever_live_p (i))
16721 mask |= ALTIVEC_REG_BIT (i);
16726 /* Next, remove the argument registers from the set. These must
16727 be in the VRSAVE mask set by the caller, so we don't need to add
16728 them in again. More importantly, the mask we compute here is
16729 used to generate CLOBBERs in the set_vrsave insn, and we do not
16730 wish the argument registers to die. */
16731 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
16732 mask &= ~ALTIVEC_REG_BIT (i);
16734 /* Similarly, remove the return value from the set. */
16737 diddle_return_value (is_altivec_return_reg, &yes);
16739 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
16745 /* For a very restricted set of circumstances, we can cut down the
16746 size of prologues/epilogues by calling our own save/restore-the-world
16750 compute_save_world_info (rs6000_stack_t *info_ptr)
16752 info_ptr->world_save_p = 1;
16753 info_ptr->world_save_p
16754 = (WORLD_SAVE_P (info_ptr)
16755 && DEFAULT_ABI == ABI_DARWIN
16756 && ! (cfun->calls_setjmp && flag_exceptions)
16757 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
16758 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
16759 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
16760 && info_ptr->cr_save_p);
16762 /* This will not work in conjunction with sibcalls. Make sure there
16763 are none. (This check is expensive, but seldom executed.) */
16764 if (WORLD_SAVE_P (info_ptr))
16767 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
16768 if ( GET_CODE (insn) == CALL_INSN
16769 && SIBLING_CALL_P (insn))
16771 info_ptr->world_save_p = 0;
16776 if (WORLD_SAVE_P (info_ptr))
16778 /* Even if we're not touching VRsave, make sure there's room on the
16779 stack for it, if it looks like we're calling SAVE_WORLD, which
16780 will attempt to save it. */
16781 info_ptr->vrsave_size = 4;
16783 /* If we are going to save the world, we need to save the link register too. */
16784 info_ptr->lr_save_p = 1;
16786 /* "Save" the VRsave register too if we're saving the world. */
16787 if (info_ptr->vrsave_mask == 0)
16788 info_ptr->vrsave_mask = compute_vrsave_mask ();
16790 /* Because the Darwin register save/restore routines only handle
16791 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
16793 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
16794 && (info_ptr->first_altivec_reg_save
16795 >= FIRST_SAVED_ALTIVEC_REGNO));
16802 is_altivec_return_reg (rtx reg, void *xyes)
16804 bool *yes = (bool *) xyes;
16805 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
16810 /* Calculate the stack information for the current function. This is
16811 complicated by having two separate calling sequences, the AIX calling
16812 sequence and the V.4 calling sequence.
16814 AIX (and Darwin/Mac OS X) stack frames look like:
16816 SP----> +---------------------------------------+
16817 | back chain to caller | 0 0
16818 +---------------------------------------+
16819 | saved CR | 4 8 (8-11)
16820 +---------------------------------------+
16822 +---------------------------------------+
16823 | reserved for compilers | 12 24
16824 +---------------------------------------+
16825 | reserved for binders | 16 32
16826 +---------------------------------------+
16827 | saved TOC pointer | 20 40
16828 +---------------------------------------+
16829 | Parameter save area (P) | 24 48
16830 +---------------------------------------+
16831 | Alloca space (A) | 24+P etc.
16832 +---------------------------------------+
16833 | Local variable space (L) | 24+P+A
16834 +---------------------------------------+
16835 | Float/int conversion temporary (X) | 24+P+A+L
16836 +---------------------------------------+
16837 | Save area for AltiVec registers (W) | 24+P+A+L+X
16838 +---------------------------------------+
16839 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
16840 +---------------------------------------+
16841 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
16842 +---------------------------------------+
16843 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
16844 +---------------------------------------+
16845 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
16846 +---------------------------------------+
16847 old SP->| back chain to caller's caller |
16848 +---------------------------------------+
16850 The required alignment for AIX configurations is two words (i.e., 8
16854 V.4 stack frames look like:
16856 SP----> +---------------------------------------+
16857 | back chain to caller | 0
16858 +---------------------------------------+
16859 | caller's saved LR | 4
16860 +---------------------------------------+
16861 | Parameter save area (P) | 8
16862 +---------------------------------------+
16863 | Alloca space (A) | 8+P
16864 +---------------------------------------+
16865 | Varargs save area (V) | 8+P+A
16866 +---------------------------------------+
16867 | Local variable space (L) | 8+P+A+V
16868 +---------------------------------------+
16869 | Float/int conversion temporary (X) | 8+P+A+V+L
16870 +---------------------------------------+
16871 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
16872 +---------------------------------------+
16873 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
16874 +---------------------------------------+
16875 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
16876 +---------------------------------------+
16877 | SPE: area for 64-bit GP registers |
16878 +---------------------------------------+
16879 | SPE alignment padding |
16880 +---------------------------------------+
16881 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
16882 +---------------------------------------+
16883 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
16884 +---------------------------------------+
16885 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
16886 +---------------------------------------+
16887 old SP->| back chain to caller's caller |
16888 +---------------------------------------+
16890 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
16891 given. (But note below and in sysv4.h that we require only 8 and
16892 may round up the size of our stack frame anyways. The historical
16893 reason is early versions of powerpc-linux which didn't properly
16894 align the stack at program startup. A happy side-effect is that
16895 -mno-eabi libraries can be used with -meabi programs.)
16897 The EABI configuration defaults to the V.4 layout. However,
16898 the stack alignment requirements may differ. If -mno-eabi is not
16899 given, the required stack alignment is 8 bytes; if -mno-eabi is
16900 given, the required alignment is 16 bytes. (But see V.4 comment
16903 #ifndef ABI_STACK_BOUNDARY
16904 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
16907 static rs6000_stack_t *
16908 rs6000_stack_info (void)
16910 static rs6000_stack_t info;
16911 rs6000_stack_t *info_ptr = &info;
16912 int reg_size = TARGET_32BIT ? 4 : 8;
16916 HOST_WIDE_INT non_fixed_size;
16918 memset (&info, 0, sizeof (info));
16922 /* Cache value so we don't rescan instruction chain over and over. */
16923 if (cfun->machine->insn_chain_scanned_p == 0)
16924 cfun->machine->insn_chain_scanned_p
16925 = spe_func_has_64bit_regs_p () + 1;
16926 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
16929 /* Select which calling sequence. */
16930 info_ptr->abi = DEFAULT_ABI;
16932 /* Calculate which registers need to be saved & save area size. */
16933 info_ptr->first_gp_reg_save = first_reg_to_save ();
16934 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
16935 even if it currently looks like we won't. Reload may need it to
16936 get at a constant; if so, it will have already created a constant
16937 pool entry for it. */
16938 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
16939 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
16940 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
16941 && crtl->uses_const_pool
16942 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
16943 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
16945 first_gp = info_ptr->first_gp_reg_save;
16947 info_ptr->gp_size = reg_size * (32 - first_gp);
16949 /* For the SPE, we have an additional upper 32-bits on each GPR.
16950 Ideally we should save the entire 64-bits only when the upper
16951 half is used in SIMD instructions. Since we only record
16952 registers live (not the size they are used in), this proves
16953 difficult because we'd have to traverse the instruction chain at
16954 the right time, taking reload into account. This is a real pain,
16955 so we opt to save the GPRs in 64-bits always if but one register
16956 gets used in 64-bits. Otherwise, all the registers in the frame
16957 get saved in 32-bits.
16959 So... since when we save all GPRs (except the SP) in 64-bits, the
16960 traditional GP save area will be empty. */
16961 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
16962 info_ptr->gp_size = 0;
16964 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
16965 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
16967 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
16968 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
16969 - info_ptr->first_altivec_reg_save);
16971 /* Does this function call anything? */
16972 info_ptr->calls_p = (! current_function_is_leaf
16973 || cfun->machine->ra_needs_full_frame);
16975 /* Determine if we need to save the link register. */
16976 if ((DEFAULT_ABI == ABI_AIX
16978 && !TARGET_PROFILE_KERNEL)
16979 #ifdef TARGET_RELOCATABLE
16980 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
16982 || (info_ptr->first_fp_reg_save != 64
16983 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
16984 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
16985 || info_ptr->calls_p
16986 || rs6000_ra_ever_killed ())
16988 info_ptr->lr_save_p = 1;
16989 df_set_regs_ever_live (LR_REGNO, true);
16992 /* Determine if we need to save the condition code registers. */
16993 if (df_regs_ever_live_p (CR2_REGNO)
16994 || df_regs_ever_live_p (CR3_REGNO)
16995 || df_regs_ever_live_p (CR4_REGNO))
16997 info_ptr->cr_save_p = 1;
16998 if (DEFAULT_ABI == ABI_V4)
16999 info_ptr->cr_size = reg_size;
17002 /* If the current function calls __builtin_eh_return, then we need
17003 to allocate stack space for registers that will hold data for
17004 the exception handler. */
17005 if (crtl->calls_eh_return)
17008 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
17011 /* SPE saves EH registers in 64-bits. */
17012 ehrd_size = i * (TARGET_SPE_ABI
17013 && info_ptr->spe_64bit_regs_used != 0
17014 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
17019 /* Determine various sizes. */
17020 info_ptr->reg_size = reg_size;
17021 info_ptr->fixed_size = RS6000_SAVE_AREA;
17022 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
17023 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
17024 TARGET_ALTIVEC ? 16 : 8);
17025 if (FRAME_GROWS_DOWNWARD)
17026 info_ptr->vars_size
17027 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
17028 + info_ptr->parm_size,
17029 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
17030 - (info_ptr->fixed_size + info_ptr->vars_size
17031 + info_ptr->parm_size);
17033 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17034 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17036 info_ptr->spe_gp_size = 0;
17038 if (TARGET_ALTIVEC_ABI)
17039 info_ptr->vrsave_mask = compute_vrsave_mask ();
17041 info_ptr->vrsave_mask = 0;
17043 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17044 info_ptr->vrsave_size = 4;
17046 info_ptr->vrsave_size = 0;
17048 compute_save_world_info (info_ptr);
17050 /* Calculate the offsets. */
17051 switch (DEFAULT_ABI)
17055 gcc_unreachable ();
17059 info_ptr->fp_save_offset = - info_ptr->fp_size;
17060 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17062 if (TARGET_ALTIVEC_ABI)
17064 info_ptr->vrsave_save_offset
17065 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17067 /* Align stack so vector save area is on a quadword boundary.
17068 The padding goes above the vectors. */
17069 if (info_ptr->altivec_size != 0)
17070 info_ptr->altivec_padding_size
17071 = info_ptr->vrsave_save_offset & 0xF;
17073 info_ptr->altivec_padding_size = 0;
17075 info_ptr->altivec_save_offset
17076 = info_ptr->vrsave_save_offset
17077 - info_ptr->altivec_padding_size
17078 - info_ptr->altivec_size;
17079 gcc_assert (info_ptr->altivec_size == 0
17080 || info_ptr->altivec_save_offset % 16 == 0);
17082 /* Adjust for AltiVec case. */
17083 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17086 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17087 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17088 info_ptr->lr_save_offset = 2*reg_size;
17092 info_ptr->fp_save_offset = - info_ptr->fp_size;
17093 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17094 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17096 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17098 /* Align stack so SPE GPR save area is aligned on a
17099 double-word boundary. */
17100 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17101 info_ptr->spe_padding_size
17102 = 8 - (-info_ptr->cr_save_offset % 8);
17104 info_ptr->spe_padding_size = 0;
17106 info_ptr->spe_gp_save_offset
17107 = info_ptr->cr_save_offset
17108 - info_ptr->spe_padding_size
17109 - info_ptr->spe_gp_size;
17111 /* Adjust for SPE case. */
17112 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17114 else if (TARGET_ALTIVEC_ABI)
17116 info_ptr->vrsave_save_offset
17117 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17119 /* Align stack so vector save area is on a quadword boundary. */
17120 if (info_ptr->altivec_size != 0)
17121 info_ptr->altivec_padding_size
17122 = 16 - (-info_ptr->vrsave_save_offset % 16);
17124 info_ptr->altivec_padding_size = 0;
17126 info_ptr->altivec_save_offset
17127 = info_ptr->vrsave_save_offset
17128 - info_ptr->altivec_padding_size
17129 - info_ptr->altivec_size;
17131 /* Adjust for AltiVec case. */
17132 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17135 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17136 info_ptr->ehrd_offset -= ehrd_size;
17137 info_ptr->lr_save_offset = reg_size;
17141 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17142 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17143 + info_ptr->gp_size
17144 + info_ptr->altivec_size
17145 + info_ptr->altivec_padding_size
17146 + info_ptr->spe_gp_size
17147 + info_ptr->spe_padding_size
17149 + info_ptr->cr_size
17150 + info_ptr->vrsave_size,
17153 non_fixed_size = (info_ptr->vars_size
17154 + info_ptr->parm_size
17155 + info_ptr->save_size);
17157 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17158 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17160 /* Determine if we need to allocate any stack frame:
17162 For AIX we need to push the stack if a frame pointer is needed
17163 (because the stack might be dynamically adjusted), if we are
17164 debugging, if we make calls, or if the sum of fp_save, gp_save,
17165 and local variables are more than the space needed to save all
17166 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17167 + 18*8 = 288 (GPR13 reserved).
17169 For V.4 we don't have the stack cushion that AIX uses, but assume
17170 that the debugger can handle stackless frames. */
17172 if (info_ptr->calls_p)
17173 info_ptr->push_p = 1;
17175 else if (DEFAULT_ABI == ABI_V4)
17176 info_ptr->push_p = non_fixed_size != 0;
17178 else if (frame_pointer_needed)
17179 info_ptr->push_p = 1;
17181 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17182 info_ptr->push_p = 1;
17185 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17187 /* Zero offsets if we're not saving those registers. */
17188 if (info_ptr->fp_size == 0)
17189 info_ptr->fp_save_offset = 0;
17191 if (info_ptr->gp_size == 0)
17192 info_ptr->gp_save_offset = 0;
17194 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17195 info_ptr->altivec_save_offset = 0;
17197 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17198 info_ptr->vrsave_save_offset = 0;
17200 if (! TARGET_SPE_ABI
17201 || info_ptr->spe_64bit_regs_used == 0
17202 || info_ptr->spe_gp_size == 0)
17203 info_ptr->spe_gp_save_offset = 0;
17205 if (! info_ptr->lr_save_p)
17206 info_ptr->lr_save_offset = 0;
17208 if (! info_ptr->cr_save_p)
17209 info_ptr->cr_save_offset = 0;
17214 /* Return true if the current function uses any GPRs in 64-bit SIMD
17218 spe_func_has_64bit_regs_p (void)
17222 /* Functions that save and restore all the call-saved registers will
17223 need to save/restore the registers in 64-bits. */
17224 if (crtl->calls_eh_return
17225 || cfun->calls_setjmp
17226 || crtl->has_nonlocal_goto)
17229 insns = get_insns ();
17231 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17237 /* FIXME: This should be implemented with attributes...
17239 (set_attr "spe64" "true")....then,
17240 if (get_spe64(insn)) return true;
17242 It's the only reliable way to do the stuff below. */
17244 i = PATTERN (insn);
17245 if (GET_CODE (i) == SET)
17247 enum machine_mode mode = GET_MODE (SET_SRC (i));
17249 if (SPE_VECTOR_MODE (mode))
17251 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17261 debug_stack_info (rs6000_stack_t *info)
17263 const char *abi_string;
17266 info = rs6000_stack_info ();
17268 fprintf (stderr, "\nStack information for function %s:\n",
17269 ((current_function_decl && DECL_NAME (current_function_decl))
17270 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17275 default: abi_string = "Unknown"; break;
17276 case ABI_NONE: abi_string = "NONE"; break;
17277 case ABI_AIX: abi_string = "AIX"; break;
17278 case ABI_DARWIN: abi_string = "Darwin"; break;
17279 case ABI_V4: abi_string = "V.4"; break;
17282 fprintf (stderr, "\tABI = %5s\n", abi_string);
17284 if (TARGET_ALTIVEC_ABI)
17285 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17287 if (TARGET_SPE_ABI)
17288 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17290 if (info->first_gp_reg_save != 32)
17291 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17293 if (info->first_fp_reg_save != 64)
17294 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17296 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17297 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17298 info->first_altivec_reg_save);
17300 if (info->lr_save_p)
17301 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17303 if (info->cr_save_p)
17304 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17306 if (info->vrsave_mask)
17307 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17310 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17313 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17315 if (info->gp_save_offset)
17316 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17318 if (info->fp_save_offset)
17319 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17321 if (info->altivec_save_offset)
17322 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17323 info->altivec_save_offset);
17325 if (info->spe_gp_save_offset)
17326 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17327 info->spe_gp_save_offset);
17329 if (info->vrsave_save_offset)
17330 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17331 info->vrsave_save_offset);
17333 if (info->lr_save_offset)
17334 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
17336 if (info->cr_save_offset)
17337 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
17339 if (info->varargs_save_offset)
17340 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
17342 if (info->total_size)
17343 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17346 if (info->vars_size)
17347 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17350 if (info->parm_size)
17351 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
17353 if (info->fixed_size)
17354 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
17357 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
17359 if (info->spe_gp_size)
17360 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
17363 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
17365 if (info->altivec_size)
17366 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
17368 if (info->vrsave_size)
17369 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
17371 if (info->altivec_padding_size)
17372 fprintf (stderr, "\taltivec_padding_size= %5d\n",
17373 info->altivec_padding_size);
17375 if (info->spe_padding_size)
17376 fprintf (stderr, "\tspe_padding_size = %5d\n",
17377 info->spe_padding_size);
17380 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
17382 if (info->save_size)
17383 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
17385 if (info->reg_size != 4)
17386 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
17388 fprintf (stderr, "\n");
17392 rs6000_return_addr (int count, rtx frame)
17394 /* Currently we don't optimize very well between prolog and body
17395 code and for PIC code the code can be actually quite bad, so
17396 don't try to be too clever here. */
17397 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
17399 cfun->machine->ra_needs_full_frame = 1;
17406 plus_constant (copy_to_reg
17407 (gen_rtx_MEM (Pmode,
17408 memory_address (Pmode, frame))),
17409 RETURN_ADDRESS_OFFSET)));
17412 cfun->machine->ra_need_lr = 1;
17413 return get_hard_reg_initial_val (Pmode, LR_REGNO);
17416 /* Say whether a function is a candidate for sibcall handling or not.
17417 We do not allow indirect calls to be optimized into sibling calls.
17418 Also, we can't do it if there are any vector parameters; there's
17419 nowhere to put the VRsave code so it works; note that functions with
17420 vector parameters are required to have a prototype, so the argument
17421 type info must be available here. (The tail recursion case can work
17422 with vector parameters, but there's no way to distinguish here.) */
17424 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
17429 if (TARGET_ALTIVEC_VRSAVE)
17431 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
17432 type; type = TREE_CHAIN (type))
17434 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
17438 if (DEFAULT_ABI == ABI_DARWIN
17439 || ((*targetm.binds_local_p) (decl)
17440 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
17442 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
17444 if (!lookup_attribute ("longcall", attr_list)
17445 || lookup_attribute ("shortcall", attr_list))
17452 /* NULL if INSN insn is valid within a low-overhead loop.
17453 Otherwise return why doloop cannot be applied.
17454 PowerPC uses the COUNT register for branch on table instructions. */
17456 static const char *
17457 rs6000_invalid_within_doloop (const_rtx insn)
17460 return "Function call in the loop.";
17463 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
17464 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
17465 return "Computed branch in the loop.";
17471 rs6000_ra_ever_killed (void)
17477 if (cfun->is_thunk)
17480 /* regs_ever_live has LR marked as used if any sibcalls are present,
17481 but this should not force saving and restoring in the
17482 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
17483 clobbers LR, so that is inappropriate. */
17485 /* Also, the prologue can generate a store into LR that
17486 doesn't really count, like this:
17489 bcl to set PIC register
17493 When we're called from the epilogue, we need to avoid counting
17494 this as a store. */
17496 push_topmost_sequence ();
17497 top = get_insns ();
17498 pop_topmost_sequence ();
17499 reg = gen_rtx_REG (Pmode, LR_REGNO);
17501 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
17507 if (!SIBLING_CALL_P (insn))
17510 else if (find_regno_note (insn, REG_INC, LR_REGNO))
17512 else if (set_of (reg, insn) != NULL_RTX
17513 && !prologue_epilogue_contains (insn))
17520 /* Emit instructions needed to load the TOC register.
17521 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
17522 a constant pool; or for SVR4 -fpic. */
17525 rs6000_emit_load_toc_table (int fromprolog)
17528 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
17530 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
17533 rtx lab, tmp1, tmp2, got;
17535 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17536 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17538 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17540 got = rs6000_got_sym ();
17541 tmp1 = tmp2 = dest;
17544 tmp1 = gen_reg_rtx (Pmode);
17545 tmp2 = gen_reg_rtx (Pmode);
17547 emit_insn (gen_load_toc_v4_PIC_1 (lab));
17548 emit_move_insn (tmp1,
17549 gen_rtx_REG (Pmode, LR_REGNO));
17550 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
17551 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
17553 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
17555 emit_insn (gen_load_toc_v4_pic_si ());
17556 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
17558 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
17561 rtx temp0 = (fromprolog
17562 ? gen_rtx_REG (Pmode, 0)
17563 : gen_reg_rtx (Pmode));
17569 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17570 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17572 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
17573 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17575 emit_insn (gen_load_toc_v4_PIC_1 (symF));
17576 emit_move_insn (dest,
17577 gen_rtx_REG (Pmode, LR_REGNO));
17578 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
17584 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17585 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
17586 emit_move_insn (dest,
17587 gen_rtx_REG (Pmode, LR_REGNO));
17588 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
17590 emit_insn (gen_addsi3 (dest, temp0, dest));
17592 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
17594 /* This is for AIX code running in non-PIC ELF32. */
17597 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
17598 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17600 emit_insn (gen_elf_high (dest, realsym));
17601 emit_insn (gen_elf_low (dest, dest, realsym));
17605 gcc_assert (DEFAULT_ABI == ABI_AIX);
17608 emit_insn (gen_load_toc_aix_si (dest));
17610 emit_insn (gen_load_toc_aix_di (dest));
17614 /* Emit instructions to restore the link register after determining where
17615 its value has been stored. */
17618 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
17620 rs6000_stack_t *info = rs6000_stack_info ();
17623 operands[0] = source;
17624 operands[1] = scratch;
17626 if (info->lr_save_p)
17628 rtx frame_rtx = stack_pointer_rtx;
17629 HOST_WIDE_INT sp_offset = 0;
17632 if (frame_pointer_needed
17633 || cfun->calls_alloca
17634 || info->total_size > 32767)
17636 tmp = gen_frame_mem (Pmode, frame_rtx);
17637 emit_move_insn (operands[1], tmp);
17638 frame_rtx = operands[1];
17640 else if (info->push_p)
17641 sp_offset = info->total_size;
17643 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
17644 tmp = gen_frame_mem (Pmode, tmp);
17645 emit_move_insn (tmp, operands[0]);
17648 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
17651 static GTY(()) alias_set_type set = -1;
17654 get_TOC_alias_set (void)
17657 set = new_alias_set ();
17661 /* This returns nonzero if the current function uses the TOC. This is
17662 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
17663 is generated by the ABI_V4 load_toc_* patterns. */
17670 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
17673 rtx pat = PATTERN (insn);
17676 if (GET_CODE (pat) == PARALLEL)
17677 for (i = 0; i < XVECLEN (pat, 0); i++)
17679 rtx sub = XVECEXP (pat, 0, i);
17680 if (GET_CODE (sub) == USE)
17682 sub = XEXP (sub, 0);
17683 if (GET_CODE (sub) == UNSPEC
17684 && XINT (sub, 1) == UNSPEC_TOC)
17694 create_TOC_reference (rtx symbol)
17696 if (TARGET_DEBUG_ADDR)
17698 if (GET_CODE (symbol) == SYMBOL_REF)
17699 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
17703 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
17704 GET_RTX_NAME (GET_CODE (symbol)));
17705 debug_rtx (symbol);
17709 if (!can_create_pseudo_p ())
17710 df_set_regs_ever_live (TOC_REGISTER, true);
17711 return gen_rtx_PLUS (Pmode,
17712 gen_rtx_REG (Pmode, TOC_REGISTER),
17713 gen_rtx_CONST (Pmode,
17714 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL)));
17717 /* Issue assembly directives that create a reference to the given DWARF
17718 FRAME_TABLE_LABEL from the current function section. */
17720 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
17722 fprintf (asm_out_file, "\t.ref %s\n",
17723 TARGET_STRIP_NAME_ENCODING (frame_table_label));
17726 /* If _Unwind_* has been called from within the same module,
17727 toc register is not guaranteed to be saved to 40(1) on function
17728 entry. Save it there in that case. */
17731 rs6000_aix_emit_builtin_unwind_init (void)
17734 rtx stack_top = gen_reg_rtx (Pmode);
17735 rtx opcode_addr = gen_reg_rtx (Pmode);
17736 rtx opcode = gen_reg_rtx (SImode);
17737 rtx tocompare = gen_reg_rtx (SImode);
17738 rtx no_toc_save_needed = gen_label_rtx ();
17740 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
17741 emit_move_insn (stack_top, mem);
17743 mem = gen_frame_mem (Pmode,
17744 gen_rtx_PLUS (Pmode, stack_top,
17745 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
17746 emit_move_insn (opcode_addr, mem);
17747 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
17748 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
17749 : 0xE8410028, SImode));
17751 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
17752 SImode, NULL_RTX, NULL_RTX,
17753 no_toc_save_needed);
17755 mem = gen_frame_mem (Pmode,
17756 gen_rtx_PLUS (Pmode, stack_top,
17757 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
17758 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
17759 emit_label (no_toc_save_needed);
17762 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
17763 and the change to the stack pointer. */
17766 rs6000_emit_stack_tie (void)
17768 rtx mem = gen_frame_mem (BLKmode,
17769 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
17771 emit_insn (gen_stack_tie (mem));
17774 /* Emit the correct code for allocating stack space, as insns.
17775 If COPY_R12, make sure a copy of the old frame is left in r12.
17776 If COPY_R11, make sure a copy of the old frame is left in r11,
17777 in preference to r12 if COPY_R12.
17778 The generated code may use hard register 0 as a temporary. */
17781 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
17784 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
17785 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
17786 rtx todec = gen_int_mode (-size, Pmode);
17789 if (INTVAL (todec) != -size)
17791 warning (0, "stack frame too large");
17792 emit_insn (gen_trap ());
17796 if (crtl->limit_stack)
17798 if (REG_P (stack_limit_rtx)
17799 && REGNO (stack_limit_rtx) > 1
17800 && REGNO (stack_limit_rtx) <= 31)
17802 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
17803 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
17806 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
17808 && DEFAULT_ABI == ABI_V4)
17810 rtx toload = gen_rtx_CONST (VOIDmode,
17811 gen_rtx_PLUS (Pmode,
17815 emit_insn (gen_elf_high (tmp_reg, toload));
17816 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
17817 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
17821 warning (0, "stack limit expression is not supported");
17824 if (copy_r12 || copy_r11)
17825 emit_move_insn (copy_r11
17826 ? gen_rtx_REG (Pmode, 11)
17827 : gen_rtx_REG (Pmode, 12),
17832 /* Need a note here so that try_split doesn't get confused. */
17833 if (get_last_insn () == NULL_RTX)
17834 emit_note (NOTE_INSN_DELETED);
17835 insn = emit_move_insn (tmp_reg, todec);
17836 try_split (PATTERN (insn), insn, 0);
17840 insn = emit_insn (TARGET_32BIT
17841 ? gen_movsi_update_stack (stack_reg, stack_reg,
17843 : gen_movdi_di_update_stack (stack_reg, stack_reg,
17844 todec, stack_reg));
17845 /* Since we didn't use gen_frame_mem to generate the MEM, grab
17846 it now and set the alias set/attributes. The above gen_*_update
17847 calls will generate a PARALLEL with the MEM set being the first
17849 par = PATTERN (insn);
17850 gcc_assert (GET_CODE (par) == PARALLEL);
17851 set = XVECEXP (par, 0, 0);
17852 gcc_assert (GET_CODE (set) == SET);
17853 mem = SET_DEST (set);
17854 gcc_assert (MEM_P (mem));
17855 MEM_NOTRAP_P (mem) = 1;
17856 set_mem_alias_set (mem, get_frame_alias_set ());
17858 RTX_FRAME_RELATED_P (insn) = 1;
17859 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
17860 gen_rtx_SET (VOIDmode, stack_reg,
17861 gen_rtx_PLUS (Pmode, stack_reg,
17862 GEN_INT (-size))));
17865 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
17866 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
17867 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
17868 deduce these equivalences by itself so it wasn't necessary to hold
17869 its hand so much. */
17872 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
17873 rtx reg2, rtx rreg)
17877 /* copy_rtx will not make unique copies of registers, so we need to
17878 ensure we don't have unwanted sharing here. */
17880 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
17883 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
17885 real = copy_rtx (PATTERN (insn));
17887 if (reg2 != NULL_RTX)
17888 real = replace_rtx (real, reg2, rreg);
17890 real = replace_rtx (real, reg,
17891 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
17892 STACK_POINTER_REGNUM),
17895 /* We expect that 'real' is either a SET or a PARALLEL containing
17896 SETs (and possibly other stuff). In a PARALLEL, all the SETs
17897 are important so they all have to be marked RTX_FRAME_RELATED_P. */
17899 if (GET_CODE (real) == SET)
17903 temp = simplify_rtx (SET_SRC (set));
17905 SET_SRC (set) = temp;
17906 temp = simplify_rtx (SET_DEST (set));
17908 SET_DEST (set) = temp;
17909 if (GET_CODE (SET_DEST (set)) == MEM)
17911 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
17913 XEXP (SET_DEST (set), 0) = temp;
17920 gcc_assert (GET_CODE (real) == PARALLEL);
17921 for (i = 0; i < XVECLEN (real, 0); i++)
17922 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
17924 rtx set = XVECEXP (real, 0, i);
17926 temp = simplify_rtx (SET_SRC (set));
17928 SET_SRC (set) = temp;
17929 temp = simplify_rtx (SET_DEST (set));
17931 SET_DEST (set) = temp;
17932 if (GET_CODE (SET_DEST (set)) == MEM)
17934 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
17936 XEXP (SET_DEST (set), 0) = temp;
17938 RTX_FRAME_RELATED_P (set) = 1;
17942 RTX_FRAME_RELATED_P (insn) = 1;
17943 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
17946 /* Returns an insn that has a vrsave set operation with the
17947 appropriate CLOBBERs. */
17950 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
17953 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
17954 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
17957 = gen_rtx_SET (VOIDmode,
17959 gen_rtx_UNSPEC_VOLATILE (SImode,
17960 gen_rtvec (2, reg, vrsave),
17961 UNSPECV_SET_VRSAVE));
17965 /* We need to clobber the registers in the mask so the scheduler
17966 does not move sets to VRSAVE before sets of AltiVec registers.
17968 However, if the function receives nonlocal gotos, reload will set
17969 all call saved registers live. We will end up with:
17971 (set (reg 999) (mem))
17972 (parallel [ (set (reg vrsave) (unspec blah))
17973 (clobber (reg 999))])
17975 The clobber will cause the store into reg 999 to be dead, and
17976 flow will attempt to delete an epilogue insn. In this case, we
17977 need an unspec use/set of the register. */
17979 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17980 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
17982 if (!epiloguep || call_used_regs [i])
17983 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
17984 gen_rtx_REG (V4SImode, i));
17987 rtx reg = gen_rtx_REG (V4SImode, i);
17990 = gen_rtx_SET (VOIDmode,
17992 gen_rtx_UNSPEC (V4SImode,
17993 gen_rtvec (1, reg), 27));
17997 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
17999 for (i = 0; i < nclobs; ++i)
18000 XVECEXP (insn, 0, i) = clobs[i];
18005 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
18006 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
18009 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
18010 unsigned int regno, int offset, HOST_WIDE_INT total_size)
18012 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
18013 rtx replacea, replaceb;
18015 int_rtx = GEN_INT (offset);
18017 /* Some cases that need register indexed addressing. */
18018 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
18019 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
18020 || (TARGET_E500_DOUBLE && mode == DFmode)
18022 && SPE_VECTOR_MODE (mode)
18023 && !SPE_CONST_OFFSET_OK (offset)))
18025 /* Whomever calls us must make sure r11 is available in the
18026 flow path of instructions in the prologue. */
18027 offset_rtx = gen_rtx_REG (Pmode, 11);
18028 emit_move_insn (offset_rtx, int_rtx);
18030 replacea = offset_rtx;
18031 replaceb = int_rtx;
18035 offset_rtx = int_rtx;
18036 replacea = NULL_RTX;
18037 replaceb = NULL_RTX;
18040 reg = gen_rtx_REG (mode, regno);
18041 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18042 mem = gen_frame_mem (mode, addr);
18044 insn = emit_move_insn (mem, reg);
18046 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18049 /* Emit an offset memory reference suitable for a frame store, while
18050 converting to a valid addressing mode. */
18053 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18055 rtx int_rtx, offset_rtx;
18057 int_rtx = GEN_INT (offset);
18059 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18060 || (TARGET_E500_DOUBLE && mode == DFmode))
18062 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18063 emit_move_insn (offset_rtx, int_rtx);
18066 offset_rtx = int_rtx;
18068 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18071 /* Look for user-defined global regs. We should not save and restore these,
18072 and cannot use stmw/lmw if there are any in its range. */
18075 no_global_regs_above (int first, bool gpr)
18078 int last = gpr ? 32 : 64;
18079 for (i = first; i < last; i++)
18080 if (global_regs[i])
18085 #ifndef TARGET_FIX_AND_CONTINUE
18086 #define TARGET_FIX_AND_CONTINUE 0
18089 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18090 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18091 #define LAST_SAVRES_REGISTER 31
18092 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18094 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18096 /* Temporary holding space for an out-of-line register save/restore
18098 static char savres_routine_name[30];
18100 /* Return the name for an out-of-line register save/restore routine.
18101 We are saving/restoring GPRs if GPR is true. */
18104 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18105 bool savep, bool gpr, bool lr)
18107 const char *prefix = "";
18108 const char *suffix = "";
18110 /* Different targets are supposed to define
18111 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18112 routine name could be defined with:
18114 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18116 This is a nice idea in practice, but in reality, things are
18117 complicated in several ways:
18119 - ELF targets have save/restore routines for GPRs.
18121 - SPE targets use different prefixes for 32/64-bit registers, and
18122 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18124 - PPC64 ELF targets have routines for save/restore of GPRs that
18125 differ in what they do with the link register, so having a set
18126 prefix doesn't work. (We only use one of the save routines at
18127 the moment, though.)
18129 - PPC32 elf targets have "exit" versions of the restore routines
18130 that restore the link register and can save some extra space.
18131 These require an extra suffix. (There are also "tail" versions
18132 of the restore routines and "GOT" versions of the save routines,
18133 but we don't generate those at present. Same problems apply,
18136 We deal with all this by synthesizing our own prefix/suffix and
18137 using that for the simple sprintf call shown above. */
18140 /* No floating point saves on the SPE. */
18144 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
18146 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
18151 else if (DEFAULT_ABI == ABI_V4)
18157 prefix = savep ? "_savegpr_" : "_restgpr_";
18159 prefix = savep ? "_savefpr_" : "_restfpr_";
18164 else if (DEFAULT_ABI == ABI_AIX)
18166 #ifndef POWERPC_LINUX
18167 /* No out-of-line save/restore routines for GPRs on AIX. */
18168 gcc_assert (!TARGET_AIX || !gpr);
18174 ? (lr ? "_savegpr0_" : "_savegpr1_")
18175 : (lr ? "_restgpr0_" : "_restgpr1_"));
18176 #ifdef POWERPC_LINUX
18178 prefix = (savep ? "_savefpr_" : "_restfpr_");
18182 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
18183 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
18186 else if (DEFAULT_ABI == ABI_DARWIN)
18187 sorry ("Out-of-line save/restore routines not supported on Darwin");
18189 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
18191 return savres_routine_name;
18194 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18195 We are saving/restoring GPRs if GPR is true. */
18198 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
18201 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18203 int select = ((savep ? 1 : 0) << 2
18205 /* On the SPE, we never have any FPRs, but we do have
18206 32/64-bit versions of the routines. */
18207 ? (info->spe_64bit_regs_used ? 1 : 0)
18208 : (gpr ? 1 : 0)) << 1)
18211 /* Don't generate bogus routine names. */
18212 gcc_assert (FIRST_SAVRES_REGISTER <= regno
18213 && regno <= LAST_SAVRES_REGISTER);
18215 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18221 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
18223 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18224 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18225 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
18231 /* Emit a sequence of insns, including a stack tie if needed, for
18232 resetting the stack pointer. If SAVRES is true, then don't reset the
18233 stack pointer, but move the base of the frame into r11 for use by
18234 out-of-line register restore routines. */
18237 rs6000_emit_stack_reset (rs6000_stack_t *info,
18238 rtx sp_reg_rtx, rtx frame_reg_rtx,
18239 int sp_offset, bool savres)
18241 /* This blockage is needed so that sched doesn't decide to move
18242 the sp change before the register restores. */
18243 if (frame_reg_rtx != sp_reg_rtx
18245 && info->spe_64bit_regs_used != 0
18246 && info->first_gp_reg_save != 32))
18247 rs6000_emit_stack_tie ();
18249 if (frame_reg_rtx != sp_reg_rtx)
18251 if (sp_offset != 0)
18253 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
18254 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
18255 GEN_INT (sp_offset)));
18258 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18260 else if (sp_offset != 0)
18262 /* If we are restoring registers out-of-line, we will be using the
18263 "exit" variants of the restore routines, which will reset the
18264 stack for us. But we do need to point r11 into the right place
18265 for those routines. */
18266 rtx dest_reg = (savres
18267 ? gen_rtx_REG (Pmode, 11)
18270 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18271 GEN_INT (sp_offset)));
18278 /* Construct a parallel rtx describing the effect of a call to an
18279 out-of-line register save/restore routine. */
18282 rs6000_make_savres_rtx (rs6000_stack_t *info,
18283 rtx frame_reg_rtx, int save_area_offset,
18284 enum machine_mode reg_mode,
18285 bool savep, bool gpr, bool lr)
18288 int offset, start_reg, end_reg, n_regs;
18289 int reg_size = GET_MODE_SIZE (reg_mode);
18295 ? info->first_gp_reg_save
18296 : info->first_fp_reg_save);
18297 end_reg = gpr ? 32 : 64;
18298 n_regs = end_reg - start_reg;
18299 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
18302 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18304 RTVEC_ELT (p, offset++)
18305 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18307 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
18308 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18309 RTVEC_ELT (p, offset++)
18310 = gen_rtx_USE (VOIDmode,
18311 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
18315 for (i = 0; i < end_reg - start_reg; i++)
18317 rtx addr, reg, mem;
18318 reg = gen_rtx_REG (reg_mode, start_reg + i);
18319 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18320 GEN_INT (save_area_offset + reg_size*i));
18321 mem = gen_frame_mem (reg_mode, addr);
18323 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
18325 savep ? reg : mem);
18330 rtx addr, reg, mem;
18331 reg = gen_rtx_REG (Pmode, 0);
18332 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18333 GEN_INT (info->lr_save_offset));
18334 mem = gen_frame_mem (Pmode, addr);
18335 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
18338 return gen_rtx_PARALLEL (VOIDmode, p);
18341 /* Determine whether the gp REG is really used. */
18344 rs6000_reg_live_or_pic_offset_p (int reg)
18346 return ((df_regs_ever_live_p (reg)
18347 && (!call_used_regs[reg]
18348 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18349 && TARGET_TOC && TARGET_MINIMAL_TOC)))
18350 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18351 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18352 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
18356 SAVRES_MULTIPLE = 0x1,
18357 SAVRES_INLINE_FPRS = 0x2,
18358 SAVRES_INLINE_GPRS = 0x4,
18359 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
18360 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
18361 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
18364 /* Determine the strategy for savings/restoring registers. */
18367 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
18368 int using_static_chain_p, int sibcall)
18370 bool using_multiple_p;
18372 bool savres_fprs_inline;
18373 bool savres_gprs_inline;
18374 bool noclobber_global_gprs
18375 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
18378 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
18379 && (!TARGET_SPE_ABI
18380 || info->spe_64bit_regs_used == 0)
18381 && info->first_gp_reg_save < 31
18382 && noclobber_global_gprs);
18383 /* Don't bother to try to save things out-of-line if r11 is occupied
18384 by the static chain. It would require too much fiddling and the
18385 static chain is rarely used anyway. */
18386 common = (using_static_chain_p
18388 || crtl->calls_eh_return
18389 || !info->lr_save_p
18390 || cfun->machine->ra_need_lr
18391 || info->total_size > 32767);
18392 savres_fprs_inline = (common
18393 || info->first_fp_reg_save == 64
18394 || !no_global_regs_above (info->first_fp_reg_save,
18396 /* The out-of-line FP routines use
18397 double-precision stores; we can't use those
18398 routines if we don't have such stores. */
18399 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18400 || FP_SAVE_INLINE (info->first_fp_reg_save));
18401 savres_gprs_inline = (common
18402 /* Saving CR interferes with the exit routines
18403 used on the SPE, so just punt here. */
18406 && info->spe_64bit_regs_used != 0
18407 && info->cr_save_p != 0)
18408 || info->first_gp_reg_save == 32
18409 || !noclobber_global_gprs
18410 || GP_SAVE_INLINE (info->first_gp_reg_save));
18413 /* If we are going to use store multiple, then don't even bother
18414 with the out-of-line routines, since the store-multiple instruction
18415 will always be smaller. */
18416 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18419 /* The situation is more complicated with load multiple. We'd
18420 prefer to use the out-of-line routines for restores, since the
18421 "exit" out-of-line routines can handle the restore of LR and
18422 the frame teardown. But we can only use the out-of-line
18423 routines if we know that we've used store multiple or
18424 out-of-line routines in the prologue, i.e. if we've saved all
18425 the registers from first_gp_reg_save. Otherwise, we risk
18426 loading garbage from the stack. Furthermore, we can only use
18427 the "exit" out-of-line gpr restore if we haven't saved any
18429 bool saved_all = !savres_gprs_inline || using_multiple_p;
18431 if (saved_all && info->first_fp_reg_save != 64)
18432 /* We can't use the exit routine; use load multiple if it's
18434 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18437 strategy = (using_multiple_p
18438 | (savres_fprs_inline << 1)
18439 | (savres_gprs_inline << 2));
18440 #ifdef POWERPC_LINUX
18443 if (!savres_fprs_inline)
18444 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
18445 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
18446 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
18449 if (TARGET_AIX && !savres_fprs_inline)
18450 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18455 /* Emit function prologue as insns. */
18458 rs6000_emit_prologue (void)
18460 rs6000_stack_t *info = rs6000_stack_info ();
18461 enum machine_mode reg_mode = Pmode;
18462 int reg_size = TARGET_32BIT ? 4 : 8;
18463 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18464 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
18465 rtx frame_reg_rtx = sp_reg_rtx;
18466 rtx cr_save_rtx = NULL_RTX;
18469 int saving_FPRs_inline;
18470 int saving_GPRs_inline;
18471 int using_store_multiple;
18472 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18473 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18474 && call_used_regs[STATIC_CHAIN_REGNUM]);
18475 HOST_WIDE_INT sp_offset = 0;
18477 if (TARGET_FIX_AND_CONTINUE)
18479 /* gdb on darwin arranges to forward a function from the old
18480 address by modifying the first 5 instructions of the function
18481 to branch to the overriding function. This is necessary to
18482 permit function pointers that point to the old function to
18483 actually forward to the new function. */
18484 emit_insn (gen_nop ());
18485 emit_insn (gen_nop ());
18486 emit_insn (gen_nop ());
18487 emit_insn (gen_nop ());
18488 emit_insn (gen_nop ());
18491 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
18493 reg_mode = V2SImode;
18497 strategy = rs6000_savres_strategy (info, /*savep=*/true,
18498 /*static_chain_p=*/using_static_chain_p,
18500 using_store_multiple = strategy & SAVRES_MULTIPLE;
18501 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
18502 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
18504 /* For V.4, update stack before we do any saving and set back pointer. */
18505 if (! WORLD_SAVE_P (info)
18507 && (DEFAULT_ABI == ABI_V4
18508 || crtl->calls_eh_return))
18510 bool need_r11 = (TARGET_SPE
18511 ? (!saving_GPRs_inline
18512 && info->spe_64bit_regs_used == 0)
18513 : (!saving_FPRs_inline || !saving_GPRs_inline));
18514 if (info->total_size < 32767)
18515 sp_offset = info->total_size;
18517 frame_reg_rtx = (need_r11
18518 ? gen_rtx_REG (Pmode, 11)
18520 rs6000_emit_allocate_stack (info->total_size,
18521 (frame_reg_rtx != sp_reg_rtx
18522 && (info->cr_save_p
18524 || info->first_fp_reg_save < 64
18525 || info->first_gp_reg_save < 32
18528 if (frame_reg_rtx != sp_reg_rtx)
18529 rs6000_emit_stack_tie ();
18532 /* Handle world saves specially here. */
18533 if (WORLD_SAVE_P (info))
18540 /* save_world expects lr in r0. */
18541 reg0 = gen_rtx_REG (Pmode, 0);
18542 if (info->lr_save_p)
18544 insn = emit_move_insn (reg0,
18545 gen_rtx_REG (Pmode, LR_REGNO));
18546 RTX_FRAME_RELATED_P (insn) = 1;
18549 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
18550 assumptions about the offsets of various bits of the stack
18552 gcc_assert (info->gp_save_offset == -220
18553 && info->fp_save_offset == -144
18554 && info->lr_save_offset == 8
18555 && info->cr_save_offset == 4
18558 && (!crtl->calls_eh_return
18559 || info->ehrd_offset == -432)
18560 && info->vrsave_save_offset == -224
18561 && info->altivec_save_offset == -416);
18563 treg = gen_rtx_REG (SImode, 11);
18564 emit_move_insn (treg, GEN_INT (-info->total_size));
18566 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
18567 in R11. It also clobbers R12, so beware! */
18569 /* Preserve CR2 for save_world prologues */
18571 sz += 32 - info->first_gp_reg_save;
18572 sz += 64 - info->first_fp_reg_save;
18573 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
18574 p = rtvec_alloc (sz);
18576 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
18577 gen_rtx_REG (SImode,
18579 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
18580 gen_rtx_SYMBOL_REF (Pmode,
18582 /* We do floats first so that the instruction pattern matches
18584 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18586 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18587 ? DFmode : SFmode),
18588 info->first_fp_reg_save + i);
18589 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18590 GEN_INT (info->fp_save_offset
18591 + sp_offset + 8 * i));
18592 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18593 ? DFmode : SFmode), addr);
18595 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18597 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
18599 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
18600 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18601 GEN_INT (info->altivec_save_offset
18602 + sp_offset + 16 * i));
18603 rtx mem = gen_frame_mem (V4SImode, addr);
18605 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18607 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18609 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18610 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18611 GEN_INT (info->gp_save_offset
18612 + sp_offset + reg_size * i));
18613 rtx mem = gen_frame_mem (reg_mode, addr);
18615 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18619 /* CR register traditionally saved as CR2. */
18620 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
18621 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18622 GEN_INT (info->cr_save_offset
18624 rtx mem = gen_frame_mem (reg_mode, addr);
18626 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18628 /* Explain about use of R0. */
18629 if (info->lr_save_p)
18631 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18632 GEN_INT (info->lr_save_offset
18634 rtx mem = gen_frame_mem (reg_mode, addr);
18636 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
18638 /* Explain what happens to the stack pointer. */
18640 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
18641 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
18644 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18645 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18646 treg, GEN_INT (-info->total_size));
18647 sp_offset = info->total_size;
18650 /* If we use the link register, get it into r0. */
18651 if (!WORLD_SAVE_P (info) && info->lr_save_p)
18653 rtx addr, reg, mem;
18655 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
18656 gen_rtx_REG (Pmode, LR_REGNO));
18657 RTX_FRAME_RELATED_P (insn) = 1;
18659 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
18660 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
18662 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18663 GEN_INT (info->lr_save_offset + sp_offset));
18664 reg = gen_rtx_REG (Pmode, 0);
18665 mem = gen_rtx_MEM (Pmode, addr);
18666 /* This should not be of rs6000_sr_alias_set, because of
18667 __builtin_return_address. */
18669 insn = emit_move_insn (mem, reg);
18670 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18671 NULL_RTX, NULL_RTX);
18675 /* If we need to save CR, put it into r12 or r11. */
18676 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
18681 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
18683 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18684 RTX_FRAME_RELATED_P (insn) = 1;
18685 /* Now, there's no way that dwarf2out_frame_debug_expr is going
18686 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
18687 But that's OK. All we have to do is specify that _one_ condition
18688 code register is saved in this stack slot. The thrower's epilogue
18689 will then restore all the call-saved registers.
18690 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
18691 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
18692 gen_rtx_REG (SImode, CR2_REGNO));
18693 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18696 /* Do any required saving of fpr's. If only one or two to save, do
18697 it ourselves. Otherwise, call function. */
18698 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
18701 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18702 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
18703 && ! call_used_regs[info->first_fp_reg_save+i]))
18704 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
18705 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18707 info->first_fp_reg_save + i,
18708 info->fp_save_offset + sp_offset + 8 * i,
18711 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
18715 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18716 info->fp_save_offset + sp_offset,
18718 /*savep=*/true, /*gpr=*/false,
18720 & SAVRES_NOINLINE_FPRS_SAVES_LR)
18722 insn = emit_insn (par);
18723 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18724 NULL_RTX, NULL_RTX);
18727 /* Save GPRs. This is done as a PARALLEL if we are using
18728 the store-multiple instructions. */
18729 if (!WORLD_SAVE_P (info)
18731 && info->spe_64bit_regs_used != 0
18732 && info->first_gp_reg_save != 32)
18735 rtx spe_save_area_ptr;
18737 /* Determine whether we can address all of the registers that need
18738 to be saved with an offset from the stack pointer that fits in
18739 the small const field for SPE memory instructions. */
18740 int spe_regs_addressable_via_sp
18741 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
18742 + (32 - info->first_gp_reg_save - 1) * reg_size)
18743 && saving_GPRs_inline);
18746 if (spe_regs_addressable_via_sp)
18748 spe_save_area_ptr = frame_reg_rtx;
18749 spe_offset = info->spe_gp_save_offset + sp_offset;
18753 /* Make r11 point to the start of the SPE save area. We need
18754 to be careful here if r11 is holding the static chain. If
18755 it is, then temporarily save it in r0. We would use r0 as
18756 our base register here, but using r0 as a base register in
18757 loads and stores means something different from what we
18759 int ool_adjust = (saving_GPRs_inline
18761 : (info->first_gp_reg_save
18762 - (FIRST_SAVRES_REGISTER+1))*8);
18763 HOST_WIDE_INT offset = (info->spe_gp_save_offset
18764 + sp_offset - ool_adjust);
18766 if (using_static_chain_p)
18768 rtx r0 = gen_rtx_REG (Pmode, 0);
18769 gcc_assert (info->first_gp_reg_save > 11);
18771 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
18774 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
18775 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
18777 GEN_INT (offset)));
18778 /* We need to make sure the move to r11 gets noted for
18779 properly outputting unwind information. */
18780 if (!saving_GPRs_inline)
18781 rs6000_frame_related (insn, frame_reg_rtx, offset,
18782 NULL_RTX, NULL_RTX);
18786 if (saving_GPRs_inline)
18788 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18789 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
18791 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18792 rtx offset, addr, mem;
18794 /* We're doing all this to ensure that the offset fits into
18795 the immediate offset of 'evstdd'. */
18796 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
18798 offset = GEN_INT (reg_size * i + spe_offset);
18799 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
18800 mem = gen_rtx_MEM (V2SImode, addr);
18802 insn = emit_move_insn (mem, reg);
18804 rs6000_frame_related (insn, spe_save_area_ptr,
18805 info->spe_gp_save_offset
18806 + sp_offset + reg_size * i,
18807 offset, const0_rtx);
18814 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
18816 /*savep=*/true, /*gpr=*/true,
18818 insn = emit_insn (par);
18819 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18820 NULL_RTX, NULL_RTX);
18824 /* Move the static chain pointer back. */
18825 if (using_static_chain_p && !spe_regs_addressable_via_sp)
18826 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
18828 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
18832 /* Need to adjust r11 (r12) if we saved any FPRs. */
18833 if (info->first_fp_reg_save != 64)
18835 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
18837 rtx offset = GEN_INT (sp_offset
18838 + (-8 * (64-info->first_fp_reg_save)));
18839 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
18842 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18843 info->gp_save_offset + sp_offset,
18845 /*savep=*/true, /*gpr=*/true,
18847 & SAVRES_NOINLINE_GPRS_SAVES_LR)
18849 insn = emit_insn (par);
18850 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18851 NULL_RTX, NULL_RTX);
18853 else if (!WORLD_SAVE_P (info) && using_store_multiple)
18857 p = rtvec_alloc (32 - info->first_gp_reg_save);
18858 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18860 rtx addr, reg, mem;
18861 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18862 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18863 GEN_INT (info->gp_save_offset
18866 mem = gen_frame_mem (reg_mode, addr);
18868 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
18870 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18871 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18872 NULL_RTX, NULL_RTX);
18874 else if (!WORLD_SAVE_P (info))
18877 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18878 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
18880 rtx addr, reg, mem;
18881 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18883 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18884 GEN_INT (info->gp_save_offset
18887 mem = gen_frame_mem (reg_mode, addr);
18889 insn = emit_move_insn (mem, reg);
18890 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18891 NULL_RTX, NULL_RTX);
18895 /* ??? There's no need to emit actual instructions here, but it's the
18896 easiest way to get the frame unwind information emitted. */
18897 if (crtl->calls_eh_return)
18899 unsigned int i, regno;
18901 /* In AIX ABI we need to pretend we save r2 here. */
18904 rtx addr, reg, mem;
18906 reg = gen_rtx_REG (reg_mode, 2);
18907 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18908 GEN_INT (sp_offset + 5 * reg_size));
18909 mem = gen_frame_mem (reg_mode, addr);
18911 insn = emit_move_insn (mem, reg);
18912 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18913 NULL_RTX, NULL_RTX);
18914 PATTERN (insn) = gen_blockage ();
18919 regno = EH_RETURN_DATA_REGNO (i);
18920 if (regno == INVALID_REGNUM)
18923 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
18924 info->ehrd_offset + sp_offset
18925 + reg_size * (int) i,
18930 /* Save CR if we use any that must be preserved. */
18931 if (!WORLD_SAVE_P (info) && info->cr_save_p)
18933 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18934 GEN_INT (info->cr_save_offset + sp_offset));
18935 rtx mem = gen_frame_mem (SImode, addr);
18936 /* See the large comment above about why CR2_REGNO is used. */
18937 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
18939 /* If r12 was used to hold the original sp, copy cr into r0 now
18941 if (REGNO (frame_reg_rtx) == 12)
18945 cr_save_rtx = gen_rtx_REG (SImode, 0);
18946 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18947 RTX_FRAME_RELATED_P (insn) = 1;
18948 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
18949 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18951 insn = emit_move_insn (mem, cr_save_rtx);
18953 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18954 NULL_RTX, NULL_RTX);
18957 /* Update stack and set back pointer unless this is V.4,
18958 for which it was done previously. */
18959 if (!WORLD_SAVE_P (info) && info->push_p
18960 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
18962 if (info->total_size < 32767)
18963 sp_offset = info->total_size;
18965 frame_reg_rtx = frame_ptr_rtx;
18966 rs6000_emit_allocate_stack (info->total_size,
18967 (frame_reg_rtx != sp_reg_rtx
18968 && ((info->altivec_size != 0)
18969 || (info->vrsave_mask != 0)
18972 if (frame_reg_rtx != sp_reg_rtx)
18973 rs6000_emit_stack_tie ();
18976 /* Set frame pointer, if needed. */
18977 if (frame_pointer_needed)
18979 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
18981 RTX_FRAME_RELATED_P (insn) = 1;
18984 /* Save AltiVec registers if needed. Save here because the red zone does
18985 not include AltiVec registers. */
18986 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
18990 /* There should be a non inline version of this, for when we
18991 are saving lots of vector registers. */
18992 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
18993 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18995 rtx areg, savereg, mem;
18998 offset = info->altivec_save_offset + sp_offset
18999 + 16 * (i - info->first_altivec_reg_save);
19001 savereg = gen_rtx_REG (V4SImode, i);
19003 areg = gen_rtx_REG (Pmode, 0);
19004 emit_move_insn (areg, GEN_INT (offset));
19006 /* AltiVec addressing mode is [reg+reg]. */
19007 mem = gen_frame_mem (V4SImode,
19008 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
19010 insn = emit_move_insn (mem, savereg);
19012 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19013 areg, GEN_INT (offset));
19017 /* VRSAVE is a bit vector representing which AltiVec registers
19018 are used. The OS uses this to determine which vector
19019 registers to save on a context switch. We need to save
19020 VRSAVE on the stack frame, add whatever AltiVec registers we
19021 used in this function, and do the corresponding magic in the
19024 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
19025 && info->vrsave_mask != 0)
19027 rtx reg, mem, vrsave;
19030 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
19031 as frame_reg_rtx and r11 as the static chain pointer for
19032 nested functions. */
19033 reg = gen_rtx_REG (SImode, 0);
19034 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19036 emit_insn (gen_get_vrsave_internal (reg));
19038 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19040 if (!WORLD_SAVE_P (info))
19043 offset = info->vrsave_save_offset + sp_offset;
19044 mem = gen_frame_mem (SImode,
19045 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19046 GEN_INT (offset)));
19047 insn = emit_move_insn (mem, reg);
19050 /* Include the registers in the mask. */
19051 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19053 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19056 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19057 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19058 || (DEFAULT_ABI == ABI_V4
19059 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19060 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19062 /* If emit_load_toc_table will use the link register, we need to save
19063 it. We use R12 for this purpose because emit_load_toc_table
19064 can use register 0. This allows us to use a plain 'blr' to return
19065 from the procedure more often. */
19066 int save_LR_around_toc_setup = (TARGET_ELF
19067 && DEFAULT_ABI != ABI_AIX
19069 && ! info->lr_save_p
19070 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19071 if (save_LR_around_toc_setup)
19073 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19075 insn = emit_move_insn (frame_ptr_rtx, lr);
19076 RTX_FRAME_RELATED_P (insn) = 1;
19078 rs6000_emit_load_toc_table (TRUE);
19080 insn = emit_move_insn (lr, frame_ptr_rtx);
19081 RTX_FRAME_RELATED_P (insn) = 1;
19084 rs6000_emit_load_toc_table (TRUE);
19088 if (DEFAULT_ABI == ABI_DARWIN
19089 && flag_pic && crtl->uses_pic_offset_table)
19091 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19092 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19094 /* Save and restore LR locally around this call (in R0). */
19095 if (!info->lr_save_p)
19096 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19098 emit_insn (gen_load_macho_picbase (src));
19100 emit_move_insn (gen_rtx_REG (Pmode,
19101 RS6000_PIC_OFFSET_TABLE_REGNUM),
19104 if (!info->lr_save_p)
19105 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19110 /* Write function prologue. */
19113 rs6000_output_function_prologue (FILE *file,
19114 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19116 rs6000_stack_t *info = rs6000_stack_info ();
19118 if (TARGET_DEBUG_STACK)
19119 debug_stack_info (info);
19121 /* Write .extern for any function we will call to save and restore
19123 if (info->first_fp_reg_save < 64
19124 && !FP_SAVE_INLINE (info->first_fp_reg_save))
19127 int regno = info->first_fp_reg_save - 32;
19129 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
19130 /*gpr=*/false, /*lr=*/false);
19131 fprintf (file, "\t.extern %s\n", name);
19133 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
19134 /*gpr=*/false, /*lr=*/true);
19135 fprintf (file, "\t.extern %s\n", name);
19138 /* Write .extern for AIX common mode routines, if needed. */
19139 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
19141 fputs ("\t.extern __mulh\n", file);
19142 fputs ("\t.extern __mull\n", file);
19143 fputs ("\t.extern __divss\n", file);
19144 fputs ("\t.extern __divus\n", file);
19145 fputs ("\t.extern __quoss\n", file);
19146 fputs ("\t.extern __quous\n", file);
19147 common_mode_defined = 1;
19150 if (! HAVE_prologue)
19156 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19157 the "toplevel" insn chain. */
19158 emit_note (NOTE_INSN_DELETED);
19159 rs6000_emit_prologue ();
19160 emit_note (NOTE_INSN_DELETED);
19162 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19166 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19168 INSN_ADDRESSES_NEW (insn, addr);
19173 prologue = get_insns ();
19176 if (TARGET_DEBUG_STACK)
19177 debug_rtx_list (prologue, 100);
19179 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
19183 rs6000_pic_labelno++;
19186 /* Non-zero if vmx regs are restored before the frame pop, zero if
19187 we restore after the pop when possible. */
19188 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19190 /* Reload CR from REG. */
19193 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
19198 if (using_mfcr_multiple)
19200 for (i = 0; i < 8; i++)
19201 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19203 gcc_assert (count);
19206 if (using_mfcr_multiple && count > 1)
19211 p = rtvec_alloc (count);
19214 for (i = 0; i < 8; i++)
19215 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19217 rtvec r = rtvec_alloc (2);
19218 RTVEC_ELT (r, 0) = reg;
19219 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19220 RTVEC_ELT (p, ndx) =
19221 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19222 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19225 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19226 gcc_assert (ndx == count);
19229 for (i = 0; i < 8; i++)
19230 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19232 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19238 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19239 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19240 below stack pointer not cloberred by signals. */
19243 offset_below_red_zone_p (HOST_WIDE_INT offset)
19245 return offset < (DEFAULT_ABI == ABI_V4
19247 : TARGET_32BIT ? -220 : -288);
19250 /* Emit function epilogue as insns. */
19253 rs6000_emit_epilogue (int sibcall)
19255 rs6000_stack_t *info;
19256 int restoring_GPRs_inline;
19257 int restoring_FPRs_inline;
19258 int using_load_multiple;
19259 int using_mtcr_multiple;
19260 int use_backchain_to_restore_sp;
19264 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19265 rtx frame_reg_rtx = sp_reg_rtx;
19266 rtx cfa_restores = NULL_RTX;
19268 rtx cr_save_reg = NULL_RTX;
19269 enum machine_mode reg_mode = Pmode;
19270 int reg_size = TARGET_32BIT ? 4 : 8;
19273 info = rs6000_stack_info ();
19275 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19277 reg_mode = V2SImode;
19281 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19282 /*static_chain_p=*/0, sibcall);
19283 using_load_multiple = strategy & SAVRES_MULTIPLE;
19284 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19285 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19286 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19287 || rs6000_cpu == PROCESSOR_PPC603
19288 || rs6000_cpu == PROCESSOR_PPC750
19290 /* Restore via the backchain when we have a large frame, since this
19291 is more efficient than an addis, addi pair. The second condition
19292 here will not trigger at the moment; We don't actually need a
19293 frame pointer for alloca, but the generic parts of the compiler
19294 give us one anyway. */
19295 use_backchain_to_restore_sp = (info->total_size > 32767
19296 || info->total_size
19297 + (info->lr_save_p ? info->lr_save_offset : 0)
19299 || (cfun->calls_alloca
19300 && !frame_pointer_needed));
19301 restore_lr = (info->lr_save_p
19302 && (restoring_FPRs_inline
19303 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
19304 && (restoring_GPRs_inline
19305 || info->first_fp_reg_save < 64));
19307 if (WORLD_SAVE_P (info))
19311 const char *alloc_rname;
19314 /* eh_rest_world_r10 will return to the location saved in the LR
19315 stack slot (which is not likely to be our caller.)
19316 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19317 rest_world is similar, except any R10 parameter is ignored.
19318 The exception-handling stuff that was here in 2.95 is no
19319 longer necessary. */
19323 + 32 - info->first_gp_reg_save
19324 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
19325 + 63 + 1 - info->first_fp_reg_save);
19327 strcpy (rname, ((crtl->calls_eh_return) ?
19328 "*eh_rest_world_r10" : "*rest_world"));
19329 alloc_rname = ggc_strdup (rname);
19332 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
19333 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19334 gen_rtx_REG (Pmode,
19337 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
19338 /* The instruction pattern requires a clobber here;
19339 it is shared with the restVEC helper. */
19341 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
19344 /* CR register traditionally saved as CR2. */
19345 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19346 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19347 GEN_INT (info->cr_save_offset));
19348 rtx mem = gen_frame_mem (reg_mode, addr);
19350 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19353 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19355 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19356 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19357 GEN_INT (info->gp_save_offset
19359 rtx mem = gen_frame_mem (reg_mode, addr);
19361 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19363 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19365 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19366 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19367 GEN_INT (info->altivec_save_offset
19369 rtx mem = gen_frame_mem (V4SImode, addr);
19371 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19373 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
19375 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19376 ? DFmode : SFmode),
19377 info->first_fp_reg_save + i);
19378 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19379 GEN_INT (info->fp_save_offset
19381 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19382 ? DFmode : SFmode), addr);
19384 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19387 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
19389 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
19391 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
19393 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
19395 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
19396 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19401 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
19403 sp_offset = info->total_size;
19405 /* Restore AltiVec registers if we must do so before adjusting the
19407 if (TARGET_ALTIVEC_ABI
19408 && info->altivec_size != 0
19409 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19410 || (DEFAULT_ABI != ABI_V4
19411 && offset_below_red_zone_p (info->altivec_save_offset))))
19415 if (use_backchain_to_restore_sp)
19417 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19418 emit_move_insn (frame_reg_rtx,
19419 gen_rtx_MEM (Pmode, sp_reg_rtx));
19422 else if (frame_pointer_needed)
19423 frame_reg_rtx = hard_frame_pointer_rtx;
19425 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19426 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19428 rtx addr, areg, mem, reg;
19430 areg = gen_rtx_REG (Pmode, 0);
19432 (areg, GEN_INT (info->altivec_save_offset
19434 + 16 * (i - info->first_altivec_reg_save)));
19436 /* AltiVec addressing mode is [reg+reg]. */
19437 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19438 mem = gen_frame_mem (V4SImode, addr);
19440 reg = gen_rtx_REG (V4SImode, i);
19441 emit_move_insn (reg, mem);
19442 if (offset_below_red_zone_p (info->altivec_save_offset
19443 + (i - info->first_altivec_reg_save)
19445 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19450 /* Restore VRSAVE if we must do so before adjusting the stack. */
19452 && TARGET_ALTIVEC_VRSAVE
19453 && info->vrsave_mask != 0
19454 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19455 || (DEFAULT_ABI != ABI_V4
19456 && offset_below_red_zone_p (info->vrsave_save_offset))))
19458 rtx addr, mem, reg;
19460 if (frame_reg_rtx == sp_reg_rtx)
19462 if (use_backchain_to_restore_sp)
19464 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19465 emit_move_insn (frame_reg_rtx,
19466 gen_rtx_MEM (Pmode, sp_reg_rtx));
19469 else if (frame_pointer_needed)
19470 frame_reg_rtx = hard_frame_pointer_rtx;
19473 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19474 GEN_INT (info->vrsave_save_offset + sp_offset));
19475 mem = gen_frame_mem (SImode, addr);
19476 reg = gen_rtx_REG (SImode, 12);
19477 emit_move_insn (reg, mem);
19479 emit_insn (generate_set_vrsave (reg, info, 1));
19483 /* If we have a large stack frame, restore the old stack pointer
19484 using the backchain. */
19485 if (use_backchain_to_restore_sp)
19487 if (frame_reg_rtx == sp_reg_rtx)
19489 /* Under V.4, don't reset the stack pointer until after we're done
19490 loading the saved registers. */
19491 if (DEFAULT_ABI == ABI_V4)
19492 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19494 insn = emit_move_insn (frame_reg_rtx,
19495 gen_rtx_MEM (Pmode, sp_reg_rtx));
19498 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19499 && DEFAULT_ABI == ABI_V4)
19500 /* frame_reg_rtx has been set up by the altivec restore. */
19504 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19505 frame_reg_rtx = sp_reg_rtx;
19508 /* If we have a frame pointer, we can restore the old stack pointer
19510 else if (frame_pointer_needed)
19512 frame_reg_rtx = sp_reg_rtx;
19513 if (DEFAULT_ABI == ABI_V4)
19514 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19516 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
19517 GEN_INT (info->total_size)));
19520 else if (info->push_p
19521 && DEFAULT_ABI != ABI_V4
19522 && !crtl->calls_eh_return)
19524 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
19525 GEN_INT (info->total_size)));
19528 if (insn && frame_reg_rtx == sp_reg_rtx)
19532 REG_NOTES (insn) = cfa_restores;
19533 cfa_restores = NULL_RTX;
19535 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19536 RTX_FRAME_RELATED_P (insn) = 1;
19539 /* Restore AltiVec registers if we have not done so already. */
19540 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19541 && TARGET_ALTIVEC_ABI
19542 && info->altivec_size != 0
19543 && (DEFAULT_ABI == ABI_V4
19544 || !offset_below_red_zone_p (info->altivec_save_offset)))
19548 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19549 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19551 rtx addr, areg, mem, reg;
19553 areg = gen_rtx_REG (Pmode, 0);
19555 (areg, GEN_INT (info->altivec_save_offset
19557 + 16 * (i - info->first_altivec_reg_save)));
19559 /* AltiVec addressing mode is [reg+reg]. */
19560 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19561 mem = gen_frame_mem (V4SImode, addr);
19563 reg = gen_rtx_REG (V4SImode, i);
19564 emit_move_insn (reg, mem);
19565 if (DEFAULT_ABI == ABI_V4)
19566 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19571 /* Restore VRSAVE if we have not done so already. */
19572 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19574 && TARGET_ALTIVEC_VRSAVE
19575 && info->vrsave_mask != 0
19576 && (DEFAULT_ABI == ABI_V4
19577 || !offset_below_red_zone_p (info->vrsave_save_offset)))
19579 rtx addr, mem, reg;
19581 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19582 GEN_INT (info->vrsave_save_offset + sp_offset));
19583 mem = gen_frame_mem (SImode, addr);
19584 reg = gen_rtx_REG (SImode, 12);
19585 emit_move_insn (reg, mem);
19587 emit_insn (generate_set_vrsave (reg, info, 1));
19590 /* Get the old lr if we saved it. If we are restoring registers
19591 out-of-line, then the out-of-line routines can do this for us. */
19592 if (restore_lr && restoring_GPRs_inline)
19594 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19595 info->lr_save_offset + sp_offset);
19597 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19600 /* Get the old cr if we saved it. */
19601 if (info->cr_save_p)
19603 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19604 GEN_INT (info->cr_save_offset + sp_offset));
19605 rtx mem = gen_frame_mem (SImode, addr);
19607 cr_save_reg = gen_rtx_REG (SImode,
19608 DEFAULT_ABI == ABI_AIX
19609 && !restoring_GPRs_inline
19610 && info->first_fp_reg_save < 64
19612 emit_move_insn (cr_save_reg, mem);
19615 /* Set LR here to try to overlap restores below. LR is always saved
19616 above incoming stack, so it never needs REG_CFA_RESTORE. */
19617 if (restore_lr && restoring_GPRs_inline)
19618 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19619 gen_rtx_REG (Pmode, 0));
19621 /* Load exception handler data registers, if needed. */
19622 if (crtl->calls_eh_return)
19624 unsigned int i, regno;
19628 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19629 GEN_INT (sp_offset + 5 * reg_size));
19630 rtx mem = gen_frame_mem (reg_mode, addr);
19632 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
19639 regno = EH_RETURN_DATA_REGNO (i);
19640 if (regno == INVALID_REGNUM)
19643 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
19644 info->ehrd_offset + sp_offset
19645 + reg_size * (int) i);
19647 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
19651 /* Restore GPRs. This is done as a PARALLEL if we are using
19652 the load-multiple instructions. */
19654 && info->spe_64bit_regs_used != 0
19655 && info->first_gp_reg_save != 32)
19657 /* Determine whether we can address all of the registers that need
19658 to be saved with an offset from the stack pointer that fits in
19659 the small const field for SPE memory instructions. */
19660 int spe_regs_addressable_via_sp
19661 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19662 + (32 - info->first_gp_reg_save - 1) * reg_size)
19663 && restoring_GPRs_inline);
19666 if (spe_regs_addressable_via_sp)
19667 spe_offset = info->spe_gp_save_offset + sp_offset;
19670 rtx old_frame_reg_rtx = frame_reg_rtx;
19671 /* Make r11 point to the start of the SPE save area. We worried about
19672 not clobbering it when we were saving registers in the prologue.
19673 There's no need to worry here because the static chain is passed
19674 anew to every function. */
19675 int ool_adjust = (restoring_GPRs_inline
19677 : (info->first_gp_reg_save
19678 - (FIRST_SAVRES_REGISTER+1))*8);
19680 if (frame_reg_rtx == sp_reg_rtx)
19681 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19682 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
19683 GEN_INT (info->spe_gp_save_offset
19686 /* Keep the invariant that frame_reg_rtx + sp_offset points
19687 at the top of the stack frame. */
19688 sp_offset = -info->spe_gp_save_offset;
19693 if (restoring_GPRs_inline)
19695 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19696 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19698 rtx offset, addr, mem, reg;
19700 /* We're doing all this to ensure that the immediate offset
19701 fits into the immediate field of 'evldd'. */
19702 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
19704 offset = GEN_INT (spe_offset + reg_size * i);
19705 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
19706 mem = gen_rtx_MEM (V2SImode, addr);
19707 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19709 insn = emit_move_insn (reg, mem);
19710 if (DEFAULT_ABI == ABI_V4)
19712 if (frame_pointer_needed
19713 && info->first_gp_reg_save + i
19714 == HARD_FRAME_POINTER_REGNUM)
19716 add_reg_note (insn, REG_CFA_DEF_CFA,
19717 plus_constant (frame_reg_rtx,
19719 RTX_FRAME_RELATED_P (insn) = 1;
19722 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19731 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19733 /*savep=*/false, /*gpr=*/true,
19735 emit_jump_insn (par);
19736 /* We don't want anybody else emitting things after we jumped
19741 else if (!restoring_GPRs_inline)
19743 /* We are jumping to an out-of-line function. */
19744 bool can_use_exit = info->first_fp_reg_save == 64;
19747 /* Emit stack reset code if we need it. */
19749 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19750 sp_offset, can_use_exit);
19753 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
19756 GEN_INT (sp_offset - info->fp_size)));
19757 if (REGNO (frame_reg_rtx) == 11)
19758 sp_offset += info->fp_size;
19761 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19762 info->gp_save_offset, reg_mode,
19763 /*savep=*/false, /*gpr=*/true,
19764 /*lr=*/can_use_exit);
19768 if (info->cr_save_p)
19770 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
19771 if (DEFAULT_ABI == ABI_V4)
19773 = alloc_reg_note (REG_CFA_RESTORE,
19774 gen_rtx_REG (SImode, CR2_REGNO),
19778 emit_jump_insn (par);
19780 /* We don't want anybody else emitting things after we jumped
19785 insn = emit_insn (par);
19786 if (DEFAULT_ABI == ABI_V4)
19788 if (frame_pointer_needed)
19790 add_reg_note (insn, REG_CFA_DEF_CFA,
19791 plus_constant (frame_reg_rtx, sp_offset));
19792 RTX_FRAME_RELATED_P (insn) = 1;
19795 for (i = info->first_gp_reg_save; i < 32; i++)
19797 = alloc_reg_note (REG_CFA_RESTORE,
19798 gen_rtx_REG (reg_mode, i), cfa_restores);
19801 else if (using_load_multiple)
19804 p = rtvec_alloc (32 - info->first_gp_reg_save);
19805 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19807 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19808 GEN_INT (info->gp_save_offset
19811 rtx mem = gen_frame_mem (reg_mode, addr);
19812 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19814 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
19815 if (DEFAULT_ABI == ABI_V4)
19816 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19819 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19820 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
19822 add_reg_note (insn, REG_CFA_DEF_CFA,
19823 plus_constant (frame_reg_rtx, sp_offset));
19824 RTX_FRAME_RELATED_P (insn) = 1;
19829 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19830 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19832 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19833 GEN_INT (info->gp_save_offset
19836 rtx mem = gen_frame_mem (reg_mode, addr);
19837 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19839 insn = emit_move_insn (reg, mem);
19840 if (DEFAULT_ABI == ABI_V4)
19842 if (frame_pointer_needed
19843 && info->first_gp_reg_save + i
19844 == HARD_FRAME_POINTER_REGNUM)
19846 add_reg_note (insn, REG_CFA_DEF_CFA,
19847 plus_constant (frame_reg_rtx, sp_offset));
19848 RTX_FRAME_RELATED_P (insn) = 1;
19851 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19857 if (restore_lr && !restoring_GPRs_inline)
19859 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19860 info->lr_save_offset + sp_offset);
19862 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19863 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19864 gen_rtx_REG (Pmode, 0));
19867 /* Restore fpr's if we need to do it without calling a function. */
19868 if (restoring_FPRs_inline)
19869 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19870 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
19871 && ! call_used_regs[info->first_fp_reg_save+i]))
19873 rtx addr, mem, reg;
19874 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19875 GEN_INT (info->fp_save_offset
19878 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19879 ? DFmode : SFmode), addr);
19880 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19881 ? DFmode : SFmode),
19882 info->first_fp_reg_save + i);
19884 emit_move_insn (reg, mem);
19885 if (DEFAULT_ABI == ABI_V4)
19886 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19890 /* If we saved cr, restore it here. Just those that were used. */
19891 if (info->cr_save_p)
19893 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
19894 if (DEFAULT_ABI == ABI_V4)
19896 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
19900 /* If this is V.4, unwind the stack pointer after all of the loads
19902 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19903 sp_offset, !restoring_FPRs_inline);
19908 REG_NOTES (insn) = cfa_restores;
19909 cfa_restores = NULL_RTX;
19911 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19912 RTX_FRAME_RELATED_P (insn) = 1;
19915 if (crtl->calls_eh_return)
19917 rtx sa = EH_RETURN_STACKADJ_RTX;
19918 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
19924 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
19925 if (! restoring_FPRs_inline)
19926 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
19928 p = rtvec_alloc (2);
19930 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
19931 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
19932 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
19933 : gen_rtx_CLOBBER (VOIDmode,
19934 gen_rtx_REG (Pmode, 65)));
19936 /* If we have to restore more than two FP registers, branch to the
19937 restore function. It will return to our caller. */
19938 if (! restoring_FPRs_inline)
19943 sym = rs6000_savres_routine_sym (info,
19947 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
19948 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
19949 gen_rtx_REG (Pmode,
19950 DEFAULT_ABI == ABI_AIX
19952 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19955 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
19956 GEN_INT (info->fp_save_offset + 8*i));
19957 mem = gen_frame_mem (DFmode, addr);
19959 RTVEC_ELT (p, i+4) =
19960 gen_rtx_SET (VOIDmode,
19961 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
19966 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19970 /* Write function epilogue. */
19973 rs6000_output_function_epilogue (FILE *file,
19974 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19976 if (! HAVE_epilogue)
19978 rtx insn = get_last_insn ();
19979 /* If the last insn was a BARRIER, we don't have to write anything except
19980 the trace table. */
19981 if (GET_CODE (insn) == NOTE)
19982 insn = prev_nonnote_insn (insn);
19983 if (insn == 0 || GET_CODE (insn) != BARRIER)
19985 /* This is slightly ugly, but at least we don't have two
19986 copies of the epilogue-emitting code. */
19989 /* A NOTE_INSN_DELETED is supposed to be at the start
19990 and end of the "toplevel" insn chain. */
19991 emit_note (NOTE_INSN_DELETED);
19992 rs6000_emit_epilogue (FALSE);
19993 emit_note (NOTE_INSN_DELETED);
19995 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19999 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20001 INSN_ADDRESSES_NEW (insn, addr);
20006 if (TARGET_DEBUG_STACK)
20007 debug_rtx_list (get_insns (), 100);
20008 final (get_insns (), file, FALSE);
20014 macho_branch_islands ();
20015 /* Mach-O doesn't support labels at the end of objects, so if
20016 it looks like we might want one, insert a NOP. */
20018 rtx insn = get_last_insn ();
20021 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
20022 insn = PREV_INSN (insn);
20026 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
20027 fputs ("\tnop\n", file);
20031 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20034 We don't output a traceback table if -finhibit-size-directive was
20035 used. The documentation for -finhibit-size-directive reads
20036 ``don't output a @code{.size} assembler directive, or anything
20037 else that would cause trouble if the function is split in the
20038 middle, and the two halves are placed at locations far apart in
20039 memory.'' The traceback table has this property, since it
20040 includes the offset from the start of the function to the
20041 traceback table itself.
20043 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20044 different traceback table. */
20045 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20046 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20048 const char *fname = NULL;
20049 const char *language_string = lang_hooks.name;
20050 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20052 int optional_tbtab;
20053 rs6000_stack_t *info = rs6000_stack_info ();
20055 if (rs6000_traceback == traceback_full)
20056 optional_tbtab = 1;
20057 else if (rs6000_traceback == traceback_part)
20058 optional_tbtab = 0;
20060 optional_tbtab = !optimize_size && !TARGET_ELF;
20062 if (optional_tbtab)
20064 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20065 while (*fname == '.') /* V.4 encodes . in the name */
20068 /* Need label immediately before tbtab, so we can compute
20069 its offset from the function start. */
20070 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20071 ASM_OUTPUT_LABEL (file, fname);
20074 /* The .tbtab pseudo-op can only be used for the first eight
20075 expressions, since it can't handle the possibly variable
20076 length fields that follow. However, if you omit the optional
20077 fields, the assembler outputs zeros for all optional fields
20078 anyways, giving each variable length field is minimum length
20079 (as defined in sys/debug.h). Thus we can not use the .tbtab
20080 pseudo-op at all. */
20082 /* An all-zero word flags the start of the tbtab, for debuggers
20083 that have to find it by searching forward from the entry
20084 point or from the current pc. */
20085 fputs ("\t.long 0\n", file);
20087 /* Tbtab format type. Use format type 0. */
20088 fputs ("\t.byte 0,", file);
20090 /* Language type. Unfortunately, there does not seem to be any
20091 official way to discover the language being compiled, so we
20092 use language_string.
20093 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20094 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20095 a number, so for now use 9. LTO isn't assigned a number either,
20096 so for now use 0. */
20097 if (! strcmp (language_string, "GNU C")
20098 || ! strcmp (language_string, "GNU GIMPLE"))
20100 else if (! strcmp (language_string, "GNU F77")
20101 || ! strcmp (language_string, "GNU Fortran"))
20103 else if (! strcmp (language_string, "GNU Pascal"))
20105 else if (! strcmp (language_string, "GNU Ada"))
20107 else if (! strcmp (language_string, "GNU C++")
20108 || ! strcmp (language_string, "GNU Objective-C++"))
20110 else if (! strcmp (language_string, "GNU Java"))
20112 else if (! strcmp (language_string, "GNU Objective-C"))
20115 gcc_unreachable ();
20116 fprintf (file, "%d,", i);
20118 /* 8 single bit fields: global linkage (not set for C extern linkage,
20119 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20120 from start of procedure stored in tbtab, internal function, function
20121 has controlled storage, function has no toc, function uses fp,
20122 function logs/aborts fp operations. */
20123 /* Assume that fp operations are used if any fp reg must be saved. */
20124 fprintf (file, "%d,",
20125 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
20127 /* 6 bitfields: function is interrupt handler, name present in
20128 proc table, function calls alloca, on condition directives
20129 (controls stack walks, 3 bits), saves condition reg, saves
20131 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20132 set up as a frame pointer, even when there is no alloca call. */
20133 fprintf (file, "%d,",
20134 ((optional_tbtab << 6)
20135 | ((optional_tbtab & frame_pointer_needed) << 5)
20136 | (info->cr_save_p << 1)
20137 | (info->lr_save_p)));
20139 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20141 fprintf (file, "%d,",
20142 (info->push_p << 7) | (64 - info->first_fp_reg_save));
20144 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20145 fprintf (file, "%d,", (32 - first_reg_to_save ()));
20147 if (optional_tbtab)
20149 /* Compute the parameter info from the function decl argument
20152 int next_parm_info_bit = 31;
20154 for (decl = DECL_ARGUMENTS (current_function_decl);
20155 decl; decl = TREE_CHAIN (decl))
20157 rtx parameter = DECL_INCOMING_RTL (decl);
20158 enum machine_mode mode = GET_MODE (parameter);
20160 if (GET_CODE (parameter) == REG)
20162 if (SCALAR_FLOAT_MODE_P (mode))
20183 gcc_unreachable ();
20186 /* If only one bit will fit, don't or in this entry. */
20187 if (next_parm_info_bit > 0)
20188 parm_info |= (bits << (next_parm_info_bit - 1));
20189 next_parm_info_bit -= 2;
20193 fixed_parms += ((GET_MODE_SIZE (mode)
20194 + (UNITS_PER_WORD - 1))
20196 next_parm_info_bit -= 1;
20202 /* Number of fixed point parameters. */
20203 /* This is actually the number of words of fixed point parameters; thus
20204 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20205 fprintf (file, "%d,", fixed_parms);
20207 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20209 /* This is actually the number of fp registers that hold parameters;
20210 and thus the maximum value is 13. */
20211 /* Set parameters on stack bit if parameters are not in their original
20212 registers, regardless of whether they are on the stack? Xlc
20213 seems to set the bit when not optimizing. */
20214 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
20216 if (! optional_tbtab)
20219 /* Optional fields follow. Some are variable length. */
20221 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20222 11 double float. */
20223 /* There is an entry for each parameter in a register, in the order that
20224 they occur in the parameter list. Any intervening arguments on the
20225 stack are ignored. If the list overflows a long (max possible length
20226 34 bits) then completely leave off all elements that don't fit. */
20227 /* Only emit this long if there was at least one parameter. */
20228 if (fixed_parms || float_parms)
20229 fprintf (file, "\t.long %d\n", parm_info);
20231 /* Offset from start of code to tb table. */
20232 fputs ("\t.long ", file);
20233 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20235 RS6000_OUTPUT_BASENAME (file, fname);
20237 assemble_name (file, fname);
20239 rs6000_output_function_entry (file, fname);
20242 /* Interrupt handler mask. */
20243 /* Omit this long, since we never set the interrupt handler bit
20246 /* Number of CTL (controlled storage) anchors. */
20247 /* Omit this long, since the has_ctl bit is never set above. */
20249 /* Displacement into stack of each CTL anchor. */
20250 /* Omit this list of longs, because there are no CTL anchors. */
20252 /* Length of function name. */
20255 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20257 /* Function name. */
20258 assemble_string (fname, strlen (fname));
20260 /* Register for alloca automatic storage; this is always reg 31.
20261 Only emit this if the alloca bit was set above. */
20262 if (frame_pointer_needed)
20263 fputs ("\t.byte 31\n", file);
20265 fputs ("\t.align 2\n", file);
20269 /* A C compound statement that outputs the assembler code for a thunk
20270 function, used to implement C++ virtual function calls with
20271 multiple inheritance. The thunk acts as a wrapper around a virtual
20272 function, adjusting the implicit object parameter before handing
20273 control off to the real function.
20275 First, emit code to add the integer DELTA to the location that
20276 contains the incoming first argument. Assume that this argument
20277 contains a pointer, and is the one used to pass the `this' pointer
20278 in C++. This is the incoming argument *before* the function
20279 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20280 values of all other incoming arguments.
20282 After the addition, emit code to jump to FUNCTION, which is a
20283 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20284 not touch the return address. Hence returning from FUNCTION will
20285 return to whoever called the current `thunk'.
20287 The effect must be as if FUNCTION had been called directly with the
20288 adjusted first argument. This macro is responsible for emitting
20289 all of the code for a thunk function; output_function_prologue()
20290 and output_function_epilogue() are not invoked.
20292 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20293 been extracted from it.) It might possibly be useful on some
20294 targets, but probably not.
20296 If you do not define this macro, the target-independent code in the
20297 C++ frontend will generate a less efficient heavyweight thunk that
20298 calls FUNCTION instead of jumping to it. The generic approach does
20299 not support varargs. */
20302 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
20303 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
20306 rtx this_rtx, insn, funexp;
20308 reload_completed = 1;
20309 epilogue_completed = 1;
20311 /* Mark the end of the (empty) prologue. */
20312 emit_note (NOTE_INSN_PROLOGUE_END);
20314 /* Find the "this" pointer. If the function returns a structure,
20315 the structure return pointer is in r3. */
20316 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
20317 this_rtx = gen_rtx_REG (Pmode, 4);
20319 this_rtx = gen_rtx_REG (Pmode, 3);
20321 /* Apply the constant offset, if required. */
20323 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
20325 /* Apply the offset from the vtable, if required. */
20328 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
20329 rtx tmp = gen_rtx_REG (Pmode, 12);
20331 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
20332 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
20334 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
20335 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
20339 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
20341 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
20343 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
20346 /* Generate a tail call to the target function. */
20347 if (!TREE_USED (function))
20349 assemble_external (function);
20350 TREE_USED (function) = 1;
20352 funexp = XEXP (DECL_RTL (function), 0);
20353 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
20356 if (MACHOPIC_INDIRECT)
20357 funexp = machopic_indirect_call_target (funexp);
20360 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
20361 generate sibcall RTL explicitly. */
20362 insn = emit_call_insn (
20363 gen_rtx_PARALLEL (VOIDmode,
20365 gen_rtx_CALL (VOIDmode,
20366 funexp, const0_rtx),
20367 gen_rtx_USE (VOIDmode, const0_rtx),
20368 gen_rtx_USE (VOIDmode,
20369 gen_rtx_REG (SImode,
20371 gen_rtx_RETURN (VOIDmode))));
20372 SIBLING_CALL_P (insn) = 1;
20375 /* Run just enough of rest_of_compilation to get the insns emitted.
20376 There's not really enough bulk here to make other passes such as
20377 instruction scheduling worth while. Note that use_thunk calls
20378 assemble_start_function and assemble_end_function. */
20379 insn = get_insns ();
20380 insn_locators_alloc ();
20381 shorten_branches (insn);
20382 final_start_function (insn, file, 1);
20383 final (insn, file, 1);
20384 final_end_function ();
20386 reload_completed = 0;
20387 epilogue_completed = 0;
20390 /* A quick summary of the various types of 'constant-pool tables'
20393 Target Flags Name One table per
20394 AIX (none) AIX TOC object file
20395 AIX -mfull-toc AIX TOC object file
20396 AIX -mminimal-toc AIX minimal TOC translation unit
20397 SVR4/EABI (none) SVR4 SDATA object file
20398 SVR4/EABI -fpic SVR4 pic object file
20399 SVR4/EABI -fPIC SVR4 PIC translation unit
20400 SVR4/EABI -mrelocatable EABI TOC function
20401 SVR4/EABI -maix AIX TOC object file
20402 SVR4/EABI -maix -mminimal-toc
20403 AIX minimal TOC translation unit
20405 Name Reg. Set by entries contains:
20406 made by addrs? fp? sum?
20408 AIX TOC 2 crt0 as Y option option
20409 AIX minimal TOC 30 prolog gcc Y Y option
20410 SVR4 SDATA 13 crt0 gcc N Y N
20411 SVR4 pic 30 prolog ld Y not yet N
20412 SVR4 PIC 30 prolog gcc Y option option
20413 EABI TOC 30 prolog gcc Y option option
20417 /* Hash functions for the hash table. */
20420 rs6000_hash_constant (rtx k)
20422 enum rtx_code code = GET_CODE (k);
20423 enum machine_mode mode = GET_MODE (k);
20424 unsigned result = (code << 3) ^ mode;
20425 const char *format;
20428 format = GET_RTX_FORMAT (code);
20429 flen = strlen (format);
20435 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
20438 if (mode != VOIDmode)
20439 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
20451 for (; fidx < flen; fidx++)
20452 switch (format[fidx])
20457 const char *str = XSTR (k, fidx);
20458 len = strlen (str);
20459 result = result * 613 + len;
20460 for (i = 0; i < len; i++)
20461 result = result * 613 + (unsigned) str[i];
20466 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
20470 result = result * 613 + (unsigned) XINT (k, fidx);
20473 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
20474 result = result * 613 + (unsigned) XWINT (k, fidx);
20478 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
20479 result = result * 613 + (unsigned) (XWINT (k, fidx)
20486 gcc_unreachable ();
20493 toc_hash_function (const void *hash_entry)
20495 const struct toc_hash_struct *thc =
20496 (const struct toc_hash_struct *) hash_entry;
20497 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
20500 /* Compare H1 and H2 for equivalence. */
20503 toc_hash_eq (const void *h1, const void *h2)
20505 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
20506 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
20508 if (((const struct toc_hash_struct *) h1)->key_mode
20509 != ((const struct toc_hash_struct *) h2)->key_mode)
20512 return rtx_equal_p (r1, r2);
20515 /* These are the names given by the C++ front-end to vtables, and
20516 vtable-like objects. Ideally, this logic should not be here;
20517 instead, there should be some programmatic way of inquiring as
20518 to whether or not an object is a vtable. */
20520 #define VTABLE_NAME_P(NAME) \
20521 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
20522 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
20523 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
20524 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
20525 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
20527 #ifdef NO_DOLLAR_IN_LABEL
20528 /* Return a GGC-allocated character string translating dollar signs in
20529 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
20532 rs6000_xcoff_strip_dollar (const char *name)
20537 p = strchr (name, '$');
20539 if (p == 0 || p == name)
20542 len = strlen (name);
20543 strip = (char *) alloca (len + 1);
20544 strcpy (strip, name);
20545 p = strchr (strip, '$');
20549 p = strchr (p + 1, '$');
20552 return ggc_alloc_string (strip, len);
20557 rs6000_output_symbol_ref (FILE *file, rtx x)
20559 /* Currently C++ toc references to vtables can be emitted before it
20560 is decided whether the vtable is public or private. If this is
20561 the case, then the linker will eventually complain that there is
20562 a reference to an unknown section. Thus, for vtables only,
20563 we emit the TOC reference to reference the symbol and not the
20565 const char *name = XSTR (x, 0);
20567 if (VTABLE_NAME_P (name))
20569 RS6000_OUTPUT_BASENAME (file, name);
20572 assemble_name (file, name);
20575 /* Output a TOC entry. We derive the entry name from what is being
20579 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
20582 const char *name = buf;
20584 HOST_WIDE_INT offset = 0;
20586 gcc_assert (!TARGET_NO_TOC);
20588 /* When the linker won't eliminate them, don't output duplicate
20589 TOC entries (this happens on AIX if there is any kind of TOC,
20590 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
20592 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
20594 struct toc_hash_struct *h;
20597 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
20598 time because GGC is not initialized at that point. */
20599 if (toc_hash_table == NULL)
20600 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
20601 toc_hash_eq, NULL);
20603 h = GGC_NEW (struct toc_hash_struct);
20605 h->key_mode = mode;
20606 h->labelno = labelno;
20608 found = htab_find_slot (toc_hash_table, h, INSERT);
20609 if (*found == NULL)
20611 else /* This is indeed a duplicate.
20612 Set this label equal to that label. */
20614 fputs ("\t.set ", file);
20615 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20616 fprintf (file, "%d,", labelno);
20617 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20618 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
20624 /* If we're going to put a double constant in the TOC, make sure it's
20625 aligned properly when strict alignment is on. */
20626 if (GET_CODE (x) == CONST_DOUBLE
20627 && STRICT_ALIGNMENT
20628 && GET_MODE_BITSIZE (mode) >= 64
20629 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
20630 ASM_OUTPUT_ALIGN (file, 3);
20633 (*targetm.asm_out.internal_label) (file, "LC", labelno);
20635 /* Handle FP constants specially. Note that if we have a minimal
20636 TOC, things we put here aren't actually in the TOC, so we can allow
20638 if (GET_CODE (x) == CONST_DOUBLE &&
20639 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
20641 REAL_VALUE_TYPE rv;
20644 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20645 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20646 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
20648 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
20652 if (TARGET_MINIMAL_TOC)
20653 fputs (DOUBLE_INT_ASM_OP, file);
20655 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20656 k[0] & 0xffffffff, k[1] & 0xffffffff,
20657 k[2] & 0xffffffff, k[3] & 0xffffffff);
20658 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
20659 k[0] & 0xffffffff, k[1] & 0xffffffff,
20660 k[2] & 0xffffffff, k[3] & 0xffffffff);
20665 if (TARGET_MINIMAL_TOC)
20666 fputs ("\t.long ", file);
20668 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20669 k[0] & 0xffffffff, k[1] & 0xffffffff,
20670 k[2] & 0xffffffff, k[3] & 0xffffffff);
20671 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
20672 k[0] & 0xffffffff, k[1] & 0xffffffff,
20673 k[2] & 0xffffffff, k[3] & 0xffffffff);
20677 else if (GET_CODE (x) == CONST_DOUBLE &&
20678 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
20680 REAL_VALUE_TYPE rv;
20683 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20685 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20686 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
20688 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
20692 if (TARGET_MINIMAL_TOC)
20693 fputs (DOUBLE_INT_ASM_OP, file);
20695 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20696 k[0] & 0xffffffff, k[1] & 0xffffffff);
20697 fprintf (file, "0x%lx%08lx\n",
20698 k[0] & 0xffffffff, k[1] & 0xffffffff);
20703 if (TARGET_MINIMAL_TOC)
20704 fputs ("\t.long ", file);
20706 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20707 k[0] & 0xffffffff, k[1] & 0xffffffff);
20708 fprintf (file, "0x%lx,0x%lx\n",
20709 k[0] & 0xffffffff, k[1] & 0xffffffff);
20713 else if (GET_CODE (x) == CONST_DOUBLE &&
20714 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
20716 REAL_VALUE_TYPE rv;
20719 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20720 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20721 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
20723 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
20727 if (TARGET_MINIMAL_TOC)
20728 fputs (DOUBLE_INT_ASM_OP, file);
20730 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20731 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
20736 if (TARGET_MINIMAL_TOC)
20737 fputs ("\t.long ", file);
20739 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20740 fprintf (file, "0x%lx\n", l & 0xffffffff);
20744 else if (GET_MODE (x) == VOIDmode
20745 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
20747 unsigned HOST_WIDE_INT low;
20748 HOST_WIDE_INT high;
20750 if (GET_CODE (x) == CONST_DOUBLE)
20752 low = CONST_DOUBLE_LOW (x);
20753 high = CONST_DOUBLE_HIGH (x);
20756 #if HOST_BITS_PER_WIDE_INT == 32
20759 high = (low & 0x80000000) ? ~0 : 0;
20763 low = INTVAL (x) & 0xffffffff;
20764 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
20768 /* TOC entries are always Pmode-sized, but since this
20769 is a bigendian machine then if we're putting smaller
20770 integer constants in the TOC we have to pad them.
20771 (This is still a win over putting the constants in
20772 a separate constant pool, because then we'd have
20773 to have both a TOC entry _and_ the actual constant.)
20775 For a 32-bit target, CONST_INT values are loaded and shifted
20776 entirely within `low' and can be stored in one TOC entry. */
20778 /* It would be easy to make this work, but it doesn't now. */
20779 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
20781 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
20783 #if HOST_BITS_PER_WIDE_INT == 32
20784 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
20785 POINTER_SIZE, &low, &high, 0);
20788 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
20789 high = (HOST_WIDE_INT) low >> 32;
20796 if (TARGET_MINIMAL_TOC)
20797 fputs (DOUBLE_INT_ASM_OP, file);
20799 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
20800 (long) high & 0xffffffff, (long) low & 0xffffffff);
20801 fprintf (file, "0x%lx%08lx\n",
20802 (long) high & 0xffffffff, (long) low & 0xffffffff);
20807 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
20809 if (TARGET_MINIMAL_TOC)
20810 fputs ("\t.long ", file);
20812 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
20813 (long) high & 0xffffffff, (long) low & 0xffffffff);
20814 fprintf (file, "0x%lx,0x%lx\n",
20815 (long) high & 0xffffffff, (long) low & 0xffffffff);
20819 if (TARGET_MINIMAL_TOC)
20820 fputs ("\t.long ", file);
20822 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
20823 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
20829 if (GET_CODE (x) == CONST)
20831 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
20832 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
20834 base = XEXP (XEXP (x, 0), 0);
20835 offset = INTVAL (XEXP (XEXP (x, 0), 1));
20838 switch (GET_CODE (base))
20841 name = XSTR (base, 0);
20845 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
20846 CODE_LABEL_NUMBER (XEXP (base, 0)));
20850 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
20854 gcc_unreachable ();
20857 if (TARGET_MINIMAL_TOC)
20858 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
20861 fputs ("\t.tc ", file);
20862 RS6000_OUTPUT_BASENAME (file, name);
20865 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
20867 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
20869 fputs ("[TC],", file);
20872 /* Currently C++ toc references to vtables can be emitted before it
20873 is decided whether the vtable is public or private. If this is
20874 the case, then the linker will eventually complain that there is
20875 a TOC reference to an unknown section. Thus, for vtables only,
20876 we emit the TOC reference to reference the symbol and not the
20878 if (VTABLE_NAME_P (name))
20880 RS6000_OUTPUT_BASENAME (file, name);
20882 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
20883 else if (offset > 0)
20884 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
20887 output_addr_const (file, x);
20891 /* Output an assembler pseudo-op to write an ASCII string of N characters
20892 starting at P to FILE.
20894 On the RS/6000, we have to do this using the .byte operation and
20895 write out special characters outside the quoted string.
20896 Also, the assembler is broken; very long strings are truncated,
20897 so we must artificially break them up early. */
20900 output_ascii (FILE *file, const char *p, int n)
20903 int i, count_string;
20904 const char *for_string = "\t.byte \"";
20905 const char *for_decimal = "\t.byte ";
20906 const char *to_close = NULL;
20909 for (i = 0; i < n; i++)
20912 if (c >= ' ' && c < 0177)
20915 fputs (for_string, file);
20918 /* Write two quotes to get one. */
20926 for_decimal = "\"\n\t.byte ";
20930 if (count_string >= 512)
20932 fputs (to_close, file);
20934 for_string = "\t.byte \"";
20935 for_decimal = "\t.byte ";
20943 fputs (for_decimal, file);
20944 fprintf (file, "%d", c);
20946 for_string = "\n\t.byte \"";
20947 for_decimal = ", ";
20953 /* Now close the string if we have written one. Then end the line. */
20955 fputs (to_close, file);
20958 /* Generate a unique section name for FILENAME for a section type
20959 represented by SECTION_DESC. Output goes into BUF.
20961 SECTION_DESC can be any string, as long as it is different for each
20962 possible section type.
20964 We name the section in the same manner as xlc. The name begins with an
20965 underscore followed by the filename (after stripping any leading directory
20966 names) with the last period replaced by the string SECTION_DESC. If
20967 FILENAME does not contain a period, SECTION_DESC is appended to the end of
20971 rs6000_gen_section_name (char **buf, const char *filename,
20972 const char *section_desc)
20974 const char *q, *after_last_slash, *last_period = 0;
20978 after_last_slash = filename;
20979 for (q = filename; *q; q++)
20982 after_last_slash = q + 1;
20983 else if (*q == '.')
20987 len = strlen (after_last_slash) + strlen (section_desc) + 2;
20988 *buf = (char *) xmalloc (len);
20993 for (q = after_last_slash; *q; q++)
20995 if (q == last_period)
20997 strcpy (p, section_desc);
20998 p += strlen (section_desc);
21002 else if (ISALNUM (*q))
21006 if (last_period == 0)
21007 strcpy (p, section_desc);
21012 /* Emit profile function. */
21015 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
21017 /* Non-standard profiling for kernels, which just saves LR then calls
21018 _mcount without worrying about arg saves. The idea is to change
21019 the function prologue as little as possible as it isn't easy to
21020 account for arg save/restore code added just for _mcount. */
21021 if (TARGET_PROFILE_KERNEL)
21024 if (DEFAULT_ABI == ABI_AIX)
21026 #ifndef NO_PROFILE_COUNTERS
21027 # define NO_PROFILE_COUNTERS 0
21029 if (NO_PROFILE_COUNTERS)
21030 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21031 LCT_NORMAL, VOIDmode, 0);
21035 const char *label_name;
21038 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21039 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21040 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21042 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21043 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21046 else if (DEFAULT_ABI == ABI_DARWIN)
21048 const char *mcount_name = RS6000_MCOUNT;
21049 int caller_addr_regno = LR_REGNO;
21051 /* Be conservative and always set this, at least for now. */
21052 crtl->uses_pic_offset_table = 1;
21055 /* For PIC code, set up a stub and collect the caller's address
21056 from r0, which is where the prologue puts it. */
21057 if (MACHOPIC_INDIRECT
21058 && crtl->uses_pic_offset_table)
21059 caller_addr_regno = 0;
21061 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21062 LCT_NORMAL, VOIDmode, 1,
21063 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21067 /* Write function profiler code. */
21070 output_function_profiler (FILE *file, int labelno)
21074 switch (DEFAULT_ABI)
21077 gcc_unreachable ();
21082 warning (0, "no profiling of 64-bit code for this ABI");
21085 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21086 fprintf (file, "\tmflr %s\n", reg_names[0]);
21087 if (NO_PROFILE_COUNTERS)
21089 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21090 reg_names[0], reg_names[1]);
21092 else if (TARGET_SECURE_PLT && flag_pic)
21094 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21095 reg_names[0], reg_names[1]);
21096 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21097 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21098 reg_names[12], reg_names[12]);
21099 assemble_name (file, buf);
21100 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21101 assemble_name (file, buf);
21102 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21104 else if (flag_pic == 1)
21106 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21107 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21108 reg_names[0], reg_names[1]);
21109 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21110 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
21111 assemble_name (file, buf);
21112 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
21114 else if (flag_pic > 1)
21116 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21117 reg_names[0], reg_names[1]);
21118 /* Now, we need to get the address of the label. */
21119 fputs ("\tbcl 20,31,1f\n\t.long ", file);
21120 assemble_name (file, buf);
21121 fputs ("-.\n1:", file);
21122 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
21123 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
21124 reg_names[0], reg_names[11]);
21125 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
21126 reg_names[0], reg_names[0], reg_names[11]);
21130 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
21131 assemble_name (file, buf);
21132 fputs ("@ha\n", file);
21133 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21134 reg_names[0], reg_names[1]);
21135 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
21136 assemble_name (file, buf);
21137 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
21140 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21141 fprintf (file, "\tbl %s%s\n",
21142 RS6000_MCOUNT, flag_pic ? "@plt" : "");
21147 if (!TARGET_PROFILE_KERNEL)
21149 /* Don't do anything, done in output_profile_hook (). */
21153 gcc_assert (!TARGET_32BIT);
21155 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
21156 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
21158 if (cfun->static_chain_decl != NULL)
21160 asm_fprintf (file, "\tstd %s,24(%s)\n",
21161 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21162 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21163 asm_fprintf (file, "\tld %s,24(%s)\n",
21164 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21167 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21175 /* The following variable value is the last issued insn. */
21177 static rtx last_scheduled_insn;
21179 /* The following variable helps to balance issuing of load and
21180 store instructions */
21182 static int load_store_pendulum;
21184 /* Power4 load update and store update instructions are cracked into a
21185 load or store and an integer insn which are executed in the same cycle.
21186 Branches have their own dispatch slot which does not count against the
21187 GCC issue rate, but it changes the program flow so there are no other
21188 instructions to issue in this cycle. */
21191 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
21192 int verbose ATTRIBUTE_UNUSED,
21193 rtx insn, int more)
21195 last_scheduled_insn = insn;
21196 if (GET_CODE (PATTERN (insn)) == USE
21197 || GET_CODE (PATTERN (insn)) == CLOBBER)
21199 cached_can_issue_more = more;
21200 return cached_can_issue_more;
21203 if (insn_terminates_group_p (insn, current_group))
21205 cached_can_issue_more = 0;
21206 return cached_can_issue_more;
21209 /* If no reservation, but reach here */
21210 if (recog_memoized (insn) < 0)
21213 if (rs6000_sched_groups)
21215 if (is_microcoded_insn (insn))
21216 cached_can_issue_more = 0;
21217 else if (is_cracked_insn (insn))
21218 cached_can_issue_more = more > 2 ? more - 2 : 0;
21220 cached_can_issue_more = more - 1;
21222 return cached_can_issue_more;
21225 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21228 cached_can_issue_more = more - 1;
21229 return cached_can_issue_more;
21232 /* Adjust the cost of a scheduling dependency. Return the new cost of
21233 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21236 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21238 enum attr_type attr_type;
21240 if (! recog_memoized (insn))
21243 switch (REG_NOTE_KIND (link))
21247 /* Data dependency; DEP_INSN writes a register that INSN reads
21248 some cycles later. */
21250 /* Separate a load from a narrower, dependent store. */
21251 if (rs6000_sched_groups
21252 && GET_CODE (PATTERN (insn)) == SET
21253 && GET_CODE (PATTERN (dep_insn)) == SET
21254 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21255 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21256 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21257 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21260 attr_type = get_attr_type (insn);
21265 /* Tell the first scheduling pass about the latency between
21266 a mtctr and bctr (and mtlr and br/blr). The first
21267 scheduling pass will not know about this latency since
21268 the mtctr instruction, which has the latency associated
21269 to it, will be generated by reload. */
21270 return TARGET_POWER ? 5 : 4;
21272 /* Leave some extra cycles between a compare and its
21273 dependent branch, to inhibit expensive mispredicts. */
21274 if ((rs6000_cpu_attr == CPU_PPC603
21275 || rs6000_cpu_attr == CPU_PPC604
21276 || rs6000_cpu_attr == CPU_PPC604E
21277 || rs6000_cpu_attr == CPU_PPC620
21278 || rs6000_cpu_attr == CPU_PPC630
21279 || rs6000_cpu_attr == CPU_PPC750
21280 || rs6000_cpu_attr == CPU_PPC7400
21281 || rs6000_cpu_attr == CPU_PPC7450
21282 || rs6000_cpu_attr == CPU_POWER4
21283 || rs6000_cpu_attr == CPU_POWER5
21284 || rs6000_cpu_attr == CPU_POWER7
21285 || rs6000_cpu_attr == CPU_CELL)
21286 && recog_memoized (dep_insn)
21287 && (INSN_CODE (dep_insn) >= 0))
21289 switch (get_attr_type (dep_insn))
21293 case TYPE_DELAYED_COMPARE:
21294 case TYPE_IMUL_COMPARE:
21295 case TYPE_LMUL_COMPARE:
21296 case TYPE_FPCOMPARE:
21297 case TYPE_CR_LOGICAL:
21298 case TYPE_DELAYED_CR:
21307 case TYPE_STORE_UX:
21309 case TYPE_FPSTORE_U:
21310 case TYPE_FPSTORE_UX:
21311 if ((rs6000_cpu == PROCESSOR_POWER6)
21312 && recog_memoized (dep_insn)
21313 && (INSN_CODE (dep_insn) >= 0))
21316 if (GET_CODE (PATTERN (insn)) != SET)
21317 /* If this happens, we have to extend this to schedule
21318 optimally. Return default for now. */
21321 /* Adjust the cost for the case where the value written
21322 by a fixed point operation is used as the address
21323 gen value on a store. */
21324 switch (get_attr_type (dep_insn))
21331 if (! store_data_bypass_p (dep_insn, insn))
21335 case TYPE_LOAD_EXT:
21336 case TYPE_LOAD_EXT_U:
21337 case TYPE_LOAD_EXT_UX:
21338 case TYPE_VAR_SHIFT_ROTATE:
21339 case TYPE_VAR_DELAYED_COMPARE:
21341 if (! store_data_bypass_p (dep_insn, insn))
21347 case TYPE_FAST_COMPARE:
21350 case TYPE_INSERT_WORD:
21351 case TYPE_INSERT_DWORD:
21352 case TYPE_FPLOAD_U:
21353 case TYPE_FPLOAD_UX:
21355 case TYPE_STORE_UX:
21356 case TYPE_FPSTORE_U:
21357 case TYPE_FPSTORE_UX:
21359 if (! store_data_bypass_p (dep_insn, insn))
21367 case TYPE_IMUL_COMPARE:
21368 case TYPE_LMUL_COMPARE:
21370 if (! store_data_bypass_p (dep_insn, insn))
21376 if (! store_data_bypass_p (dep_insn, insn))
21382 if (! store_data_bypass_p (dep_insn, insn))
21395 case TYPE_LOAD_EXT:
21396 case TYPE_LOAD_EXT_U:
21397 case TYPE_LOAD_EXT_UX:
21398 if ((rs6000_cpu == PROCESSOR_POWER6)
21399 && recog_memoized (dep_insn)
21400 && (INSN_CODE (dep_insn) >= 0))
21403 /* Adjust the cost for the case where the value written
21404 by a fixed point instruction is used within the address
21405 gen portion of a subsequent load(u)(x) */
21406 switch (get_attr_type (dep_insn))
21413 if (set_to_load_agen (dep_insn, insn))
21417 case TYPE_LOAD_EXT:
21418 case TYPE_LOAD_EXT_U:
21419 case TYPE_LOAD_EXT_UX:
21420 case TYPE_VAR_SHIFT_ROTATE:
21421 case TYPE_VAR_DELAYED_COMPARE:
21423 if (set_to_load_agen (dep_insn, insn))
21429 case TYPE_FAST_COMPARE:
21432 case TYPE_INSERT_WORD:
21433 case TYPE_INSERT_DWORD:
21434 case TYPE_FPLOAD_U:
21435 case TYPE_FPLOAD_UX:
21437 case TYPE_STORE_UX:
21438 case TYPE_FPSTORE_U:
21439 case TYPE_FPSTORE_UX:
21441 if (set_to_load_agen (dep_insn, insn))
21449 case TYPE_IMUL_COMPARE:
21450 case TYPE_LMUL_COMPARE:
21452 if (set_to_load_agen (dep_insn, insn))
21458 if (set_to_load_agen (dep_insn, insn))
21464 if (set_to_load_agen (dep_insn, insn))
21475 if ((rs6000_cpu == PROCESSOR_POWER6)
21476 && recog_memoized (dep_insn)
21477 && (INSN_CODE (dep_insn) >= 0)
21478 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
21485 /* Fall out to return default cost. */
21489 case REG_DEP_OUTPUT:
21490 /* Output dependency; DEP_INSN writes a register that INSN writes some
21492 if ((rs6000_cpu == PROCESSOR_POWER6)
21493 && recog_memoized (dep_insn)
21494 && (INSN_CODE (dep_insn) >= 0))
21496 attr_type = get_attr_type (insn);
21501 if (get_attr_type (dep_insn) == TYPE_FP)
21505 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
21513 /* Anti dependency; DEP_INSN reads a register that INSN writes some
21518 gcc_unreachable ();
21524 /* Debug version of rs6000_adjust_cost. */
21527 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21529 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
21535 switch (REG_NOTE_KIND (link))
21537 default: dep = "unknown depencency"; break;
21538 case REG_DEP_TRUE: dep = "data dependency"; break;
21539 case REG_DEP_OUTPUT: dep = "output dependency"; break;
21540 case REG_DEP_ANTI: dep = "anti depencency"; break;
21544 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
21545 "%s, insn:\n", ret, cost, dep);
21553 /* The function returns a true if INSN is microcoded.
21554 Return false otherwise. */
21557 is_microcoded_insn (rtx insn)
21559 if (!insn || !NONDEBUG_INSN_P (insn)
21560 || GET_CODE (PATTERN (insn)) == USE
21561 || GET_CODE (PATTERN (insn)) == CLOBBER)
21564 if (rs6000_cpu_attr == CPU_CELL)
21565 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
21567 if (rs6000_sched_groups)
21569 enum attr_type type = get_attr_type (insn);
21570 if (type == TYPE_LOAD_EXT_U
21571 || type == TYPE_LOAD_EXT_UX
21572 || type == TYPE_LOAD_UX
21573 || type == TYPE_STORE_UX
21574 || type == TYPE_MFCR)
21581 /* The function returns true if INSN is cracked into 2 instructions
21582 by the processor (and therefore occupies 2 issue slots). */
21585 is_cracked_insn (rtx insn)
21587 if (!insn || !NONDEBUG_INSN_P (insn)
21588 || GET_CODE (PATTERN (insn)) == USE
21589 || GET_CODE (PATTERN (insn)) == CLOBBER)
21592 if (rs6000_sched_groups)
21594 enum attr_type type = get_attr_type (insn);
21595 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
21596 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
21597 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
21598 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
21599 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
21600 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
21601 || type == TYPE_IDIV || type == TYPE_LDIV
21602 || type == TYPE_INSERT_WORD)
21609 /* The function returns true if INSN can be issued only from
21610 the branch slot. */
21613 is_branch_slot_insn (rtx insn)
21615 if (!insn || !NONDEBUG_INSN_P (insn)
21616 || GET_CODE (PATTERN (insn)) == USE
21617 || GET_CODE (PATTERN (insn)) == CLOBBER)
21620 if (rs6000_sched_groups)
21622 enum attr_type type = get_attr_type (insn);
21623 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
21631 /* The function returns true if out_inst sets a value that is
21632 used in the address generation computation of in_insn */
21634 set_to_load_agen (rtx out_insn, rtx in_insn)
21636 rtx out_set, in_set;
21638 /* For performance reasons, only handle the simple case where
21639 both loads are a single_set. */
21640 out_set = single_set (out_insn);
21643 in_set = single_set (in_insn);
21645 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
21651 /* The function returns true if the target storage location of
21652 out_insn is adjacent to the target storage location of in_insn */
21653 /* Return 1 if memory locations are adjacent. */
21656 adjacent_mem_locations (rtx insn1, rtx insn2)
21659 rtx a = get_store_dest (PATTERN (insn1));
21660 rtx b = get_store_dest (PATTERN (insn2));
21662 if ((GET_CODE (XEXP (a, 0)) == REG
21663 || (GET_CODE (XEXP (a, 0)) == PLUS
21664 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
21665 && (GET_CODE (XEXP (b, 0)) == REG
21666 || (GET_CODE (XEXP (b, 0)) == PLUS
21667 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
21669 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
21672 if (GET_CODE (XEXP (a, 0)) == PLUS)
21674 reg0 = XEXP (XEXP (a, 0), 0);
21675 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
21678 reg0 = XEXP (a, 0);
21680 if (GET_CODE (XEXP (b, 0)) == PLUS)
21682 reg1 = XEXP (XEXP (b, 0), 0);
21683 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
21686 reg1 = XEXP (b, 0);
21688 val_diff = val1 - val0;
21690 return ((REGNO (reg0) == REGNO (reg1))
21691 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
21692 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
21698 /* A C statement (sans semicolon) to update the integer scheduling
21699 priority INSN_PRIORITY (INSN). Increase the priority to execute the
21700 INSN earlier, reduce the priority to execute INSN later. Do not
21701 define this macro if you do not need to adjust the scheduling
21702 priorities of insns. */
21705 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
21707 /* On machines (like the 750) which have asymmetric integer units,
21708 where one integer unit can do multiply and divides and the other
21709 can't, reduce the priority of multiply/divide so it is scheduled
21710 before other integer operations. */
21713 if (! INSN_P (insn))
21716 if (GET_CODE (PATTERN (insn)) == USE)
21719 switch (rs6000_cpu_attr) {
21721 switch (get_attr_type (insn))
21728 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
21729 priority, priority);
21730 if (priority >= 0 && priority < 0x01000000)
21737 if (insn_must_be_first_in_group (insn)
21738 && reload_completed
21739 && current_sched_info->sched_max_insns_priority
21740 && rs6000_sched_restricted_insns_priority)
21743 /* Prioritize insns that can be dispatched only in the first
21745 if (rs6000_sched_restricted_insns_priority == 1)
21746 /* Attach highest priority to insn. This means that in
21747 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
21748 precede 'priority' (critical path) considerations. */
21749 return current_sched_info->sched_max_insns_priority;
21750 else if (rs6000_sched_restricted_insns_priority == 2)
21751 /* Increase priority of insn by a minimal amount. This means that in
21752 haifa-sched.c:ready_sort(), only 'priority' (critical path)
21753 considerations precede dispatch-slot restriction considerations. */
21754 return (priority + 1);
21757 if (rs6000_cpu == PROCESSOR_POWER6
21758 && ((load_store_pendulum == -2 && is_load_insn (insn))
21759 || (load_store_pendulum == 2 && is_store_insn (insn))))
21760 /* Attach highest priority to insn if the scheduler has just issued two
21761 stores and this instruction is a load, or two loads and this instruction
21762 is a store. Power6 wants loads and stores scheduled alternately
21764 return current_sched_info->sched_max_insns_priority;
21769 /* Return true if the instruction is nonpipelined on the Cell. */
21771 is_nonpipeline_insn (rtx insn)
21773 enum attr_type type;
21774 if (!insn || !NONDEBUG_INSN_P (insn)
21775 || GET_CODE (PATTERN (insn)) == USE
21776 || GET_CODE (PATTERN (insn)) == CLOBBER)
21779 type = get_attr_type (insn);
21780 if (type == TYPE_IMUL
21781 || type == TYPE_IMUL2
21782 || type == TYPE_IMUL3
21783 || type == TYPE_LMUL
21784 || type == TYPE_IDIV
21785 || type == TYPE_LDIV
21786 || type == TYPE_SDIV
21787 || type == TYPE_DDIV
21788 || type == TYPE_SSQRT
21789 || type == TYPE_DSQRT
21790 || type == TYPE_MFCR
21791 || type == TYPE_MFCRF
21792 || type == TYPE_MFJMPR)
21800 /* Return how many instructions the machine can issue per cycle. */
21803 rs6000_issue_rate (void)
21805 /* Unless scheduling for register pressure, use issue rate of 1 for
21806 first scheduling pass to decrease degradation. */
21807 if (!reload_completed && !flag_sched_pressure)
21810 switch (rs6000_cpu_attr) {
21811 case CPU_RIOS1: /* ? */
21813 case CPU_PPC601: /* ? */
21822 case CPU_PPCE300C2:
21823 case CPU_PPCE300C3:
21824 case CPU_PPCE500MC:
21843 /* Return how many instructions to look ahead for better insn
21847 rs6000_use_sched_lookahead (void)
21849 if (rs6000_cpu_attr == CPU_PPC8540)
21851 if (rs6000_cpu_attr == CPU_CELL)
21852 return (reload_completed ? 8 : 0);
21856 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
21858 rs6000_use_sched_lookahead_guard (rtx insn)
21860 if (rs6000_cpu_attr != CPU_CELL)
21863 if (insn == NULL_RTX || !INSN_P (insn))
21866 if (!reload_completed
21867 || is_nonpipeline_insn (insn)
21868 || is_microcoded_insn (insn))
21874 /* Determine is PAT refers to memory. */
21877 is_mem_ref (rtx pat)
21883 /* stack_tie does not produce any real memory traffic. */
21884 if (GET_CODE (pat) == UNSPEC
21885 && XINT (pat, 1) == UNSPEC_TIE)
21888 if (GET_CODE (pat) == MEM)
21891 /* Recursively process the pattern. */
21892 fmt = GET_RTX_FORMAT (GET_CODE (pat));
21894 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
21897 ret |= is_mem_ref (XEXP (pat, i));
21898 else if (fmt[i] == 'E')
21899 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
21900 ret |= is_mem_ref (XVECEXP (pat, i, j));
21906 /* Determine if PAT is a PATTERN of a load insn. */
21909 is_load_insn1 (rtx pat)
21911 if (!pat || pat == NULL_RTX)
21914 if (GET_CODE (pat) == SET)
21915 return is_mem_ref (SET_SRC (pat));
21917 if (GET_CODE (pat) == PARALLEL)
21921 for (i = 0; i < XVECLEN (pat, 0); i++)
21922 if (is_load_insn1 (XVECEXP (pat, 0, i)))
21929 /* Determine if INSN loads from memory. */
21932 is_load_insn (rtx insn)
21934 if (!insn || !INSN_P (insn))
21937 if (GET_CODE (insn) == CALL_INSN)
21940 return is_load_insn1 (PATTERN (insn));
21943 /* Determine if PAT is a PATTERN of a store insn. */
21946 is_store_insn1 (rtx pat)
21948 if (!pat || pat == NULL_RTX)
21951 if (GET_CODE (pat) == SET)
21952 return is_mem_ref (SET_DEST (pat));
21954 if (GET_CODE (pat) == PARALLEL)
21958 for (i = 0; i < XVECLEN (pat, 0); i++)
21959 if (is_store_insn1 (XVECEXP (pat, 0, i)))
21966 /* Determine if INSN stores to memory. */
21969 is_store_insn (rtx insn)
21971 if (!insn || !INSN_P (insn))
21974 return is_store_insn1 (PATTERN (insn));
21977 /* Return the dest of a store insn. */
21980 get_store_dest (rtx pat)
21982 gcc_assert (is_store_insn1 (pat));
21984 if (GET_CODE (pat) == SET)
21985 return SET_DEST (pat);
21986 else if (GET_CODE (pat) == PARALLEL)
21990 for (i = 0; i < XVECLEN (pat, 0); i++)
21992 rtx inner_pat = XVECEXP (pat, 0, i);
21993 if (GET_CODE (inner_pat) == SET
21994 && is_mem_ref (SET_DEST (inner_pat)))
21998 /* We shouldn't get here, because we should have either a simple
21999 store insn or a store with update which are covered above. */
22003 /* Returns whether the dependence between INSN and NEXT is considered
22004 costly by the given target. */
22007 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
22012 /* If the flag is not enabled - no dependence is considered costly;
22013 allow all dependent insns in the same group.
22014 This is the most aggressive option. */
22015 if (rs6000_sched_costly_dep == no_dep_costly)
22018 /* If the flag is set to 1 - a dependence is always considered costly;
22019 do not allow dependent instructions in the same group.
22020 This is the most conservative option. */
22021 if (rs6000_sched_costly_dep == all_deps_costly)
22024 insn = DEP_PRO (dep);
22025 next = DEP_CON (dep);
22027 if (rs6000_sched_costly_dep == store_to_load_dep_costly
22028 && is_load_insn (next)
22029 && is_store_insn (insn))
22030 /* Prevent load after store in the same group. */
22033 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
22034 && is_load_insn (next)
22035 && is_store_insn (insn)
22036 && DEP_TYPE (dep) == REG_DEP_TRUE)
22037 /* Prevent load after store in the same group if it is a true
22041 /* The flag is set to X; dependences with latency >= X are considered costly,
22042 and will not be scheduled in the same group. */
22043 if (rs6000_sched_costly_dep <= max_dep_latency
22044 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22050 /* Return the next insn after INSN that is found before TAIL is reached,
22051 skipping any "non-active" insns - insns that will not actually occupy
22052 an issue slot. Return NULL_RTX if such an insn is not found. */
22055 get_next_active_insn (rtx insn, rtx tail)
22057 if (insn == NULL_RTX || insn == tail)
22062 insn = NEXT_INSN (insn);
22063 if (insn == NULL_RTX || insn == tail)
22068 || (NONJUMP_INSN_P (insn)
22069 && GET_CODE (PATTERN (insn)) != USE
22070 && GET_CODE (PATTERN (insn)) != CLOBBER
22071 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22077 /* We are about to begin issuing insns for this clock cycle. */
22080 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22081 rtx *ready ATTRIBUTE_UNUSED,
22082 int *pn_ready ATTRIBUTE_UNUSED,
22083 int clock_var ATTRIBUTE_UNUSED)
22085 int n_ready = *pn_ready;
22088 fprintf (dump, "// rs6000_sched_reorder :\n");
22090 /* Reorder the ready list, if the second to last ready insn
22091 is a nonepipeline insn. */
22092 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22094 if (is_nonpipeline_insn (ready[n_ready - 1])
22095 && (recog_memoized (ready[n_ready - 2]) > 0))
22096 /* Simply swap first two insns. */
22098 rtx tmp = ready[n_ready - 1];
22099 ready[n_ready - 1] = ready[n_ready - 2];
22100 ready[n_ready - 2] = tmp;
22104 if (rs6000_cpu == PROCESSOR_POWER6)
22105 load_store_pendulum = 0;
22107 return rs6000_issue_rate ();
22110 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22113 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
22114 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
22117 fprintf (dump, "// rs6000_sched_reorder2 :\n");
22119 /* For Power6, we need to handle some special cases to try and keep the
22120 store queue from overflowing and triggering expensive flushes.
22122 This code monitors how load and store instructions are being issued
22123 and skews the ready list one way or the other to increase the likelihood
22124 that a desired instruction is issued at the proper time.
22126 A couple of things are done. First, we maintain a "load_store_pendulum"
22127 to track the current state of load/store issue.
22129 - If the pendulum is at zero, then no loads or stores have been
22130 issued in the current cycle so we do nothing.
22132 - If the pendulum is 1, then a single load has been issued in this
22133 cycle and we attempt to locate another load in the ready list to
22136 - If the pendulum is -2, then two stores have already been
22137 issued in this cycle, so we increase the priority of the first load
22138 in the ready list to increase it's likelihood of being chosen first
22141 - If the pendulum is -1, then a single store has been issued in this
22142 cycle and we attempt to locate another store in the ready list to
22143 issue with it, preferring a store to an adjacent memory location to
22144 facilitate store pairing in the store queue.
22146 - If the pendulum is 2, then two loads have already been
22147 issued in this cycle, so we increase the priority of the first store
22148 in the ready list to increase it's likelihood of being chosen first
22151 - If the pendulum < -2 or > 2, then do nothing.
22153 Note: This code covers the most common scenarios. There exist non
22154 load/store instructions which make use of the LSU and which
22155 would need to be accounted for to strictly model the behavior
22156 of the machine. Those instructions are currently unaccounted
22157 for to help minimize compile time overhead of this code.
22159 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
22165 if (is_store_insn (last_scheduled_insn))
22166 /* Issuing a store, swing the load_store_pendulum to the left */
22167 load_store_pendulum--;
22168 else if (is_load_insn (last_scheduled_insn))
22169 /* Issuing a load, swing the load_store_pendulum to the right */
22170 load_store_pendulum++;
22172 return cached_can_issue_more;
22174 /* If the pendulum is balanced, or there is only one instruction on
22175 the ready list, then all is well, so return. */
22176 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
22177 return cached_can_issue_more;
22179 if (load_store_pendulum == 1)
22181 /* A load has been issued in this cycle. Scan the ready list
22182 for another load to issue with it */
22187 if (is_load_insn (ready[pos]))
22189 /* Found a load. Move it to the head of the ready list,
22190 and adjust it's priority so that it is more likely to
22193 for (i=pos; i<*pn_ready-1; i++)
22194 ready[i] = ready[i + 1];
22195 ready[*pn_ready-1] = tmp;
22197 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22198 INSN_PRIORITY (tmp)++;
22204 else if (load_store_pendulum == -2)
22206 /* Two stores have been issued in this cycle. Increase the
22207 priority of the first load in the ready list to favor it for
22208 issuing in the next cycle. */
22213 if (is_load_insn (ready[pos])
22215 && INSN_PRIORITY_KNOWN (ready[pos]))
22217 INSN_PRIORITY (ready[pos])++;
22219 /* Adjust the pendulum to account for the fact that a load
22220 was found and increased in priority. This is to prevent
22221 increasing the priority of multiple loads */
22222 load_store_pendulum--;
22229 else if (load_store_pendulum == -1)
22231 /* A store has been issued in this cycle. Scan the ready list for
22232 another store to issue with it, preferring a store to an adjacent
22234 int first_store_pos = -1;
22240 if (is_store_insn (ready[pos]))
22242 /* Maintain the index of the first store found on the
22244 if (first_store_pos == -1)
22245 first_store_pos = pos;
22247 if (is_store_insn (last_scheduled_insn)
22248 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22250 /* Found an adjacent store. Move it to the head of the
22251 ready list, and adjust it's priority so that it is
22252 more likely to stay there */
22254 for (i=pos; i<*pn_ready-1; i++)
22255 ready[i] = ready[i + 1];
22256 ready[*pn_ready-1] = tmp;
22258 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22259 INSN_PRIORITY (tmp)++;
22261 first_store_pos = -1;
22269 if (first_store_pos >= 0)
22271 /* An adjacent store wasn't found, but a non-adjacent store was,
22272 so move the non-adjacent store to the front of the ready
22273 list, and adjust its priority so that it is more likely to
22275 tmp = ready[first_store_pos];
22276 for (i=first_store_pos; i<*pn_ready-1; i++)
22277 ready[i] = ready[i + 1];
22278 ready[*pn_ready-1] = tmp;
22279 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22280 INSN_PRIORITY (tmp)++;
22283 else if (load_store_pendulum == 2)
22285 /* Two loads have been issued in this cycle. Increase the priority
22286 of the first store in the ready list to favor it for issuing in
22292 if (is_store_insn (ready[pos])
22294 && INSN_PRIORITY_KNOWN (ready[pos]))
22296 INSN_PRIORITY (ready[pos])++;
22298 /* Adjust the pendulum to account for the fact that a store
22299 was found and increased in priority. This is to prevent
22300 increasing the priority of multiple stores */
22301 load_store_pendulum++;
22310 return cached_can_issue_more;
22313 /* Return whether the presence of INSN causes a dispatch group termination
22314 of group WHICH_GROUP.
22316 If WHICH_GROUP == current_group, this function will return true if INSN
22317 causes the termination of the current group (i.e, the dispatch group to
22318 which INSN belongs). This means that INSN will be the last insn in the
22319 group it belongs to.
22321 If WHICH_GROUP == previous_group, this function will return true if INSN
22322 causes the termination of the previous group (i.e, the dispatch group that
22323 precedes the group to which INSN belongs). This means that INSN will be
22324 the first insn in the group it belongs to). */
22327 insn_terminates_group_p (rtx insn, enum group_termination which_group)
22334 first = insn_must_be_first_in_group (insn);
22335 last = insn_must_be_last_in_group (insn);
22340 if (which_group == current_group)
22342 else if (which_group == previous_group)
22350 insn_must_be_first_in_group (rtx insn)
22352 enum attr_type type;
22355 || GET_CODE (insn) == NOTE
22356 || DEBUG_INSN_P (insn)
22357 || GET_CODE (PATTERN (insn)) == USE
22358 || GET_CODE (PATTERN (insn)) == CLOBBER)
22361 switch (rs6000_cpu)
22363 case PROCESSOR_POWER5:
22364 if (is_cracked_insn (insn))
22366 case PROCESSOR_POWER4:
22367 if (is_microcoded_insn (insn))
22370 if (!rs6000_sched_groups)
22373 type = get_attr_type (insn);
22380 case TYPE_DELAYED_CR:
22381 case TYPE_CR_LOGICAL:
22395 case PROCESSOR_POWER6:
22396 type = get_attr_type (insn);
22400 case TYPE_INSERT_DWORD:
22404 case TYPE_VAR_SHIFT_ROTATE:
22411 case TYPE_INSERT_WORD:
22412 case TYPE_DELAYED_COMPARE:
22413 case TYPE_IMUL_COMPARE:
22414 case TYPE_LMUL_COMPARE:
22415 case TYPE_FPCOMPARE:
22426 case TYPE_LOAD_EXT_UX:
22428 case TYPE_STORE_UX:
22429 case TYPE_FPLOAD_U:
22430 case TYPE_FPLOAD_UX:
22431 case TYPE_FPSTORE_U:
22432 case TYPE_FPSTORE_UX:
22438 case PROCESSOR_POWER7:
22439 type = get_attr_type (insn);
22443 case TYPE_CR_LOGICAL:
22450 case TYPE_DELAYED_COMPARE:
22451 case TYPE_VAR_DELAYED_COMPARE:
22457 case TYPE_LOAD_EXT:
22458 case TYPE_LOAD_EXT_U:
22459 case TYPE_LOAD_EXT_UX:
22461 case TYPE_STORE_UX:
22462 case TYPE_FPLOAD_U:
22463 case TYPE_FPLOAD_UX:
22464 case TYPE_FPSTORE_U:
22465 case TYPE_FPSTORE_UX:
22481 insn_must_be_last_in_group (rtx insn)
22483 enum attr_type type;
22486 || GET_CODE (insn) == NOTE
22487 || DEBUG_INSN_P (insn)
22488 || GET_CODE (PATTERN (insn)) == USE
22489 || GET_CODE (PATTERN (insn)) == CLOBBER)
22492 switch (rs6000_cpu) {
22493 case PROCESSOR_POWER4:
22494 case PROCESSOR_POWER5:
22495 if (is_microcoded_insn (insn))
22498 if (is_branch_slot_insn (insn))
22502 case PROCESSOR_POWER6:
22503 type = get_attr_type (insn);
22510 case TYPE_VAR_SHIFT_ROTATE:
22517 case TYPE_DELAYED_COMPARE:
22518 case TYPE_IMUL_COMPARE:
22519 case TYPE_LMUL_COMPARE:
22520 case TYPE_FPCOMPARE:
22534 case PROCESSOR_POWER7:
22535 type = get_attr_type (insn);
22543 case TYPE_LOAD_EXT_U:
22544 case TYPE_LOAD_EXT_UX:
22545 case TYPE_STORE_UX:
22558 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
22559 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
22562 is_costly_group (rtx *group_insns, rtx next_insn)
22565 int issue_rate = rs6000_issue_rate ();
22567 for (i = 0; i < issue_rate; i++)
22569 sd_iterator_def sd_it;
22571 rtx insn = group_insns[i];
22576 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
22578 rtx next = DEP_CON (dep);
22580 if (next == next_insn
22581 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
22589 /* Utility of the function redefine_groups.
22590 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
22591 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
22592 to keep it "far" (in a separate group) from GROUP_INSNS, following
22593 one of the following schemes, depending on the value of the flag
22594 -minsert_sched_nops = X:
22595 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
22596 in order to force NEXT_INSN into a separate group.
22597 (2) X < sched_finish_regroup_exact: insert exactly X nops.
22598 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
22599 insertion (has a group just ended, how many vacant issue slots remain in the
22600 last group, and how many dispatch groups were encountered so far). */
22603 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
22604 rtx next_insn, bool *group_end, int can_issue_more,
22609 int issue_rate = rs6000_issue_rate ();
22610 bool end = *group_end;
22613 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
22614 return can_issue_more;
22616 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
22617 return can_issue_more;
22619 force = is_costly_group (group_insns, next_insn);
22621 return can_issue_more;
22623 if (sched_verbose > 6)
22624 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
22625 *group_count ,can_issue_more);
22627 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
22630 can_issue_more = 0;
22632 /* Since only a branch can be issued in the last issue_slot, it is
22633 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
22634 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
22635 in this case the last nop will start a new group and the branch
22636 will be forced to the new group. */
22637 if (can_issue_more && !is_branch_slot_insn (next_insn))
22640 while (can_issue_more > 0)
22643 emit_insn_before (nop, next_insn);
22651 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
22653 int n_nops = rs6000_sched_insert_nops;
22655 /* Nops can't be issued from the branch slot, so the effective
22656 issue_rate for nops is 'issue_rate - 1'. */
22657 if (can_issue_more == 0)
22658 can_issue_more = issue_rate;
22660 if (can_issue_more == 0)
22662 can_issue_more = issue_rate - 1;
22665 for (i = 0; i < issue_rate; i++)
22667 group_insns[i] = 0;
22674 emit_insn_before (nop, next_insn);
22675 if (can_issue_more == issue_rate - 1) /* new group begins */
22678 if (can_issue_more == 0)
22680 can_issue_more = issue_rate - 1;
22683 for (i = 0; i < issue_rate; i++)
22685 group_insns[i] = 0;
22691 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
22694 /* Is next_insn going to start a new group? */
22697 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22698 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22699 || (can_issue_more < issue_rate &&
22700 insn_terminates_group_p (next_insn, previous_group)));
22701 if (*group_end && end)
22704 if (sched_verbose > 6)
22705 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
22706 *group_count, can_issue_more);
22707 return can_issue_more;
22710 return can_issue_more;
22713 /* This function tries to synch the dispatch groups that the compiler "sees"
22714 with the dispatch groups that the processor dispatcher is expected to
22715 form in practice. It tries to achieve this synchronization by forcing the
22716 estimated processor grouping on the compiler (as opposed to the function
22717 'pad_goups' which tries to force the scheduler's grouping on the processor).
22719 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
22720 examines the (estimated) dispatch groups that will be formed by the processor
22721 dispatcher. It marks these group boundaries to reflect the estimated
22722 processor grouping, overriding the grouping that the scheduler had marked.
22723 Depending on the value of the flag '-minsert-sched-nops' this function can
22724 force certain insns into separate groups or force a certain distance between
22725 them by inserting nops, for example, if there exists a "costly dependence"
22728 The function estimates the group boundaries that the processor will form as
22729 follows: It keeps track of how many vacant issue slots are available after
22730 each insn. A subsequent insn will start a new group if one of the following
22732 - no more vacant issue slots remain in the current dispatch group.
22733 - only the last issue slot, which is the branch slot, is vacant, but the next
22734 insn is not a branch.
22735 - only the last 2 or less issue slots, including the branch slot, are vacant,
22736 which means that a cracked insn (which occupies two issue slots) can't be
22737 issued in this group.
22738 - less than 'issue_rate' slots are vacant, and the next insn always needs to
22739 start a new group. */
22742 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22744 rtx insn, next_insn;
22746 int can_issue_more;
22749 int group_count = 0;
22753 issue_rate = rs6000_issue_rate ();
22754 group_insns = XALLOCAVEC (rtx, issue_rate);
22755 for (i = 0; i < issue_rate; i++)
22757 group_insns[i] = 0;
22759 can_issue_more = issue_rate;
22761 insn = get_next_active_insn (prev_head_insn, tail);
22764 while (insn != NULL_RTX)
22766 slot = (issue_rate - can_issue_more);
22767 group_insns[slot] = insn;
22769 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
22770 if (insn_terminates_group_p (insn, current_group))
22771 can_issue_more = 0;
22773 next_insn = get_next_active_insn (insn, tail);
22774 if (next_insn == NULL_RTX)
22775 return group_count + 1;
22777 /* Is next_insn going to start a new group? */
22779 = (can_issue_more == 0
22780 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22781 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22782 || (can_issue_more < issue_rate &&
22783 insn_terminates_group_p (next_insn, previous_group)));
22785 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
22786 next_insn, &group_end, can_issue_more,
22792 can_issue_more = 0;
22793 for (i = 0; i < issue_rate; i++)
22795 group_insns[i] = 0;
22799 if (GET_MODE (next_insn) == TImode && can_issue_more)
22800 PUT_MODE (next_insn, VOIDmode);
22801 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
22802 PUT_MODE (next_insn, TImode);
22805 if (can_issue_more == 0)
22806 can_issue_more = issue_rate;
22809 return group_count;
22812 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
22813 dispatch group boundaries that the scheduler had marked. Pad with nops
22814 any dispatch groups which have vacant issue slots, in order to force the
22815 scheduler's grouping on the processor dispatcher. The function
22816 returns the number of dispatch groups found. */
22819 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22821 rtx insn, next_insn;
22824 int can_issue_more;
22826 int group_count = 0;
22828 /* Initialize issue_rate. */
22829 issue_rate = rs6000_issue_rate ();
22830 can_issue_more = issue_rate;
22832 insn = get_next_active_insn (prev_head_insn, tail);
22833 next_insn = get_next_active_insn (insn, tail);
22835 while (insn != NULL_RTX)
22838 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
22840 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
22842 if (next_insn == NULL_RTX)
22847 /* If the scheduler had marked group termination at this location
22848 (between insn and next_insn), and neither insn nor next_insn will
22849 force group termination, pad the group with nops to force group
22852 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
22853 && !insn_terminates_group_p (insn, current_group)
22854 && !insn_terminates_group_p (next_insn, previous_group))
22856 if (!is_branch_slot_insn (next_insn))
22859 while (can_issue_more)
22862 emit_insn_before (nop, next_insn);
22867 can_issue_more = issue_rate;
22872 next_insn = get_next_active_insn (insn, tail);
22875 return group_count;
22878 /* We're beginning a new block. Initialize data structures as necessary. */
22881 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
22882 int sched_verbose ATTRIBUTE_UNUSED,
22883 int max_ready ATTRIBUTE_UNUSED)
22885 last_scheduled_insn = NULL_RTX;
22886 load_store_pendulum = 0;
22889 /* The following function is called at the end of scheduling BB.
22890 After reload, it inserts nops at insn group bundling. */
22893 rs6000_sched_finish (FILE *dump, int sched_verbose)
22898 fprintf (dump, "=== Finishing schedule.\n");
22900 if (reload_completed && rs6000_sched_groups)
22902 /* Do not run sched_finish hook when selective scheduling enabled. */
22903 if (sel_sched_p ())
22906 if (rs6000_sched_insert_nops == sched_finish_none)
22909 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
22910 n_groups = pad_groups (dump, sched_verbose,
22911 current_sched_info->prev_head,
22912 current_sched_info->next_tail);
22914 n_groups = redefine_groups (dump, sched_verbose,
22915 current_sched_info->prev_head,
22916 current_sched_info->next_tail);
22918 if (sched_verbose >= 6)
22920 fprintf (dump, "ngroups = %d\n", n_groups);
22921 print_rtl (dump, current_sched_info->prev_head);
22922 fprintf (dump, "Done finish_sched\n");
22927 struct _rs6000_sched_context
22929 short cached_can_issue_more;
22930 rtx last_scheduled_insn;
22931 int load_store_pendulum;
22934 typedef struct _rs6000_sched_context rs6000_sched_context_def;
22935 typedef rs6000_sched_context_def *rs6000_sched_context_t;
22937 /* Allocate store for new scheduling context. */
22939 rs6000_alloc_sched_context (void)
22941 return xmalloc (sizeof (rs6000_sched_context_def));
22944 /* If CLEAN_P is true then initializes _SC with clean data,
22945 and from the global context otherwise. */
22947 rs6000_init_sched_context (void *_sc, bool clean_p)
22949 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
22953 sc->cached_can_issue_more = 0;
22954 sc->last_scheduled_insn = NULL_RTX;
22955 sc->load_store_pendulum = 0;
22959 sc->cached_can_issue_more = cached_can_issue_more;
22960 sc->last_scheduled_insn = last_scheduled_insn;
22961 sc->load_store_pendulum = load_store_pendulum;
22965 /* Sets the global scheduling context to the one pointed to by _SC. */
22967 rs6000_set_sched_context (void *_sc)
22969 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
22971 gcc_assert (sc != NULL);
22973 cached_can_issue_more = sc->cached_can_issue_more;
22974 last_scheduled_insn = sc->last_scheduled_insn;
22975 load_store_pendulum = sc->load_store_pendulum;
22980 rs6000_free_sched_context (void *_sc)
22982 gcc_assert (_sc != NULL);
22988 /* Length in units of the trampoline for entering a nested function. */
22991 rs6000_trampoline_size (void)
22995 switch (DEFAULT_ABI)
22998 gcc_unreachable ();
23001 ret = (TARGET_32BIT) ? 12 : 24;
23006 ret = (TARGET_32BIT) ? 40 : 48;
23013 /* Emit RTL insns to initialize the variable parts of a trampoline.
23014 FNADDR is an RTX for the address of the function's pure code.
23015 CXT is an RTX for the static chain value for the function. */
23018 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
23020 int regsize = (TARGET_32BIT) ? 4 : 8;
23021 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
23022 rtx ctx_reg = force_reg (Pmode, cxt);
23023 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
23025 switch (DEFAULT_ABI)
23028 gcc_unreachable ();
23030 /* Under AIX, just build the 3 word function descriptor */
23033 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
23034 rtx fn_reg = gen_reg_rtx (Pmode);
23035 rtx toc_reg = gen_reg_rtx (Pmode);
23037 /* Macro to shorten the code expansions below. */
23038 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23040 m_tramp = replace_equiv_address (m_tramp, addr);
23042 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
23043 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23044 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23045 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23046 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23052 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23055 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23056 LCT_NORMAL, VOIDmode, 4,
23058 GEN_INT (rs6000_trampoline_size ()), SImode,
23066 /* Handle the "altivec" attribute. The attribute may have
23067 arguments as follows:
23069 __attribute__((altivec(vector__)))
23070 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23071 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23073 and may appear more than once (e.g., 'vector bool char') in a
23074 given declaration. */
23077 rs6000_handle_altivec_attribute (tree *node,
23078 tree name ATTRIBUTE_UNUSED,
23080 int flags ATTRIBUTE_UNUSED,
23081 bool *no_add_attrs)
23083 tree type = *node, result = NULL_TREE;
23084 enum machine_mode mode;
23087 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23088 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23089 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23092 while (POINTER_TYPE_P (type)
23093 || TREE_CODE (type) == FUNCTION_TYPE
23094 || TREE_CODE (type) == METHOD_TYPE
23095 || TREE_CODE (type) == ARRAY_TYPE)
23096 type = TREE_TYPE (type);
23098 mode = TYPE_MODE (type);
23100 /* Check for invalid AltiVec type qualifiers. */
23101 if (type == long_double_type_node)
23102 error ("use of %<long double%> in AltiVec types is invalid");
23103 else if (type == boolean_type_node)
23104 error ("use of boolean types in AltiVec types is invalid");
23105 else if (TREE_CODE (type) == COMPLEX_TYPE)
23106 error ("use of %<complex%> in AltiVec types is invalid");
23107 else if (DECIMAL_FLOAT_MODE_P (mode))
23108 error ("use of decimal floating point types in AltiVec types is invalid");
23109 else if (!TARGET_VSX)
23111 if (type == long_unsigned_type_node || type == long_integer_type_node)
23114 error ("use of %<long%> in AltiVec types is invalid for "
23115 "64-bit code without -mvsx");
23116 else if (rs6000_warn_altivec_long)
23117 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23120 else if (type == long_long_unsigned_type_node
23121 || type == long_long_integer_type_node)
23122 error ("use of %<long long%> in AltiVec types is invalid without "
23124 else if (type == double_type_node)
23125 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23128 switch (altivec_type)
23131 unsigned_p = TYPE_UNSIGNED (type);
23135 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
23138 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
23141 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
23144 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
23146 case SFmode: result = V4SF_type_node; break;
23147 case DFmode: result = V2DF_type_node; break;
23148 /* If the user says 'vector int bool', we may be handed the 'bool'
23149 attribute _before_ the 'vector' attribute, and so select the
23150 proper type in the 'b' case below. */
23151 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
23152 case V2DImode: case V2DFmode:
23160 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
23161 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
23162 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
23163 case QImode: case V16QImode: result = bool_V16QI_type_node;
23170 case V8HImode: result = pixel_V8HI_type_node;
23176 /* Propagate qualifiers attached to the element type
23177 onto the vector type. */
23178 if (result && result != type && TYPE_QUALS (type))
23179 result = build_qualified_type (result, TYPE_QUALS (type));
23181 *no_add_attrs = true; /* No need to hang on to the attribute. */
23184 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
23189 /* AltiVec defines four built-in scalar types that serve as vector
23190 elements; we must teach the compiler how to mangle them. */
23192 static const char *
23193 rs6000_mangle_type (const_tree type)
23195 type = TYPE_MAIN_VARIANT (type);
23197 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
23198 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
23201 if (type == bool_char_type_node) return "U6__boolc";
23202 if (type == bool_short_type_node) return "U6__bools";
23203 if (type == pixel_type_node) return "u7__pixel";
23204 if (type == bool_int_type_node) return "U6__booli";
23205 if (type == bool_long_type_node) return "U6__booll";
23207 /* Mangle IBM extended float long double as `g' (__float128) on
23208 powerpc*-linux where long-double-64 previously was the default. */
23209 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
23211 && TARGET_LONG_DOUBLE_128
23212 && !TARGET_IEEEQUAD)
23215 /* For all other types, use normal C++ mangling. */
23219 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23220 struct attribute_spec.handler. */
23223 rs6000_handle_longcall_attribute (tree *node, tree name,
23224 tree args ATTRIBUTE_UNUSED,
23225 int flags ATTRIBUTE_UNUSED,
23226 bool *no_add_attrs)
23228 if (TREE_CODE (*node) != FUNCTION_TYPE
23229 && TREE_CODE (*node) != FIELD_DECL
23230 && TREE_CODE (*node) != TYPE_DECL)
23232 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23234 *no_add_attrs = true;
23240 /* Set longcall attributes on all functions declared when
23241 rs6000_default_long_calls is true. */
23243 rs6000_set_default_type_attributes (tree type)
23245 if (rs6000_default_long_calls
23246 && (TREE_CODE (type) == FUNCTION_TYPE
23247 || TREE_CODE (type) == METHOD_TYPE))
23248 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23250 TYPE_ATTRIBUTES (type));
23253 darwin_set_default_type_attributes (type);
23257 /* Return a reference suitable for calling a function with the
23258 longcall attribute. */
23261 rs6000_longcall_ref (rtx call_ref)
23263 const char *call_name;
23266 if (GET_CODE (call_ref) != SYMBOL_REF)
23269 /* System V adds '.' to the internal name, so skip them. */
23270 call_name = XSTR (call_ref, 0);
23271 if (*call_name == '.')
23273 while (*call_name == '.')
23276 node = get_identifier (call_name);
23277 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
23280 return force_reg (Pmode, call_ref);
23283 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23284 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23287 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23288 struct attribute_spec.handler. */
23290 rs6000_handle_struct_attribute (tree *node, tree name,
23291 tree args ATTRIBUTE_UNUSED,
23292 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
23295 if (DECL_P (*node))
23297 if (TREE_CODE (*node) == TYPE_DECL)
23298 type = &TREE_TYPE (*node);
23303 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
23304 || TREE_CODE (*type) == UNION_TYPE)))
23306 warning (OPT_Wattributes, "%qE attribute ignored", name);
23307 *no_add_attrs = true;
23310 else if ((is_attribute_p ("ms_struct", name)
23311 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
23312 || ((is_attribute_p ("gcc_struct", name)
23313 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
23315 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
23317 *no_add_attrs = true;
23324 rs6000_ms_bitfield_layout_p (const_tree record_type)
23326 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
23327 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
23328 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
23331 #ifdef USING_ELFOS_H
23333 /* A get_unnamed_section callback, used for switching to toc_section. */
23336 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23338 if (DEFAULT_ABI == ABI_AIX
23339 && TARGET_MINIMAL_TOC
23340 && !TARGET_RELOCATABLE)
23342 if (!toc_initialized)
23344 toc_initialized = 1;
23345 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23346 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
23347 fprintf (asm_out_file, "\t.tc ");
23348 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
23349 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23350 fprintf (asm_out_file, "\n");
23352 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23353 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23354 fprintf (asm_out_file, " = .+32768\n");
23357 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23359 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
23360 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23363 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23364 if (!toc_initialized)
23366 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23367 fprintf (asm_out_file, " = .+32768\n");
23368 toc_initialized = 1;
23373 /* Implement TARGET_ASM_INIT_SECTIONS. */
23376 rs6000_elf_asm_init_sections (void)
23379 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
23382 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
23383 SDATA2_SECTION_ASM_OP);
23386 /* Implement TARGET_SELECT_RTX_SECTION. */
23389 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
23390 unsigned HOST_WIDE_INT align)
23392 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23393 return toc_section;
23395 return default_elf_select_rtx_section (mode, x, align);
23398 /* For a SYMBOL_REF, set generic flags and then perform some
23399 target-specific processing.
23401 When the AIX ABI is requested on a non-AIX system, replace the
23402 function name with the real name (with a leading .) rather than the
23403 function descriptor name. This saves a lot of overriding code to
23404 read the prefixes. */
23407 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
23409 default_encode_section_info (decl, rtl, first);
23412 && TREE_CODE (decl) == FUNCTION_DECL
23414 && DEFAULT_ABI == ABI_AIX)
23416 rtx sym_ref = XEXP (rtl, 0);
23417 size_t len = strlen (XSTR (sym_ref, 0));
23418 char *str = XALLOCAVEC (char, len + 2);
23420 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
23421 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
23426 compare_section_name (const char *section, const char *templ)
23430 len = strlen (templ);
23431 return (strncmp (section, templ, len) == 0
23432 && (section[len] == 0 || section[len] == '.'));
23436 rs6000_elf_in_small_data_p (const_tree decl)
23438 if (rs6000_sdata == SDATA_NONE)
23441 /* We want to merge strings, so we never consider them small data. */
23442 if (TREE_CODE (decl) == STRING_CST)
23445 /* Functions are never in the small data area. */
23446 if (TREE_CODE (decl) == FUNCTION_DECL)
23449 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
23451 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
23452 if (compare_section_name (section, ".sdata")
23453 || compare_section_name (section, ".sdata2")
23454 || compare_section_name (section, ".gnu.linkonce.s")
23455 || compare_section_name (section, ".sbss")
23456 || compare_section_name (section, ".sbss2")
23457 || compare_section_name (section, ".gnu.linkonce.sb")
23458 || strcmp (section, ".PPC.EMB.sdata0") == 0
23459 || strcmp (section, ".PPC.EMB.sbss0") == 0)
23464 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
23467 && (unsigned HOST_WIDE_INT) size <= g_switch_value
23468 /* If it's not public, and we're not going to reference it there,
23469 there's no need to put it in the small data section. */
23470 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
23477 #endif /* USING_ELFOS_H */
23479 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
23482 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
23484 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
23487 /* Return a REG that occurs in ADDR with coefficient 1.
23488 ADDR can be effectively incremented by incrementing REG.
23490 r0 is special and we must not select it as an address
23491 register by this routine since our caller will try to
23492 increment the returned register via an "la" instruction. */
23495 find_addr_reg (rtx addr)
23497 while (GET_CODE (addr) == PLUS)
23499 if (GET_CODE (XEXP (addr, 0)) == REG
23500 && REGNO (XEXP (addr, 0)) != 0)
23501 addr = XEXP (addr, 0);
23502 else if (GET_CODE (XEXP (addr, 1)) == REG
23503 && REGNO (XEXP (addr, 1)) != 0)
23504 addr = XEXP (addr, 1);
23505 else if (CONSTANT_P (XEXP (addr, 0)))
23506 addr = XEXP (addr, 1);
23507 else if (CONSTANT_P (XEXP (addr, 1)))
23508 addr = XEXP (addr, 0);
23510 gcc_unreachable ();
23512 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
23517 rs6000_fatal_bad_address (rtx op)
23519 fatal_insn ("bad address", op);
23524 static tree branch_island_list = 0;
23526 /* Remember to generate a branch island for far calls to the given
23530 add_compiler_branch_island (tree label_name, tree function_name,
23533 tree branch_island = build_tree_list (function_name, label_name);
23534 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
23535 TREE_CHAIN (branch_island) = branch_island_list;
23536 branch_island_list = branch_island;
23539 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
23540 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
23541 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
23542 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
23544 /* Generate far-jump branch islands for everything on the
23545 branch_island_list. Invoked immediately after the last instruction
23546 of the epilogue has been emitted; the branch-islands must be
23547 appended to, and contiguous with, the function body. Mach-O stubs
23548 are generated in machopic_output_stub(). */
23551 macho_branch_islands (void)
23554 tree branch_island;
23556 for (branch_island = branch_island_list;
23558 branch_island = TREE_CHAIN (branch_island))
23560 const char *label =
23561 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
23563 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
23564 char name_buf[512];
23565 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
23566 if (name[0] == '*' || name[0] == '&')
23567 strcpy (name_buf, name+1);
23571 strcpy (name_buf+1, name);
23573 strcpy (tmp_buf, "\n");
23574 strcat (tmp_buf, label);
23575 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23576 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23577 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23578 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23581 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
23582 strcat (tmp_buf, label);
23583 strcat (tmp_buf, "_pic\n");
23584 strcat (tmp_buf, label);
23585 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
23587 strcat (tmp_buf, "\taddis r11,r11,ha16(");
23588 strcat (tmp_buf, name_buf);
23589 strcat (tmp_buf, " - ");
23590 strcat (tmp_buf, label);
23591 strcat (tmp_buf, "_pic)\n");
23593 strcat (tmp_buf, "\tmtlr r0\n");
23595 strcat (tmp_buf, "\taddi r12,r11,lo16(");
23596 strcat (tmp_buf, name_buf);
23597 strcat (tmp_buf, " - ");
23598 strcat (tmp_buf, label);
23599 strcat (tmp_buf, "_pic)\n");
23601 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
23605 strcat (tmp_buf, ":\nlis r12,hi16(");
23606 strcat (tmp_buf, name_buf);
23607 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
23608 strcat (tmp_buf, name_buf);
23609 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
23611 output_asm_insn (tmp_buf, 0);
23612 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23613 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23614 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23615 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23618 branch_island_list = 0;
23621 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
23622 already there or not. */
23625 no_previous_def (tree function_name)
23627 tree branch_island;
23628 for (branch_island = branch_island_list;
23630 branch_island = TREE_CHAIN (branch_island))
23631 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23636 /* GET_PREV_LABEL gets the label name from the previous definition of
23640 get_prev_label (tree function_name)
23642 tree branch_island;
23643 for (branch_island = branch_island_list;
23645 branch_island = TREE_CHAIN (branch_island))
23646 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23647 return BRANCH_ISLAND_LABEL_NAME (branch_island);
23651 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
23652 #define DARWIN_LINKER_GENERATES_ISLANDS 0
23655 /* KEXTs still need branch islands. */
23656 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
23657 || flag_mkernel || flag_apple_kext)
23659 /* INSN is either a function call or a millicode call. It may have an
23660 unconditional jump in its delay slot.
23662 CALL_DEST is the routine we are calling. */
23665 output_call (rtx insn, rtx *operands, int dest_operand_number,
23666 int cookie_operand_number)
23668 static char buf[256];
23669 if (DARWIN_GENERATE_ISLANDS
23670 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
23671 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
23674 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
23676 if (no_previous_def (funname))
23678 rtx label_rtx = gen_label_rtx ();
23679 char *label_buf, temp_buf[256];
23680 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
23681 CODE_LABEL_NUMBER (label_rtx));
23682 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
23683 labelname = get_identifier (label_buf);
23684 add_compiler_branch_island (labelname, funname, insn_line (insn));
23687 labelname = get_prev_label (funname);
23689 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
23690 instruction will reach 'foo', otherwise link as 'bl L42'".
23691 "L42" should be a 'branch island', that will do a far jump to
23692 'foo'. Branch islands are generated in
23693 macho_branch_islands(). */
23694 sprintf (buf, "jbsr %%z%d,%.246s",
23695 dest_operand_number, IDENTIFIER_POINTER (labelname));
23698 sprintf (buf, "bl %%z%d", dest_operand_number);
23702 /* Generate PIC and indirect symbol stubs. */
23705 machopic_output_stub (FILE *file, const char *symb, const char *stub)
23707 unsigned int length;
23708 char *symbol_name, *lazy_ptr_name;
23709 char *local_label_0;
23710 static int label = 0;
23712 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
23713 symb = (*targetm.strip_name_encoding) (symb);
23716 length = strlen (symb);
23717 symbol_name = XALLOCAVEC (char, length + 32);
23718 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
23720 lazy_ptr_name = XALLOCAVEC (char, length + 32);
23721 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
23724 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
23726 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
23730 fprintf (file, "\t.align 5\n");
23732 fprintf (file, "%s:\n", stub);
23733 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23736 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
23737 sprintf (local_label_0, "\"L%011d$spb\"", label);
23739 fprintf (file, "\tmflr r0\n");
23740 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
23741 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
23742 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
23743 lazy_ptr_name, local_label_0);
23744 fprintf (file, "\tmtlr r0\n");
23745 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
23746 (TARGET_64BIT ? "ldu" : "lwzu"),
23747 lazy_ptr_name, local_label_0);
23748 fprintf (file, "\tmtctr r12\n");
23749 fprintf (file, "\tbctr\n");
23753 fprintf (file, "\t.align 4\n");
23755 fprintf (file, "%s:\n", stub);
23756 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23758 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
23759 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
23760 (TARGET_64BIT ? "ldu" : "lwzu"),
23762 fprintf (file, "\tmtctr r12\n");
23763 fprintf (file, "\tbctr\n");
23766 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
23767 fprintf (file, "%s:\n", lazy_ptr_name);
23768 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23769 fprintf (file, "%sdyld_stub_binding_helper\n",
23770 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
23773 /* Legitimize PIC addresses. If the address is already
23774 position-independent, we return ORIG. Newly generated
23775 position-independent addresses go into a reg. This is REG if non
23776 zero, otherwise we allocate register(s) as necessary. */
23778 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
23781 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
23786 if (reg == NULL && ! reload_in_progress && ! reload_completed)
23787 reg = gen_reg_rtx (Pmode);
23789 if (GET_CODE (orig) == CONST)
23793 if (GET_CODE (XEXP (orig, 0)) == PLUS
23794 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
23797 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
23799 /* Use a different reg for the intermediate value, as
23800 it will be marked UNCHANGING. */
23801 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
23802 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
23805 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
23808 if (GET_CODE (offset) == CONST_INT)
23810 if (SMALL_INT (offset))
23811 return plus_constant (base, INTVAL (offset));
23812 else if (! reload_in_progress && ! reload_completed)
23813 offset = force_reg (Pmode, offset);
23816 rtx mem = force_const_mem (Pmode, orig);
23817 return machopic_legitimize_pic_address (mem, Pmode, reg);
23820 return gen_rtx_PLUS (Pmode, base, offset);
23823 /* Fall back on generic machopic code. */
23824 return machopic_legitimize_pic_address (orig, mode, reg);
23827 /* Output a .machine directive for the Darwin assembler, and call
23828 the generic start_file routine. */
23831 rs6000_darwin_file_start (void)
23833 static const struct
23839 { "ppc64", "ppc64", MASK_64BIT },
23840 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
23841 { "power4", "ppc970", 0 },
23842 { "G5", "ppc970", 0 },
23843 { "7450", "ppc7450", 0 },
23844 { "7400", "ppc7400", MASK_ALTIVEC },
23845 { "G4", "ppc7400", 0 },
23846 { "750", "ppc750", 0 },
23847 { "740", "ppc750", 0 },
23848 { "G3", "ppc750", 0 },
23849 { "604e", "ppc604e", 0 },
23850 { "604", "ppc604", 0 },
23851 { "603e", "ppc603", 0 },
23852 { "603", "ppc603", 0 },
23853 { "601", "ppc601", 0 },
23854 { NULL, "ppc", 0 } };
23855 const char *cpu_id = "";
23858 rs6000_file_start ();
23859 darwin_file_start ();
23861 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
23862 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
23863 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
23864 && rs6000_select[i].string[0] != '\0')
23865 cpu_id = rs6000_select[i].string;
23867 /* Look through the mapping array. Pick the first name that either
23868 matches the argument, has a bit set in IF_SET that is also set
23869 in the target flags, or has a NULL name. */
23872 while (mapping[i].arg != NULL
23873 && strcmp (mapping[i].arg, cpu_id) != 0
23874 && (mapping[i].if_set & target_flags) == 0)
23877 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
23880 #endif /* TARGET_MACHO */
23884 rs6000_elf_reloc_rw_mask (void)
23888 else if (DEFAULT_ABI == ABI_AIX)
23894 /* Record an element in the table of global constructors. SYMBOL is
23895 a SYMBOL_REF of the function to be called; PRIORITY is a number
23896 between 0 and MAX_INIT_PRIORITY.
23898 This differs from default_named_section_asm_out_constructor in
23899 that we have special handling for -mrelocatable. */
23902 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
23904 const char *section = ".ctors";
23907 if (priority != DEFAULT_INIT_PRIORITY)
23909 sprintf (buf, ".ctors.%.5u",
23910 /* Invert the numbering so the linker puts us in the proper
23911 order; constructors are run from right to left, and the
23912 linker sorts in increasing order. */
23913 MAX_INIT_PRIORITY - priority);
23917 switch_to_section (get_section (section, SECTION_WRITE, NULL));
23918 assemble_align (POINTER_SIZE);
23920 if (TARGET_RELOCATABLE)
23922 fputs ("\t.long (", asm_out_file);
23923 output_addr_const (asm_out_file, symbol);
23924 fputs (")@fixup\n", asm_out_file);
23927 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
23931 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
23933 const char *section = ".dtors";
23936 if (priority != DEFAULT_INIT_PRIORITY)
23938 sprintf (buf, ".dtors.%.5u",
23939 /* Invert the numbering so the linker puts us in the proper
23940 order; constructors are run from right to left, and the
23941 linker sorts in increasing order. */
23942 MAX_INIT_PRIORITY - priority);
23946 switch_to_section (get_section (section, SECTION_WRITE, NULL));
23947 assemble_align (POINTER_SIZE);
23949 if (TARGET_RELOCATABLE)
23951 fputs ("\t.long (", asm_out_file);
23952 output_addr_const (asm_out_file, symbol);
23953 fputs (")@fixup\n", asm_out_file);
23956 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
23960 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
23964 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
23965 ASM_OUTPUT_LABEL (file, name);
23966 fputs (DOUBLE_INT_ASM_OP, file);
23967 rs6000_output_function_entry (file, name);
23968 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
23971 fputs ("\t.size\t", file);
23972 assemble_name (file, name);
23973 fputs (",24\n\t.type\t.", file);
23974 assemble_name (file, name);
23975 fputs (",@function\n", file);
23976 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
23978 fputs ("\t.globl\t.", file);
23979 assemble_name (file, name);
23984 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
23985 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
23986 rs6000_output_function_entry (file, name);
23987 fputs (":\n", file);
23991 if (TARGET_RELOCATABLE
23992 && !TARGET_SECURE_PLT
23993 && (get_pool_size () != 0 || crtl->profile)
23998 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
24000 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
24001 fprintf (file, "\t.long ");
24002 assemble_name (file, buf);
24004 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
24005 assemble_name (file, buf);
24009 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24010 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24012 if (DEFAULT_ABI == ABI_AIX)
24014 const char *desc_name, *orig_name;
24016 orig_name = (*targetm.strip_name_encoding) (name);
24017 desc_name = orig_name;
24018 while (*desc_name == '.')
24021 if (TREE_PUBLIC (decl))
24022 fprintf (file, "\t.globl %s\n", desc_name);
24024 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24025 fprintf (file, "%s:\n", desc_name);
24026 fprintf (file, "\t.long %s\n", orig_name);
24027 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
24028 if (DEFAULT_ABI == ABI_AIX)
24029 fputs ("\t.long 0\n", file);
24030 fprintf (file, "\t.previous\n");
24032 ASM_OUTPUT_LABEL (file, name);
24036 rs6000_elf_end_indicate_exec_stack (void)
24039 file_end_indicate_exec_stack ();
24045 rs6000_xcoff_asm_output_anchor (rtx symbol)
24049 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24050 SYMBOL_REF_BLOCK_OFFSET (symbol));
24051 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24055 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24057 fputs (GLOBAL_ASM_OP, stream);
24058 RS6000_OUTPUT_BASENAME (stream, name);
24059 putc ('\n', stream);
24062 /* A get_unnamed_decl callback, used for read-only sections. PTR
24063 points to the section string variable. */
24066 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24068 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24069 *(const char *const *) directive,
24070 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24073 /* Likewise for read-write sections. */
24076 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24078 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24079 *(const char *const *) directive,
24080 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24083 /* A get_unnamed_section callback, used for switching to toc_section. */
24086 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24088 if (TARGET_MINIMAL_TOC)
24090 /* toc_section is always selected at least once from
24091 rs6000_xcoff_file_start, so this is guaranteed to
24092 always be defined once and only once in each file. */
24093 if (!toc_initialized)
24095 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24096 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24097 toc_initialized = 1;
24099 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
24100 (TARGET_32BIT ? "" : ",3"));
24103 fputs ("\t.toc\n", asm_out_file);
24106 /* Implement TARGET_ASM_INIT_SECTIONS. */
24109 rs6000_xcoff_asm_init_sections (void)
24111 read_only_data_section
24112 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24113 &xcoff_read_only_section_name);
24115 private_data_section
24116 = get_unnamed_section (SECTION_WRITE,
24117 rs6000_xcoff_output_readwrite_section_asm_op,
24118 &xcoff_private_data_section_name);
24120 read_only_private_data_section
24121 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24122 &xcoff_private_data_section_name);
24125 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
24127 readonly_data_section = read_only_data_section;
24128 exception_section = data_section;
24132 rs6000_xcoff_reloc_rw_mask (void)
24138 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
24139 tree decl ATTRIBUTE_UNUSED)
24142 static const char * const suffix[3] = { "PR", "RO", "RW" };
24144 if (flags & SECTION_CODE)
24146 else if (flags & SECTION_WRITE)
24151 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
24152 (flags & SECTION_CODE) ? "." : "",
24153 name, suffix[smclass], flags & SECTION_ENTSIZE);
24157 rs6000_xcoff_select_section (tree decl, int reloc,
24158 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24160 if (decl_readonly_section (decl, reloc))
24162 if (TREE_PUBLIC (decl))
24163 return read_only_data_section;
24165 return read_only_private_data_section;
24169 if (TREE_PUBLIC (decl))
24170 return data_section;
24172 return private_data_section;
24177 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
24181 /* Use select_section for private and uninitialized data. */
24182 if (!TREE_PUBLIC (decl)
24183 || DECL_COMMON (decl)
24184 || DECL_INITIAL (decl) == NULL_TREE
24185 || DECL_INITIAL (decl) == error_mark_node
24186 || (flag_zero_initialized_in_bss
24187 && initializer_zerop (DECL_INITIAL (decl))))
24190 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
24191 name = (*targetm.strip_name_encoding) (name);
24192 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
24195 /* Select section for constant in constant pool.
24197 On RS/6000, all constants are in the private read-only data area.
24198 However, if this is being placed in the TOC it must be output as a
24202 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
24203 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24205 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24206 return toc_section;
24208 return read_only_private_data_section;
24211 /* Remove any trailing [DS] or the like from the symbol name. */
24213 static const char *
24214 rs6000_xcoff_strip_name_encoding (const char *name)
24219 len = strlen (name);
24220 if (name[len - 1] == ']')
24221 return ggc_alloc_string (name, len - 4);
24226 /* Section attributes. AIX is always PIC. */
24228 static unsigned int
24229 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24231 unsigned int align;
24232 unsigned int flags = default_section_type_flags (decl, name, reloc);
24234 /* Align to at least UNIT size. */
24235 if (flags & SECTION_CODE)
24236 align = MIN_UNITS_PER_WORD;
24238 /* Increase alignment of large objects if not already stricter. */
24239 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24240 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24241 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24243 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24246 /* Output at beginning of assembler file.
24248 Initialize the section names for the RS/6000 at this point.
24250 Specify filename, including full path, to assembler.
24252 We want to go into the TOC section so at least one .toc will be emitted.
24253 Also, in order to output proper .bs/.es pairs, we need at least one static
24254 [RW] section emitted.
24256 Finally, declare mcount when profiling to make the assembler happy. */
24259 rs6000_xcoff_file_start (void)
24261 rs6000_gen_section_name (&xcoff_bss_section_name,
24262 main_input_filename, ".bss_");
24263 rs6000_gen_section_name (&xcoff_private_data_section_name,
24264 main_input_filename, ".rw_");
24265 rs6000_gen_section_name (&xcoff_read_only_section_name,
24266 main_input_filename, ".ro_");
24268 fputs ("\t.file\t", asm_out_file);
24269 output_quoted_string (asm_out_file, main_input_filename);
24270 fputc ('\n', asm_out_file);
24271 if (write_symbols != NO_DEBUG)
24272 switch_to_section (private_data_section);
24273 switch_to_section (text_section);
24275 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
24276 rs6000_file_start ();
24279 /* Output at end of assembler file.
24280 On the RS/6000, referencing data should automatically pull in text. */
24283 rs6000_xcoff_file_end (void)
24285 switch_to_section (text_section);
24286 fputs ("_section_.text:\n", asm_out_file);
24287 switch_to_section (data_section);
24288 fputs (TARGET_32BIT
24289 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24292 #endif /* TARGET_XCOFF */
24294 /* Compute a (partial) cost for rtx X. Return true if the complete
24295 cost has been computed, and false if subexpressions should be
24296 scanned. In either case, *TOTAL contains the cost result. */
24299 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
24302 enum machine_mode mode = GET_MODE (x);
24306 /* On the RS/6000, if it is valid in the insn, it is free. */
24308 if (((outer_code == SET
24309 || outer_code == PLUS
24310 || outer_code == MINUS)
24311 && (satisfies_constraint_I (x)
24312 || satisfies_constraint_L (x)))
24313 || (outer_code == AND
24314 && (satisfies_constraint_K (x)
24316 ? satisfies_constraint_L (x)
24317 : satisfies_constraint_J (x))
24318 || mask_operand (x, mode)
24320 && mask64_operand (x, DImode))))
24321 || ((outer_code == IOR || outer_code == XOR)
24322 && (satisfies_constraint_K (x)
24324 ? satisfies_constraint_L (x)
24325 : satisfies_constraint_J (x))))
24326 || outer_code == ASHIFT
24327 || outer_code == ASHIFTRT
24328 || outer_code == LSHIFTRT
24329 || outer_code == ROTATE
24330 || outer_code == ROTATERT
24331 || outer_code == ZERO_EXTRACT
24332 || (outer_code == MULT
24333 && satisfies_constraint_I (x))
24334 || ((outer_code == DIV || outer_code == UDIV
24335 || outer_code == MOD || outer_code == UMOD)
24336 && exact_log2 (INTVAL (x)) >= 0)
24337 || (outer_code == COMPARE
24338 && (satisfies_constraint_I (x)
24339 || satisfies_constraint_K (x)))
24340 || (outer_code == EQ
24341 && (satisfies_constraint_I (x)
24342 || satisfies_constraint_K (x)
24344 ? satisfies_constraint_L (x)
24345 : satisfies_constraint_J (x))))
24346 || (outer_code == GTU
24347 && satisfies_constraint_I (x))
24348 || (outer_code == LTU
24349 && satisfies_constraint_P (x)))
24354 else if ((outer_code == PLUS
24355 && reg_or_add_cint_operand (x, VOIDmode))
24356 || (outer_code == MINUS
24357 && reg_or_sub_cint_operand (x, VOIDmode))
24358 || ((outer_code == SET
24359 || outer_code == IOR
24360 || outer_code == XOR)
24362 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
24364 *total = COSTS_N_INSNS (1);
24370 if (mode == DImode && code == CONST_DOUBLE)
24372 if ((outer_code == IOR || outer_code == XOR)
24373 && CONST_DOUBLE_HIGH (x) == 0
24374 && (CONST_DOUBLE_LOW (x)
24375 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
24380 else if ((outer_code == AND && and64_2_operand (x, DImode))
24381 || ((outer_code == SET
24382 || outer_code == IOR
24383 || outer_code == XOR)
24384 && CONST_DOUBLE_HIGH (x) == 0))
24386 *total = COSTS_N_INSNS (1);
24396 /* When optimizing for size, MEM should be slightly more expensive
24397 than generating address, e.g., (plus (reg) (const)).
24398 L1 cache latency is about two instructions. */
24399 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
24407 if (mode == DFmode)
24409 if (GET_CODE (XEXP (x, 0)) == MULT)
24411 /* FNMA accounted in outer NEG. */
24412 if (outer_code == NEG)
24413 *total = rs6000_cost->dmul - rs6000_cost->fp;
24415 *total = rs6000_cost->dmul;
24418 *total = rs6000_cost->fp;
24420 else if (mode == SFmode)
24422 /* FNMA accounted in outer NEG. */
24423 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24426 *total = rs6000_cost->fp;
24429 *total = COSTS_N_INSNS (1);
24433 if (mode == DFmode)
24435 if (GET_CODE (XEXP (x, 0)) == MULT
24436 || GET_CODE (XEXP (x, 1)) == MULT)
24438 /* FNMA accounted in outer NEG. */
24439 if (outer_code == NEG)
24440 *total = rs6000_cost->dmul - rs6000_cost->fp;
24442 *total = rs6000_cost->dmul;
24445 *total = rs6000_cost->fp;
24447 else if (mode == SFmode)
24449 /* FNMA accounted in outer NEG. */
24450 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24453 *total = rs6000_cost->fp;
24456 *total = COSTS_N_INSNS (1);
24460 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24461 && satisfies_constraint_I (XEXP (x, 1)))
24463 if (INTVAL (XEXP (x, 1)) >= -256
24464 && INTVAL (XEXP (x, 1)) <= 255)
24465 *total = rs6000_cost->mulsi_const9;
24467 *total = rs6000_cost->mulsi_const;
24469 /* FMA accounted in outer PLUS/MINUS. */
24470 else if ((mode == DFmode || mode == SFmode)
24471 && (outer_code == PLUS || outer_code == MINUS))
24473 else if (mode == DFmode)
24474 *total = rs6000_cost->dmul;
24475 else if (mode == SFmode)
24476 *total = rs6000_cost->fp;
24477 else if (mode == DImode)
24478 *total = rs6000_cost->muldi;
24480 *total = rs6000_cost->mulsi;
24485 if (FLOAT_MODE_P (mode))
24487 *total = mode == DFmode ? rs6000_cost->ddiv
24488 : rs6000_cost->sdiv;
24495 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24496 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
24498 if (code == DIV || code == MOD)
24500 *total = COSTS_N_INSNS (2);
24503 *total = COSTS_N_INSNS (1);
24507 if (GET_MODE (XEXP (x, 1)) == DImode)
24508 *total = rs6000_cost->divdi;
24510 *total = rs6000_cost->divsi;
24512 /* Add in shift and subtract for MOD. */
24513 if (code == MOD || code == UMOD)
24514 *total += COSTS_N_INSNS (2);
24519 *total = COSTS_N_INSNS (4);
24523 *total = COSTS_N_INSNS (6);
24527 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
24539 *total = COSTS_N_INSNS (1);
24547 /* Handle mul_highpart. */
24548 if (outer_code == TRUNCATE
24549 && GET_CODE (XEXP (x, 0)) == MULT)
24551 if (mode == DImode)
24552 *total = rs6000_cost->muldi;
24554 *total = rs6000_cost->mulsi;
24557 else if (outer_code == AND)
24560 *total = COSTS_N_INSNS (1);
24565 if (GET_CODE (XEXP (x, 0)) == MEM)
24568 *total = COSTS_N_INSNS (1);
24574 if (!FLOAT_MODE_P (mode))
24576 *total = COSTS_N_INSNS (1);
24582 case UNSIGNED_FLOAT:
24585 case FLOAT_TRUNCATE:
24586 *total = rs6000_cost->fp;
24590 if (mode == DFmode)
24593 *total = rs6000_cost->fp;
24597 switch (XINT (x, 1))
24600 *total = rs6000_cost->fp;
24612 *total = COSTS_N_INSNS (1);
24615 else if (FLOAT_MODE_P (mode)
24616 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
24618 *total = rs6000_cost->fp;
24626 /* Carry bit requires mode == Pmode.
24627 NEG or PLUS already counted so only add one. */
24629 && (outer_code == NEG || outer_code == PLUS))
24631 *total = COSTS_N_INSNS (1);
24634 if (outer_code == SET)
24636 if (XEXP (x, 1) == const0_rtx)
24638 *total = COSTS_N_INSNS (2);
24641 else if (mode == Pmode)
24643 *total = COSTS_N_INSNS (3);
24652 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
24654 *total = COSTS_N_INSNS (2);
24658 if (outer_code == COMPARE)
24672 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
24675 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
24678 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
24681 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
24682 "total = %d, speed = %s, x:\n",
24683 ret ? "complete" : "scan inner",
24684 GET_RTX_NAME (code),
24685 GET_RTX_NAME (outer_code),
24687 speed ? "true" : "false");
24694 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
24697 rs6000_debug_address_cost (rtx x, bool speed)
24699 int ret = TARGET_ADDRESS_COST (x, speed);
24701 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
24702 ret, speed ? "true" : "false");
24709 /* A C expression returning the cost of moving data from a register of class
24710 CLASS1 to one of CLASS2. */
24713 rs6000_register_move_cost (enum machine_mode mode,
24714 enum reg_class from, enum reg_class to)
24718 /* Moves from/to GENERAL_REGS. */
24719 if (reg_classes_intersect_p (to, GENERAL_REGS)
24720 || reg_classes_intersect_p (from, GENERAL_REGS))
24722 if (! reg_classes_intersect_p (to, GENERAL_REGS))
24725 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
24726 ret = (rs6000_memory_move_cost (mode, from, 0)
24727 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
24729 /* It's more expensive to move CR_REGS than CR0_REGS because of the
24731 else if (from == CR_REGS)
24734 /* Power6 has slower LR/CTR moves so make them more expensive than
24735 memory in order to bias spills to memory .*/
24736 else if (rs6000_cpu == PROCESSOR_POWER6
24737 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
24738 ret = 6 * hard_regno_nregs[0][mode];
24741 /* A move will cost one instruction per GPR moved. */
24742 ret = 2 * hard_regno_nregs[0][mode];
24745 /* If we have VSX, we can easily move between FPR or Altivec registers. */
24746 else if (VECTOR_UNIT_VSX_P (mode)
24747 && reg_classes_intersect_p (to, VSX_REGS)
24748 && reg_classes_intersect_p (from, VSX_REGS))
24749 ret = 2 * hard_regno_nregs[32][mode];
24751 /* Moving between two similar registers is just one instruction. */
24752 else if (reg_classes_intersect_p (to, from))
24753 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
24755 /* Everything else has to go through GENERAL_REGS. */
24757 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
24758 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
24760 if (TARGET_DEBUG_COST)
24762 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
24763 ret, GET_MODE_NAME (mode), reg_class_names[from],
24764 reg_class_names[to]);
24769 /* A C expressions returning the cost of moving data of MODE from a register to
24773 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
24774 int in ATTRIBUTE_UNUSED)
24778 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
24779 ret = 4 * hard_regno_nregs[0][mode];
24780 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
24781 ret = 4 * hard_regno_nregs[32][mode];
24782 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
24783 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
24785 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
24787 if (TARGET_DEBUG_COST)
24789 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
24790 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
24795 /* Returns a code for a target-specific builtin that implements
24796 reciprocal of the function, or NULL_TREE if not available. */
24799 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
24800 bool sqrt ATTRIBUTE_UNUSED)
24802 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
24803 && flag_finite_math_only && !flag_trapping_math
24804 && flag_unsafe_math_optimizations))
24812 case BUILT_IN_SQRTF:
24813 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
24820 /* Newton-Raphson approximation of single-precision floating point divide n/d.
24821 Assumes no trapping math and finite arguments. */
24824 rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
24826 rtx x0, e0, e1, y1, u0, v0, one;
24828 x0 = gen_reg_rtx (SFmode);
24829 e0 = gen_reg_rtx (SFmode);
24830 e1 = gen_reg_rtx (SFmode);
24831 y1 = gen_reg_rtx (SFmode);
24832 u0 = gen_reg_rtx (SFmode);
24833 v0 = gen_reg_rtx (SFmode);
24834 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
24836 /* x0 = 1./d estimate */
24837 emit_insn (gen_rtx_SET (VOIDmode, x0,
24838 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
24840 /* e0 = 1. - d * x0 */
24841 emit_insn (gen_rtx_SET (VOIDmode, e0,
24842 gen_rtx_MINUS (SFmode, one,
24843 gen_rtx_MULT (SFmode, d, x0))));
24844 /* e1 = e0 + e0 * e0 */
24845 emit_insn (gen_rtx_SET (VOIDmode, e1,
24846 gen_rtx_PLUS (SFmode,
24847 gen_rtx_MULT (SFmode, e0, e0), e0)));
24848 /* y1 = x0 + e1 * x0 */
24849 emit_insn (gen_rtx_SET (VOIDmode, y1,
24850 gen_rtx_PLUS (SFmode,
24851 gen_rtx_MULT (SFmode, e1, x0), x0)));
24853 emit_insn (gen_rtx_SET (VOIDmode, u0,
24854 gen_rtx_MULT (SFmode, n, y1)));
24855 /* v0 = n - d * u0 */
24856 emit_insn (gen_rtx_SET (VOIDmode, v0,
24857 gen_rtx_MINUS (SFmode, n,
24858 gen_rtx_MULT (SFmode, d, u0))));
24859 /* dst = u0 + v0 * y1 */
24860 emit_insn (gen_rtx_SET (VOIDmode, dst,
24861 gen_rtx_PLUS (SFmode,
24862 gen_rtx_MULT (SFmode, v0, y1), u0)));
24865 /* Newton-Raphson approximation of double-precision floating point divide n/d.
24866 Assumes no trapping math and finite arguments. */
24869 rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
24871 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
24873 x0 = gen_reg_rtx (DFmode);
24874 e0 = gen_reg_rtx (DFmode);
24875 e1 = gen_reg_rtx (DFmode);
24876 e2 = gen_reg_rtx (DFmode);
24877 y1 = gen_reg_rtx (DFmode);
24878 y2 = gen_reg_rtx (DFmode);
24879 y3 = gen_reg_rtx (DFmode);
24880 u0 = gen_reg_rtx (DFmode);
24881 v0 = gen_reg_rtx (DFmode);
24882 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
24884 /* x0 = 1./d estimate */
24885 emit_insn (gen_rtx_SET (VOIDmode, x0,
24886 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
24888 /* e0 = 1. - d * x0 */
24889 emit_insn (gen_rtx_SET (VOIDmode, e0,
24890 gen_rtx_MINUS (DFmode, one,
24891 gen_rtx_MULT (SFmode, d, x0))));
24892 /* y1 = x0 + e0 * x0 */
24893 emit_insn (gen_rtx_SET (VOIDmode, y1,
24894 gen_rtx_PLUS (DFmode,
24895 gen_rtx_MULT (DFmode, e0, x0), x0)));
24897 emit_insn (gen_rtx_SET (VOIDmode, e1,
24898 gen_rtx_MULT (DFmode, e0, e0)));
24899 /* y2 = y1 + e1 * y1 */
24900 emit_insn (gen_rtx_SET (VOIDmode, y2,
24901 gen_rtx_PLUS (DFmode,
24902 gen_rtx_MULT (DFmode, e1, y1), y1)));
24904 emit_insn (gen_rtx_SET (VOIDmode, e2,
24905 gen_rtx_MULT (DFmode, e1, e1)));
24906 /* y3 = y2 + e2 * y2 */
24907 emit_insn (gen_rtx_SET (VOIDmode, y3,
24908 gen_rtx_PLUS (DFmode,
24909 gen_rtx_MULT (DFmode, e2, y2), y2)));
24911 emit_insn (gen_rtx_SET (VOIDmode, u0,
24912 gen_rtx_MULT (DFmode, n, y3)));
24913 /* v0 = n - d * u0 */
24914 emit_insn (gen_rtx_SET (VOIDmode, v0,
24915 gen_rtx_MINUS (DFmode, n,
24916 gen_rtx_MULT (DFmode, d, u0))));
24917 /* dst = u0 + v0 * y3 */
24918 emit_insn (gen_rtx_SET (VOIDmode, dst,
24919 gen_rtx_PLUS (DFmode,
24920 gen_rtx_MULT (DFmode, v0, y3), u0)));
24924 /* Newton-Raphson approximation of single-precision floating point rsqrt.
24925 Assumes no trapping math and finite arguments. */
24928 rs6000_emit_swrsqrtsf (rtx dst, rtx src)
24930 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
24931 half, one, halfthree, c1, cond, label;
24933 x0 = gen_reg_rtx (SFmode);
24934 x1 = gen_reg_rtx (SFmode);
24935 x2 = gen_reg_rtx (SFmode);
24936 y1 = gen_reg_rtx (SFmode);
24937 u0 = gen_reg_rtx (SFmode);
24938 u1 = gen_reg_rtx (SFmode);
24939 u2 = gen_reg_rtx (SFmode);
24940 v0 = gen_reg_rtx (SFmode);
24941 v1 = gen_reg_rtx (SFmode);
24942 v2 = gen_reg_rtx (SFmode);
24943 t0 = gen_reg_rtx (SFmode);
24944 halfthree = gen_reg_rtx (SFmode);
24945 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
24946 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
24948 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
24949 emit_insn (gen_rtx_SET (VOIDmode, t0,
24950 gen_rtx_MULT (SFmode, src, src)));
24952 emit_insn (gen_rtx_SET (VOIDmode, cond,
24953 gen_rtx_COMPARE (CCFPmode, t0, src)));
24954 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
24955 emit_unlikely_jump (c1, label);
24957 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
24958 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
24960 /* halfthree = 1.5 = 1.0 + 0.5 */
24961 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
24962 gen_rtx_PLUS (SFmode, one, half)));
24964 /* x0 = rsqrt estimate */
24965 emit_insn (gen_rtx_SET (VOIDmode, x0,
24966 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
24969 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
24970 emit_insn (gen_rtx_SET (VOIDmode, y1,
24971 gen_rtx_MINUS (SFmode,
24972 gen_rtx_MULT (SFmode, src, halfthree),
24975 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
24976 emit_insn (gen_rtx_SET (VOIDmode, u0,
24977 gen_rtx_MULT (SFmode, x0, x0)));
24978 emit_insn (gen_rtx_SET (VOIDmode, v0,
24979 gen_rtx_MINUS (SFmode,
24981 gen_rtx_MULT (SFmode, y1, u0))));
24982 emit_insn (gen_rtx_SET (VOIDmode, x1,
24983 gen_rtx_MULT (SFmode, x0, v0)));
24985 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
24986 emit_insn (gen_rtx_SET (VOIDmode, u1,
24987 gen_rtx_MULT (SFmode, x1, x1)));
24988 emit_insn (gen_rtx_SET (VOIDmode, v1,
24989 gen_rtx_MINUS (SFmode,
24991 gen_rtx_MULT (SFmode, y1, u1))));
24992 emit_insn (gen_rtx_SET (VOIDmode, x2,
24993 gen_rtx_MULT (SFmode, x1, v1)));
24995 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
24996 emit_insn (gen_rtx_SET (VOIDmode, u2,
24997 gen_rtx_MULT (SFmode, x2, x2)));
24998 emit_insn (gen_rtx_SET (VOIDmode, v2,
24999 gen_rtx_MINUS (SFmode,
25001 gen_rtx_MULT (SFmode, y1, u2))));
25002 emit_insn (gen_rtx_SET (VOIDmode, dst,
25003 gen_rtx_MULT (SFmode, x2, v2)));
25005 emit_label (XEXP (label, 0));
25008 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
25009 (Power7) targets. DST is the target, and SRC is the argument operand. */
25012 rs6000_emit_popcount (rtx dst, rtx src)
25014 enum machine_mode mode = GET_MODE (dst);
25017 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
25018 if (TARGET_POPCNTD)
25020 if (mode == SImode)
25021 emit_insn (gen_popcntwsi2 (dst, src));
25023 emit_insn (gen_popcntddi2 (dst, src));
25027 tmp1 = gen_reg_rtx (mode);
25029 if (mode == SImode)
25031 emit_insn (gen_popcntbsi2 (tmp1, src));
25032 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
25034 tmp2 = force_reg (SImode, tmp2);
25035 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
25039 emit_insn (gen_popcntbdi2 (tmp1, src));
25040 tmp2 = expand_mult (DImode, tmp1,
25041 GEN_INT ((HOST_WIDE_INT)
25042 0x01010101 << 32 | 0x01010101),
25044 tmp2 = force_reg (DImode, tmp2);
25045 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
25050 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25051 target, and SRC is the argument operand. */
25054 rs6000_emit_parity (rtx dst, rtx src)
25056 enum machine_mode mode = GET_MODE (dst);
25059 tmp = gen_reg_rtx (mode);
25060 if (mode == SImode)
25062 /* Is mult+shift >= shift+xor+shift+xor? */
25063 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
25065 rtx tmp1, tmp2, tmp3, tmp4;
25067 tmp1 = gen_reg_rtx (SImode);
25068 emit_insn (gen_popcntbsi2 (tmp1, src));
25070 tmp2 = gen_reg_rtx (SImode);
25071 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
25072 tmp3 = gen_reg_rtx (SImode);
25073 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
25075 tmp4 = gen_reg_rtx (SImode);
25076 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
25077 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
25080 rs6000_emit_popcount (tmp, src);
25081 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
25085 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25086 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
25088 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
25090 tmp1 = gen_reg_rtx (DImode);
25091 emit_insn (gen_popcntbdi2 (tmp1, src));
25093 tmp2 = gen_reg_rtx (DImode);
25094 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
25095 tmp3 = gen_reg_rtx (DImode);
25096 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
25098 tmp4 = gen_reg_rtx (DImode);
25099 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
25100 tmp5 = gen_reg_rtx (DImode);
25101 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
25103 tmp6 = gen_reg_rtx (DImode);
25104 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
25105 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
25108 rs6000_emit_popcount (tmp, src);
25109 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
25113 /* Return an RTX representing where to find the function value of a
25114 function returning MODE. */
25116 rs6000_complex_function_value (enum machine_mode mode)
25118 unsigned int regno;
25120 enum machine_mode inner = GET_MODE_INNER (mode);
25121 unsigned int inner_bytes = GET_MODE_SIZE (inner);
25123 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25124 regno = FP_ARG_RETURN;
25127 regno = GP_ARG_RETURN;
25129 /* 32-bit is OK since it'll go in r3/r4. */
25130 if (TARGET_32BIT && inner_bytes >= 4)
25131 return gen_rtx_REG (mode, regno);
25134 if (inner_bytes >= 8)
25135 return gen_rtx_REG (mode, regno);
25137 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
25139 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
25140 GEN_INT (inner_bytes));
25141 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
25144 /* Target hook for TARGET_FUNCTION_VALUE.
25146 On the SPE, both FPs and vectors are returned in r3.
25148 On RS/6000 an integer value is in r3 and a floating-point value is in
25149 fp1, unless -msoft-float. */
25152 rs6000_function_value (const_tree valtype,
25153 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
25154 bool outgoing ATTRIBUTE_UNUSED)
25156 enum machine_mode mode;
25157 unsigned int regno;
25159 /* Special handling for structs in darwin64. */
25160 if (rs6000_darwin64_abi
25161 && TYPE_MODE (valtype) == BLKmode
25162 && TREE_CODE (valtype) == RECORD_TYPE
25163 && int_size_in_bytes (valtype) > 0)
25165 CUMULATIVE_ARGS valcum;
25169 valcum.fregno = FP_ARG_MIN_REG;
25170 valcum.vregno = ALTIVEC_ARG_MIN_REG;
25171 /* Do a trial code generation as if this were going to be passed as
25172 an argument; if any part goes in memory, we return NULL. */
25173 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
25176 /* Otherwise fall through to standard ABI rules. */
25179 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
25181 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25182 return gen_rtx_PARALLEL (DImode,
25184 gen_rtx_EXPR_LIST (VOIDmode,
25185 gen_rtx_REG (SImode, GP_ARG_RETURN),
25187 gen_rtx_EXPR_LIST (VOIDmode,
25188 gen_rtx_REG (SImode,
25189 GP_ARG_RETURN + 1),
25192 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
25194 return gen_rtx_PARALLEL (DCmode,
25196 gen_rtx_EXPR_LIST (VOIDmode,
25197 gen_rtx_REG (SImode, GP_ARG_RETURN),
25199 gen_rtx_EXPR_LIST (VOIDmode,
25200 gen_rtx_REG (SImode,
25201 GP_ARG_RETURN + 1),
25203 gen_rtx_EXPR_LIST (VOIDmode,
25204 gen_rtx_REG (SImode,
25205 GP_ARG_RETURN + 2),
25207 gen_rtx_EXPR_LIST (VOIDmode,
25208 gen_rtx_REG (SImode,
25209 GP_ARG_RETURN + 3),
25213 mode = TYPE_MODE (valtype);
25214 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
25215 || POINTER_TYPE_P (valtype))
25216 mode = TARGET_32BIT ? SImode : DImode;
25218 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25219 /* _Decimal128 must use an even/odd register pair. */
25220 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25221 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
25222 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
25223 regno = FP_ARG_RETURN;
25224 else if (TREE_CODE (valtype) == COMPLEX_TYPE
25225 && targetm.calls.split_complex_arg)
25226 return rs6000_complex_function_value (mode);
25227 else if (TREE_CODE (valtype) == VECTOR_TYPE
25228 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
25229 && ALTIVEC_VECTOR_MODE (mode))
25230 regno = ALTIVEC_ARG_RETURN;
25231 else if (TREE_CODE (valtype) == VECTOR_TYPE
25232 && TARGET_VSX && TARGET_ALTIVEC_ABI
25233 && VSX_VECTOR_MODE (mode))
25234 regno = ALTIVEC_ARG_RETURN;
25235 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25236 && (mode == DFmode || mode == DCmode
25237 || mode == TFmode || mode == TCmode))
25238 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25240 regno = GP_ARG_RETURN;
25242 return gen_rtx_REG (mode, regno);
25245 /* Define how to find the value returned by a library function
25246 assuming the value has mode MODE. */
25248 rs6000_libcall_value (enum machine_mode mode)
25250 unsigned int regno;
25252 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
25254 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25255 return gen_rtx_PARALLEL (DImode,
25257 gen_rtx_EXPR_LIST (VOIDmode,
25258 gen_rtx_REG (SImode, GP_ARG_RETURN),
25260 gen_rtx_EXPR_LIST (VOIDmode,
25261 gen_rtx_REG (SImode,
25262 GP_ARG_RETURN + 1),
25266 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25267 /* _Decimal128 must use an even/odd register pair. */
25268 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25269 else if (SCALAR_FLOAT_MODE_P (mode)
25270 && TARGET_HARD_FLOAT && TARGET_FPRS
25271 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
25272 regno = FP_ARG_RETURN;
25273 else if (ALTIVEC_VECTOR_MODE (mode)
25274 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
25275 regno = ALTIVEC_ARG_RETURN;
25276 else if (VSX_VECTOR_MODE (mode)
25277 && TARGET_VSX && TARGET_ALTIVEC_ABI)
25278 regno = ALTIVEC_ARG_RETURN;
25279 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
25280 return rs6000_complex_function_value (mode);
25281 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25282 && (mode == DFmode || mode == DCmode
25283 || mode == TFmode || mode == TCmode))
25284 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25286 regno = GP_ARG_RETURN;
25288 return gen_rtx_REG (mode, regno);
25292 /* Given FROM and TO register numbers, say whether this elimination is allowed.
25293 Frame pointer elimination is automatically handled.
25295 For the RS/6000, if frame pointer elimination is being done, we would like
25296 to convert ap into fp, not sp.
25298 We need r30 if -mminimal-toc was specified, and there are constant pool
25302 rs6000_can_eliminate (const int from, const int to)
25304 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
25305 ? ! frame_pointer_needed
25306 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
25307 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
25311 /* Define the offset between two registers, FROM to be eliminated and its
25312 replacement TO, at the start of a routine. */
25314 rs6000_initial_elimination_offset (int from, int to)
25316 rs6000_stack_t *info = rs6000_stack_info ();
25317 HOST_WIDE_INT offset;
25319 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25320 offset = info->push_p ? 0 : -info->total_size;
25321 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25323 offset = info->push_p ? 0 : -info->total_size;
25324 if (FRAME_GROWS_DOWNWARD)
25325 offset += info->fixed_size + info->vars_size + info->parm_size;
25327 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25328 offset = FRAME_GROWS_DOWNWARD
25329 ? info->fixed_size + info->vars_size + info->parm_size
25331 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25332 offset = info->total_size;
25333 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25334 offset = info->push_p ? info->total_size : 0;
25335 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
25338 gcc_unreachable ();
25344 rs6000_dwarf_register_span (rtx reg)
25348 unsigned regno = REGNO (reg);
25349 enum machine_mode mode = GET_MODE (reg);
25353 && (SPE_VECTOR_MODE (GET_MODE (reg))
25354 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
25355 && mode != SFmode && mode != SDmode && mode != SCmode)))
25360 regno = REGNO (reg);
25362 /* The duality of the SPE register size wreaks all kinds of havoc.
25363 This is a way of distinguishing r0 in 32-bits from r0 in
25365 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
25366 gcc_assert (words <= 4);
25367 for (i = 0; i < words; i++, regno++)
25369 if (BYTES_BIG_ENDIAN)
25371 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
25372 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
25376 parts[2 * i] = gen_rtx_REG (SImode, regno);
25377 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
25381 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
25384 /* Fill in sizes for SPE register high parts in table used by unwinder. */
25387 rs6000_init_dwarf_reg_sizes_extra (tree address)
25392 enum machine_mode mode = TYPE_MODE (char_type_node);
25393 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
25394 rtx mem = gen_rtx_MEM (BLKmode, addr);
25395 rtx value = gen_int_mode (4, mode);
25397 for (i = 1201; i < 1232; i++)
25399 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
25400 HOST_WIDE_INT offset
25401 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
25403 emit_move_insn (adjust_address (mem, mode, offset), value);
25408 /* Map internal gcc register numbers to DWARF2 register numbers. */
25411 rs6000_dbx_register_number (unsigned int regno)
25413 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
25415 if (regno == MQ_REGNO)
25417 if (regno == LR_REGNO)
25419 if (regno == CTR_REGNO)
25421 if (CR_REGNO_P (regno))
25422 return regno - CR0_REGNO + 86;
25423 if (regno == XER_REGNO)
25425 if (ALTIVEC_REGNO_P (regno))
25426 return regno - FIRST_ALTIVEC_REGNO + 1124;
25427 if (regno == VRSAVE_REGNO)
25429 if (regno == VSCR_REGNO)
25431 if (regno == SPE_ACC_REGNO)
25433 if (regno == SPEFSCR_REGNO)
25435 /* SPE high reg number. We get these values of regno from
25436 rs6000_dwarf_register_span. */
25437 gcc_assert (regno >= 1200 && regno < 1232);
25441 /* target hook eh_return_filter_mode */
25442 static enum machine_mode
25443 rs6000_eh_return_filter_mode (void)
25445 return TARGET_32BIT ? SImode : word_mode;
25448 /* Target hook for scalar_mode_supported_p. */
25450 rs6000_scalar_mode_supported_p (enum machine_mode mode)
25452 if (DECIMAL_FLOAT_MODE_P (mode))
25453 return default_decimal_float_supported_p ();
25455 return default_scalar_mode_supported_p (mode);
25458 /* Target hook for vector_mode_supported_p. */
25460 rs6000_vector_mode_supported_p (enum machine_mode mode)
25463 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
25466 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
25469 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
25476 /* Target hook for invalid_arg_for_unprototyped_fn. */
25477 static const char *
25478 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
25480 return (!rs6000_darwin64_abi
25482 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
25483 && (funcdecl == NULL_TREE
25484 || (TREE_CODE (funcdecl) == FUNCTION_DECL
25485 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
25486 ? N_("AltiVec argument passed to unprototyped function")
25490 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
25491 setup by using __stack_chk_fail_local hidden function instead of
25492 calling __stack_chk_fail directly. Otherwise it is better to call
25493 __stack_chk_fail directly. */
25496 rs6000_stack_protect_fail (void)
25498 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
25499 ? default_hidden_stack_protect_fail ()
25500 : default_external_stack_protect_fail ();
25504 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
25505 int num_operands ATTRIBUTE_UNUSED)
25507 if (rs6000_warn_cell_microcode)
25510 int insn_code_number = recog_memoized (insn);
25511 location_t location = locator_location (INSN_LOCATOR (insn));
25513 /* Punt on insns we cannot recognize. */
25514 if (insn_code_number < 0)
25517 temp = get_insn_template (insn_code_number, insn);
25519 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
25520 warning_at (location, OPT_mwarn_cell_microcode,
25521 "emitting microcode insn %s\t[%s] #%d",
25522 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25523 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
25524 warning_at (location, OPT_mwarn_cell_microcode,
25525 "emitting conditional microcode insn %s\t[%s] #%d",
25526 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25530 #include "gt-rs6000.h"