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 PPC601 processors. */
516 struct processor_costs ppc601_cost = {
517 COSTS_N_INSNS (5), /* mulsi */
518 COSTS_N_INSNS (5), /* mulsi_const */
519 COSTS_N_INSNS (5), /* mulsi_const9 */
520 COSTS_N_INSNS (5), /* muldi */
521 COSTS_N_INSNS (36), /* divsi */
522 COSTS_N_INSNS (36), /* divdi */
523 COSTS_N_INSNS (4), /* fp */
524 COSTS_N_INSNS (5), /* dmul */
525 COSTS_N_INSNS (17), /* sdiv */
526 COSTS_N_INSNS (31), /* ddiv */
527 32, /* cache line size */
533 /* Instruction costs on PPC603 processors. */
535 struct processor_costs ppc603_cost = {
536 COSTS_N_INSNS (5), /* mulsi */
537 COSTS_N_INSNS (3), /* mulsi_const */
538 COSTS_N_INSNS (2), /* mulsi_const9 */
539 COSTS_N_INSNS (5), /* muldi */
540 COSTS_N_INSNS (37), /* divsi */
541 COSTS_N_INSNS (37), /* divdi */
542 COSTS_N_INSNS (3), /* fp */
543 COSTS_N_INSNS (4), /* dmul */
544 COSTS_N_INSNS (18), /* sdiv */
545 COSTS_N_INSNS (33), /* ddiv */
546 32, /* cache line size */
552 /* Instruction costs on PPC604 processors. */
554 struct processor_costs ppc604_cost = {
555 COSTS_N_INSNS (4), /* mulsi */
556 COSTS_N_INSNS (4), /* mulsi_const */
557 COSTS_N_INSNS (4), /* mulsi_const9 */
558 COSTS_N_INSNS (4), /* muldi */
559 COSTS_N_INSNS (20), /* divsi */
560 COSTS_N_INSNS (20), /* divdi */
561 COSTS_N_INSNS (3), /* fp */
562 COSTS_N_INSNS (3), /* dmul */
563 COSTS_N_INSNS (18), /* sdiv */
564 COSTS_N_INSNS (32), /* ddiv */
565 32, /* cache line size */
571 /* Instruction costs on PPC604e processors. */
573 struct processor_costs ppc604e_cost = {
574 COSTS_N_INSNS (2), /* mulsi */
575 COSTS_N_INSNS (2), /* mulsi_const */
576 COSTS_N_INSNS (2), /* mulsi_const9 */
577 COSTS_N_INSNS (2), /* 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 PPC620 processors. */
592 struct processor_costs ppc620_cost = {
593 COSTS_N_INSNS (5), /* mulsi */
594 COSTS_N_INSNS (4), /* mulsi_const */
595 COSTS_N_INSNS (3), /* mulsi_const9 */
596 COSTS_N_INSNS (7), /* muldi */
597 COSTS_N_INSNS (21), /* divsi */
598 COSTS_N_INSNS (37), /* 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 128, /* cache line size */
609 /* Instruction costs on PPC630 processors. */
611 struct processor_costs ppc630_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 (17), /* sdiv */
621 COSTS_N_INSNS (21), /* ddiv */
622 128, /* cache line size */
628 /* Instruction costs on Cell processor. */
629 /* COSTS_N_INSNS (1) ~ one add. */
631 struct processor_costs ppccell_cost = {
632 COSTS_N_INSNS (9/2)+2, /* mulsi */
633 COSTS_N_INSNS (6/2), /* mulsi_const */
634 COSTS_N_INSNS (6/2), /* mulsi_const9 */
635 COSTS_N_INSNS (15/2)+2, /* muldi */
636 COSTS_N_INSNS (38/2), /* divsi */
637 COSTS_N_INSNS (70/2), /* divdi */
638 COSTS_N_INSNS (10/2), /* fp */
639 COSTS_N_INSNS (10/2), /* dmul */
640 COSTS_N_INSNS (74/2), /* sdiv */
641 COSTS_N_INSNS (74/2), /* ddiv */
642 128, /* cache line size */
648 /* Instruction costs on PPC750 and PPC7400 processors. */
650 struct processor_costs ppc750_cost = {
651 COSTS_N_INSNS (5), /* mulsi */
652 COSTS_N_INSNS (3), /* mulsi_const */
653 COSTS_N_INSNS (2), /* mulsi_const9 */
654 COSTS_N_INSNS (5), /* muldi */
655 COSTS_N_INSNS (17), /* divsi */
656 COSTS_N_INSNS (17), /* divdi */
657 COSTS_N_INSNS (3), /* fp */
658 COSTS_N_INSNS (3), /* dmul */
659 COSTS_N_INSNS (17), /* sdiv */
660 COSTS_N_INSNS (31), /* ddiv */
661 32, /* cache line size */
667 /* Instruction costs on PPC7450 processors. */
669 struct processor_costs ppc7450_cost = {
670 COSTS_N_INSNS (4), /* mulsi */
671 COSTS_N_INSNS (3), /* mulsi_const */
672 COSTS_N_INSNS (3), /* mulsi_const9 */
673 COSTS_N_INSNS (4), /* muldi */
674 COSTS_N_INSNS (23), /* divsi */
675 COSTS_N_INSNS (23), /* divdi */
676 COSTS_N_INSNS (5), /* fp */
677 COSTS_N_INSNS (5), /* dmul */
678 COSTS_N_INSNS (21), /* sdiv */
679 COSTS_N_INSNS (35), /* ddiv */
680 32, /* cache line size */
686 /* Instruction costs on PPC8540 processors. */
688 struct processor_costs ppc8540_cost = {
689 COSTS_N_INSNS (4), /* mulsi */
690 COSTS_N_INSNS (4), /* mulsi_const */
691 COSTS_N_INSNS (4), /* mulsi_const9 */
692 COSTS_N_INSNS (4), /* muldi */
693 COSTS_N_INSNS (19), /* divsi */
694 COSTS_N_INSNS (19), /* divdi */
695 COSTS_N_INSNS (4), /* fp */
696 COSTS_N_INSNS (4), /* dmul */
697 COSTS_N_INSNS (29), /* sdiv */
698 COSTS_N_INSNS (29), /* ddiv */
699 32, /* cache line size */
702 1, /* prefetch streams /*/
705 /* Instruction costs on E300C2 and E300C3 cores. */
707 struct processor_costs ppce300c2c3_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 (3), /* fp */
715 COSTS_N_INSNS (4), /* dmul */
716 COSTS_N_INSNS (18), /* sdiv */
717 COSTS_N_INSNS (33), /* ddiv */
721 1, /* prefetch streams /*/
724 /* Instruction costs on PPCE500MC processors. */
726 struct processor_costs ppce500mc_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 (14), /* divsi */
732 COSTS_N_INSNS (14), /* divdi */
733 COSTS_N_INSNS (8), /* fp */
734 COSTS_N_INSNS (10), /* dmul */
735 COSTS_N_INSNS (36), /* sdiv */
736 COSTS_N_INSNS (66), /* ddiv */
737 64, /* cache line size */
740 1, /* prefetch streams /*/
743 /* Instruction costs on POWER4 and POWER5 processors. */
745 struct processor_costs power4_cost = {
746 COSTS_N_INSNS (3), /* mulsi */
747 COSTS_N_INSNS (2), /* mulsi_const */
748 COSTS_N_INSNS (2), /* mulsi_const9 */
749 COSTS_N_INSNS (4), /* muldi */
750 COSTS_N_INSNS (18), /* divsi */
751 COSTS_N_INSNS (34), /* divdi */
752 COSTS_N_INSNS (3), /* fp */
753 COSTS_N_INSNS (3), /* dmul */
754 COSTS_N_INSNS (17), /* sdiv */
755 COSTS_N_INSNS (17), /* ddiv */
756 128, /* cache line size */
759 8, /* prefetch streams /*/
762 /* Instruction costs on POWER6 processors. */
764 struct processor_costs power6_cost = {
765 COSTS_N_INSNS (8), /* mulsi */
766 COSTS_N_INSNS (8), /* mulsi_const */
767 COSTS_N_INSNS (8), /* mulsi_const9 */
768 COSTS_N_INSNS (8), /* muldi */
769 COSTS_N_INSNS (22), /* divsi */
770 COSTS_N_INSNS (28), /* divdi */
771 COSTS_N_INSNS (3), /* fp */
772 COSTS_N_INSNS (3), /* dmul */
773 COSTS_N_INSNS (13), /* sdiv */
774 COSTS_N_INSNS (16), /* ddiv */
775 128, /* cache line size */
778 16, /* prefetch streams */
781 /* Instruction costs on POWER7 processors. */
783 struct processor_costs power7_cost = {
784 COSTS_N_INSNS (2), /* mulsi */
785 COSTS_N_INSNS (2), /* mulsi_const */
786 COSTS_N_INSNS (2), /* mulsi_const9 */
787 COSTS_N_INSNS (2), /* muldi */
788 COSTS_N_INSNS (18), /* divsi */
789 COSTS_N_INSNS (34), /* divdi */
790 COSTS_N_INSNS (3), /* fp */
791 COSTS_N_INSNS (3), /* dmul */
792 COSTS_N_INSNS (13), /* sdiv */
793 COSTS_N_INSNS (16), /* ddiv */
794 128, /* cache line size */
797 12, /* prefetch streams */
801 static bool rs6000_function_ok_for_sibcall (tree, tree);
802 static const char *rs6000_invalid_within_doloop (const_rtx);
803 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
804 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
805 static rtx rs6000_generate_compare (rtx, enum machine_mode);
806 static void rs6000_emit_stack_tie (void);
807 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
808 static bool spe_func_has_64bit_regs_p (void);
809 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
811 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
812 static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int, int);
813 static unsigned rs6000_hash_constant (rtx);
814 static unsigned toc_hash_function (const void *);
815 static int toc_hash_eq (const void *, const void *);
816 static bool reg_offset_addressing_ok_p (enum machine_mode);
817 static bool virtual_stack_registers_memory_p (rtx);
818 static bool constant_pool_expr_p (rtx);
819 static bool legitimate_small_data_p (enum machine_mode, rtx);
820 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
821 static struct machine_function * rs6000_init_machine_status (void);
822 static bool rs6000_assemble_integer (rtx, unsigned int, int);
823 static bool no_global_regs_above (int, bool);
824 #ifdef HAVE_GAS_HIDDEN
825 static void rs6000_assemble_visibility (tree, int);
827 static int rs6000_ra_ever_killed (void);
828 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
829 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
830 static bool rs6000_ms_bitfield_layout_p (const_tree);
831 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
832 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
833 static const char *rs6000_mangle_type (const_tree);
834 static void rs6000_set_default_type_attributes (tree);
835 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
836 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
837 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
838 enum machine_mode, bool, bool, bool);
839 static bool rs6000_reg_live_or_pic_offset_p (int);
840 static tree rs6000_builtin_vectorized_function (unsigned int, tree, tree);
841 static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
842 static void rs6000_restore_saved_cr (rtx, int);
843 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
844 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
845 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
847 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
848 static bool rs6000_return_in_memory (const_tree, const_tree);
849 static rtx rs6000_function_value (const_tree, const_tree, bool);
850 static void rs6000_file_start (void);
852 static int rs6000_elf_reloc_rw_mask (void);
853 static void rs6000_elf_asm_out_constructor (rtx, int);
854 static void rs6000_elf_asm_out_destructor (rtx, int);
855 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
856 static void rs6000_elf_asm_init_sections (void);
857 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
858 unsigned HOST_WIDE_INT);
859 static void rs6000_elf_encode_section_info (tree, rtx, int)
862 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
863 static void rs6000_alloc_sdmode_stack_slot (void);
864 static void rs6000_instantiate_decls (void);
866 static void rs6000_xcoff_asm_output_anchor (rtx);
867 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
868 static void rs6000_xcoff_asm_init_sections (void);
869 static int rs6000_xcoff_reloc_rw_mask (void);
870 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
871 static section *rs6000_xcoff_select_section (tree, int,
872 unsigned HOST_WIDE_INT);
873 static void rs6000_xcoff_unique_section (tree, int);
874 static section *rs6000_xcoff_select_rtx_section
875 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
876 static const char * rs6000_xcoff_strip_name_encoding (const char *);
877 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
878 static void rs6000_xcoff_file_start (void);
879 static void rs6000_xcoff_file_end (void);
881 static int rs6000_variable_issue (FILE *, int, rtx, int);
882 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
883 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
884 static int rs6000_debug_address_cost (rtx, bool);
885 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
886 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
887 static void rs6000_sched_init (FILE *, int, int);
888 static bool is_microcoded_insn (rtx);
889 static bool is_nonpipeline_insn (rtx);
890 static bool is_cracked_insn (rtx);
891 static bool is_branch_slot_insn (rtx);
892 static bool is_load_insn (rtx);
893 static rtx get_store_dest (rtx pat);
894 static bool is_store_insn (rtx);
895 static bool set_to_load_agen (rtx,rtx);
896 static bool adjacent_mem_locations (rtx,rtx);
897 static int rs6000_adjust_priority (rtx, int);
898 static int rs6000_issue_rate (void);
899 static bool rs6000_is_costly_dependence (dep_t, int, int);
900 static rtx get_next_active_insn (rtx, rtx);
901 static bool insn_terminates_group_p (rtx , enum group_termination);
902 static bool insn_must_be_first_in_group (rtx);
903 static bool insn_must_be_last_in_group (rtx);
904 static bool is_costly_group (rtx *, rtx);
905 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
906 static int redefine_groups (FILE *, int, rtx, rtx);
907 static int pad_groups (FILE *, int, rtx, rtx);
908 static void rs6000_sched_finish (FILE *, int);
909 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
910 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
911 static int rs6000_use_sched_lookahead (void);
912 static int rs6000_use_sched_lookahead_guard (rtx);
913 static void * rs6000_alloc_sched_context (void);
914 static void rs6000_init_sched_context (void *, bool);
915 static void rs6000_set_sched_context (void *);
916 static void rs6000_free_sched_context (void *);
917 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
918 static tree rs6000_builtin_mask_for_load (void);
919 static tree rs6000_builtin_mul_widen_even (tree);
920 static tree rs6000_builtin_mul_widen_odd (tree);
921 static tree rs6000_builtin_conversion (unsigned int, tree);
922 static tree rs6000_builtin_vec_perm (tree, tree *);
923 static bool rs6000_builtin_support_vector_misalignment (enum
928 static void def_builtin (int, const char *, tree, int);
929 static bool rs6000_vector_alignment_reachable (const_tree, bool);
930 static void rs6000_init_builtins (void);
931 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
932 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
933 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
934 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
935 static void altivec_init_builtins (void);
936 static unsigned builtin_hash_function (const void *);
937 static int builtin_hash_eq (const void *, const void *);
938 static tree builtin_function_type (enum machine_mode, enum machine_mode,
939 enum machine_mode, enum machine_mode,
940 enum rs6000_builtins, const char *name);
941 static void rs6000_common_init_builtins (void);
942 static void rs6000_init_libfuncs (void);
944 static void paired_init_builtins (void);
945 static rtx paired_expand_builtin (tree, rtx, bool *);
946 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
947 static rtx paired_expand_stv_builtin (enum insn_code, tree);
948 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
950 static void enable_mask_for_builtins (struct builtin_description *, int,
951 enum rs6000_builtins,
952 enum rs6000_builtins);
953 static void spe_init_builtins (void);
954 static rtx spe_expand_builtin (tree, rtx, bool *);
955 static rtx spe_expand_stv_builtin (enum insn_code, tree);
956 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
957 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
958 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
959 static rs6000_stack_t *rs6000_stack_info (void);
960 static void debug_stack_info (rs6000_stack_t *);
962 static rtx altivec_expand_builtin (tree, rtx, bool *);
963 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
964 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
965 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
966 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
967 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
968 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
969 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
970 static rtx altivec_expand_vec_set_builtin (tree);
971 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
972 static int get_element_number (tree, tree);
973 static bool rs6000_handle_option (size_t, const char *, int);
974 static void rs6000_parse_tls_size_option (void);
975 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
976 static int first_altivec_reg_to_save (void);
977 static unsigned int compute_vrsave_mask (void);
978 static void compute_save_world_info (rs6000_stack_t *info_ptr);
979 static void is_altivec_return_reg (rtx, void *);
980 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
981 int easy_vector_constant (rtx, enum machine_mode);
982 static rtx rs6000_dwarf_register_span (rtx);
983 static void rs6000_init_dwarf_reg_sizes_extra (tree);
984 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
985 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
986 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
987 static rtx rs6000_delegitimize_address (rtx);
988 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
989 static rtx rs6000_tls_get_addr (void);
990 static rtx rs6000_got_sym (void);
991 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
992 static const char *rs6000_get_some_local_dynamic_name (void);
993 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
994 static rtx rs6000_complex_function_value (enum machine_mode);
995 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
996 enum machine_mode, tree);
997 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
999 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1000 tree, HOST_WIDE_INT);
1001 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1004 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1005 const_tree, HOST_WIDE_INT,
1007 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
1008 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
1009 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1010 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1011 enum machine_mode, tree,
1013 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1015 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1017 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1019 static void macho_branch_islands (void);
1020 static int no_previous_def (tree function_name);
1021 static tree get_prev_label (tree function_name);
1022 static void rs6000_darwin_file_start (void);
1025 static tree rs6000_build_builtin_va_list (void);
1026 static void rs6000_va_start (tree, rtx);
1027 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1028 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1029 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1030 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1031 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1032 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1034 static tree rs6000_stack_protect_fail (void);
1036 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1039 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1042 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1044 = rs6000_legitimize_reload_address;
1046 static bool rs6000_mode_dependent_address (rtx);
1047 static bool rs6000_debug_mode_dependent_address (rtx);
1048 bool (*rs6000_mode_dependent_address_ptr) (rtx)
1049 = rs6000_mode_dependent_address;
1051 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1052 enum machine_mode, rtx);
1053 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1056 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1057 enum machine_mode, rtx)
1058 = rs6000_secondary_reload_class;
1060 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1061 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1063 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1064 = rs6000_preferred_reload_class;
1066 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1069 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1073 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1075 = rs6000_secondary_memory_needed;
1077 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1080 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1084 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1087 = rs6000_cannot_change_mode_class;
1089 static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class,
1091 struct secondary_reload_info *);
1093 static const enum reg_class *rs6000_ira_cover_classes (void);
1095 const int INSN_NOT_AVAILABLE = -1;
1096 static enum machine_mode rs6000_eh_return_filter_mode (void);
1097 static bool rs6000_can_eliminate (const int, const int);
1098 static void rs6000_trampoline_init (rtx, tree, rtx);
1100 /* Hash table stuff for keeping track of TOC entries. */
1102 struct GTY(()) toc_hash_struct
1104 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1105 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1107 enum machine_mode key_mode;
1111 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1113 /* Hash table to keep track of the argument types for builtin functions. */
1115 struct GTY(()) builtin_hash_struct
1118 enum machine_mode mode[4]; /* return value + 3 arguments. */
1119 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1122 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1124 /* Default register names. */
1125 char rs6000_reg_names[][8] =
1127 "0", "1", "2", "3", "4", "5", "6", "7",
1128 "8", "9", "10", "11", "12", "13", "14", "15",
1129 "16", "17", "18", "19", "20", "21", "22", "23",
1130 "24", "25", "26", "27", "28", "29", "30", "31",
1131 "0", "1", "2", "3", "4", "5", "6", "7",
1132 "8", "9", "10", "11", "12", "13", "14", "15",
1133 "16", "17", "18", "19", "20", "21", "22", "23",
1134 "24", "25", "26", "27", "28", "29", "30", "31",
1135 "mq", "lr", "ctr","ap",
1136 "0", "1", "2", "3", "4", "5", "6", "7",
1138 /* AltiVec registers. */
1139 "0", "1", "2", "3", "4", "5", "6", "7",
1140 "8", "9", "10", "11", "12", "13", "14", "15",
1141 "16", "17", "18", "19", "20", "21", "22", "23",
1142 "24", "25", "26", "27", "28", "29", "30", "31",
1144 /* SPE registers. */
1145 "spe_acc", "spefscr",
1146 /* Soft frame pointer. */
1150 #ifdef TARGET_REGNAMES
1151 static const char alt_reg_names[][8] =
1153 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1154 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1155 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1156 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1157 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1158 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1159 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1160 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1161 "mq", "lr", "ctr", "ap",
1162 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1164 /* AltiVec registers. */
1165 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1166 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1167 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1168 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1170 /* SPE registers. */
1171 "spe_acc", "spefscr",
1172 /* Soft frame pointer. */
1177 /* Table of valid machine attributes. */
1179 static const struct attribute_spec rs6000_attribute_table[] =
1181 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1182 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1183 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1184 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1185 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1186 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1187 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1188 SUBTARGET_ATTRIBUTE_TABLE,
1190 { NULL, 0, 0, false, false, false, NULL }
1193 #ifndef MASK_STRICT_ALIGN
1194 #define MASK_STRICT_ALIGN 0
1196 #ifndef TARGET_PROFILE_KERNEL
1197 #define TARGET_PROFILE_KERNEL 0
1198 #define SET_PROFILE_KERNEL(N)
1200 #define SET_PROFILE_KERNEL(N) TARGET_PROFILE_KERNEL = (N)
1203 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1204 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1206 /* Initialize the GCC target structure. */
1207 #undef TARGET_ATTRIBUTE_TABLE
1208 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1209 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1210 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1212 #undef TARGET_ASM_ALIGNED_DI_OP
1213 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1215 /* Default unaligned ops are only provided for ELF. Find the ops needed
1216 for non-ELF systems. */
1217 #ifndef OBJECT_FORMAT_ELF
1219 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1221 #undef TARGET_ASM_UNALIGNED_HI_OP
1222 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1223 #undef TARGET_ASM_UNALIGNED_SI_OP
1224 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1225 #undef TARGET_ASM_UNALIGNED_DI_OP
1226 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1229 #undef TARGET_ASM_UNALIGNED_HI_OP
1230 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1231 #undef TARGET_ASM_UNALIGNED_SI_OP
1232 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1233 #undef TARGET_ASM_UNALIGNED_DI_OP
1234 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1235 #undef TARGET_ASM_ALIGNED_DI_OP
1236 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1240 /* This hook deals with fixups for relocatable code and DI-mode objects
1242 #undef TARGET_ASM_INTEGER
1243 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1245 #ifdef HAVE_GAS_HIDDEN
1246 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1247 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1250 #undef TARGET_HAVE_TLS
1251 #define TARGET_HAVE_TLS HAVE_AS_TLS
1253 #undef TARGET_CANNOT_FORCE_CONST_MEM
1254 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1256 #undef TARGET_ASM_FUNCTION_PROLOGUE
1257 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1258 #undef TARGET_ASM_FUNCTION_EPILOGUE
1259 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1261 #undef TARGET_LEGITIMIZE_ADDRESS
1262 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1264 #undef TARGET_SCHED_VARIABLE_ISSUE
1265 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1267 #undef TARGET_SCHED_ISSUE_RATE
1268 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1269 #undef TARGET_SCHED_ADJUST_COST
1270 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1271 #undef TARGET_SCHED_ADJUST_PRIORITY
1272 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1273 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1274 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1275 #undef TARGET_SCHED_INIT
1276 #define TARGET_SCHED_INIT rs6000_sched_init
1277 #undef TARGET_SCHED_FINISH
1278 #define TARGET_SCHED_FINISH rs6000_sched_finish
1279 #undef TARGET_SCHED_REORDER
1280 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1281 #undef TARGET_SCHED_REORDER2
1282 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1284 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1285 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1287 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1288 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1290 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1291 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1292 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1293 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1294 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1295 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1296 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1297 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1299 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1300 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1301 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1302 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1303 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1304 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1305 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1306 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1307 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1308 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1309 #undef TARGET_SUPPORT_VECTOR_MISALIGNMENT
1310 #define TARGET_SUPPORT_VECTOR_MISALIGNMENT \
1311 rs6000_builtin_support_vector_misalignment
1312 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1313 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1315 #undef TARGET_INIT_BUILTINS
1316 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1318 #undef TARGET_EXPAND_BUILTIN
1319 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1321 #undef TARGET_MANGLE_TYPE
1322 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1324 #undef TARGET_INIT_LIBFUNCS
1325 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1328 #undef TARGET_BINDS_LOCAL_P
1329 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1332 #undef TARGET_MS_BITFIELD_LAYOUT_P
1333 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1335 #undef TARGET_ASM_OUTPUT_MI_THUNK
1336 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1338 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1339 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1341 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1342 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1344 #undef TARGET_INVALID_WITHIN_DOLOOP
1345 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1347 #undef TARGET_RTX_COSTS
1348 #define TARGET_RTX_COSTS rs6000_rtx_costs
1349 #undef TARGET_ADDRESS_COST
1350 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1352 #undef TARGET_DWARF_REGISTER_SPAN
1353 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1355 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1356 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1358 /* On rs6000, function arguments are promoted, as are function return
1360 #undef TARGET_PROMOTE_FUNCTION_MODE
1361 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1363 #undef TARGET_RETURN_IN_MEMORY
1364 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1366 #undef TARGET_SETUP_INCOMING_VARARGS
1367 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1369 /* Always strict argument naming on rs6000. */
1370 #undef TARGET_STRICT_ARGUMENT_NAMING
1371 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1372 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1373 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1374 #undef TARGET_SPLIT_COMPLEX_ARG
1375 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1376 #undef TARGET_MUST_PASS_IN_STACK
1377 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1378 #undef TARGET_PASS_BY_REFERENCE
1379 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1380 #undef TARGET_ARG_PARTIAL_BYTES
1381 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1383 #undef TARGET_BUILD_BUILTIN_VA_LIST
1384 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1386 #undef TARGET_EXPAND_BUILTIN_VA_START
1387 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1389 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1390 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1392 #undef TARGET_EH_RETURN_FILTER_MODE
1393 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1395 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1396 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1398 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1399 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1401 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1402 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1404 #undef TARGET_HANDLE_OPTION
1405 #define TARGET_HANDLE_OPTION rs6000_handle_option
1407 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1408 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1409 rs6000_builtin_vectorized_function
1411 #undef TARGET_DEFAULT_TARGET_FLAGS
1412 #define TARGET_DEFAULT_TARGET_FLAGS \
1415 #undef TARGET_STACK_PROTECT_FAIL
1416 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1418 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1419 The PowerPC architecture requires only weak consistency among
1420 processors--that is, memory accesses between processors need not be
1421 sequentially consistent and memory accesses among processors can occur
1422 in any order. The ability to order memory accesses weakly provides
1423 opportunities for more efficient use of the system bus. Unless a
1424 dependency exists, the 604e allows read operations to precede store
1426 #undef TARGET_RELAXED_ORDERING
1427 #define TARGET_RELAXED_ORDERING true
1430 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1431 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1434 /* Use a 32-bit anchor range. This leads to sequences like:
1436 addis tmp,anchor,high
1439 where tmp itself acts as an anchor, and can be shared between
1440 accesses to the same 64k page. */
1441 #undef TARGET_MIN_ANCHOR_OFFSET
1442 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1443 #undef TARGET_MAX_ANCHOR_OFFSET
1444 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1445 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1446 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1448 #undef TARGET_DELEGITIMIZE_ADDRESS
1449 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1451 #undef TARGET_BUILTIN_RECIPROCAL
1452 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1454 #undef TARGET_EXPAND_TO_RTL_HOOK
1455 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1457 #undef TARGET_INSTANTIATE_DECLS
1458 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1460 #undef TARGET_SECONDARY_RELOAD
1461 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1463 #undef TARGET_IRA_COVER_CLASSES
1464 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1466 #undef TARGET_LEGITIMATE_ADDRESS_P
1467 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1469 #undef TARGET_CAN_ELIMINATE
1470 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1472 #undef TARGET_TRAMPOLINE_INIT
1473 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1475 #undef TARGET_FUNCTION_VALUE
1476 #define TARGET_FUNCTION_VALUE rs6000_function_value
1478 struct gcc_target targetm = TARGET_INITIALIZER;
1480 /* Return number of consecutive hard regs needed starting at reg REGNO
1481 to hold something of mode MODE.
1482 This is ordinarily the length in words of a value of mode MODE
1483 but can be less for certain modes in special long registers.
1485 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1486 scalar instructions. The upper 32 bits are only available to the
1489 POWER and PowerPC GPRs hold 32 bits worth;
1490 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1493 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1495 unsigned HOST_WIDE_INT reg_size;
1497 if (FP_REGNO_P (regno))
1498 reg_size = (VECTOR_MEM_VSX_P (mode)
1499 ? UNITS_PER_VSX_WORD
1500 : UNITS_PER_FP_WORD);
1502 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1503 reg_size = UNITS_PER_SPE_WORD;
1505 else if (ALTIVEC_REGNO_P (regno))
1506 reg_size = UNITS_PER_ALTIVEC_WORD;
1508 /* The value returned for SCmode in the E500 double case is 2 for
1509 ABI compatibility; storing an SCmode value in a single register
1510 would require function_arg and rs6000_spe_function_arg to handle
1511 SCmode so as to pass the value correctly in a pair of
1513 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1514 && !DECIMAL_FLOAT_MODE_P (mode))
1515 reg_size = UNITS_PER_FP_WORD;
1518 reg_size = UNITS_PER_WORD;
1520 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1523 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1526 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1528 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1530 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1531 implementations. Don't allow an item to be split between a FP register
1532 and an Altivec register. */
1533 if (VECTOR_MEM_VSX_P (mode))
1535 if (FP_REGNO_P (regno))
1536 return FP_REGNO_P (last_regno);
1538 if (ALTIVEC_REGNO_P (regno))
1539 return ALTIVEC_REGNO_P (last_regno);
1542 /* The GPRs can hold any mode, but values bigger than one register
1543 cannot go past R31. */
1544 if (INT_REGNO_P (regno))
1545 return INT_REGNO_P (last_regno);
1547 /* The float registers (except for VSX vector modes) can only hold floating
1548 modes and DImode. This excludes the 32-bit decimal float mode for
1550 if (FP_REGNO_P (regno))
1552 if (SCALAR_FLOAT_MODE_P (mode)
1553 && (mode != TDmode || (regno % 2) == 0)
1554 && FP_REGNO_P (last_regno))
1557 if (GET_MODE_CLASS (mode) == MODE_INT
1558 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1561 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1562 && PAIRED_VECTOR_MODE (mode))
1568 /* The CR register can only hold CC modes. */
1569 if (CR_REGNO_P (regno))
1570 return GET_MODE_CLASS (mode) == MODE_CC;
1572 if (XER_REGNO_P (regno))
1573 return mode == PSImode;
1575 /* AltiVec only in AldyVec registers. */
1576 if (ALTIVEC_REGNO_P (regno))
1577 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1579 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1580 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1583 /* We cannot put TImode anywhere except general register and it must be able
1584 to fit within the register set. In the future, allow TImode in the
1585 Altivec or VSX registers. */
1587 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1590 /* Print interesting facts about registers. */
1592 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1596 for (r = first_regno; r <= last_regno; ++r)
1598 const char *comma = "";
1601 if (first_regno == last_regno)
1602 fprintf (stderr, "%s:\t", reg_name);
1604 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1607 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1608 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1612 fprintf (stderr, ",\n\t");
1617 if (rs6000_hard_regno_nregs[m][r] > 1)
1618 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1619 rs6000_hard_regno_nregs[m][r]);
1621 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1626 if (call_used_regs[r])
1630 fprintf (stderr, ",\n\t");
1635 len += fprintf (stderr, "%s%s", comma, "call-used");
1643 fprintf (stderr, ",\n\t");
1648 len += fprintf (stderr, "%s%s", comma, "fixed");
1654 fprintf (stderr, ",\n\t");
1658 fprintf (stderr, "%sregno = %d\n", comma, r);
1662 /* Print various interesting information with -mdebug=reg. */
1664 rs6000_debug_reg_global (void)
1666 const char *nl = (const char *)0;
1668 char costly_num[20];
1670 const char *costly_str;
1671 const char *nop_str;
1673 /* Map enum rs6000_vector to string. */
1674 static const char *rs6000_debug_vector_unit[] = {
1683 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1684 LAST_VIRTUAL_REGISTER);
1685 rs6000_debug_reg_print (0, 31, "gr");
1686 rs6000_debug_reg_print (32, 63, "fp");
1687 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1690 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1691 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1692 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1693 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1694 rs6000_debug_reg_print (XER_REGNO, XER_REGNO, "xer");
1695 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1696 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1697 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1698 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1702 "d reg_class = %s\n"
1703 "f reg_class = %s\n"
1704 "v reg_class = %s\n"
1705 "wa reg_class = %s\n"
1706 "wd reg_class = %s\n"
1707 "wf reg_class = %s\n"
1708 "ws reg_class = %s\n\n",
1709 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1710 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1711 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1712 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1713 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1714 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1715 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1717 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1718 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1721 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1723 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1724 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1730 switch (rs6000_sched_costly_dep)
1732 case max_dep_latency:
1733 costly_str = "max_dep_latency";
1737 costly_str = "no_dep_costly";
1740 case all_deps_costly:
1741 costly_str = "all_deps_costly";
1744 case true_store_to_load_dep_costly:
1745 costly_str = "true_store_to_load_dep_costly";
1748 case store_to_load_dep_costly:
1749 costly_str = "store_to_load_dep_costly";
1753 costly_str = costly_num;
1754 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1758 switch (rs6000_sched_insert_nops)
1760 case sched_finish_regroup_exact:
1761 nop_str = "sched_finish_regroup_exact";
1764 case sched_finish_pad_groups:
1765 nop_str = "sched_finish_pad_groups";
1768 case sched_finish_none:
1769 nop_str = "sched_finish_none";
1774 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1779 "always_hint = %s\n"
1780 "align_branch_targets = %s\n"
1781 "sched_restricted_insns_priority = %d\n"
1782 "sched_costly_dep = %s\n"
1783 "sched_insert_nops = %s\n\n",
1784 rs6000_always_hint ? "true" : "false",
1785 rs6000_align_branch_targets ? "true" : "false",
1786 (int)rs6000_sched_restricted_insns_priority,
1787 costly_str, nop_str);
1790 /* Initialize the various global tables that are based on register size. */
1792 rs6000_init_hard_regno_mode_ok (void)
1798 /* Precalculate REGNO_REG_CLASS. */
1799 rs6000_regno_regclass[0] = GENERAL_REGS;
1800 for (r = 1; r < 32; ++r)
1801 rs6000_regno_regclass[r] = BASE_REGS;
1803 for (r = 32; r < 64; ++r)
1804 rs6000_regno_regclass[r] = FLOAT_REGS;
1806 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1807 rs6000_regno_regclass[r] = NO_REGS;
1809 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
1810 rs6000_regno_regclass[r] = ALTIVEC_REGS;
1812 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
1813 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
1814 rs6000_regno_regclass[r] = CR_REGS;
1816 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
1817 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
1818 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
1819 rs6000_regno_regclass[XER_REGNO] = XER_REGS;
1820 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
1821 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
1822 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
1823 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
1824 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
1825 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
1827 /* Precalculate vector information, this must be set up before the
1828 rs6000_hard_regno_nregs_internal below. */
1829 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1831 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
1832 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
1833 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
1836 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
1837 rs6000_constraints[c] = NO_REGS;
1839 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
1840 believes it can use native alignment or still uses 128-bit alignment. */
1841 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
1852 /* V2DF mode, VSX only. */
1855 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
1856 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
1857 rs6000_vector_align[V2DFmode] = align64;
1860 /* V4SF mode, either VSX or Altivec. */
1863 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
1864 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
1865 rs6000_vector_align[V4SFmode] = align32;
1867 else if (TARGET_ALTIVEC)
1869 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
1870 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
1871 rs6000_vector_align[V4SFmode] = align32;
1874 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
1878 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
1879 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
1880 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
1881 rs6000_vector_align[V4SImode] = align32;
1882 rs6000_vector_align[V8HImode] = align32;
1883 rs6000_vector_align[V16QImode] = align32;
1887 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
1888 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
1889 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
1893 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
1894 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
1895 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
1899 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
1900 Altivec doesn't have 64-bit support. */
1903 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
1904 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
1905 rs6000_vector_align[V2DImode] = align64;
1908 /* DFmode, see if we want to use the VSX unit. */
1909 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
1911 rs6000_vector_unit[DFmode] = VECTOR_VSX;
1912 rs6000_vector_mem[DFmode]
1913 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
1914 rs6000_vector_align[DFmode] = align64;
1917 /* TODO add SPE and paired floating point vector support. */
1919 /* Register class constaints for the constraints that depend on compile
1921 if (TARGET_HARD_FLOAT && TARGET_FPRS)
1922 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
1924 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
1925 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
1929 /* At present, we just use VSX_REGS, but we have different constraints
1930 based on the use, in case we want to fine tune the default register
1931 class used. wa = any VSX register, wf = register class to use for
1932 V4SF, wd = register class to use for V2DF, and ws = register classs to
1933 use for DF scalars. */
1934 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
1935 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
1936 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
1937 if (TARGET_VSX_SCALAR_DOUBLE)
1938 rs6000_constraints[RS6000_CONSTRAINT_ws] = VSX_REGS;
1942 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
1944 /* Set up the reload helper functions. */
1945 if (TARGET_VSX || TARGET_ALTIVEC)
1949 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
1950 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
1951 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
1952 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
1953 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
1954 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
1955 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
1956 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
1957 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
1958 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
1959 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
1960 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
1964 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
1965 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
1966 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
1967 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
1968 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
1969 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
1970 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
1971 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
1972 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
1973 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
1974 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
1975 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
1979 /* Precalculate HARD_REGNO_NREGS. */
1980 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
1981 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1982 rs6000_hard_regno_nregs[m][r]
1983 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
1985 /* Precalculate HARD_REGNO_MODE_OK. */
1986 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
1987 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1988 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
1989 rs6000_hard_regno_mode_ok_p[m][r] = true;
1991 /* Precalculate CLASS_MAX_NREGS sizes. */
1992 for (c = 0; c < LIM_REG_CLASSES; ++c)
1996 if (TARGET_VSX && VSX_REG_CLASS_P (c))
1997 reg_size = UNITS_PER_VSX_WORD;
1999 else if (c == ALTIVEC_REGS)
2000 reg_size = UNITS_PER_ALTIVEC_WORD;
2002 else if (c == FLOAT_REGS)
2003 reg_size = UNITS_PER_FP_WORD;
2006 reg_size = UNITS_PER_WORD;
2008 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2009 rs6000_class_max_nregs[m][c]
2010 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2013 if (TARGET_E500_DOUBLE)
2014 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2016 if (TARGET_DEBUG_REG)
2017 rs6000_debug_reg_global ();
2021 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2024 darwin_rs6000_override_options (void)
2026 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2028 rs6000_altivec_abi = 1;
2029 TARGET_ALTIVEC_VRSAVE = 1;
2030 if (DEFAULT_ABI == ABI_DARWIN)
2032 if (MACHO_DYNAMIC_NO_PIC_P)
2035 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2038 else if (flag_pic == 1)
2043 if (TARGET_64BIT && ! TARGET_POWERPC64)
2045 target_flags |= MASK_POWERPC64;
2046 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2050 rs6000_default_long_calls = 1;
2051 target_flags |= MASK_SOFT_FLOAT;
2054 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2056 if (!flag_mkernel && !flag_apple_kext
2058 && ! (target_flags_explicit & MASK_ALTIVEC))
2059 target_flags |= MASK_ALTIVEC;
2061 /* Unless the user (not the configurer) has explicitly overridden
2062 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2063 G4 unless targetting the kernel. */
2066 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2067 && ! (target_flags_explicit & MASK_ALTIVEC)
2068 && ! rs6000_select[1].string)
2070 target_flags |= MASK_ALTIVEC;
2075 /* If not otherwise specified by a target, make 'long double' equivalent to
2078 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2079 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2082 /* Override command line options. Mostly we process the processor
2083 type and sometimes adjust other TARGET_ options. */
2086 rs6000_override_options (const char *default_cpu)
2089 struct rs6000_cpu_select *ptr;
2092 /* Simplifications for entries below. */
2095 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2096 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2099 /* This table occasionally claims that a processor does not support
2100 a particular feature even though it does, but the feature is slower
2101 than the alternative. Thus, it shouldn't be relied on as a
2102 complete description of the processor's support.
2104 Please keep this list in order, and don't forget to update the
2105 documentation in invoke.texi when adding a new processor or
2109 const char *const name; /* Canonical processor name. */
2110 const enum processor_type processor; /* Processor type enum value. */
2111 const int target_enable; /* Target flags to enable. */
2112 } const processor_target_table[]
2113 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2114 {"403", PROCESSOR_PPC403,
2115 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2116 {"405", PROCESSOR_PPC405,
2117 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2118 {"405fp", PROCESSOR_PPC405,
2119 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2120 {"440", PROCESSOR_PPC440,
2121 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2122 {"440fp", PROCESSOR_PPC440,
2123 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2124 {"464", PROCESSOR_PPC440,
2125 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2126 {"464fp", PROCESSOR_PPC440,
2127 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2128 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2129 {"601", PROCESSOR_PPC601,
2130 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2131 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2132 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2133 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2134 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2135 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2136 {"620", PROCESSOR_PPC620,
2137 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2138 {"630", PROCESSOR_PPC630,
2139 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2140 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2141 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2142 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2143 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2144 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2145 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2146 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2147 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2149 /* 8548 has a dummy entry for now. */
2150 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2152 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2153 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2154 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2156 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2157 {"970", PROCESSOR_POWER4,
2158 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2159 {"cell", PROCESSOR_CELL,
2160 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2161 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2162 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2163 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2164 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2165 {"G5", PROCESSOR_POWER4,
2166 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2167 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2168 {"power2", PROCESSOR_POWER,
2169 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2170 {"power3", PROCESSOR_PPC630,
2171 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2172 {"power4", PROCESSOR_POWER4,
2173 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2175 {"power5", PROCESSOR_POWER5,
2176 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2177 | MASK_MFCRF | MASK_POPCNTB},
2178 {"power5+", PROCESSOR_POWER5,
2179 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2180 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2181 {"power6", PROCESSOR_POWER6,
2182 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2183 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP},
2184 {"power6x", PROCESSOR_POWER6,
2185 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2186 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2188 {"power7", PROCESSOR_POWER7,
2189 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2190 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2191 | MASK_VSX}, /* Don't add MASK_ISEL by default */
2192 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2193 {"powerpc64", PROCESSOR_POWERPC64,
2194 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2195 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2196 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2197 {"rios2", PROCESSOR_RIOS2,
2198 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2199 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2200 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2201 {"rs64", PROCESSOR_RS64A,
2202 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2205 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2207 /* Some OSs don't support saving the high part of 64-bit registers on
2208 context switch. Other OSs don't support saving Altivec registers.
2209 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2210 settings; if the user wants either, the user must explicitly specify
2211 them and we won't interfere with the user's specification. */
2214 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2215 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2216 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2217 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2218 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2219 | MASK_POPCNTD | MASK_VSX | MASK_ISEL)
2222 /* Set the pointer size. */
2225 rs6000_pmode = (int)DImode;
2226 rs6000_pointer_size = 64;
2230 rs6000_pmode = (int)SImode;
2231 rs6000_pointer_size = 32;
2234 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2235 #ifdef OS_MISSING_POWERPC64
2236 if (OS_MISSING_POWERPC64)
2237 set_masks &= ~MASK_POWERPC64;
2239 #ifdef OS_MISSING_ALTIVEC
2240 if (OS_MISSING_ALTIVEC)
2241 set_masks &= ~MASK_ALTIVEC;
2244 /* Don't override by the processor default if given explicitly. */
2245 set_masks &= ~target_flags_explicit;
2247 /* Identify the processor type. */
2248 rs6000_select[0].string = default_cpu;
2249 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2251 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2253 ptr = &rs6000_select[i];
2254 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2256 for (j = 0; j < ptt_size; j++)
2257 if (! strcmp (ptr->string, processor_target_table[j].name))
2259 if (ptr->set_tune_p)
2260 rs6000_cpu = processor_target_table[j].processor;
2262 if (ptr->set_arch_p)
2264 target_flags &= ~set_masks;
2265 target_flags |= (processor_target_table[j].target_enable
2272 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2276 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2277 || rs6000_cpu == PROCESSOR_PPCE500MC)
2280 error ("AltiVec not supported in this target");
2282 error ("Spe not supported in this target");
2285 /* Disable Cell microcode if we are optimizing for the Cell
2286 and not optimizing for size. */
2287 if (rs6000_gen_cell_microcode == -1)
2288 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2291 /* If we are optimizing big endian systems for space, use the load/store
2292 multiple and string instructions unless we are not generating
2294 if (BYTES_BIG_ENDIAN && optimize_size && !rs6000_gen_cell_microcode)
2295 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2297 /* Don't allow -mmultiple or -mstring on little endian systems
2298 unless the cpu is a 750, because the hardware doesn't support the
2299 instructions used in little endian mode, and causes an alignment
2300 trap. The 750 does not cause an alignment trap (except when the
2301 target is unaligned). */
2303 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2305 if (TARGET_MULTIPLE)
2307 target_flags &= ~MASK_MULTIPLE;
2308 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2309 warning (0, "-mmultiple is not supported on little endian systems");
2314 target_flags &= ~MASK_STRING;
2315 if ((target_flags_explicit & MASK_STRING) != 0)
2316 warning (0, "-mstring is not supported on little endian systems");
2320 /* Add some warnings for VSX. Enable -maltivec unless the user explicitly
2321 used -mno-altivec */
2324 const char *msg = NULL;
2325 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2326 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2328 if (target_flags_explicit & MASK_VSX)
2329 msg = N_("-mvsx requires hardware floating point");
2331 target_flags &= ~ MASK_VSX;
2333 else if (TARGET_PAIRED_FLOAT)
2334 msg = N_("-mvsx and -mpaired are incompatible");
2335 /* The hardware will allow VSX and little endian, but until we make sure
2336 things like vector select, etc. work don't allow VSX on little endian
2337 systems at this point. */
2338 else if (!BYTES_BIG_ENDIAN)
2339 msg = N_("-mvsx used with little endian code");
2340 else if (TARGET_AVOID_XFORM > 0)
2341 msg = N_("-mvsx needs indexed addressing");
2346 target_flags &= ~ MASK_VSX;
2348 else if (TARGET_VSX && !TARGET_ALTIVEC
2349 && (target_flags_explicit & MASK_ALTIVEC) == 0)
2350 target_flags |= MASK_ALTIVEC;
2353 /* Set debug flags */
2354 if (rs6000_debug_name)
2356 if (! strcmp (rs6000_debug_name, "all"))
2357 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2358 = rs6000_debug_addr = rs6000_debug_cost = 1;
2359 else if (! strcmp (rs6000_debug_name, "stack"))
2360 rs6000_debug_stack = 1;
2361 else if (! strcmp (rs6000_debug_name, "arg"))
2362 rs6000_debug_arg = 1;
2363 else if (! strcmp (rs6000_debug_name, "reg"))
2364 rs6000_debug_reg = 1;
2365 else if (! strcmp (rs6000_debug_name, "addr"))
2366 rs6000_debug_addr = 1;
2367 else if (! strcmp (rs6000_debug_name, "cost"))
2368 rs6000_debug_cost = 1;
2370 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2372 /* If the appropriate debug option is enabled, replace the target hooks
2373 with debug versions that call the real version and then prints
2374 debugging information. */
2375 if (TARGET_DEBUG_COST)
2377 targetm.rtx_costs = rs6000_debug_rtx_costs;
2378 targetm.address_cost = rs6000_debug_address_cost;
2379 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2382 if (TARGET_DEBUG_ADDR)
2384 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2385 targetm.legitimize_address = rs6000_debug_legitimize_address;
2386 rs6000_secondary_reload_class_ptr
2387 = rs6000_debug_secondary_reload_class;
2388 rs6000_secondary_memory_needed_ptr
2389 = rs6000_debug_secondary_memory_needed;
2390 rs6000_cannot_change_mode_class_ptr
2391 = rs6000_debug_cannot_change_mode_class;
2392 rs6000_preferred_reload_class_ptr
2393 = rs6000_debug_preferred_reload_class;
2394 rs6000_legitimize_reload_address_ptr
2395 = rs6000_debug_legitimize_reload_address;
2396 rs6000_mode_dependent_address_ptr
2397 = rs6000_debug_mode_dependent_address;
2401 if (rs6000_traceback_name)
2403 if (! strncmp (rs6000_traceback_name, "full", 4))
2404 rs6000_traceback = traceback_full;
2405 else if (! strncmp (rs6000_traceback_name, "part", 4))
2406 rs6000_traceback = traceback_part;
2407 else if (! strncmp (rs6000_traceback_name, "no", 2))
2408 rs6000_traceback = traceback_none;
2410 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2411 rs6000_traceback_name);
2414 if (!rs6000_explicit_options.long_double)
2415 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2417 #ifndef POWERPC_LINUX
2418 if (!rs6000_explicit_options.ieee)
2419 rs6000_ieeequad = 1;
2422 /* Enable Altivec ABI for AIX -maltivec. */
2423 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2424 rs6000_altivec_abi = 1;
2426 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2427 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2428 be explicitly overridden in either case. */
2431 if (!rs6000_explicit_options.altivec_abi
2432 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2433 rs6000_altivec_abi = 1;
2435 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2436 if (!rs6000_explicit_options.vrsave)
2437 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2440 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2441 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2443 rs6000_darwin64_abi = 1;
2445 darwin_one_byte_bool = 1;
2447 /* Default to natural alignment, for better performance. */
2448 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2451 /* Place FP constants in the constant pool instead of TOC
2452 if section anchors enabled. */
2453 if (flag_section_anchors)
2454 TARGET_NO_FP_IN_TOC = 1;
2456 /* Handle -mtls-size option. */
2457 rs6000_parse_tls_size_option ();
2459 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2460 SUBTARGET_OVERRIDE_OPTIONS;
2462 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2463 SUBSUBTARGET_OVERRIDE_OPTIONS;
2465 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2466 SUB3TARGET_OVERRIDE_OPTIONS;
2469 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC)
2471 /* The e500 and e500mc do not have string instructions, and we set
2472 MASK_STRING above when optimizing for size. */
2473 if ((target_flags & MASK_STRING) != 0)
2474 target_flags = target_flags & ~MASK_STRING;
2476 else if (rs6000_select[1].string != NULL)
2478 /* For the powerpc-eabispe configuration, we set all these by
2479 default, so let's unset them if we manually set another
2480 CPU that is not the E500. */
2481 if (!rs6000_explicit_options.spe_abi)
2483 if (!rs6000_explicit_options.spe)
2485 if (!rs6000_explicit_options.float_gprs)
2486 rs6000_float_gprs = 0;
2487 if (!(target_flags_explicit & MASK_ISEL))
2488 target_flags &= ~MASK_ISEL;
2491 /* Detect invalid option combinations with E500. */
2494 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2495 && rs6000_cpu != PROCESSOR_POWER5
2496 && rs6000_cpu != PROCESSOR_POWER6
2497 && rs6000_cpu != PROCESSOR_POWER7
2498 && rs6000_cpu != PROCESSOR_CELL);
2499 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2500 || rs6000_cpu == PROCESSOR_POWER5
2501 || rs6000_cpu == PROCESSOR_POWER7);
2502 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2503 || rs6000_cpu == PROCESSOR_POWER5
2504 || rs6000_cpu == PROCESSOR_POWER6
2505 || rs6000_cpu == PROCESSOR_POWER7);
2507 /* Allow debug switches to override the above settings. */
2508 if (TARGET_ALWAYS_HINT > 0)
2509 rs6000_always_hint = TARGET_ALWAYS_HINT;
2511 if (TARGET_SCHED_GROUPS > 0)
2512 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2514 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2515 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2517 rs6000_sched_restricted_insns_priority
2518 = (rs6000_sched_groups ? 1 : 0);
2520 /* Handle -msched-costly-dep option. */
2521 rs6000_sched_costly_dep
2522 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2524 if (rs6000_sched_costly_dep_str)
2526 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2527 rs6000_sched_costly_dep = no_dep_costly;
2528 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2529 rs6000_sched_costly_dep = all_deps_costly;
2530 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2531 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2532 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2533 rs6000_sched_costly_dep = store_to_load_dep_costly;
2535 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2536 atoi (rs6000_sched_costly_dep_str));
2539 /* Handle -minsert-sched-nops option. */
2540 rs6000_sched_insert_nops
2541 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2543 if (rs6000_sched_insert_nops_str)
2545 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2546 rs6000_sched_insert_nops = sched_finish_none;
2547 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2548 rs6000_sched_insert_nops = sched_finish_pad_groups;
2549 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2550 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2552 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2553 atoi (rs6000_sched_insert_nops_str));
2556 #ifdef TARGET_REGNAMES
2557 /* If the user desires alternate register names, copy in the
2558 alternate names now. */
2559 if (TARGET_REGNAMES)
2560 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2563 /* Set aix_struct_return last, after the ABI is determined.
2564 If -maix-struct-return or -msvr4-struct-return was explicitly
2565 used, don't override with the ABI default. */
2566 if (!rs6000_explicit_options.aix_struct_ret)
2567 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2569 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2570 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2573 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2575 /* We can only guarantee the availability of DI pseudo-ops when
2576 assembling for 64-bit targets. */
2579 targetm.asm_out.aligned_op.di = NULL;
2580 targetm.asm_out.unaligned_op.di = NULL;
2583 /* Set branch target alignment, if not optimizing for size. */
2586 /* Cell wants to be aligned 8byte for dual issue. */
2587 if (rs6000_cpu == PROCESSOR_CELL)
2589 if (align_functions <= 0)
2590 align_functions = 8;
2591 if (align_jumps <= 0)
2593 if (align_loops <= 0)
2596 if (rs6000_align_branch_targets)
2598 if (align_functions <= 0)
2599 align_functions = 16;
2600 if (align_jumps <= 0)
2602 if (align_loops <= 0)
2605 if (align_jumps_max_skip <= 0)
2606 align_jumps_max_skip = 15;
2607 if (align_loops_max_skip <= 0)
2608 align_loops_max_skip = 15;
2611 /* Arrange to save and restore machine status around nested functions. */
2612 init_machine_status = rs6000_init_machine_status;
2614 /* We should always be splitting complex arguments, but we can't break
2615 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2616 if (DEFAULT_ABI != ABI_AIX)
2617 targetm.calls.split_complex_arg = NULL;
2619 /* Initialize rs6000_cost with the appropriate target costs. */
2621 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2625 case PROCESSOR_RIOS1:
2626 rs6000_cost = &rios1_cost;
2629 case PROCESSOR_RIOS2:
2630 rs6000_cost = &rios2_cost;
2633 case PROCESSOR_RS64A:
2634 rs6000_cost = &rs64a_cost;
2637 case PROCESSOR_MPCCORE:
2638 rs6000_cost = &mpccore_cost;
2641 case PROCESSOR_PPC403:
2642 rs6000_cost = &ppc403_cost;
2645 case PROCESSOR_PPC405:
2646 rs6000_cost = &ppc405_cost;
2649 case PROCESSOR_PPC440:
2650 rs6000_cost = &ppc440_cost;
2653 case PROCESSOR_PPC601:
2654 rs6000_cost = &ppc601_cost;
2657 case PROCESSOR_PPC603:
2658 rs6000_cost = &ppc603_cost;
2661 case PROCESSOR_PPC604:
2662 rs6000_cost = &ppc604_cost;
2665 case PROCESSOR_PPC604e:
2666 rs6000_cost = &ppc604e_cost;
2669 case PROCESSOR_PPC620:
2670 rs6000_cost = &ppc620_cost;
2673 case PROCESSOR_PPC630:
2674 rs6000_cost = &ppc630_cost;
2677 case PROCESSOR_CELL:
2678 rs6000_cost = &ppccell_cost;
2681 case PROCESSOR_PPC750:
2682 case PROCESSOR_PPC7400:
2683 rs6000_cost = &ppc750_cost;
2686 case PROCESSOR_PPC7450:
2687 rs6000_cost = &ppc7450_cost;
2690 case PROCESSOR_PPC8540:
2691 rs6000_cost = &ppc8540_cost;
2694 case PROCESSOR_PPCE300C2:
2695 case PROCESSOR_PPCE300C3:
2696 rs6000_cost = &ppce300c2c3_cost;
2699 case PROCESSOR_PPCE500MC:
2700 rs6000_cost = &ppce500mc_cost;
2703 case PROCESSOR_POWER4:
2704 case PROCESSOR_POWER5:
2705 rs6000_cost = &power4_cost;
2708 case PROCESSOR_POWER6:
2709 rs6000_cost = &power6_cost;
2712 case PROCESSOR_POWER7:
2713 rs6000_cost = &power7_cost;
2720 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
2721 set_param_value ("simultaneous-prefetches",
2722 rs6000_cost->simultaneous_prefetches);
2723 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
2724 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
2725 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
2726 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
2727 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
2728 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
2730 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
2731 can be optimized to ap = __builtin_next_arg (0). */
2732 if (DEFAULT_ABI != ABI_V4)
2733 targetm.expand_builtin_va_start = NULL;
2735 /* Set up single/double float flags.
2736 If TARGET_HARD_FLOAT is set, but neither single or double is set,
2737 then set both flags. */
2738 if (TARGET_HARD_FLOAT && TARGET_FPRS
2739 && rs6000_single_float == 0 && rs6000_double_float == 0)
2740 rs6000_single_float = rs6000_double_float = 1;
2742 /* Reset single and double FP flags if target is E500. */
2745 rs6000_single_float = rs6000_double_float = 0;
2746 if (TARGET_E500_SINGLE)
2747 rs6000_single_float = 1;
2748 if (TARGET_E500_DOUBLE)
2749 rs6000_single_float = rs6000_double_float = 1;
2752 /* If not explicitly specified via option, decide whether to generate indexed
2753 load/store instructions. */
2754 if (TARGET_AVOID_XFORM == -1)
2755 /* Avoid indexed addressing when targeting Power6 in order to avoid
2756 the DERAT mispredict penalty. */
2757 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
2759 rs6000_init_hard_regno_mode_ok ();
2762 /* Implement targetm.vectorize.builtin_mask_for_load. */
2764 rs6000_builtin_mask_for_load (void)
2766 if (TARGET_ALTIVEC || TARGET_VSX)
2767 return altivec_builtin_mask_for_load;
2772 /* Implement targetm.vectorize.builtin_conversion.
2773 Returns a decl of a function that implements conversion of an integer vector
2774 into a floating-point vector, or vice-versa. TYPE is the type of the integer
2775 side of the conversion.
2776 Return NULL_TREE if it is not available. */
2778 rs6000_builtin_conversion (unsigned int tcode, tree type)
2780 enum tree_code code = (enum tree_code) tcode;
2784 case FIX_TRUNC_EXPR:
2785 switch (TYPE_MODE (type))
2788 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2791 return TYPE_UNSIGNED (type)
2792 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
2793 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
2796 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2799 return TYPE_UNSIGNED (type)
2800 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
2801 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
2808 switch (TYPE_MODE (type))
2811 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2814 return TYPE_UNSIGNED (type)
2815 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
2816 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
2819 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2822 return TYPE_UNSIGNED (type)
2823 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
2824 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
2835 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2837 rs6000_builtin_mul_widen_even (tree type)
2839 if (!TARGET_ALTIVEC)
2842 switch (TYPE_MODE (type))
2845 return TYPE_UNSIGNED (type)
2846 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
2847 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
2850 return TYPE_UNSIGNED (type)
2851 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
2852 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
2858 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2860 rs6000_builtin_mul_widen_odd (tree type)
2862 if (!TARGET_ALTIVEC)
2865 switch (TYPE_MODE (type))
2868 return TYPE_UNSIGNED (type)
2869 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
2870 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
2873 return TYPE_UNSIGNED (type)
2874 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
2875 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
2882 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2883 after applying N number of iterations. This routine does not determine
2884 how may iterations are required to reach desired alignment. */
2887 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
2894 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
2897 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
2907 /* Assuming that all other types are naturally aligned. CHECKME! */
2912 /* Return true if the vector misalignment factor is supported by the
2915 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
2922 /* Return if movmisalign pattern is not supported for this mode. */
2923 if (optab_handler (movmisalign_optab, mode)->insn_code ==
2927 if (misalignment == -1)
2929 /* misalignment factor is unknown at compile time but we know
2930 it's word aligned. */
2931 if (rs6000_vector_alignment_reachable (type, is_packed))
2935 /* VSX supports word-aligned vector. */
2936 if (misalignment % 4 == 0)
2942 /* Implement targetm.vectorize.builtin_vec_perm. */
2944 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
2946 tree inner_type = TREE_TYPE (type);
2947 bool uns_p = TYPE_UNSIGNED (inner_type);
2950 *mask_element_type = unsigned_char_type_node;
2952 switch (TYPE_MODE (type))
2956 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
2957 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
2962 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
2963 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
2968 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
2969 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
2973 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
2977 if (!TARGET_ALLOW_DF_PERMUTE)
2980 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
2984 if (!TARGET_ALLOW_DF_PERMUTE)
2988 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
2989 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3000 /* Handle generic options of the form -mfoo=yes/no.
3001 NAME is the option name.
3002 VALUE is the option value.
3003 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3004 whether the option value is 'yes' or 'no' respectively. */
3006 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3010 else if (!strcmp (value, "yes"))
3012 else if (!strcmp (value, "no"))
3015 error ("unknown -m%s= option specified: '%s'", name, value);
3018 /* Validate and record the size specified with the -mtls-size option. */
3021 rs6000_parse_tls_size_option (void)
3023 if (rs6000_tls_size_string == 0)
3025 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3026 rs6000_tls_size = 16;
3027 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3028 rs6000_tls_size = 32;
3029 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3030 rs6000_tls_size = 64;
3032 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3036 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3038 if (DEFAULT_ABI == ABI_DARWIN)
3039 /* The Darwin libraries never set errno, so we might as well
3040 avoid calling them when that's the only reason we would. */
3041 flag_errno_math = 0;
3043 /* Double growth factor to counter reduced min jump length. */
3044 set_param_value ("max-grow-copy-bb-insns", 16);
3046 /* Enable section anchors by default.
3047 Skip section anchors for Objective C and Objective C++
3048 until front-ends fixed. */
3049 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3050 flag_section_anchors = 2;
3053 static enum fpu_type_t
3054 rs6000_parse_fpu_option (const char *option)
3056 if (!strcmp("none", option)) return FPU_NONE;
3057 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3058 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3059 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3060 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3061 error("unknown value %s for -mfpu", option);
3065 /* Returns a function decl for a vectorized version of the builtin function
3066 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3067 if it is not available. */
3070 rs6000_builtin_vectorized_function (unsigned int fn, tree type_out,
3073 enum machine_mode in_mode, out_mode;
3076 if (TREE_CODE (type_out) != VECTOR_TYPE
3077 || TREE_CODE (type_in) != VECTOR_TYPE
3078 || !TARGET_VECTORIZE_BUILTINS)
3081 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3082 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3083 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3084 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3088 case BUILT_IN_COPYSIGN:
3089 if (VECTOR_UNIT_VSX_P (V2DFmode)
3090 && out_mode == DFmode && out_n == 2
3091 && in_mode == DFmode && in_n == 2)
3092 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3094 case BUILT_IN_COPYSIGNF:
3095 if (out_mode != SFmode || out_n != 4
3096 || in_mode != SFmode || in_n != 4)
3098 if (VECTOR_UNIT_VSX_P (V4SFmode))
3099 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3100 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3101 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3104 if (VECTOR_UNIT_VSX_P (V2DFmode)
3105 && out_mode == DFmode && out_n == 2
3106 && in_mode == DFmode && in_n == 2)
3107 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3109 case BUILT_IN_SQRTF:
3110 if (VECTOR_UNIT_VSX_P (V4SFmode)
3111 && out_mode == SFmode && out_n == 4
3112 && in_mode == SFmode && in_n == 4)
3113 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3116 if (VECTOR_UNIT_VSX_P (V2DFmode)
3117 && out_mode == DFmode && out_n == 2
3118 && in_mode == DFmode && in_n == 2)
3119 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3121 case BUILT_IN_CEILF:
3122 if (out_mode != SFmode || out_n != 4
3123 || in_mode != SFmode || in_n != 4)
3125 if (VECTOR_UNIT_VSX_P (V4SFmode))
3126 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3127 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3128 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3130 case BUILT_IN_FLOOR:
3131 if (VECTOR_UNIT_VSX_P (V2DFmode)
3132 && out_mode == DFmode && out_n == 2
3133 && in_mode == DFmode && in_n == 2)
3134 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3136 case BUILT_IN_FLOORF:
3137 if (out_mode != SFmode || out_n != 4
3138 || in_mode != SFmode || in_n != 4)
3140 if (VECTOR_UNIT_VSX_P (V4SFmode))
3141 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3142 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3143 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3145 case BUILT_IN_TRUNC:
3146 if (VECTOR_UNIT_VSX_P (V2DFmode)
3147 && out_mode == DFmode && out_n == 2
3148 && in_mode == DFmode && in_n == 2)
3149 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3151 case BUILT_IN_TRUNCF:
3152 if (out_mode != SFmode || out_n != 4
3153 || in_mode != SFmode || in_n != 4)
3155 if (VECTOR_UNIT_VSX_P (V4SFmode))
3156 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3157 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3158 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3160 case BUILT_IN_NEARBYINT:
3161 if (VECTOR_UNIT_VSX_P (V2DFmode)
3162 && flag_unsafe_math_optimizations
3163 && out_mode == DFmode && out_n == 2
3164 && in_mode == DFmode && in_n == 2)
3165 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3167 case BUILT_IN_NEARBYINTF:
3168 if (VECTOR_UNIT_VSX_P (V4SFmode)
3169 && flag_unsafe_math_optimizations
3170 && out_mode == SFmode && out_n == 4
3171 && in_mode == SFmode && in_n == 4)
3172 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3175 if (VECTOR_UNIT_VSX_P (V2DFmode)
3176 && !flag_trapping_math
3177 && out_mode == DFmode && out_n == 2
3178 && in_mode == DFmode && in_n == 2)
3179 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3181 case BUILT_IN_RINTF:
3182 if (VECTOR_UNIT_VSX_P (V4SFmode)
3183 && !flag_trapping_math
3184 && out_mode == SFmode && out_n == 4
3185 && in_mode == SFmode && in_n == 4)
3186 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3195 /* Implement TARGET_HANDLE_OPTION. */
3198 rs6000_handle_option (size_t code, const char *arg, int value)
3200 enum fpu_type_t fpu_type = FPU_NONE;
3206 target_flags &= ~(MASK_POWER | MASK_POWER2
3207 | MASK_MULTIPLE | MASK_STRING);
3208 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3209 | MASK_MULTIPLE | MASK_STRING);
3211 case OPT_mno_powerpc:
3212 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3213 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3214 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3215 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3218 target_flags &= ~MASK_MINIMAL_TOC;
3219 TARGET_NO_FP_IN_TOC = 0;
3220 TARGET_NO_SUM_IN_TOC = 0;
3221 target_flags_explicit |= MASK_MINIMAL_TOC;
3222 #ifdef TARGET_USES_SYSV4_OPT
3223 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3224 just the same as -mminimal-toc. */
3225 target_flags |= MASK_MINIMAL_TOC;
3226 target_flags_explicit |= MASK_MINIMAL_TOC;
3230 #ifdef TARGET_USES_SYSV4_OPT
3232 /* Make -mtoc behave like -mminimal-toc. */
3233 target_flags |= MASK_MINIMAL_TOC;
3234 target_flags_explicit |= MASK_MINIMAL_TOC;
3238 #ifdef TARGET_USES_AIX64_OPT
3243 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3244 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3245 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3248 #ifdef TARGET_USES_AIX64_OPT
3253 target_flags &= ~MASK_POWERPC64;
3254 target_flags_explicit |= MASK_POWERPC64;
3257 case OPT_minsert_sched_nops_:
3258 rs6000_sched_insert_nops_str = arg;
3261 case OPT_mminimal_toc:
3264 TARGET_NO_FP_IN_TOC = 0;
3265 TARGET_NO_SUM_IN_TOC = 0;
3272 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3273 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3280 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3281 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3285 case OPT_mpowerpc_gpopt:
3286 case OPT_mpowerpc_gfxopt:
3289 target_flags |= MASK_POWERPC;
3290 target_flags_explicit |= MASK_POWERPC;
3294 case OPT_maix_struct_return:
3295 case OPT_msvr4_struct_return:
3296 rs6000_explicit_options.aix_struct_ret = true;
3300 rs6000_explicit_options.vrsave = true;
3301 TARGET_ALTIVEC_VRSAVE = value;
3305 rs6000_explicit_options.vrsave = true;
3306 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3310 target_flags_explicit |= MASK_ISEL;
3312 rs6000_parse_yes_no_option ("isel", arg, &isel);
3314 target_flags |= MASK_ISEL;
3316 target_flags &= ~MASK_ISEL;
3320 rs6000_explicit_options.spe = true;
3325 rs6000_explicit_options.spe = true;
3326 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3330 rs6000_debug_name = arg;
3333 #ifdef TARGET_USES_SYSV4_OPT
3335 rs6000_abi_name = arg;
3339 rs6000_sdata_name = arg;
3342 case OPT_mtls_size_:
3343 rs6000_tls_size_string = arg;
3346 case OPT_mrelocatable:
3349 target_flags |= MASK_MINIMAL_TOC;
3350 target_flags_explicit |= MASK_MINIMAL_TOC;
3351 TARGET_NO_FP_IN_TOC = 1;
3355 case OPT_mrelocatable_lib:
3358 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3359 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3360 TARGET_NO_FP_IN_TOC = 1;
3364 target_flags &= ~MASK_RELOCATABLE;
3365 target_flags_explicit |= MASK_RELOCATABLE;
3371 if (!strcmp (arg, "altivec"))
3373 rs6000_explicit_options.altivec_abi = true;
3374 rs6000_altivec_abi = 1;
3376 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3379 else if (! strcmp (arg, "no-altivec"))
3381 rs6000_explicit_options.altivec_abi = true;
3382 rs6000_altivec_abi = 0;
3384 else if (! strcmp (arg, "spe"))
3386 rs6000_explicit_options.spe_abi = true;
3388 rs6000_altivec_abi = 0;
3389 if (!TARGET_SPE_ABI)
3390 error ("not configured for ABI: '%s'", arg);
3392 else if (! strcmp (arg, "no-spe"))
3394 rs6000_explicit_options.spe_abi = true;
3398 /* These are here for testing during development only, do not
3399 document in the manual please. */
3400 else if (! strcmp (arg, "d64"))
3402 rs6000_darwin64_abi = 1;
3403 warning (0, "Using darwin64 ABI");
3405 else if (! strcmp (arg, "d32"))
3407 rs6000_darwin64_abi = 0;
3408 warning (0, "Using old darwin ABI");
3411 else if (! strcmp (arg, "ibmlongdouble"))
3413 rs6000_explicit_options.ieee = true;
3414 rs6000_ieeequad = 0;
3415 warning (0, "Using IBM extended precision long double");
3417 else if (! strcmp (arg, "ieeelongdouble"))
3419 rs6000_explicit_options.ieee = true;
3420 rs6000_ieeequad = 1;
3421 warning (0, "Using IEEE extended precision long double");
3426 error ("unknown ABI specified: '%s'", arg);
3432 rs6000_select[1].string = arg;
3436 rs6000_select[2].string = arg;
3439 case OPT_mtraceback_:
3440 rs6000_traceback_name = arg;
3443 case OPT_mfloat_gprs_:
3444 rs6000_explicit_options.float_gprs = true;
3445 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3446 rs6000_float_gprs = 1;
3447 else if (! strcmp (arg, "double"))
3448 rs6000_float_gprs = 2;
3449 else if (! strcmp (arg, "no"))
3450 rs6000_float_gprs = 0;
3453 error ("invalid option for -mfloat-gprs: '%s'", arg);
3458 case OPT_mlong_double_:
3459 rs6000_explicit_options.long_double = true;
3460 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3461 if (value != 64 && value != 128)
3463 error ("Unknown switch -mlong-double-%s", arg);
3464 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3468 rs6000_long_double_type_size = value;
3471 case OPT_msched_costly_dep_:
3472 rs6000_sched_costly_dep_str = arg;
3476 rs6000_explicit_options.alignment = true;
3477 if (! strcmp (arg, "power"))
3479 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3480 some C library functions, so warn about it. The flag may be
3481 useful for performance studies from time to time though, so
3482 don't disable it entirely. */
3483 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3484 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3485 " it is incompatible with the installed C and C++ libraries");
3486 rs6000_alignment_flags = MASK_ALIGN_POWER;
3488 else if (! strcmp (arg, "natural"))
3489 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3492 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3497 case OPT_msingle_float:
3498 if (!TARGET_SINGLE_FPU)
3499 warning (0, "-msingle-float option equivalent to -mhard-float");
3500 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3501 rs6000_double_float = 0;
3502 target_flags &= ~MASK_SOFT_FLOAT;
3503 target_flags_explicit |= MASK_SOFT_FLOAT;
3506 case OPT_mdouble_float:
3507 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3508 rs6000_single_float = 1;
3509 target_flags &= ~MASK_SOFT_FLOAT;
3510 target_flags_explicit |= MASK_SOFT_FLOAT;
3513 case OPT_msimple_fpu:
3514 if (!TARGET_SINGLE_FPU)
3515 warning (0, "-msimple-fpu option ignored");
3518 case OPT_mhard_float:
3519 /* -mhard_float implies -msingle-float and -mdouble-float. */
3520 rs6000_single_float = rs6000_double_float = 1;
3523 case OPT_msoft_float:
3524 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3525 rs6000_single_float = rs6000_double_float = 0;
3529 fpu_type = rs6000_parse_fpu_option(arg);
3530 if (fpu_type != FPU_NONE)
3531 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3533 target_flags &= ~MASK_SOFT_FLOAT;
3534 target_flags_explicit |= MASK_SOFT_FLOAT;
3535 rs6000_xilinx_fpu = 1;
3536 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3537 rs6000_single_float = 1;
3538 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3539 rs6000_single_float = rs6000_double_float = 1;
3540 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3541 rs6000_simple_fpu = 1;
3545 /* -mfpu=none is equivalent to -msoft-float */
3546 target_flags |= MASK_SOFT_FLOAT;
3547 target_flags_explicit |= MASK_SOFT_FLOAT;
3548 rs6000_single_float = rs6000_double_float = 0;
3555 /* Do anything needed at the start of the asm file. */
3558 rs6000_file_start (void)
3562 const char *start = buffer;
3563 struct rs6000_cpu_select *ptr;
3564 const char *default_cpu = TARGET_CPU_DEFAULT;
3565 FILE *file = asm_out_file;
3567 default_file_start ();
3569 #ifdef TARGET_BI_ARCH
3570 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3574 if (flag_verbose_asm)
3576 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3577 rs6000_select[0].string = default_cpu;
3579 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3581 ptr = &rs6000_select[i];
3582 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
3584 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
3589 if (PPC405_ERRATUM77)
3591 fprintf (file, "%s PPC405CR_ERRATUM77", start);
3595 #ifdef USING_ELFOS_H
3596 switch (rs6000_sdata)
3598 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
3599 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
3600 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
3601 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
3604 if (rs6000_sdata && g_switch_value)
3606 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
3616 #ifdef HAVE_AS_GNU_ATTRIBUTE
3617 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
3619 fprintf (file, "\t.gnu_attribute 4, %d\n",
3620 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
3621 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
3623 fprintf (file, "\t.gnu_attribute 8, %d\n",
3624 (TARGET_ALTIVEC_ABI ? 2
3625 : TARGET_SPE_ABI ? 3
3627 fprintf (file, "\t.gnu_attribute 12, %d\n",
3628 aix_struct_return ? 2 : 1);
3633 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
3635 switch_to_section (toc_section);
3636 switch_to_section (text_section);
3641 /* Return nonzero if this function is known to have a null epilogue. */
3644 direct_return (void)
3646 if (reload_completed)
3648 rs6000_stack_t *info = rs6000_stack_info ();
3650 if (info->first_gp_reg_save == 32
3651 && info->first_fp_reg_save == 64
3652 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
3653 && ! info->lr_save_p
3654 && ! info->cr_save_p
3655 && info->vrsave_mask == 0
3663 /* Return the number of instructions it takes to form a constant in an
3664 integer register. */
3667 num_insns_constant_wide (HOST_WIDE_INT value)
3669 /* signed constant loadable with {cal|addi} */
3670 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
3673 /* constant loadable with {cau|addis} */
3674 else if ((value & 0xffff) == 0
3675 && (value >> 31 == -1 || value >> 31 == 0))
3678 #if HOST_BITS_PER_WIDE_INT == 64
3679 else if (TARGET_POWERPC64)
3681 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
3682 HOST_WIDE_INT high = value >> 31;
3684 if (high == 0 || high == -1)
3690 return num_insns_constant_wide (high) + 1;
3692 return (num_insns_constant_wide (high)
3693 + num_insns_constant_wide (low) + 1);
3702 num_insns_constant (rtx op, enum machine_mode mode)
3704 HOST_WIDE_INT low, high;
3706 switch (GET_CODE (op))
3709 #if HOST_BITS_PER_WIDE_INT == 64
3710 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
3711 && mask64_operand (op, mode))
3715 return num_insns_constant_wide (INTVAL (op));
3718 if (mode == SFmode || mode == SDmode)
3723 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3724 if (DECIMAL_FLOAT_MODE_P (mode))
3725 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
3727 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
3728 return num_insns_constant_wide ((HOST_WIDE_INT) l);
3731 if (mode == VOIDmode || mode == DImode)
3733 high = CONST_DOUBLE_HIGH (op);
3734 low = CONST_DOUBLE_LOW (op);
3741 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3742 if (DECIMAL_FLOAT_MODE_P (mode))
3743 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
3745 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
3746 high = l[WORDS_BIG_ENDIAN == 0];
3747 low = l[WORDS_BIG_ENDIAN != 0];
3751 return (num_insns_constant_wide (low)
3752 + num_insns_constant_wide (high));
3755 if ((high == 0 && low >= 0)
3756 || (high == -1 && low < 0))
3757 return num_insns_constant_wide (low);
3759 else if (mask64_operand (op, mode))
3763 return num_insns_constant_wide (high) + 1;
3766 return (num_insns_constant_wide (high)
3767 + num_insns_constant_wide (low) + 1);
3775 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
3776 If the mode of OP is MODE_VECTOR_INT, this simply returns the
3777 corresponding element of the vector, but for V4SFmode and V2SFmode,
3778 the corresponding "float" is interpreted as an SImode integer. */
3781 const_vector_elt_as_int (rtx op, unsigned int elt)
3783 rtx tmp = CONST_VECTOR_ELT (op, elt);
3784 if (GET_MODE (op) == V4SFmode
3785 || GET_MODE (op) == V2SFmode)
3786 tmp = gen_lowpart (SImode, tmp);
3787 return INTVAL (tmp);
3790 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
3791 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
3792 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
3793 all items are set to the same value and contain COPIES replicas of the
3794 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
3795 operand and the others are set to the value of the operand's msb. */
3798 vspltis_constant (rtx op, unsigned step, unsigned copies)
3800 enum machine_mode mode = GET_MODE (op);
3801 enum machine_mode inner = GET_MODE_INNER (mode);
3804 unsigned nunits = GET_MODE_NUNITS (mode);
3805 unsigned bitsize = GET_MODE_BITSIZE (inner);
3806 unsigned mask = GET_MODE_MASK (inner);
3808 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
3809 HOST_WIDE_INT splat_val = val;
3810 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
3812 /* Construct the value to be splatted, if possible. If not, return 0. */
3813 for (i = 2; i <= copies; i *= 2)
3815 HOST_WIDE_INT small_val;
3817 small_val = splat_val >> bitsize;
3819 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
3821 splat_val = small_val;
3824 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
3825 if (EASY_VECTOR_15 (splat_val))
3828 /* Also check if we can splat, and then add the result to itself. Do so if
3829 the value is positive, of if the splat instruction is using OP's mode;
3830 for splat_val < 0, the splat and the add should use the same mode. */
3831 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
3832 && (splat_val >= 0 || (step == 1 && copies == 1)))
3835 /* Also check if are loading up the most significant bit which can be done by
3836 loading up -1 and shifting the value left by -1. */
3837 else if (EASY_VECTOR_MSB (splat_val, inner))
3843 /* Check if VAL is present in every STEP-th element, and the
3844 other elements are filled with its most significant bit. */
3845 for (i = 0; i < nunits - 1; ++i)
3847 HOST_WIDE_INT desired_val;
3848 if (((i + 1) & (step - 1)) == 0)
3851 desired_val = msb_val;
3853 if (desired_val != const_vector_elt_as_int (op, i))
3861 /* Return true if OP is of the given MODE and can be synthesized
3862 with a vspltisb, vspltish or vspltisw. */
3865 easy_altivec_constant (rtx op, enum machine_mode mode)
3867 unsigned step, copies;
3869 if (mode == VOIDmode)
3870 mode = GET_MODE (op);
3871 else if (mode != GET_MODE (op))
3874 /* Start with a vspltisw. */
3875 step = GET_MODE_NUNITS (mode) / 4;
3878 if (vspltis_constant (op, step, copies))
3881 /* Then try with a vspltish. */
3887 if (vspltis_constant (op, step, copies))
3890 /* And finally a vspltisb. */
3896 if (vspltis_constant (op, step, copies))
3902 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
3903 result is OP. Abort if it is not possible. */
3906 gen_easy_altivec_constant (rtx op)
3908 enum machine_mode mode = GET_MODE (op);
3909 int nunits = GET_MODE_NUNITS (mode);
3910 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
3911 unsigned step = nunits / 4;
3912 unsigned copies = 1;
3914 /* Start with a vspltisw. */
3915 if (vspltis_constant (op, step, copies))
3916 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
3918 /* Then try with a vspltish. */
3924 if (vspltis_constant (op, step, copies))
3925 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
3927 /* And finally a vspltisb. */
3933 if (vspltis_constant (op, step, copies))
3934 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
3940 output_vec_const_move (rtx *operands)
3943 enum machine_mode mode;
3948 mode = GET_MODE (dest);
3950 if (TARGET_VSX && zero_constant (vec, mode))
3951 return "xxlxor %x0,%x0,%x0";
3956 if (zero_constant (vec, mode))
3957 return "vxor %0,%0,%0";
3959 splat_vec = gen_easy_altivec_constant (vec);
3960 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
3961 operands[1] = XEXP (splat_vec, 0);
3962 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
3965 switch (GET_MODE (splat_vec))
3968 return "vspltisw %0,%1";
3971 return "vspltish %0,%1";
3974 return "vspltisb %0,%1";
3981 gcc_assert (TARGET_SPE);
3983 /* Vector constant 0 is handled as a splitter of V2SI, and in the
3984 pattern of V1DI, V4HI, and V2SF.
3986 FIXME: We should probably return # and add post reload
3987 splitters for these, but this way is so easy ;-). */
3988 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
3989 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
3990 operands[1] = CONST_VECTOR_ELT (vec, 0);
3991 operands[2] = CONST_VECTOR_ELT (vec, 1);
3993 return "li %0,%1\n\tevmergelo %0,%0,%0";
3995 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
3998 /* Initialize TARGET of vector PAIRED to VALS. */
4001 paired_expand_vector_init (rtx target, rtx vals)
4003 enum machine_mode mode = GET_MODE (target);
4004 int n_elts = GET_MODE_NUNITS (mode);
4006 rtx x, new_rtx, tmp, constant_op, op1, op2;
4009 for (i = 0; i < n_elts; ++i)
4011 x = XVECEXP (vals, 0, i);
4012 if (!CONSTANT_P (x))
4017 /* Load from constant pool. */
4018 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4024 /* The vector is initialized only with non-constants. */
4025 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4026 XVECEXP (vals, 0, 1));
4028 emit_move_insn (target, new_rtx);
4032 /* One field is non-constant and the other one is a constant. Load the
4033 constant from the constant pool and use ps_merge instruction to
4034 construct the whole vector. */
4035 op1 = XVECEXP (vals, 0, 0);
4036 op2 = XVECEXP (vals, 0, 1);
4038 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4040 tmp = gen_reg_rtx (GET_MODE (constant_op));
4041 emit_move_insn (tmp, constant_op);
4043 if (CONSTANT_P (op1))
4044 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4046 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4048 emit_move_insn (target, new_rtx);
4052 paired_expand_vector_move (rtx operands[])
4054 rtx op0 = operands[0], op1 = operands[1];
4056 emit_move_insn (op0, op1);
4059 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4060 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4061 operands for the relation operation COND. This is a recursive
4065 paired_emit_vector_compare (enum rtx_code rcode,
4066 rtx dest, rtx op0, rtx op1,
4067 rtx cc_op0, rtx cc_op1)
4069 rtx tmp = gen_reg_rtx (V2SFmode);
4070 rtx tmp1, max, min, equal_zero;
4072 gcc_assert (TARGET_PAIRED_FLOAT);
4073 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4079 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4083 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4084 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4088 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4091 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4094 tmp1 = gen_reg_rtx (V2SFmode);
4095 max = gen_reg_rtx (V2SFmode);
4096 min = gen_reg_rtx (V2SFmode);
4097 equal_zero = gen_reg_rtx (V2SFmode);
4099 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4100 emit_insn (gen_selv2sf4
4101 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4102 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4103 emit_insn (gen_selv2sf4
4104 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4105 emit_insn (gen_subv2sf3 (tmp1, min, max));
4106 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4109 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4112 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4115 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4118 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4121 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4130 /* Emit vector conditional expression.
4131 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4132 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4135 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4136 rtx cond, rtx cc_op0, rtx cc_op1)
4138 enum rtx_code rcode = GET_CODE (cond);
4140 if (!TARGET_PAIRED_FLOAT)
4143 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4148 /* Initialize vector TARGET to VALS. */
4151 rs6000_expand_vector_init (rtx target, rtx vals)
4153 enum machine_mode mode = GET_MODE (target);
4154 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4155 int n_elts = GET_MODE_NUNITS (mode);
4156 int n_var = 0, one_var = -1;
4157 bool all_same = true, all_const_zero = true;
4161 for (i = 0; i < n_elts; ++i)
4163 x = XVECEXP (vals, 0, i);
4164 if (!CONSTANT_P (x))
4165 ++n_var, one_var = i;
4166 else if (x != CONST0_RTX (inner_mode))
4167 all_const_zero = false;
4169 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4175 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4176 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4177 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4179 /* Zero register. */
4180 emit_insn (gen_rtx_SET (VOIDmode, target,
4181 gen_rtx_XOR (mode, target, target)));
4184 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4186 /* Splat immediate. */
4187 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4192 /* Load from constant pool. */
4193 emit_move_insn (target, const_vec);
4198 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4199 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4203 rtx element = XVECEXP (vals, 0, 0);
4204 if (mode == V2DFmode)
4205 emit_insn (gen_vsx_splat_v2df (target, element));
4207 emit_insn (gen_vsx_splat_v2di (target, element));
4211 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4212 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4213 if (mode == V2DFmode)
4214 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4216 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4221 /* With single precision floating point on VSX, know that internally single
4222 precision is actually represented as a double, and either make 2 V2DF
4223 vectors, and convert these vectors to single precision, or do one
4224 conversion, and splat the result to the other elements. */
4225 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4229 rtx freg = gen_reg_rtx (V4SFmode);
4230 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4232 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4233 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4237 rtx dbl_even = gen_reg_rtx (V2DFmode);
4238 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4239 rtx flt_even = gen_reg_rtx (V4SFmode);
4240 rtx flt_odd = gen_reg_rtx (V4SFmode);
4242 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4243 copy_to_reg (XVECEXP (vals, 0, 0)),
4244 copy_to_reg (XVECEXP (vals, 0, 1))));
4245 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4246 copy_to_reg (XVECEXP (vals, 0, 2)),
4247 copy_to_reg (XVECEXP (vals, 0, 3))));
4248 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4249 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4250 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4255 /* Store value to stack temp. Load vector element. Splat. However, splat
4256 of 64-bit items is not supported on Altivec. */
4257 if (all_same && GET_MODE_SIZE (mode) <= 4)
4259 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4260 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4261 XVECEXP (vals, 0, 0));
4262 x = gen_rtx_UNSPEC (VOIDmode,
4263 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4264 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4266 gen_rtx_SET (VOIDmode,
4269 x = gen_rtx_VEC_SELECT (inner_mode, target,
4270 gen_rtx_PARALLEL (VOIDmode,
4271 gen_rtvec (1, const0_rtx)));
4272 emit_insn (gen_rtx_SET (VOIDmode, target,
4273 gen_rtx_VEC_DUPLICATE (mode, x)));
4277 /* One field is non-constant. Load constant then overwrite
4281 rtx copy = copy_rtx (vals);
4283 /* Load constant part of vector, substitute neighboring value for
4285 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4286 rs6000_expand_vector_init (target, copy);
4288 /* Insert variable. */
4289 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4293 /* Construct the vector in memory one field at a time
4294 and load the whole vector. */
4295 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4296 for (i = 0; i < n_elts; i++)
4297 emit_move_insn (adjust_address_nv (mem, inner_mode,
4298 i * GET_MODE_SIZE (inner_mode)),
4299 XVECEXP (vals, 0, i));
4300 emit_move_insn (target, mem);
4303 /* Set field ELT of TARGET to VAL. */
4306 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4308 enum machine_mode mode = GET_MODE (target);
4309 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4310 rtx reg = gen_reg_rtx (mode);
4312 int width = GET_MODE_SIZE (inner_mode);
4315 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4317 rtx (*set_func) (rtx, rtx, rtx, rtx)
4318 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4319 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4323 /* Load single variable value. */
4324 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4325 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4326 x = gen_rtx_UNSPEC (VOIDmode,
4327 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4328 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4330 gen_rtx_SET (VOIDmode,
4334 /* Linear sequence. */
4335 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4336 for (i = 0; i < 16; ++i)
4337 XVECEXP (mask, 0, i) = GEN_INT (i);
4339 /* Set permute mask to insert element into target. */
4340 for (i = 0; i < width; ++i)
4341 XVECEXP (mask, 0, elt*width + i)
4342 = GEN_INT (i + 0x10);
4343 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4344 x = gen_rtx_UNSPEC (mode,
4345 gen_rtvec (3, target, reg,
4346 force_reg (V16QImode, x)),
4348 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4351 /* Extract field ELT from VEC into TARGET. */
4354 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4356 enum machine_mode mode = GET_MODE (vec);
4357 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4360 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4362 rtx (*extract_func) (rtx, rtx, rtx)
4363 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4364 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4368 /* Allocate mode-sized buffer. */
4369 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4371 /* Add offset to field within buffer matching vector element. */
4372 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4374 /* Store single field into mode-sized buffer. */
4375 x = gen_rtx_UNSPEC (VOIDmode,
4376 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4377 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4379 gen_rtx_SET (VOIDmode,
4382 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4385 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4386 implement ANDing by the mask IN. */
4388 build_mask64_2_operands (rtx in, rtx *out)
4390 #if HOST_BITS_PER_WIDE_INT >= 64
4391 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4394 gcc_assert (GET_CODE (in) == CONST_INT);
4399 /* Assume c initially something like 0x00fff000000fffff. The idea
4400 is to rotate the word so that the middle ^^^^^^ group of zeros
4401 is at the MS end and can be cleared with an rldicl mask. We then
4402 rotate back and clear off the MS ^^ group of zeros with a
4404 c = ~c; /* c == 0xff000ffffff00000 */
4405 lsb = c & -c; /* lsb == 0x0000000000100000 */
4406 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4407 c = ~c; /* c == 0x00fff000000fffff */
4408 c &= -lsb; /* c == 0x00fff00000000000 */
4409 lsb = c & -c; /* lsb == 0x0000100000000000 */
4410 c = ~c; /* c == 0xff000fffffffffff */
4411 c &= -lsb; /* c == 0xff00000000000000 */
4413 while ((lsb >>= 1) != 0)
4414 shift++; /* shift == 44 on exit from loop */
4415 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4416 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4417 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4421 /* Assume c initially something like 0xff000f0000000000. The idea
4422 is to rotate the word so that the ^^^ middle group of zeros
4423 is at the LS end and can be cleared with an rldicr mask. We then
4424 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4426 lsb = c & -c; /* lsb == 0x0000010000000000 */
4427 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4428 c = ~c; /* c == 0x00fff0ffffffffff */
4429 c &= -lsb; /* c == 0x00fff00000000000 */
4430 lsb = c & -c; /* lsb == 0x0000100000000000 */
4431 c = ~c; /* c == 0xff000fffffffffff */
4432 c &= -lsb; /* c == 0xff00000000000000 */
4434 while ((lsb >>= 1) != 0)
4435 shift++; /* shift == 44 on exit from loop */
4436 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4437 m1 >>= shift; /* m1 == 0x0000000000000fff */
4438 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4441 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4442 masks will be all 1's. We are guaranteed more than one transition. */
4443 out[0] = GEN_INT (64 - shift);
4444 out[1] = GEN_INT (m1);
4445 out[2] = GEN_INT (shift);
4446 out[3] = GEN_INT (m2);
4454 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4457 invalid_e500_subreg (rtx op, enum machine_mode mode)
4459 if (TARGET_E500_DOUBLE)
4461 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4462 subreg:TI and reg:TF. Decimal float modes are like integer
4463 modes (only low part of each register used) for this
4465 if (GET_CODE (op) == SUBREG
4466 && (mode == SImode || mode == DImode || mode == TImode
4467 || mode == DDmode || mode == TDmode)
4468 && REG_P (SUBREG_REG (op))
4469 && (GET_MODE (SUBREG_REG (op)) == DFmode
4470 || GET_MODE (SUBREG_REG (op)) == TFmode))
4473 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4475 if (GET_CODE (op) == SUBREG
4476 && (mode == DFmode || mode == TFmode)
4477 && REG_P (SUBREG_REG (op))
4478 && (GET_MODE (SUBREG_REG (op)) == DImode
4479 || GET_MODE (SUBREG_REG (op)) == TImode
4480 || GET_MODE (SUBREG_REG (op)) == DDmode
4481 || GET_MODE (SUBREG_REG (op)) == TDmode))
4486 && GET_CODE (op) == SUBREG
4488 && REG_P (SUBREG_REG (op))
4489 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4495 /* AIX increases natural record alignment to doubleword if the first
4496 field is an FP double while the FP fields remain word aligned. */
4499 rs6000_special_round_type_align (tree type, unsigned int computed,
4500 unsigned int specified)
4502 unsigned int align = MAX (computed, specified);
4503 tree field = TYPE_FIELDS (type);
4505 /* Skip all non field decls */
4506 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4507 field = TREE_CHAIN (field);
4509 if (field != NULL && field != type)
4511 type = TREE_TYPE (field);
4512 while (TREE_CODE (type) == ARRAY_TYPE)
4513 type = TREE_TYPE (type);
4515 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4516 align = MAX (align, 64);
4522 /* Darwin increases record alignment to the natural alignment of
4526 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4527 unsigned int specified)
4529 unsigned int align = MAX (computed, specified);
4531 if (TYPE_PACKED (type))
4534 /* Find the first field, looking down into aggregates. */
4536 tree field = TYPE_FIELDS (type);
4537 /* Skip all non field decls */
4538 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4539 field = TREE_CHAIN (field);
4542 type = TREE_TYPE (field);
4543 while (TREE_CODE (type) == ARRAY_TYPE)
4544 type = TREE_TYPE (type);
4545 } while (AGGREGATE_TYPE_P (type));
4547 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
4548 align = MAX (align, TYPE_ALIGN (type));
4553 /* Return 1 for an operand in small memory on V.4/eabi. */
4556 small_data_operand (rtx op ATTRIBUTE_UNUSED,
4557 enum machine_mode mode ATTRIBUTE_UNUSED)
4562 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
4565 if (DEFAULT_ABI != ABI_V4)
4568 /* Vector and float memory instructions have a limited offset on the
4569 SPE, so using a vector or float variable directly as an operand is
4572 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
4575 if (GET_CODE (op) == SYMBOL_REF)
4578 else if (GET_CODE (op) != CONST
4579 || GET_CODE (XEXP (op, 0)) != PLUS
4580 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
4581 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
4586 rtx sum = XEXP (op, 0);
4587 HOST_WIDE_INT summand;
4589 /* We have to be careful here, because it is the referenced address
4590 that must be 32k from _SDA_BASE_, not just the symbol. */
4591 summand = INTVAL (XEXP (sum, 1));
4592 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
4595 sym_ref = XEXP (sum, 0);
4598 return SYMBOL_REF_SMALL_P (sym_ref);
4604 /* Return true if either operand is a general purpose register. */
4607 gpr_or_gpr_p (rtx op0, rtx op1)
4609 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
4610 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
4614 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
4617 reg_offset_addressing_ok_p (enum machine_mode mode)
4627 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
4628 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
4636 /* Paired vector modes. Only reg+reg addressing is valid. */
4637 if (TARGET_PAIRED_FLOAT)
4649 virtual_stack_registers_memory_p (rtx op)
4653 if (GET_CODE (op) == REG)
4654 regnum = REGNO (op);
4656 else if (GET_CODE (op) == PLUS
4657 && GET_CODE (XEXP (op, 0)) == REG
4658 && GET_CODE (XEXP (op, 1)) == CONST_INT)
4659 regnum = REGNO (XEXP (op, 0));
4664 return (regnum >= FIRST_VIRTUAL_REGISTER
4665 && regnum <= LAST_VIRTUAL_REGISTER);
4669 constant_pool_expr_p (rtx op)
4673 split_const (op, &base, &offset);
4674 return (GET_CODE (base) == SYMBOL_REF
4675 && CONSTANT_POOL_ADDRESS_P (base)
4676 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
4680 toc_relative_expr_p (rtx op)
4684 if (GET_CODE (op) != CONST)
4687 split_const (op, &base, &offset);
4688 return (GET_CODE (base) == UNSPEC
4689 && XINT (base, 1) == UNSPEC_TOCREL);
4693 legitimate_constant_pool_address_p (rtx x)
4696 && GET_CODE (x) == PLUS
4697 && GET_CODE (XEXP (x, 0)) == REG
4698 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
4699 && toc_relative_expr_p (XEXP (x, 1)));
4703 legitimate_small_data_p (enum machine_mode mode, rtx x)
4705 return (DEFAULT_ABI == ABI_V4
4706 && !flag_pic && !TARGET_TOC
4707 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
4708 && small_data_operand (x, mode));
4711 /* SPE offset addressing is limited to 5-bits worth of double words. */
4712 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
4715 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
4717 unsigned HOST_WIDE_INT offset, extra;
4719 if (GET_CODE (x) != PLUS)
4721 if (GET_CODE (XEXP (x, 0)) != REG)
4723 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4725 if (!reg_offset_addressing_ok_p (mode))
4726 return virtual_stack_registers_memory_p (x);
4727 if (legitimate_constant_pool_address_p (x))
4729 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4732 offset = INTVAL (XEXP (x, 1));
4740 /* SPE vector modes. */
4741 return SPE_CONST_OFFSET_OK (offset);
4744 if (TARGET_E500_DOUBLE)
4745 return SPE_CONST_OFFSET_OK (offset);
4747 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
4749 if (VECTOR_MEM_VSX_P (DFmode))
4754 /* On e500v2, we may have:
4756 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
4758 Which gets addressed with evldd instructions. */
4759 if (TARGET_E500_DOUBLE)
4760 return SPE_CONST_OFFSET_OK (offset);
4762 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
4764 else if (offset & 3)
4769 if (TARGET_E500_DOUBLE)
4770 return (SPE_CONST_OFFSET_OK (offset)
4771 && SPE_CONST_OFFSET_OK (offset + 8));
4775 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
4777 else if (offset & 3)
4788 return (offset < 0x10000) && (offset + extra < 0x10000);
4792 legitimate_indexed_address_p (rtx x, int strict)
4796 if (GET_CODE (x) != PLUS)
4802 /* Recognize the rtl generated by reload which we know will later be
4803 replaced with proper base and index regs. */
4805 && reload_in_progress
4806 && (REG_P (op0) || GET_CODE (op0) == PLUS)
4810 return (REG_P (op0) && REG_P (op1)
4811 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
4812 && INT_REG_OK_FOR_INDEX_P (op1, strict))
4813 || (INT_REG_OK_FOR_BASE_P (op1, strict)
4814 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
4818 avoiding_indexed_address_p (enum machine_mode mode)
4820 /* Avoid indexed addressing for modes that have non-indexed
4821 load/store instruction forms. */
4822 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
4826 legitimate_indirect_address_p (rtx x, int strict)
4828 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
4832 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
4834 if (!TARGET_MACHO || !flag_pic
4835 || mode != SImode || GET_CODE (x) != MEM)
4839 if (GET_CODE (x) != LO_SUM)
4841 if (GET_CODE (XEXP (x, 0)) != REG)
4843 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
4847 return CONSTANT_P (x);
4851 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
4853 if (GET_CODE (x) != LO_SUM)
4855 if (GET_CODE (XEXP (x, 0)) != REG)
4857 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4859 /* Restrict addressing for DI because of our SUBREG hackery. */
4860 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4861 || mode == DDmode || mode == TDmode
4866 if (TARGET_ELF || TARGET_MACHO)
4868 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
4872 if (GET_MODE_NUNITS (mode) != 1)
4874 if (GET_MODE_BITSIZE (mode) > 64
4875 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
4876 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4877 && (mode == DFmode || mode == DDmode))))
4880 return CONSTANT_P (x);
4887 /* Try machine-dependent ways of modifying an illegitimate address
4888 to be legitimate. If we find one, return the new, valid address.
4889 This is used from only one place: `memory_address' in explow.c.
4891 OLDX is the address as it was before break_out_memory_refs was
4892 called. In some cases it is useful to look at this to decide what
4895 It is always safe for this function to do nothing. It exists to
4896 recognize opportunities to optimize the output.
4898 On RS/6000, first check for the sum of a register with a constant
4899 integer that is out of range. If so, generate code to add the
4900 constant with the low-order 16 bits masked to the register and force
4901 this result into another register (this can be done with `cau').
4902 Then generate an address of REG+(CONST&0xffff), allowing for the
4903 possibility of bit 16 being a one.
4905 Then check for the sum of a register and something not constant, try to
4906 load the other things into a register and return the sum. */
4909 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
4910 enum machine_mode mode)
4912 unsigned int extra = 0;
4914 if (!reg_offset_addressing_ok_p (mode))
4916 if (virtual_stack_registers_memory_p (x))
4919 /* In theory we should not be seeing addresses of the form reg+0,
4920 but just in case it is generated, optimize it away. */
4921 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
4922 return force_reg (Pmode, XEXP (x, 0));
4924 /* Make sure both operands are registers. */
4925 else if (GET_CODE (x) == PLUS)
4926 return gen_rtx_PLUS (Pmode,
4927 force_reg (Pmode, XEXP (x, 0)),
4928 force_reg (Pmode, XEXP (x, 1)));
4930 return force_reg (Pmode, x);
4932 if (GET_CODE (x) == SYMBOL_REF)
4934 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
4936 return rs6000_legitimize_tls_address (x, model);
4946 if (!TARGET_POWERPC64)
4954 extra = TARGET_POWERPC64 ? 8 : 12;
4960 if (GET_CODE (x) == PLUS
4961 && GET_CODE (XEXP (x, 0)) == REG
4962 && GET_CODE (XEXP (x, 1)) == CONST_INT
4963 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
4965 && !((TARGET_POWERPC64
4966 && (mode == DImode || mode == TImode)
4967 && (INTVAL (XEXP (x, 1)) & 3) != 0)
4968 || SPE_VECTOR_MODE (mode)
4969 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4970 || mode == DImode || mode == DDmode
4971 || mode == TDmode))))
4973 HOST_WIDE_INT high_int, low_int;
4975 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
4976 if (low_int >= 0x8000 - extra)
4978 high_int = INTVAL (XEXP (x, 1)) - low_int;
4979 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
4980 GEN_INT (high_int)), 0);
4981 return plus_constant (sum, low_int);
4983 else if (GET_CODE (x) == PLUS
4984 && GET_CODE (XEXP (x, 0)) == REG
4985 && GET_CODE (XEXP (x, 1)) != CONST_INT
4986 && GET_MODE_NUNITS (mode) == 1
4987 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
4989 || ((mode != DImode && mode != DFmode && mode != DDmode)
4990 || (TARGET_E500_DOUBLE && mode != DDmode)))
4991 && (TARGET_POWERPC64 || mode != DImode)
4992 && !avoiding_indexed_address_p (mode)
4997 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
4998 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5000 else if (SPE_VECTOR_MODE (mode)
5001 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5002 || mode == DDmode || mode == TDmode
5003 || mode == DImode)))
5007 /* We accept [reg + reg] and [reg + OFFSET]. */
5009 if (GET_CODE (x) == PLUS)
5011 rtx op1 = XEXP (x, 0);
5012 rtx op2 = XEXP (x, 1);
5015 op1 = force_reg (Pmode, op1);
5017 if (GET_CODE (op2) != REG
5018 && (GET_CODE (op2) != CONST_INT
5019 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5020 || (GET_MODE_SIZE (mode) > 8
5021 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5022 op2 = force_reg (Pmode, op2);
5024 /* We can't always do [reg + reg] for these, because [reg +
5025 reg + offset] is not a legitimate addressing mode. */
5026 y = gen_rtx_PLUS (Pmode, op1, op2);
5028 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5029 return force_reg (Pmode, y);
5034 return force_reg (Pmode, x);
5040 && GET_CODE (x) != CONST_INT
5041 && GET_CODE (x) != CONST_DOUBLE
5043 && GET_MODE_NUNITS (mode) == 1
5044 && (GET_MODE_BITSIZE (mode) <= 32
5045 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5046 && (mode == DFmode || mode == DDmode))))
5048 rtx reg = gen_reg_rtx (Pmode);
5049 emit_insn (gen_elf_high (reg, x));
5050 return gen_rtx_LO_SUM (Pmode, reg, x);
5052 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5055 && ! MACHO_DYNAMIC_NO_PIC_P
5057 && GET_CODE (x) != CONST_INT
5058 && GET_CODE (x) != CONST_DOUBLE
5060 && GET_MODE_NUNITS (mode) == 1
5061 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5062 || (mode != DFmode && mode != DDmode))
5066 rtx reg = gen_reg_rtx (Pmode);
5067 emit_insn (gen_macho_high (reg, x));
5068 return gen_rtx_LO_SUM (Pmode, reg, x);
5071 && GET_CODE (x) == SYMBOL_REF
5072 && constant_pool_expr_p (x)
5073 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5075 return create_TOC_reference (x);
5081 /* Debug version of rs6000_legitimize_address. */
5083 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5089 ret = rs6000_legitimize_address (x, oldx, mode);
5090 insns = get_insns ();
5096 "\nrs6000_legitimize_address: mode %s, old code %s, "
5097 "new code %s, modified\n",
5098 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5099 GET_RTX_NAME (GET_CODE (ret)));
5101 fprintf (stderr, "Original address:\n");
5104 fprintf (stderr, "oldx:\n");
5107 fprintf (stderr, "New address:\n");
5112 fprintf (stderr, "Insns added:\n");
5113 debug_rtx_list (insns, 20);
5119 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5120 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5131 /* If ORIG_X is a constant pool reference, return its known value,
5132 otherwise ORIG_X. */
5135 rs6000_delegitimize_address (rtx x)
5137 rtx orig_x = delegitimize_mem_from_attrs (x);
5146 if (legitimate_constant_pool_address_p (x)
5147 && GET_CODE (XEXP (x, 1)) == CONST
5148 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
5149 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
5150 && constant_pool_expr_p (XEXP (XEXP (XEXP (x, 1), 0), 0))
5151 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF
5152 && toc_relative_expr_p (XEXP (XEXP (XEXP (x, 1), 0), 1)))
5153 return get_pool_constant (XEXP (XEXP (XEXP (x, 1), 0), 0));
5158 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5159 We need to emit DTP-relative relocations. */
5162 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5167 fputs ("\t.long\t", file);
5170 fputs (DOUBLE_INT_ASM_OP, file);
5175 output_addr_const (file, x);
5176 fputs ("@dtprel+0x8000", file);
5179 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5181 static GTY(()) rtx rs6000_tls_symbol;
5183 rs6000_tls_get_addr (void)
5185 if (!rs6000_tls_symbol)
5186 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5188 return rs6000_tls_symbol;
5191 /* Construct the SYMBOL_REF for TLS GOT references. */
5193 static GTY(()) rtx rs6000_got_symbol;
5195 rs6000_got_sym (void)
5197 if (!rs6000_got_symbol)
5199 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5200 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5201 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5204 return rs6000_got_symbol;
5207 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5208 this (thread-local) address. */
5211 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5215 dest = gen_reg_rtx (Pmode);
5216 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5222 tlsreg = gen_rtx_REG (Pmode, 13);
5223 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5227 tlsreg = gen_rtx_REG (Pmode, 2);
5228 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5232 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5236 tmp = gen_reg_rtx (Pmode);
5239 tlsreg = gen_rtx_REG (Pmode, 13);
5240 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5244 tlsreg = gen_rtx_REG (Pmode, 2);
5245 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5249 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5251 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5256 rtx r3, got, tga, tmp1, tmp2, eqv;
5258 /* We currently use relocations like @got@tlsgd for tls, which
5259 means the linker will handle allocation of tls entries, placing
5260 them in the .got section. So use a pointer to the .got section,
5261 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5262 or to secondary GOT sections used by 32-bit -fPIC. */
5264 got = gen_rtx_REG (Pmode, 2);
5268 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5271 rtx gsym = rs6000_got_sym ();
5272 got = gen_reg_rtx (Pmode);
5274 rs6000_emit_move (got, gsym, Pmode);
5280 tmp1 = gen_reg_rtx (Pmode);
5281 tmp2 = gen_reg_rtx (Pmode);
5282 tmp3 = gen_reg_rtx (Pmode);
5283 mem = gen_const_mem (Pmode, tmp1);
5285 first = emit_insn (gen_load_toc_v4_PIC_1b (gsym));
5286 emit_move_insn (tmp1,
5287 gen_rtx_REG (Pmode, LR_REGNO));
5288 emit_move_insn (tmp2, mem);
5289 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
5290 last = emit_move_insn (got, tmp3);
5291 set_unique_reg_note (last, REG_EQUAL, gsym);
5296 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5298 r3 = gen_rtx_REG (Pmode, 3);
5299 tga = rs6000_tls_get_addr ();
5301 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5302 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5303 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5304 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5305 else if (DEFAULT_ABI == ABI_V4)
5306 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5311 insn = emit_call_insn (insn);
5312 RTL_CONST_CALL_P (insn) = 1;
5313 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5314 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5315 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5316 insn = get_insns ();
5318 emit_libcall_block (insn, dest, r3, addr);
5320 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5322 r3 = gen_rtx_REG (Pmode, 3);
5323 tga = rs6000_tls_get_addr ();
5325 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5326 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5327 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5328 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5329 else if (DEFAULT_ABI == ABI_V4)
5330 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5335 insn = emit_call_insn (insn);
5336 RTL_CONST_CALL_P (insn) = 1;
5337 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5338 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5339 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5340 insn = get_insns ();
5342 tmp1 = gen_reg_rtx (Pmode);
5343 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
5345 emit_libcall_block (insn, tmp1, r3, eqv);
5346 if (rs6000_tls_size == 16)
5349 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5351 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5353 else if (rs6000_tls_size == 32)
5355 tmp2 = gen_reg_rtx (Pmode);
5357 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5359 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5362 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5364 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5368 tmp2 = gen_reg_rtx (Pmode);
5370 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5372 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5374 insn = gen_rtx_SET (Pmode, dest,
5375 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5381 /* IE, or 64-bit offset LE. */
5382 tmp2 = gen_reg_rtx (Pmode);
5384 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5386 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5389 insn = gen_tls_tls_64 (dest, tmp2, addr);
5391 insn = gen_tls_tls_32 (dest, tmp2, addr);
5399 /* Return 1 if X contains a thread-local symbol. */
5402 rs6000_tls_referenced_p (rtx x)
5404 if (! TARGET_HAVE_TLS)
5407 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5410 /* Return 1 if *X is a thread-local symbol. This is the same as
5411 rs6000_tls_symbol_ref except for the type of the unused argument. */
5414 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5416 return RS6000_SYMBOL_REF_TLS_P (*x);
5419 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5420 replace the input X, or the original X if no replacement is called for.
5421 The output parameter *WIN is 1 if the calling macro should goto WIN,
5424 For RS/6000, we wish to handle large displacements off a base
5425 register by splitting the addend across an addiu/addis and the mem insn.
5426 This cuts number of extra insns needed from 3 to 1.
5428 On Darwin, we use this to generate code for floating point constants.
5429 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5430 The Darwin code is inside #if TARGET_MACHO because only then are the
5431 machopic_* functions defined. */
5433 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5434 int opnum, int type,
5435 int ind_levels ATTRIBUTE_UNUSED, int *win)
5437 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5439 /* We must recognize output that we have already generated ourselves. */
5440 if (GET_CODE (x) == PLUS
5441 && GET_CODE (XEXP (x, 0)) == PLUS
5442 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5443 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5444 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5446 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5447 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5448 opnum, (enum reload_type)type);
5454 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5455 && GET_CODE (x) == LO_SUM
5456 && GET_CODE (XEXP (x, 0)) == PLUS
5457 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5458 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5459 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5460 && machopic_operand_p (XEXP (x, 1)))
5462 /* Result of previous invocation of this function on Darwin
5463 floating point constant. */
5464 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5465 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5466 opnum, (enum reload_type)type);
5472 /* Force ld/std non-word aligned offset into base register by wrapping
5474 if (GET_CODE (x) == PLUS
5475 && GET_CODE (XEXP (x, 0)) == REG
5476 && REGNO (XEXP (x, 0)) < 32
5477 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5478 && GET_CODE (XEXP (x, 1)) == CONST_INT
5480 && (INTVAL (XEXP (x, 1)) & 3) != 0
5481 && VECTOR_MEM_NONE_P (mode)
5482 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5483 && TARGET_POWERPC64)
5485 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5486 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5487 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5488 opnum, (enum reload_type) type);
5493 if (GET_CODE (x) == PLUS
5494 && GET_CODE (XEXP (x, 0)) == REG
5495 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5496 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5497 && GET_CODE (XEXP (x, 1)) == CONST_INT
5499 && !SPE_VECTOR_MODE (mode)
5500 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5501 || mode == DDmode || mode == TDmode
5503 && VECTOR_MEM_NONE_P (mode))
5505 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5506 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5508 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5510 /* Check for 32-bit overflow. */
5511 if (high + low != val)
5517 /* Reload the high part into a base reg; leave the low part
5518 in the mem directly. */
5520 x = gen_rtx_PLUS (GET_MODE (x),
5521 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5525 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5526 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5527 opnum, (enum reload_type)type);
5532 if (GET_CODE (x) == SYMBOL_REF
5534 && VECTOR_MEM_NONE_P (mode)
5535 && !SPE_VECTOR_MODE (mode)
5537 && DEFAULT_ABI == ABI_DARWIN
5538 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
5540 && DEFAULT_ABI == ABI_V4
5543 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
5544 The same goes for DImode without 64-bit gprs and DFmode and DDmode
5548 && (mode != DImode || TARGET_POWERPC64)
5549 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
5550 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
5555 rtx offset = machopic_gen_offset (x);
5556 x = gen_rtx_LO_SUM (GET_MODE (x),
5557 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
5558 gen_rtx_HIGH (Pmode, offset)), offset);
5562 x = gen_rtx_LO_SUM (GET_MODE (x),
5563 gen_rtx_HIGH (Pmode, x), x);
5565 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5566 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5567 opnum, (enum reload_type)type);
5572 /* Reload an offset address wrapped by an AND that represents the
5573 masking of the lower bits. Strip the outer AND and let reload
5574 convert the offset address into an indirect address. For VSX,
5575 force reload to create the address with an AND in a separate
5576 register, because we can't guarantee an altivec register will
5578 if (VECTOR_MEM_ALTIVEC_P (mode)
5579 && GET_CODE (x) == AND
5580 && GET_CODE (XEXP (x, 0)) == PLUS
5581 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5582 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5583 && GET_CODE (XEXP (x, 1)) == CONST_INT
5584 && INTVAL (XEXP (x, 1)) == -16)
5593 && GET_CODE (x) == SYMBOL_REF
5594 && constant_pool_expr_p (x)
5595 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
5597 x = create_TOC_reference (x);
5605 /* Debug version of rs6000_legitimize_reload_address. */
5607 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
5608 int opnum, int type,
5609 int ind_levels, int *win)
5611 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
5614 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
5615 "type = %d, ind_levels = %d, win = %d, original addr:\n",
5616 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
5620 fprintf (stderr, "Same address returned\n");
5622 fprintf (stderr, "NULL returned\n");
5625 fprintf (stderr, "New address:\n");
5632 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
5633 that is a valid memory address for an instruction.
5634 The MODE argument is the machine mode for the MEM expression
5635 that wants to use this address.
5637 On the RS/6000, there are four valid address: a SYMBOL_REF that
5638 refers to a constant pool entry of an address (or the sum of it
5639 plus a constant), a short (16-bit signed) constant plus a register,
5640 the sum of two registers, or a register indirect, possibly with an
5641 auto-increment. For DFmode, DDmode and DImode with a constant plus
5642 register, we must ensure that both words are addressable or PowerPC64
5643 with offset word aligned.
5645 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
5646 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
5647 because adjacent memory cells are accessed by adding word-sized offsets
5648 during assembly output. */
5650 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
5652 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5654 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
5655 if (VECTOR_MEM_ALTIVEC_P (mode)
5656 && GET_CODE (x) == AND
5657 && GET_CODE (XEXP (x, 1)) == CONST_INT
5658 && INTVAL (XEXP (x, 1)) == -16)
5661 if (RS6000_SYMBOL_REF_TLS_P (x))
5663 if (legitimate_indirect_address_p (x, reg_ok_strict))
5665 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
5666 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5667 && !SPE_VECTOR_MODE (mode)
5670 /* Restrict addressing for DI because of our SUBREG hackery. */
5671 && !(TARGET_E500_DOUBLE
5672 && (mode == DFmode || mode == DDmode || mode == DImode))
5674 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
5676 if (virtual_stack_registers_memory_p (x))
5678 if (reg_offset_p && legitimate_small_data_p (mode, x))
5680 if (reg_offset_p && legitimate_constant_pool_address_p (x))
5682 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
5685 && GET_CODE (x) == PLUS
5686 && GET_CODE (XEXP (x, 0)) == REG
5687 && (XEXP (x, 0) == virtual_stack_vars_rtx
5688 || XEXP (x, 0) == arg_pointer_rtx)
5689 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5691 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
5696 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5698 || (mode != DFmode && mode != DDmode)
5699 || (TARGET_E500_DOUBLE && mode != DDmode))
5700 && (TARGET_POWERPC64 || mode != DImode)
5701 && !avoiding_indexed_address_p (mode)
5702 && legitimate_indexed_address_p (x, reg_ok_strict))
5704 if (GET_CODE (x) == PRE_MODIFY
5708 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5710 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
5711 && (TARGET_POWERPC64 || mode != DImode)
5712 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5713 && !SPE_VECTOR_MODE (mode)
5714 /* Restrict addressing for DI because of our SUBREG hackery. */
5715 && !(TARGET_E500_DOUBLE
5716 && (mode == DFmode || mode == DDmode || mode == DImode))
5718 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
5719 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
5720 || (!avoiding_indexed_address_p (mode)
5721 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
5722 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5724 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
5729 /* Debug version of rs6000_legitimate_address_p. */
5731 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
5734 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
5736 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
5737 "strict = %d, code = %s\n",
5738 ret ? "true" : "false",
5739 GET_MODE_NAME (mode),
5741 GET_RTX_NAME (GET_CODE (x)));
5747 /* Go to LABEL if ADDR (a legitimate address expression)
5748 has an effect that depends on the machine mode it is used for.
5750 On the RS/6000 this is true of all integral offsets (since AltiVec
5751 and VSX modes don't allow them) or is a pre-increment or decrement.
5753 ??? Except that due to conceptual problems in offsettable_address_p
5754 we can't really report the problems of integral offsets. So leave
5755 this assuming that the adjustable offset must be valid for the
5756 sub-words of a TFmode operand, which is what we had before. */
5759 rs6000_mode_dependent_address (rtx addr)
5761 switch (GET_CODE (addr))
5764 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
5765 is considered a legitimate address before reload, so there
5766 are no offset restrictions in that case. Note that this
5767 condition is safe in strict mode because any address involving
5768 virtual_stack_vars_rtx or arg_pointer_rtx would already have
5769 been rejected as illegitimate. */
5770 if (XEXP (addr, 0) != virtual_stack_vars_rtx
5771 && XEXP (addr, 0) != arg_pointer_rtx
5772 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5774 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
5775 return val + 12 + 0x8000 >= 0x10000;
5782 /* Auto-increment cases are now treated generically in recog.c. */
5784 return TARGET_UPDATE;
5786 /* AND is only allowed in Altivec loads. */
5797 /* Debug version of rs6000_mode_dependent_address. */
5799 rs6000_debug_mode_dependent_address (rtx addr)
5801 bool ret = rs6000_mode_dependent_address (addr);
5803 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
5804 ret ? "true" : "false");
5810 /* Implement FIND_BASE_TERM. */
5813 rs6000_find_base_term (rtx op)
5817 split_const (op, &base, &offset);
5818 if (GET_CODE (base) == UNSPEC)
5819 switch (XINT (base, 1))
5822 case UNSPEC_MACHOPIC_OFFSET:
5823 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
5824 for aliasing purposes. */
5825 return XVECEXP (base, 0, 0);
5831 /* More elaborate version of recog's offsettable_memref_p predicate
5832 that works around the ??? note of rs6000_mode_dependent_address.
5833 In particular it accepts
5835 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
5837 in 32-bit mode, that the recog predicate rejects. */
5840 rs6000_offsettable_memref_p (rtx op)
5845 /* First mimic offsettable_memref_p. */
5846 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
5849 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
5850 the latter predicate knows nothing about the mode of the memory
5851 reference and, therefore, assumes that it is the largest supported
5852 mode (TFmode). As a consequence, legitimate offsettable memory
5853 references are rejected. rs6000_legitimate_offset_address_p contains
5854 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
5855 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
5858 /* Change register usage conditional on target flags. */
5860 rs6000_conditional_register_usage (void)
5864 /* Set MQ register fixed (already call_used) if not POWER
5865 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
5870 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
5872 fixed_regs[13] = call_used_regs[13]
5873 = call_really_used_regs[13] = 1;
5875 /* Conditionally disable FPRs. */
5876 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
5877 for (i = 32; i < 64; i++)
5878 fixed_regs[i] = call_used_regs[i]
5879 = call_really_used_regs[i] = 1;
5881 /* The TOC register is not killed across calls in a way that is
5882 visible to the compiler. */
5883 if (DEFAULT_ABI == ABI_AIX)
5884 call_really_used_regs[2] = 0;
5886 if (DEFAULT_ABI == ABI_V4
5887 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
5889 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5891 if (DEFAULT_ABI == ABI_V4
5892 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
5894 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5895 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5896 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5898 if (DEFAULT_ABI == ABI_DARWIN
5899 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
5900 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5901 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5902 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5904 if (TARGET_TOC && TARGET_MINIMAL_TOC)
5905 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5906 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5910 global_regs[SPEFSCR_REGNO] = 1;
5911 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
5912 registers in prologues and epilogues. We no longer use r14
5913 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
5914 pool for link-compatibility with older versions of GCC. Once
5915 "old" code has died out, we can return r14 to the allocation
5918 = call_used_regs[14]
5919 = call_really_used_regs[14] = 1;
5922 if (!TARGET_ALTIVEC && !TARGET_VSX)
5924 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
5925 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
5926 call_really_used_regs[VRSAVE_REGNO] = 1;
5929 if (TARGET_ALTIVEC || TARGET_VSX)
5930 global_regs[VSCR_REGNO] = 1;
5932 if (TARGET_ALTIVEC_ABI)
5934 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
5935 call_used_regs[i] = call_really_used_regs[i] = 1;
5937 /* AIX reserves VR20:31 in non-extended ABI mode. */
5939 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
5940 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
5944 /* Try to output insns to set TARGET equal to the constant C if it can
5945 be done in less than N insns. Do all computations in MODE.
5946 Returns the place where the output has been placed if it can be
5947 done and the insns have been emitted. If it would take more than N
5948 insns, zero is returned and no insns and emitted. */
5951 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
5952 rtx source, int n ATTRIBUTE_UNUSED)
5954 rtx result, insn, set;
5955 HOST_WIDE_INT c0, c1;
5962 dest = gen_reg_rtx (mode);
5963 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
5967 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
5969 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
5970 GEN_INT (INTVAL (source)
5971 & (~ (HOST_WIDE_INT) 0xffff))));
5972 emit_insn (gen_rtx_SET (VOIDmode, dest,
5973 gen_rtx_IOR (SImode, copy_rtx (result),
5974 GEN_INT (INTVAL (source) & 0xffff))));
5979 switch (GET_CODE (source))
5982 c0 = INTVAL (source);
5987 #if HOST_BITS_PER_WIDE_INT >= 64
5988 c0 = CONST_DOUBLE_LOW (source);
5991 c0 = CONST_DOUBLE_LOW (source);
5992 c1 = CONST_DOUBLE_HIGH (source);
6000 result = rs6000_emit_set_long_const (dest, c0, c1);
6007 insn = get_last_insn ();
6008 set = single_set (insn);
6009 if (! CONSTANT_P (SET_SRC (set)))
6010 set_unique_reg_note (insn, REG_EQUAL, source);
6015 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6016 fall back to a straight forward decomposition. We do this to avoid
6017 exponential run times encountered when looking for longer sequences
6018 with rs6000_emit_set_const. */
6020 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6022 if (!TARGET_POWERPC64)
6024 rtx operand1, operand2;
6026 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6028 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6030 emit_move_insn (operand1, GEN_INT (c1));
6031 emit_move_insn (operand2, GEN_INT (c2));
6035 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6038 ud2 = (c1 & 0xffff0000) >> 16;
6039 #if HOST_BITS_PER_WIDE_INT >= 64
6043 ud4 = (c2 & 0xffff0000) >> 16;
6045 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6046 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6049 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6051 emit_move_insn (dest, GEN_INT (ud1));
6054 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6055 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6058 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6061 emit_move_insn (dest, GEN_INT (ud2 << 16));
6063 emit_move_insn (copy_rtx (dest),
6064 gen_rtx_IOR (DImode, copy_rtx (dest),
6067 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6068 || (ud4 == 0 && ! (ud3 & 0x8000)))
6071 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6074 emit_move_insn (dest, GEN_INT (ud3 << 16));
6077 emit_move_insn (copy_rtx (dest),
6078 gen_rtx_IOR (DImode, copy_rtx (dest),
6080 emit_move_insn (copy_rtx (dest),
6081 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6084 emit_move_insn (copy_rtx (dest),
6085 gen_rtx_IOR (DImode, copy_rtx (dest),
6091 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6094 emit_move_insn (dest, GEN_INT (ud4 << 16));
6097 emit_move_insn (copy_rtx (dest),
6098 gen_rtx_IOR (DImode, copy_rtx (dest),
6101 emit_move_insn (copy_rtx (dest),
6102 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6105 emit_move_insn (copy_rtx (dest),
6106 gen_rtx_IOR (DImode, copy_rtx (dest),
6107 GEN_INT (ud2 << 16)));
6109 emit_move_insn (copy_rtx (dest),
6110 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6116 /* Helper for the following. Get rid of [r+r] memory refs
6117 in cases where it won't work (TImode, TFmode, TDmode). */
6120 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6122 if (GET_CODE (operands[0]) == MEM
6123 && GET_CODE (XEXP (operands[0], 0)) != REG
6124 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
6125 && ! reload_in_progress)
6127 = replace_equiv_address (operands[0],
6128 copy_addr_to_reg (XEXP (operands[0], 0)));
6130 if (GET_CODE (operands[1]) == MEM
6131 && GET_CODE (XEXP (operands[1], 0)) != REG
6132 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
6133 && ! reload_in_progress)
6135 = replace_equiv_address (operands[1],
6136 copy_addr_to_reg (XEXP (operands[1], 0)));
6139 /* Emit a move from SOURCE to DEST in mode MODE. */
6141 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6145 operands[1] = source;
6147 if (TARGET_DEBUG_ADDR)
6150 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6151 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6152 GET_MODE_NAME (mode),
6155 can_create_pseudo_p ());
6157 fprintf (stderr, "source:\n");
6161 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6162 if (GET_CODE (operands[1]) == CONST_DOUBLE
6163 && ! FLOAT_MODE_P (mode)
6164 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6166 /* FIXME. This should never happen. */
6167 /* Since it seems that it does, do the safe thing and convert
6169 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6171 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6172 || FLOAT_MODE_P (mode)
6173 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6174 || CONST_DOUBLE_LOW (operands[1]) < 0)
6175 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6176 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6178 /* Check if GCC is setting up a block move that will end up using FP
6179 registers as temporaries. We must make sure this is acceptable. */
6180 if (GET_CODE (operands[0]) == MEM
6181 && GET_CODE (operands[1]) == MEM
6183 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6184 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6185 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6186 ? 32 : MEM_ALIGN (operands[0])))
6187 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6189 : MEM_ALIGN (operands[1]))))
6190 && ! MEM_VOLATILE_P (operands [0])
6191 && ! MEM_VOLATILE_P (operands [1]))
6193 emit_move_insn (adjust_address (operands[0], SImode, 0),
6194 adjust_address (operands[1], SImode, 0));
6195 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6196 adjust_address (copy_rtx (operands[1]), SImode, 4));
6200 /* Fix up invalid (const (plus (symbol_ref) (reg))) that seems to be created
6201 in the secondary_reload phase, which evidently overwrites the CONST_INT
6203 if (GET_CODE (source) == CONST && GET_CODE (XEXP (source, 0)) == PLUS
6206 rtx add_op0 = XEXP (XEXP (source, 0), 0);
6207 rtx add_op1 = XEXP (XEXP (source, 0), 1);
6209 if (GET_CODE (add_op0) == SYMBOL_REF && GET_CODE (add_op1) == REG)
6211 rtx tmp = (can_create_pseudo_p ()) ? gen_reg_rtx (Pmode) : dest;
6213 if (TARGET_DEBUG_ADDR)
6215 fprintf (stderr, "\nrs6000_emit_move: bad source\n");
6219 rs6000_emit_move (tmp, add_op0, Pmode);
6220 emit_insn (gen_rtx_SET (VOIDmode, dest,
6221 gen_rtx_PLUS (Pmode, tmp, add_op1)));
6226 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6227 && !gpc_reg_operand (operands[1], mode))
6228 operands[1] = force_reg (mode, operands[1]);
6230 if (mode == SFmode && ! TARGET_POWERPC
6231 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6232 && GET_CODE (operands[0]) == MEM)
6236 if (reload_in_progress || reload_completed)
6237 regnum = true_regnum (operands[1]);
6238 else if (GET_CODE (operands[1]) == REG)
6239 regnum = REGNO (operands[1]);
6243 /* If operands[1] is a register, on POWER it may have
6244 double-precision data in it, so truncate it to single
6246 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6249 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6250 : gen_reg_rtx (mode));
6251 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6252 operands[1] = newreg;
6256 /* Recognize the case where operand[1] is a reference to thread-local
6257 data and load its address to a register. */
6258 if (rs6000_tls_referenced_p (operands[1]))
6260 enum tls_model model;
6261 rtx tmp = operands[1];
6264 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6266 addend = XEXP (XEXP (tmp, 0), 1);
6267 tmp = XEXP (XEXP (tmp, 0), 0);
6270 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6271 model = SYMBOL_REF_TLS_MODEL (tmp);
6272 gcc_assert (model != 0);
6274 tmp = rs6000_legitimize_tls_address (tmp, model);
6277 tmp = gen_rtx_PLUS (mode, tmp, addend);
6278 tmp = force_operand (tmp, operands[0]);
6283 /* Handle the case where reload calls us with an invalid address. */
6284 if (reload_in_progress && mode == Pmode
6285 && (! general_operand (operands[1], mode)
6286 || ! nonimmediate_operand (operands[0], mode)))
6289 /* 128-bit constant floating-point values on Darwin should really be
6290 loaded as two parts. */
6291 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6292 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6294 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6295 know how to get a DFmode SUBREG of a TFmode. */
6296 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6297 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6298 simplify_gen_subreg (imode, operands[1], mode, 0),
6300 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6301 GET_MODE_SIZE (imode)),
6302 simplify_gen_subreg (imode, operands[1], mode,
6303 GET_MODE_SIZE (imode)),
6308 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6309 cfun->machine->sdmode_stack_slot =
6310 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6312 if (reload_in_progress
6314 && MEM_P (operands[0])
6315 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6316 && REG_P (operands[1]))
6318 if (FP_REGNO_P (REGNO (operands[1])))
6320 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6321 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6322 emit_insn (gen_movsd_store (mem, operands[1]));
6324 else if (INT_REGNO_P (REGNO (operands[1])))
6326 rtx mem = adjust_address_nv (operands[0], mode, 4);
6327 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6328 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6334 if (reload_in_progress
6336 && REG_P (operands[0])
6337 && MEM_P (operands[1])
6338 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6340 if (FP_REGNO_P (REGNO (operands[0])))
6342 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6343 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6344 emit_insn (gen_movsd_load (operands[0], mem));
6346 else if (INT_REGNO_P (REGNO (operands[0])))
6348 rtx mem = adjust_address_nv (operands[1], mode, 4);
6349 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6350 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6357 /* FIXME: In the long term, this switch statement should go away
6358 and be replaced by a sequence of tests based on things like
6364 if (CONSTANT_P (operands[1])
6365 && GET_CODE (operands[1]) != CONST_INT)
6366 operands[1] = force_const_mem (mode, operands[1]);
6371 rs6000_eliminate_indexed_memrefs (operands);
6378 if (CONSTANT_P (operands[1])
6379 && ! easy_fp_constant (operands[1], mode))
6380 operands[1] = force_const_mem (mode, operands[1]);
6393 if (CONSTANT_P (operands[1])
6394 && !easy_vector_constant (operands[1], mode))
6395 operands[1] = force_const_mem (mode, operands[1]);
6400 /* Use default pattern for address of ELF small data */
6403 && DEFAULT_ABI == ABI_V4
6404 && (GET_CODE (operands[1]) == SYMBOL_REF
6405 || GET_CODE (operands[1]) == CONST)
6406 && small_data_operand (operands[1], mode))
6408 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6412 if (DEFAULT_ABI == ABI_V4
6413 && mode == Pmode && mode == SImode
6414 && flag_pic == 1 && got_operand (operands[1], mode))
6416 emit_insn (gen_movsi_got (operands[0], operands[1]));
6420 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6424 && CONSTANT_P (operands[1])
6425 && GET_CODE (operands[1]) != HIGH
6426 && GET_CODE (operands[1]) != CONST_INT)
6428 rtx target = (!can_create_pseudo_p ()
6430 : gen_reg_rtx (mode));
6432 /* If this is a function address on -mcall-aixdesc,
6433 convert it to the address of the descriptor. */
6434 if (DEFAULT_ABI == ABI_AIX
6435 && GET_CODE (operands[1]) == SYMBOL_REF
6436 && XSTR (operands[1], 0)[0] == '.')
6438 const char *name = XSTR (operands[1], 0);
6440 while (*name == '.')
6442 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6443 CONSTANT_POOL_ADDRESS_P (new_ref)
6444 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6445 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6446 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6447 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6448 operands[1] = new_ref;
6451 if (DEFAULT_ABI == ABI_DARWIN)
6454 if (MACHO_DYNAMIC_NO_PIC_P)
6456 /* Take care of any required data indirection. */
6457 operands[1] = rs6000_machopic_legitimize_pic_address (
6458 operands[1], mode, operands[0]);
6459 if (operands[0] != operands[1])
6460 emit_insn (gen_rtx_SET (VOIDmode,
6461 operands[0], operands[1]));
6465 emit_insn (gen_macho_high (target, operands[1]));
6466 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6470 emit_insn (gen_elf_high (target, operands[1]));
6471 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6475 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6476 and we have put it in the TOC, we just need to make a TOC-relative
6479 && GET_CODE (operands[1]) == SYMBOL_REF
6480 && constant_pool_expr_p (operands[1])
6481 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6482 get_pool_mode (operands[1])))
6484 operands[1] = create_TOC_reference (operands[1]);
6486 else if (mode == Pmode
6487 && CONSTANT_P (operands[1])
6488 && ((GET_CODE (operands[1]) != CONST_INT
6489 && ! easy_fp_constant (operands[1], mode))
6490 || (GET_CODE (operands[1]) == CONST_INT
6491 && num_insns_constant (operands[1], mode) > 2)
6492 || (GET_CODE (operands[0]) == REG
6493 && FP_REGNO_P (REGNO (operands[0]))))
6494 && GET_CODE (operands[1]) != HIGH
6495 && ! legitimate_constant_pool_address_p (operands[1])
6496 && ! toc_relative_expr_p (operands[1]))
6500 /* Darwin uses a special PIC legitimizer. */
6501 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
6504 rs6000_machopic_legitimize_pic_address (operands[1], mode,
6506 if (operands[0] != operands[1])
6507 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6512 /* If we are to limit the number of things we put in the TOC and
6513 this is a symbol plus a constant we can add in one insn,
6514 just put the symbol in the TOC and add the constant. Don't do
6515 this if reload is in progress. */
6516 if (GET_CODE (operands[1]) == CONST
6517 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
6518 && GET_CODE (XEXP (operands[1], 0)) == PLUS
6519 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
6520 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
6521 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
6522 && ! side_effects_p (operands[0]))
6525 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
6526 rtx other = XEXP (XEXP (operands[1], 0), 1);
6528 sym = force_reg (mode, sym);
6529 emit_insn (gen_add3_insn (operands[0], sym, other));
6533 operands[1] = force_const_mem (mode, operands[1]);
6536 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6537 && constant_pool_expr_p (XEXP (operands[1], 0))
6538 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
6539 get_pool_constant (XEXP (operands[1], 0)),
6540 get_pool_mode (XEXP (operands[1], 0))))
6543 = gen_const_mem (mode,
6544 create_TOC_reference (XEXP (operands[1], 0)));
6545 set_mem_alias_set (operands[1], get_TOC_alias_set ());
6551 rs6000_eliminate_indexed_memrefs (operands);
6555 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6557 gen_rtx_SET (VOIDmode,
6558 operands[0], operands[1]),
6559 gen_rtx_CLOBBER (VOIDmode,
6560 gen_rtx_SCRATCH (SImode)))));
6566 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
6569 /* Above, we may have called force_const_mem which may have returned
6570 an invalid address. If we can, fix this up; otherwise, reload will
6571 have to deal with it. */
6572 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
6573 operands[1] = validize_mem (operands[1]);
6576 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6579 /* Nonzero if we can use a floating-point register to pass this arg. */
6580 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
6581 (SCALAR_FLOAT_MODE_P (MODE) \
6582 && (CUM)->fregno <= FP_ARG_MAX_REG \
6583 && TARGET_HARD_FLOAT && TARGET_FPRS)
6585 /* Nonzero if we can use an AltiVec register to pass this arg. */
6586 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
6587 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
6588 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
6589 && TARGET_ALTIVEC_ABI \
6592 /* Return a nonzero value to say to return the function value in
6593 memory, just as large structures are always returned. TYPE will be
6594 the data type of the value, and FNTYPE will be the type of the
6595 function doing the returning, or @code{NULL} for libcalls.
6597 The AIX ABI for the RS/6000 specifies that all structures are
6598 returned in memory. The Darwin ABI does the same. The SVR4 ABI
6599 specifies that structures <= 8 bytes are returned in r3/r4, but a
6600 draft put them in memory, and GCC used to implement the draft
6601 instead of the final standard. Therefore, aix_struct_return
6602 controls this instead of DEFAULT_ABI; V.4 targets needing backward
6603 compatibility can change DRAFT_V4_STRUCT_RET to override the
6604 default, and -m switches get the final word. See
6605 rs6000_override_options for more details.
6607 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
6608 long double support is enabled. These values are returned in memory.
6610 int_size_in_bytes returns -1 for variable size objects, which go in
6611 memory always. The cast to unsigned makes -1 > 8. */
6614 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6616 /* In the darwin64 abi, try to use registers for larger structs
6618 if (rs6000_darwin64_abi
6619 && TREE_CODE (type) == RECORD_TYPE
6620 && int_size_in_bytes (type) > 0)
6622 CUMULATIVE_ARGS valcum;
6626 valcum.fregno = FP_ARG_MIN_REG;
6627 valcum.vregno = ALTIVEC_ARG_MIN_REG;
6628 /* Do a trial code generation as if this were going to be passed
6629 as an argument; if any part goes in memory, we return NULL. */
6630 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
6633 /* Otherwise fall through to more conventional ABI rules. */
6636 if (AGGREGATE_TYPE_P (type)
6637 && (aix_struct_return
6638 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
6641 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6642 modes only exist for GCC vector types if -maltivec. */
6643 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
6644 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6647 /* Return synthetic vectors in memory. */
6648 if (TREE_CODE (type) == VECTOR_TYPE
6649 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
6651 static bool warned_for_return_big_vectors = false;
6652 if (!warned_for_return_big_vectors)
6654 warning (0, "GCC vector returned by reference: "
6655 "non-standard ABI extension with no compatibility guarantee");
6656 warned_for_return_big_vectors = true;
6661 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
6667 /* Initialize a variable CUM of type CUMULATIVE_ARGS
6668 for a call to a function whose data type is FNTYPE.
6669 For a library call, FNTYPE is 0.
6671 For incoming args we set the number of arguments in the prototype large
6672 so we never return a PARALLEL. */
6675 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
6676 rtx libname ATTRIBUTE_UNUSED, int incoming,
6677 int libcall, int n_named_args)
6679 static CUMULATIVE_ARGS zero_cumulative;
6681 *cum = zero_cumulative;
6683 cum->fregno = FP_ARG_MIN_REG;
6684 cum->vregno = ALTIVEC_ARG_MIN_REG;
6685 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
6686 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
6687 ? CALL_LIBCALL : CALL_NORMAL);
6688 cum->sysv_gregno = GP_ARG_MIN_REG;
6689 cum->stdarg = fntype
6690 && (TYPE_ARG_TYPES (fntype) != 0
6691 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
6692 != void_type_node));
6694 cum->nargs_prototype = 0;
6695 if (incoming || cum->prototype)
6696 cum->nargs_prototype = n_named_args;
6698 /* Check for a longcall attribute. */
6699 if ((!fntype && rs6000_default_long_calls)
6701 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
6702 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
6703 cum->call_cookie |= CALL_LONG;
6705 if (TARGET_DEBUG_ARG)
6707 fprintf (stderr, "\ninit_cumulative_args:");
6710 tree ret_type = TREE_TYPE (fntype);
6711 fprintf (stderr, " ret code = %s,",
6712 tree_code_name[ (int)TREE_CODE (ret_type) ]);
6715 if (cum->call_cookie & CALL_LONG)
6716 fprintf (stderr, " longcall,");
6718 fprintf (stderr, " proto = %d, nargs = %d\n",
6719 cum->prototype, cum->nargs_prototype);
6724 && TARGET_ALTIVEC_ABI
6725 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
6727 error ("cannot return value in vector register because"
6728 " altivec instructions are disabled, use -maltivec"
6733 /* Return true if TYPE must be passed on the stack and not in registers. */
6736 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
6738 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
6739 return must_pass_in_stack_var_size (mode, type);
6741 return must_pass_in_stack_var_size_or_pad (mode, type);
6744 /* If defined, a C expression which determines whether, and in which
6745 direction, to pad out an argument with extra space. The value
6746 should be of type `enum direction': either `upward' to pad above
6747 the argument, `downward' to pad below, or `none' to inhibit
6750 For the AIX ABI structs are always stored left shifted in their
6754 function_arg_padding (enum machine_mode mode, const_tree type)
6756 #ifndef AGGREGATE_PADDING_FIXED
6757 #define AGGREGATE_PADDING_FIXED 0
6759 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
6760 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
6763 if (!AGGREGATE_PADDING_FIXED)
6765 /* GCC used to pass structures of the same size as integer types as
6766 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
6767 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6768 passed padded downward, except that -mstrict-align further
6769 muddied the water in that multi-component structures of 2 and 4
6770 bytes in size were passed padded upward.
6772 The following arranges for best compatibility with previous
6773 versions of gcc, but removes the -mstrict-align dependency. */
6774 if (BYTES_BIG_ENDIAN)
6776 HOST_WIDE_INT size = 0;
6778 if (mode == BLKmode)
6780 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
6781 size = int_size_in_bytes (type);
6784 size = GET_MODE_SIZE (mode);
6786 if (size == 1 || size == 2 || size == 4)
6792 if (AGGREGATES_PAD_UPWARD_ALWAYS)
6794 if (type != 0 && AGGREGATE_TYPE_P (type))
6798 /* Fall back to the default. */
6799 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
6802 /* If defined, a C expression that gives the alignment boundary, in bits,
6803 of an argument with the specified mode and type. If it is not defined,
6804 PARM_BOUNDARY is used for all arguments.
6806 V.4 wants long longs and doubles to be double word aligned. Just
6807 testing the mode size is a boneheaded way to do this as it means
6808 that other types such as complex int are also double word aligned.
6809 However, we're stuck with this because changing the ABI might break
6810 existing library interfaces.
6812 Doubleword align SPE vectors.
6813 Quadword align Altivec vectors.
6814 Quadword align large synthetic vector types. */
6817 function_arg_boundary (enum machine_mode mode, tree type)
6819 if (DEFAULT_ABI == ABI_V4
6820 && (GET_MODE_SIZE (mode) == 8
6821 || (TARGET_HARD_FLOAT
6823 && (mode == TFmode || mode == TDmode))))
6825 else if (SPE_VECTOR_MODE (mode)
6826 || (type && TREE_CODE (type) == VECTOR_TYPE
6827 && int_size_in_bytes (type) >= 8
6828 && int_size_in_bytes (type) < 16))
6830 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
6831 || (type && TREE_CODE (type) == VECTOR_TYPE
6832 && int_size_in_bytes (type) >= 16))
6834 else if (rs6000_darwin64_abi && mode == BLKmode
6835 && type && TYPE_ALIGN (type) > 64)
6838 return PARM_BOUNDARY;
6841 /* For a function parm of MODE and TYPE, return the starting word in
6842 the parameter area. NWORDS of the parameter area are already used. */
6845 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
6848 unsigned int parm_offset;
6850 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
6851 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
6852 return nwords + (-(parm_offset + nwords) & align);
6855 /* Compute the size (in words) of a function argument. */
6857 static unsigned long
6858 rs6000_arg_size (enum machine_mode mode, tree type)
6862 if (mode != BLKmode)
6863 size = GET_MODE_SIZE (mode);
6865 size = int_size_in_bytes (type);
6868 return (size + 3) >> 2;
6870 return (size + 7) >> 3;
6873 /* Use this to flush pending int fields. */
6876 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
6877 HOST_WIDE_INT bitpos)
6879 unsigned int startbit, endbit;
6880 int intregs, intoffset;
6881 enum machine_mode mode;
6883 if (cum->intoffset == -1)
6886 intoffset = cum->intoffset;
6887 cum->intoffset = -1;
6889 if (intoffset % BITS_PER_WORD != 0)
6891 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
6893 if (mode == BLKmode)
6895 /* We couldn't find an appropriate mode, which happens,
6896 e.g., in packed structs when there are 3 bytes to load.
6897 Back intoffset back to the beginning of the word in this
6899 intoffset = intoffset & -BITS_PER_WORD;
6903 startbit = intoffset & -BITS_PER_WORD;
6904 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
6905 intregs = (endbit - startbit) / BITS_PER_WORD;
6906 cum->words += intregs;
6909 /* The darwin64 ABI calls for us to recurse down through structs,
6910 looking for elements passed in registers. Unfortunately, we have
6911 to track int register count here also because of misalignments
6912 in powerpc alignment mode. */
6915 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
6917 HOST_WIDE_INT startbitpos)
6921 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
6922 if (TREE_CODE (f) == FIELD_DECL)
6924 HOST_WIDE_INT bitpos = startbitpos;
6925 tree ftype = TREE_TYPE (f);
6926 enum machine_mode mode;
6927 if (ftype == error_mark_node)
6929 mode = TYPE_MODE (ftype);
6931 if (DECL_SIZE (f) != 0
6932 && host_integerp (bit_position (f), 1))
6933 bitpos += int_bit_position (f);
6935 /* ??? FIXME: else assume zero offset. */
6937 if (TREE_CODE (ftype) == RECORD_TYPE)
6938 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
6939 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
6941 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
6942 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
6943 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
6945 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
6947 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
6951 else if (cum->intoffset == -1)
6952 cum->intoffset = bitpos;
6956 /* Update the data in CUM to advance over an argument
6957 of mode MODE and data type TYPE.
6958 (TYPE is null for libcalls where that information may not be available.)
6960 Note that for args passed by reference, function_arg will be called
6961 with MODE and TYPE set to that of the pointer to the arg, not the arg
6965 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
6966 tree type, int named, int depth)
6970 /* Only tick off an argument if we're not recursing. */
6972 cum->nargs_prototype--;
6974 if (TARGET_ALTIVEC_ABI
6975 && (ALTIVEC_VECTOR_MODE (mode)
6976 || VSX_VECTOR_MODE (mode)
6977 || (type && TREE_CODE (type) == VECTOR_TYPE
6978 && int_size_in_bytes (type) == 16)))
6982 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
6985 if (!TARGET_ALTIVEC)
6986 error ("cannot pass argument in vector register because"
6987 " altivec instructions are disabled, use -maltivec"
6990 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
6991 even if it is going to be passed in a vector register.
6992 Darwin does the same for variable-argument functions. */
6993 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6994 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7004 /* Vector parameters must be 16-byte aligned. This places
7005 them at 2 mod 4 in terms of words in 32-bit mode, since
7006 the parameter save area starts at offset 24 from the
7007 stack. In 64-bit mode, they just have to start on an
7008 even word, since the parameter save area is 16-byte
7009 aligned. Space for GPRs is reserved even if the argument
7010 will be passed in memory. */
7012 align = (2 - cum->words) & 3;
7014 align = cum->words & 1;
7015 cum->words += align + rs6000_arg_size (mode, type);
7017 if (TARGET_DEBUG_ARG)
7019 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7021 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7022 cum->nargs_prototype, cum->prototype,
7023 GET_MODE_NAME (mode));
7027 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7029 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7032 else if (rs6000_darwin64_abi
7034 && TREE_CODE (type) == RECORD_TYPE
7035 && (size = int_size_in_bytes (type)) > 0)
7037 /* Variable sized types have size == -1 and are
7038 treated as if consisting entirely of ints.
7039 Pad to 16 byte boundary if needed. */
7040 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7041 && (cum->words % 2) != 0)
7043 /* For varargs, we can just go up by the size of the struct. */
7045 cum->words += (size + 7) / 8;
7048 /* It is tempting to say int register count just goes up by
7049 sizeof(type)/8, but this is wrong in a case such as
7050 { int; double; int; } [powerpc alignment]. We have to
7051 grovel through the fields for these too. */
7053 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7054 rs6000_darwin64_record_arg_advance_flush (cum,
7055 size * BITS_PER_UNIT);
7058 else if (DEFAULT_ABI == ABI_V4)
7060 if (TARGET_HARD_FLOAT && TARGET_FPRS
7061 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7062 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7063 || (mode == TFmode && !TARGET_IEEEQUAD)
7064 || mode == SDmode || mode == DDmode || mode == TDmode))
7066 /* _Decimal128 must use an even/odd register pair. This assumes
7067 that the register number is odd when fregno is odd. */
7068 if (mode == TDmode && (cum->fregno % 2) == 1)
7071 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7072 <= FP_ARG_V4_MAX_REG)
7073 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7076 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7077 if (mode == DFmode || mode == TFmode
7078 || mode == DDmode || mode == TDmode)
7079 cum->words += cum->words & 1;
7080 cum->words += rs6000_arg_size (mode, type);
7085 int n_words = rs6000_arg_size (mode, type);
7086 int gregno = cum->sysv_gregno;
7088 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7089 (r7,r8) or (r9,r10). As does any other 2 word item such
7090 as complex int due to a historical mistake. */
7092 gregno += (1 - gregno) & 1;
7094 /* Multi-reg args are not split between registers and stack. */
7095 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7097 /* Long long and SPE vectors are aligned on the stack.
7098 So are other 2 word items such as complex int due to
7099 a historical mistake. */
7101 cum->words += cum->words & 1;
7102 cum->words += n_words;
7105 /* Note: continuing to accumulate gregno past when we've started
7106 spilling to the stack indicates the fact that we've started
7107 spilling to the stack to expand_builtin_saveregs. */
7108 cum->sysv_gregno = gregno + n_words;
7111 if (TARGET_DEBUG_ARG)
7113 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7114 cum->words, cum->fregno);
7115 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7116 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7117 fprintf (stderr, "mode = %4s, named = %d\n",
7118 GET_MODE_NAME (mode), named);
7123 int n_words = rs6000_arg_size (mode, type);
7124 int start_words = cum->words;
7125 int align_words = rs6000_parm_start (mode, type, start_words);
7127 cum->words = align_words + n_words;
7129 if (SCALAR_FLOAT_MODE_P (mode)
7130 && TARGET_HARD_FLOAT && TARGET_FPRS)
7132 /* _Decimal128 must be passed in an even/odd float register pair.
7133 This assumes that the register number is odd when fregno is
7135 if (mode == TDmode && (cum->fregno % 2) == 1)
7137 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7140 if (TARGET_DEBUG_ARG)
7142 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7143 cum->words, cum->fregno);
7144 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7145 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7146 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7147 named, align_words - start_words, depth);
7153 spe_build_register_parallel (enum machine_mode mode, int gregno)
7160 r1 = gen_rtx_REG (DImode, gregno);
7161 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7162 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7166 r1 = gen_rtx_REG (DImode, gregno);
7167 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7168 r3 = gen_rtx_REG (DImode, gregno + 2);
7169 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7170 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7173 r1 = gen_rtx_REG (DImode, gregno);
7174 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7175 r3 = gen_rtx_REG (DImode, gregno + 2);
7176 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7177 r5 = gen_rtx_REG (DImode, gregno + 4);
7178 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7179 r7 = gen_rtx_REG (DImode, gregno + 6);
7180 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7181 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7188 /* Determine where to put a SIMD argument on the SPE. */
7190 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7193 int gregno = cum->sysv_gregno;
7195 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7196 are passed and returned in a pair of GPRs for ABI compatibility. */
7197 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7198 || mode == DCmode || mode == TCmode))
7200 int n_words = rs6000_arg_size (mode, type);
7202 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7204 gregno += (1 - gregno) & 1;
7206 /* Multi-reg args are not split between registers and stack. */
7207 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7210 return spe_build_register_parallel (mode, gregno);
7214 int n_words = rs6000_arg_size (mode, type);
7216 /* SPE vectors are put in odd registers. */
7217 if (n_words == 2 && (gregno & 1) == 0)
7220 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7223 enum machine_mode m = SImode;
7225 r1 = gen_rtx_REG (m, gregno);
7226 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7227 r2 = gen_rtx_REG (m, gregno + 1);
7228 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7229 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7236 if (gregno <= GP_ARG_MAX_REG)
7237 return gen_rtx_REG (mode, gregno);
7243 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7244 structure between cum->intoffset and bitpos to integer registers. */
7247 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7248 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7250 enum machine_mode mode;
7252 unsigned int startbit, endbit;
7253 int this_regno, intregs, intoffset;
7256 if (cum->intoffset == -1)
7259 intoffset = cum->intoffset;
7260 cum->intoffset = -1;
7262 /* If this is the trailing part of a word, try to only load that
7263 much into the register. Otherwise load the whole register. Note
7264 that in the latter case we may pick up unwanted bits. It's not a
7265 problem at the moment but may wish to revisit. */
7267 if (intoffset % BITS_PER_WORD != 0)
7269 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7271 if (mode == BLKmode)
7273 /* We couldn't find an appropriate mode, which happens,
7274 e.g., in packed structs when there are 3 bytes to load.
7275 Back intoffset back to the beginning of the word in this
7277 intoffset = intoffset & -BITS_PER_WORD;
7284 startbit = intoffset & -BITS_PER_WORD;
7285 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7286 intregs = (endbit - startbit) / BITS_PER_WORD;
7287 this_regno = cum->words + intoffset / BITS_PER_WORD;
7289 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7292 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7296 intoffset /= BITS_PER_UNIT;
7299 regno = GP_ARG_MIN_REG + this_regno;
7300 reg = gen_rtx_REG (mode, regno);
7302 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7305 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7309 while (intregs > 0);
7312 /* Recursive workhorse for the following. */
7315 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7316 HOST_WIDE_INT startbitpos, rtx rvec[],
7321 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7322 if (TREE_CODE (f) == FIELD_DECL)
7324 HOST_WIDE_INT bitpos = startbitpos;
7325 tree ftype = TREE_TYPE (f);
7326 enum machine_mode mode;
7327 if (ftype == error_mark_node)
7329 mode = TYPE_MODE (ftype);
7331 if (DECL_SIZE (f) != 0
7332 && host_integerp (bit_position (f), 1))
7333 bitpos += int_bit_position (f);
7335 /* ??? FIXME: else assume zero offset. */
7337 if (TREE_CODE (ftype) == RECORD_TYPE)
7338 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7339 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7344 case SCmode: mode = SFmode; break;
7345 case DCmode: mode = DFmode; break;
7346 case TCmode: mode = TFmode; break;
7350 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7352 = gen_rtx_EXPR_LIST (VOIDmode,
7353 gen_rtx_REG (mode, cum->fregno++),
7354 GEN_INT (bitpos / BITS_PER_UNIT));
7355 if (mode == TFmode || mode == TDmode)
7358 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7360 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7362 = gen_rtx_EXPR_LIST (VOIDmode,
7363 gen_rtx_REG (mode, cum->vregno++),
7364 GEN_INT (bitpos / BITS_PER_UNIT));
7366 else if (cum->intoffset == -1)
7367 cum->intoffset = bitpos;
7371 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7372 the register(s) to be used for each field and subfield of a struct
7373 being passed by value, along with the offset of where the
7374 register's value may be found in the block. FP fields go in FP
7375 register, vector fields go in vector registers, and everything
7376 else goes in int registers, packed as in memory.
7378 This code is also used for function return values. RETVAL indicates
7379 whether this is the case.
7381 Much of this is taken from the SPARC V9 port, which has a similar
7382 calling convention. */
7385 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7386 int named, bool retval)
7388 rtx rvec[FIRST_PSEUDO_REGISTER];
7389 int k = 1, kbase = 1;
7390 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7391 /* This is a copy; modifications are not visible to our caller. */
7392 CUMULATIVE_ARGS copy_cum = *orig_cum;
7393 CUMULATIVE_ARGS *cum = ©_cum;
7395 /* Pad to 16 byte boundary if needed. */
7396 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7397 && (cum->words % 2) != 0)
7404 /* Put entries into rvec[] for individual FP and vector fields, and
7405 for the chunks of memory that go in int regs. Note we start at
7406 element 1; 0 is reserved for an indication of using memory, and
7407 may or may not be filled in below. */
7408 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7409 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7411 /* If any part of the struct went on the stack put all of it there.
7412 This hack is because the generic code for
7413 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7414 parts of the struct are not at the beginning. */
7418 return NULL_RTX; /* doesn't go in registers at all */
7420 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7422 if (k > 1 || cum->use_stack)
7423 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7428 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7431 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7435 rtx rvec[GP_ARG_NUM_REG + 1];
7437 if (align_words >= GP_ARG_NUM_REG)
7440 n_units = rs6000_arg_size (mode, type);
7442 /* Optimize the simple case where the arg fits in one gpr, except in
7443 the case of BLKmode due to assign_parms assuming that registers are
7444 BITS_PER_WORD wide. */
7446 || (n_units == 1 && mode != BLKmode))
7447 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7450 if (align_words + n_units > GP_ARG_NUM_REG)
7451 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7452 using a magic NULL_RTX component.
7453 This is not strictly correct. Only some of the arg belongs in
7454 memory, not all of it. However, the normal scheme using
7455 function_arg_partial_nregs can result in unusual subregs, eg.
7456 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7457 store the whole arg to memory is often more efficient than code
7458 to store pieces, and we know that space is available in the right
7459 place for the whole arg. */
7460 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7465 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7466 rtx off = GEN_INT (i++ * 4);
7467 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7469 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7471 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7474 /* Determine where to put an argument to a function.
7475 Value is zero to push the argument on the stack,
7476 or a hard register in which to store the argument.
7478 MODE is the argument's machine mode.
7479 TYPE is the data type of the argument (as a tree).
7480 This is null for libcalls where that information may
7482 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7483 the preceding args and about the function being called. It is
7484 not modified in this routine.
7485 NAMED is nonzero if this argument is a named parameter
7486 (otherwise it is an extra parameter matching an ellipsis).
7488 On RS/6000 the first eight words of non-FP are normally in registers
7489 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7490 Under V.4, the first 8 FP args are in registers.
7492 If this is floating-point and no prototype is specified, we use
7493 both an FP and integer register (or possibly FP reg and stack). Library
7494 functions (when CALL_LIBCALL is set) always have the proper types for args,
7495 so we can pass the FP value just in one register. emit_library_function
7496 doesn't support PARALLEL anyway.
7498 Note that for args passed by reference, function_arg will be called
7499 with MODE and TYPE set to that of the pointer to the arg, not the arg
7503 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7504 tree type, int named)
7506 enum rs6000_abi abi = DEFAULT_ABI;
7508 /* Return a marker to indicate whether CR1 needs to set or clear the
7509 bit that V.4 uses to say fp args were passed in registers.
7510 Assume that we don't need the marker for software floating point,
7511 or compiler generated library calls. */
7512 if (mode == VOIDmode)
7515 && (cum->call_cookie & CALL_LIBCALL) == 0
7517 || (cum->nargs_prototype < 0
7518 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7520 /* For the SPE, we need to crxor CR6 always. */
7522 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
7523 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
7524 return GEN_INT (cum->call_cookie
7525 | ((cum->fregno == FP_ARG_MIN_REG)
7526 ? CALL_V4_SET_FP_ARGS
7527 : CALL_V4_CLEAR_FP_ARGS));
7530 return GEN_INT (cum->call_cookie);
7533 if (rs6000_darwin64_abi && mode == BLKmode
7534 && TREE_CODE (type) == RECORD_TYPE)
7536 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
7537 if (rslt != NULL_RTX)
7539 /* Else fall through to usual handling. */
7542 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7543 if (TARGET_64BIT && ! cum->prototype)
7545 /* Vector parameters get passed in vector register
7546 and also in GPRs or memory, in absence of prototype. */
7549 align_words = (cum->words + 1) & ~1;
7551 if (align_words >= GP_ARG_NUM_REG)
7557 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7559 return gen_rtx_PARALLEL (mode,
7561 gen_rtx_EXPR_LIST (VOIDmode,
7563 gen_rtx_EXPR_LIST (VOIDmode,
7564 gen_rtx_REG (mode, cum->vregno),
7568 return gen_rtx_REG (mode, cum->vregno);
7569 else if (TARGET_ALTIVEC_ABI
7570 && (ALTIVEC_VECTOR_MODE (mode)
7571 || VSX_VECTOR_MODE (mode)
7572 || (type && TREE_CODE (type) == VECTOR_TYPE
7573 && int_size_in_bytes (type) == 16)))
7575 if (named || abi == ABI_V4)
7579 /* Vector parameters to varargs functions under AIX or Darwin
7580 get passed in memory and possibly also in GPRs. */
7581 int align, align_words, n_words;
7582 enum machine_mode part_mode;
7584 /* Vector parameters must be 16-byte aligned. This places them at
7585 2 mod 4 in terms of words in 32-bit mode, since the parameter
7586 save area starts at offset 24 from the stack. In 64-bit mode,
7587 they just have to start on an even word, since the parameter
7588 save area is 16-byte aligned. */
7590 align = (2 - cum->words) & 3;
7592 align = cum->words & 1;
7593 align_words = cum->words + align;
7595 /* Out of registers? Memory, then. */
7596 if (align_words >= GP_ARG_NUM_REG)
7599 if (TARGET_32BIT && TARGET_POWERPC64)
7600 return rs6000_mixed_function_arg (mode, type, align_words);
7602 /* The vector value goes in GPRs. Only the part of the
7603 value in GPRs is reported here. */
7605 n_words = rs6000_arg_size (mode, type);
7606 if (align_words + n_words > GP_ARG_NUM_REG)
7607 /* Fortunately, there are only two possibilities, the value
7608 is either wholly in GPRs or half in GPRs and half not. */
7611 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
7614 else if (TARGET_SPE_ABI && TARGET_SPE
7615 && (SPE_VECTOR_MODE (mode)
7616 || (TARGET_E500_DOUBLE && (mode == DFmode
7619 || mode == TCmode))))
7620 return rs6000_spe_function_arg (cum, mode, type);
7622 else if (abi == ABI_V4)
7624 if (TARGET_HARD_FLOAT && TARGET_FPRS
7625 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7626 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7627 || (mode == TFmode && !TARGET_IEEEQUAD)
7628 || mode == SDmode || mode == DDmode || mode == TDmode))
7630 /* _Decimal128 must use an even/odd register pair. This assumes
7631 that the register number is odd when fregno is odd. */
7632 if (mode == TDmode && (cum->fregno % 2) == 1)
7635 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7636 <= FP_ARG_V4_MAX_REG)
7637 return gen_rtx_REG (mode, cum->fregno);
7643 int n_words = rs6000_arg_size (mode, type);
7644 int gregno = cum->sysv_gregno;
7646 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7647 (r7,r8) or (r9,r10). As does any other 2 word item such
7648 as complex int due to a historical mistake. */
7650 gregno += (1 - gregno) & 1;
7652 /* Multi-reg args are not split between registers and stack. */
7653 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7656 if (TARGET_32BIT && TARGET_POWERPC64)
7657 return rs6000_mixed_function_arg (mode, type,
7658 gregno - GP_ARG_MIN_REG);
7659 return gen_rtx_REG (mode, gregno);
7664 int align_words = rs6000_parm_start (mode, type, cum->words);
7666 /* _Decimal128 must be passed in an even/odd float register pair.
7667 This assumes that the register number is odd when fregno is odd. */
7668 if (mode == TDmode && (cum->fregno % 2) == 1)
7671 if (USE_FP_FOR_ARG_P (cum, mode, type))
7673 rtx rvec[GP_ARG_NUM_REG + 1];
7677 enum machine_mode fmode = mode;
7678 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
7680 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
7682 /* Currently, we only ever need one reg here because complex
7683 doubles are split. */
7684 gcc_assert (cum->fregno == FP_ARG_MAX_REG
7685 && (fmode == TFmode || fmode == TDmode));
7687 /* Long double or _Decimal128 split over regs and memory. */
7688 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
7691 /* Do we also need to pass this arg in the parameter save
7694 && (cum->nargs_prototype <= 0
7695 || (DEFAULT_ABI == ABI_AIX
7697 && align_words >= GP_ARG_NUM_REG)));
7699 if (!needs_psave && mode == fmode)
7700 return gen_rtx_REG (fmode, cum->fregno);
7705 /* Describe the part that goes in gprs or the stack.
7706 This piece must come first, before the fprs. */
7707 if (align_words < GP_ARG_NUM_REG)
7709 unsigned long n_words = rs6000_arg_size (mode, type);
7711 if (align_words + n_words > GP_ARG_NUM_REG
7712 || (TARGET_32BIT && TARGET_POWERPC64))
7714 /* If this is partially on the stack, then we only
7715 include the portion actually in registers here. */
7716 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
7719 if (align_words + n_words > GP_ARG_NUM_REG)
7720 /* Not all of the arg fits in gprs. Say that it
7721 goes in memory too, using a magic NULL_RTX
7722 component. Also see comment in
7723 rs6000_mixed_function_arg for why the normal
7724 function_arg_partial_nregs scheme doesn't work
7726 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
7730 r = gen_rtx_REG (rmode,
7731 GP_ARG_MIN_REG + align_words);
7732 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
7733 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7735 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
7739 /* The whole arg fits in gprs. */
7740 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7741 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7745 /* It's entirely in memory. */
7746 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7749 /* Describe where this piece goes in the fprs. */
7750 r = gen_rtx_REG (fmode, cum->fregno);
7751 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7753 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7755 else if (align_words < GP_ARG_NUM_REG)
7757 if (TARGET_32BIT && TARGET_POWERPC64)
7758 return rs6000_mixed_function_arg (mode, type, align_words);
7760 if (mode == BLKmode)
7763 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7770 /* For an arg passed partly in registers and partly in memory, this is
7771 the number of bytes passed in registers. For args passed entirely in
7772 registers or entirely in memory, zero. When an arg is described by a
7773 PARALLEL, perhaps using more than one register type, this function
7774 returns the number of bytes used by the first element of the PARALLEL. */
7777 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7778 tree type, bool named)
7783 if (DEFAULT_ABI == ABI_V4)
7786 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
7787 && cum->nargs_prototype >= 0)
7790 /* In this complicated case we just disable the partial_nregs code. */
7791 if (rs6000_darwin64_abi && mode == BLKmode
7792 && TREE_CODE (type) == RECORD_TYPE
7793 && int_size_in_bytes (type) > 0)
7796 align_words = rs6000_parm_start (mode, type, cum->words);
7798 if (USE_FP_FOR_ARG_P (cum, mode, type))
7800 /* If we are passing this arg in the fixed parameter save area
7801 (gprs or memory) as well as fprs, then this function should
7802 return the number of partial bytes passed in the parameter
7803 save area rather than partial bytes passed in fprs. */
7805 && (cum->nargs_prototype <= 0
7806 || (DEFAULT_ABI == ABI_AIX
7808 && align_words >= GP_ARG_NUM_REG)))
7810 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
7811 > FP_ARG_MAX_REG + 1)
7812 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
7813 else if (cum->nargs_prototype >= 0)
7817 if (align_words < GP_ARG_NUM_REG
7818 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
7819 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
7821 if (ret != 0 && TARGET_DEBUG_ARG)
7822 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
7827 /* A C expression that indicates when an argument must be passed by
7828 reference. If nonzero for an argument, a copy of that argument is
7829 made in memory and a pointer to the argument is passed instead of
7830 the argument itself. The pointer is passed in whatever way is
7831 appropriate for passing a pointer to that type.
7833 Under V.4, aggregates and long double are passed by reference.
7835 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
7836 reference unless the AltiVec vector extension ABI is in force.
7838 As an extension to all ABIs, variable sized types are passed by
7842 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
7843 enum machine_mode mode, const_tree type,
7844 bool named ATTRIBUTE_UNUSED)
7846 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
7848 if (TARGET_DEBUG_ARG)
7849 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
7856 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
7858 if (TARGET_DEBUG_ARG)
7859 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
7863 if (int_size_in_bytes (type) < 0)
7865 if (TARGET_DEBUG_ARG)
7866 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
7870 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7871 modes only exist for GCC vector types if -maltivec. */
7872 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
7874 if (TARGET_DEBUG_ARG)
7875 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
7879 /* Pass synthetic vectors in memory. */
7880 if (TREE_CODE (type) == VECTOR_TYPE
7881 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7883 static bool warned_for_pass_big_vectors = false;
7884 if (TARGET_DEBUG_ARG)
7885 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
7886 if (!warned_for_pass_big_vectors)
7888 warning (0, "GCC vector passed by reference: "
7889 "non-standard ABI extension with no compatibility guarantee");
7890 warned_for_pass_big_vectors = true;
7899 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
7902 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
7907 for (i = 0; i < nregs; i++)
7909 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
7910 if (reload_completed)
7912 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
7915 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
7916 i * GET_MODE_SIZE (reg_mode));
7919 tem = replace_equiv_address (tem, XEXP (tem, 0));
7923 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
7927 /* Perform any needed actions needed for a function that is receiving a
7928 variable number of arguments.
7932 MODE and TYPE are the mode and type of the current parameter.
7934 PRETEND_SIZE is a variable that should be set to the amount of stack
7935 that must be pushed by the prolog to pretend that our caller pushed
7938 Normally, this macro will push all remaining incoming registers on the
7939 stack and set PRETEND_SIZE to the length of the registers pushed. */
7942 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7943 tree type, int *pretend_size ATTRIBUTE_UNUSED,
7946 CUMULATIVE_ARGS next_cum;
7947 int reg_size = TARGET_32BIT ? 4 : 8;
7948 rtx save_area = NULL_RTX, mem;
7949 int first_reg_offset;
7952 /* Skip the last named argument. */
7954 function_arg_advance (&next_cum, mode, type, 1, 0);
7956 if (DEFAULT_ABI == ABI_V4)
7958 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
7962 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
7963 HOST_WIDE_INT offset = 0;
7965 /* Try to optimize the size of the varargs save area.
7966 The ABI requires that ap.reg_save_area is doubleword
7967 aligned, but we don't need to allocate space for all
7968 the bytes, only those to which we actually will save
7970 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
7971 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
7972 if (TARGET_HARD_FLOAT && TARGET_FPRS
7973 && next_cum.fregno <= FP_ARG_V4_MAX_REG
7974 && cfun->va_list_fpr_size)
7977 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
7978 * UNITS_PER_FP_WORD;
7979 if (cfun->va_list_fpr_size
7980 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
7981 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
7983 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
7984 * UNITS_PER_FP_WORD;
7988 offset = -((first_reg_offset * reg_size) & ~7);
7989 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
7991 gpr_reg_num = cfun->va_list_gpr_size;
7992 if (reg_size == 4 && (first_reg_offset & 1))
7995 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
7998 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8000 - (int) (GP_ARG_NUM_REG * reg_size);
8002 if (gpr_size + fpr_size)
8005 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8006 gcc_assert (GET_CODE (reg_save_area) == MEM);
8007 reg_save_area = XEXP (reg_save_area, 0);
8008 if (GET_CODE (reg_save_area) == PLUS)
8010 gcc_assert (XEXP (reg_save_area, 0)
8011 == virtual_stack_vars_rtx);
8012 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8013 offset += INTVAL (XEXP (reg_save_area, 1));
8016 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8019 cfun->machine->varargs_save_offset = offset;
8020 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8025 first_reg_offset = next_cum.words;
8026 save_area = virtual_incoming_args_rtx;
8028 if (targetm.calls.must_pass_in_stack (mode, type))
8029 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8032 set = get_varargs_alias_set ();
8033 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8034 && cfun->va_list_gpr_size)
8036 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8038 if (va_list_gpr_counter_field)
8040 /* V4 va_list_gpr_size counts number of registers needed. */
8041 if (nregs > cfun->va_list_gpr_size)
8042 nregs = cfun->va_list_gpr_size;
8046 /* char * va_list instead counts number of bytes needed. */
8047 if (nregs > cfun->va_list_gpr_size / reg_size)
8048 nregs = cfun->va_list_gpr_size / reg_size;
8051 mem = gen_rtx_MEM (BLKmode,
8052 plus_constant (save_area,
8053 first_reg_offset * reg_size));
8054 MEM_NOTRAP_P (mem) = 1;
8055 set_mem_alias_set (mem, set);
8056 set_mem_align (mem, BITS_PER_WORD);
8058 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8062 /* Save FP registers if needed. */
8063 if (DEFAULT_ABI == ABI_V4
8064 && TARGET_HARD_FLOAT && TARGET_FPRS
8066 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8067 && cfun->va_list_fpr_size)
8069 int fregno = next_cum.fregno, nregs;
8070 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8071 rtx lab = gen_label_rtx ();
8072 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8073 * UNITS_PER_FP_WORD);
8076 (gen_rtx_SET (VOIDmode,
8078 gen_rtx_IF_THEN_ELSE (VOIDmode,
8079 gen_rtx_NE (VOIDmode, cr1,
8081 gen_rtx_LABEL_REF (VOIDmode, lab),
8085 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8086 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8088 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8090 plus_constant (save_area, off));
8091 MEM_NOTRAP_P (mem) = 1;
8092 set_mem_alias_set (mem, set);
8093 set_mem_align (mem, GET_MODE_ALIGNMENT (
8094 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8095 ? DFmode : SFmode));
8096 emit_move_insn (mem, gen_rtx_REG (
8097 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8098 ? DFmode : SFmode, fregno));
8105 /* Create the va_list data type. */
8108 rs6000_build_builtin_va_list (void)
8110 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8112 /* For AIX, prefer 'char *' because that's what the system
8113 header files like. */
8114 if (DEFAULT_ABI != ABI_V4)
8115 return build_pointer_type (char_type_node);
8117 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8118 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8119 get_identifier ("__va_list_tag"), record);
8121 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8122 unsigned_char_type_node);
8123 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8124 unsigned_char_type_node);
8125 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8127 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8128 get_identifier ("reserved"), short_unsigned_type_node);
8129 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8130 get_identifier ("overflow_arg_area"),
8132 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8133 get_identifier ("reg_save_area"),
8136 va_list_gpr_counter_field = f_gpr;
8137 va_list_fpr_counter_field = f_fpr;
8139 DECL_FIELD_CONTEXT (f_gpr) = record;
8140 DECL_FIELD_CONTEXT (f_fpr) = record;
8141 DECL_FIELD_CONTEXT (f_res) = record;
8142 DECL_FIELD_CONTEXT (f_ovf) = record;
8143 DECL_FIELD_CONTEXT (f_sav) = record;
8145 TREE_CHAIN (record) = type_decl;
8146 TYPE_NAME (record) = type_decl;
8147 TYPE_FIELDS (record) = f_gpr;
8148 TREE_CHAIN (f_gpr) = f_fpr;
8149 TREE_CHAIN (f_fpr) = f_res;
8150 TREE_CHAIN (f_res) = f_ovf;
8151 TREE_CHAIN (f_ovf) = f_sav;
8153 layout_type (record);
8155 /* The correct type is an array type of one element. */
8156 return build_array_type (record, build_index_type (size_zero_node));
8159 /* Implement va_start. */
8162 rs6000_va_start (tree valist, rtx nextarg)
8164 HOST_WIDE_INT words, n_gpr, n_fpr;
8165 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8166 tree gpr, fpr, ovf, sav, t;
8168 /* Only SVR4 needs something special. */
8169 if (DEFAULT_ABI != ABI_V4)
8171 std_expand_builtin_va_start (valist, nextarg);
8175 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8176 f_fpr = TREE_CHAIN (f_gpr);
8177 f_res = TREE_CHAIN (f_fpr);
8178 f_ovf = TREE_CHAIN (f_res);
8179 f_sav = TREE_CHAIN (f_ovf);
8181 valist = build_va_arg_indirect_ref (valist);
8182 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8183 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8185 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8187 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8190 /* Count number of gp and fp argument registers used. */
8191 words = crtl->args.info.words;
8192 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8194 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8197 if (TARGET_DEBUG_ARG)
8198 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8199 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8200 words, n_gpr, n_fpr);
8202 if (cfun->va_list_gpr_size)
8204 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8205 build_int_cst (NULL_TREE, n_gpr));
8206 TREE_SIDE_EFFECTS (t) = 1;
8207 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8210 if (cfun->va_list_fpr_size)
8212 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8213 build_int_cst (NULL_TREE, n_fpr));
8214 TREE_SIDE_EFFECTS (t) = 1;
8215 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8218 /* Find the overflow area. */
8219 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8221 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8222 size_int (words * UNITS_PER_WORD));
8223 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8224 TREE_SIDE_EFFECTS (t) = 1;
8225 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8227 /* If there were no va_arg invocations, don't set up the register
8229 if (!cfun->va_list_gpr_size
8230 && !cfun->va_list_fpr_size
8231 && n_gpr < GP_ARG_NUM_REG
8232 && n_fpr < FP_ARG_V4_MAX_REG)
8235 /* Find the register save area. */
8236 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8237 if (cfun->machine->varargs_save_offset)
8238 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8239 size_int (cfun->machine->varargs_save_offset));
8240 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8241 TREE_SIDE_EFFECTS (t) = 1;
8242 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8245 /* Implement va_arg. */
8248 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8251 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8252 tree gpr, fpr, ovf, sav, reg, t, u;
8253 int size, rsize, n_reg, sav_ofs, sav_scale;
8254 tree lab_false, lab_over, addr;
8256 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8260 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8262 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8263 return build_va_arg_indirect_ref (t);
8266 if (DEFAULT_ABI != ABI_V4)
8268 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8270 tree elem_type = TREE_TYPE (type);
8271 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8272 int elem_size = GET_MODE_SIZE (elem_mode);
8274 if (elem_size < UNITS_PER_WORD)
8276 tree real_part, imag_part;
8277 gimple_seq post = NULL;
8279 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8281 /* Copy the value into a temporary, lest the formal temporary
8282 be reused out from under us. */
8283 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8284 gimple_seq_add_seq (pre_p, post);
8286 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8289 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8293 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8296 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8297 f_fpr = TREE_CHAIN (f_gpr);
8298 f_res = TREE_CHAIN (f_fpr);
8299 f_ovf = TREE_CHAIN (f_res);
8300 f_sav = TREE_CHAIN (f_ovf);
8302 valist = build_va_arg_indirect_ref (valist);
8303 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8304 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8306 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8308 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8311 size = int_size_in_bytes (type);
8312 rsize = (size + 3) / 4;
8315 if (TARGET_HARD_FLOAT && TARGET_FPRS
8316 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8317 || (TARGET_DOUBLE_FLOAT
8318 && (TYPE_MODE (type) == DFmode
8319 || TYPE_MODE (type) == TFmode
8320 || TYPE_MODE (type) == SDmode
8321 || TYPE_MODE (type) == DDmode
8322 || TYPE_MODE (type) == TDmode))))
8324 /* FP args go in FP registers, if present. */
8326 n_reg = (size + 7) / 8;
8327 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8328 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8329 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8334 /* Otherwise into GP registers. */
8343 /* Pull the value out of the saved registers.... */
8346 addr = create_tmp_var (ptr_type_node, "addr");
8348 /* AltiVec vectors never go in registers when -mabi=altivec. */
8349 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8353 lab_false = create_artificial_label (input_location);
8354 lab_over = create_artificial_label (input_location);
8356 /* Long long and SPE vectors are aligned in the registers.
8357 As are any other 2 gpr item such as complex int due to a
8358 historical mistake. */
8360 if (n_reg == 2 && reg == gpr)
8363 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8364 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8365 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8366 unshare_expr (reg), u);
8368 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8369 reg number is 0 for f1, so we want to make it odd. */
8370 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8372 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8373 build_int_cst (TREE_TYPE (reg), 1));
8374 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8377 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8378 t = build2 (GE_EXPR, boolean_type_node, u, t);
8379 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8380 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8381 gimplify_and_add (t, pre_p);
8385 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8387 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8388 build_int_cst (TREE_TYPE (reg), n_reg));
8389 u = fold_convert (sizetype, u);
8390 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8391 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8393 /* _Decimal32 varargs are located in the second word of the 64-bit
8394 FP register for 32-bit binaries. */
8395 if (!TARGET_POWERPC64
8396 && TARGET_HARD_FLOAT && TARGET_FPRS
8397 && TYPE_MODE (type) == SDmode)
8398 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8400 gimplify_assign (addr, t, pre_p);
8402 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8404 stmt = gimple_build_label (lab_false);
8405 gimple_seq_add_stmt (pre_p, stmt);
8407 if ((n_reg == 2 && !regalign) || n_reg > 2)
8409 /* Ensure that we don't find any more args in regs.
8410 Alignment has taken care of for special cases. */
8411 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8415 /* ... otherwise out of the overflow area. */
8417 /* Care for on-stack alignment if needed. */
8421 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8422 t = fold_convert (sizetype, t);
8423 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8425 t = fold_convert (TREE_TYPE (ovf), t);
8427 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8429 gimplify_assign (unshare_expr (addr), t, pre_p);
8431 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8432 gimplify_assign (unshare_expr (ovf), t, pre_p);
8436 stmt = gimple_build_label (lab_over);
8437 gimple_seq_add_stmt (pre_p, stmt);
8440 if (STRICT_ALIGNMENT
8441 && (TYPE_ALIGN (type)
8442 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8444 /* The value (of type complex double, for example) may not be
8445 aligned in memory in the saved registers, so copy via a
8446 temporary. (This is the same code as used for SPARC.) */
8447 tree tmp = create_tmp_var (type, "va_arg_tmp");
8448 tree dest_addr = build_fold_addr_expr (tmp);
8450 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8451 3, dest_addr, addr, size_int (rsize * 4));
8453 gimplify_and_add (copy, pre_p);
8457 addr = fold_convert (ptrtype, addr);
8458 return build_va_arg_indirect_ref (addr);
8464 def_builtin (int mask, const char *name, tree type, int code)
8466 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8468 if (rs6000_builtin_decls[code])
8469 fatal_error ("internal error: builtin function to %s already processed.",
8472 rs6000_builtin_decls[code] =
8473 add_builtin_function (name, type, code, BUILT_IN_MD,
8478 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
8480 static const struct builtin_description bdesc_3arg[] =
8482 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
8483 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
8484 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
8485 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
8486 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
8487 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
8488 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
8489 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
8490 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
8491 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
8492 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
8493 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
8494 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
8495 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
8496 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
8497 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
8498 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
8499 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
8500 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
8501 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
8502 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
8503 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
8504 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
8505 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
8506 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
8507 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
8508 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
8509 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
8510 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
8511 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
8512 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
8513 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
8514 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
8515 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
8516 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
8518 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
8519 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
8520 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
8521 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
8522 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
8523 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
8524 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
8525 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
8526 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
8527 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
8528 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
8529 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
8530 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
8531 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
8532 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
8534 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
8535 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
8536 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
8537 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
8539 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
8540 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
8541 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
8542 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
8544 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
8545 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
8547 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
8548 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
8549 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
8550 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
8551 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
8552 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
8553 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
8554 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
8555 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
8556 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
8558 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
8559 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
8560 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
8561 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
8562 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
8563 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
8564 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
8565 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
8566 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
8567 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
8569 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
8570 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
8571 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
8572 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
8573 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
8574 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
8575 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
8576 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
8577 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
8579 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
8580 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
8581 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
8582 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
8583 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
8584 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
8585 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
8587 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
8588 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
8589 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
8590 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
8591 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
8592 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
8593 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
8594 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
8595 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
8598 /* DST operations: void foo (void *, const int, const char). */
8600 static const struct builtin_description bdesc_dst[] =
8602 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
8603 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
8604 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
8605 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
8607 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
8608 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
8609 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
8610 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
8613 /* Simple binary operations: VECc = foo (VECa, VECb). */
8615 static struct builtin_description bdesc_2arg[] =
8617 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
8618 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
8619 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
8620 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
8621 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
8622 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
8623 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
8624 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
8625 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
8626 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
8627 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
8628 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
8629 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
8630 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
8631 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
8632 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
8633 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
8634 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
8635 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
8636 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
8637 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
8638 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
8639 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
8640 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
8641 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
8642 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
8643 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
8644 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
8645 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
8646 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
8647 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
8648 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
8649 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
8650 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
8651 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
8652 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
8653 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
8654 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
8655 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
8656 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
8657 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
8658 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
8659 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
8660 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
8661 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
8662 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
8663 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
8664 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
8665 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
8666 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
8667 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
8668 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
8669 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
8670 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
8671 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
8672 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
8673 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
8674 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
8675 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
8676 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
8677 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
8678 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
8679 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
8680 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
8681 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
8682 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
8683 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
8684 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
8685 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
8686 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
8687 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
8688 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
8689 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
8690 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
8691 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
8692 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
8693 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
8694 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
8695 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
8696 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
8697 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
8698 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
8699 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
8700 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
8701 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
8702 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
8703 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
8704 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
8705 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
8706 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
8707 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
8708 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
8709 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
8710 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
8711 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
8712 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
8713 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
8714 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
8715 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
8716 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
8717 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
8718 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
8719 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
8720 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
8721 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
8722 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
8723 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
8724 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
8725 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
8726 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
8727 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
8728 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
8729 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
8730 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
8731 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
8732 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
8734 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
8735 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
8736 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
8737 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
8738 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
8739 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
8740 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
8741 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
8742 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
8743 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
8744 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
8746 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
8747 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
8748 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
8749 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
8750 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
8751 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
8752 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
8753 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
8754 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
8755 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
8756 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
8758 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
8759 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
8760 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
8761 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
8762 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
8763 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
8765 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
8766 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
8767 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
8768 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
8769 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
8770 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
8771 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
8772 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
8774 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
8775 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
8776 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
8777 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
8778 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
8779 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
8780 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
8781 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
8782 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
8783 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
8784 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
8785 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
8786 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
8787 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
8788 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
8789 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
8790 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
8791 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
8792 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
8793 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
8794 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
8795 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
8796 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
8797 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
8798 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
8799 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
8800 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
8801 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
8802 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
8803 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
8804 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
8805 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
8806 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
8807 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
8808 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
8809 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
8810 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
8811 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
8812 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
8813 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
8814 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
8815 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
8816 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
8817 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
8818 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
8819 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
8820 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
8821 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
8822 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
8823 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
8824 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
8825 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
8826 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
8827 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
8828 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
8829 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
8830 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
8831 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
8832 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
8833 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
8834 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
8835 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
8836 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
8837 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
8838 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
8839 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
8840 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
8841 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
8842 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
8843 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
8844 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
8845 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
8846 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
8847 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
8848 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
8849 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
8850 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
8851 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
8852 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
8853 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
8854 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
8855 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
8856 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
8857 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
8858 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
8859 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
8860 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
8861 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
8862 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
8863 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
8864 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
8865 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
8866 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
8867 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
8868 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
8869 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
8870 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
8871 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
8872 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
8873 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
8874 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
8875 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
8876 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
8877 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
8878 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
8879 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
8880 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
8881 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
8882 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
8883 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
8884 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
8885 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
8886 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
8887 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
8888 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
8889 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
8890 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
8891 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
8892 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
8893 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
8894 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
8895 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
8896 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
8897 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
8898 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
8899 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
8900 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
8901 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
8903 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
8904 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
8906 { 0, CODE_FOR_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
8907 { 0, CODE_FOR_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
8908 { 0, CODE_FOR_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
8909 { 0, CODE_FOR_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
8910 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
8911 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
8912 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
8913 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
8914 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
8915 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
8917 /* Place holder, leave as first spe builtin. */
8918 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
8919 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
8920 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
8921 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
8922 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
8923 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
8924 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
8925 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
8926 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
8927 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
8928 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
8929 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
8930 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
8931 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
8932 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
8933 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
8934 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
8935 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
8936 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
8937 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
8938 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
8939 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
8940 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
8941 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
8942 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
8943 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
8944 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
8945 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
8946 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
8947 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
8948 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
8949 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
8950 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
8951 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
8952 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
8953 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
8954 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
8955 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
8956 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
8957 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
8958 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
8959 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
8960 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
8961 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
8962 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
8963 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
8964 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
8965 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
8966 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
8967 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
8968 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
8969 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
8970 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
8971 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
8972 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
8973 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
8974 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
8975 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
8976 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
8977 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
8978 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
8979 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
8980 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
8981 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
8982 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
8983 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
8984 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
8985 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
8986 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
8987 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
8988 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
8989 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
8990 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
8991 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
8992 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
8993 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
8994 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
8995 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
8996 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
8997 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
8998 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
8999 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9000 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9001 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9002 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9003 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9004 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9005 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9006 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9007 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9008 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9009 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9010 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9011 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9012 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9013 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9014 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9015 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9016 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9017 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9018 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9019 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9020 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9021 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9022 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9023 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9024 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9025 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9026 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9028 /* SPE binary operations expecting a 5-bit unsigned literal. */
9029 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9031 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9032 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9033 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9034 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9035 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9036 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9037 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9038 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9039 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9040 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9041 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9042 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9043 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9044 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9045 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9046 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9047 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9048 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9049 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9050 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9051 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9052 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9053 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9054 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9055 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9056 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9058 /* Place-holder. Leave as last binary SPE builtin. */
9059 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9062 /* AltiVec predicates. */
9064 struct builtin_description_predicates
9066 const unsigned int mask;
9067 const enum insn_code icode;
9068 const char *const name;
9069 const enum rs6000_builtins code;
9072 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9074 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9075 ALTIVEC_BUILTIN_VCMPBFP_P },
9076 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9077 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9078 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9079 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9080 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9081 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9082 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9083 ALTIVEC_BUILTIN_VCMPEQUW_P },
9084 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9085 ALTIVEC_BUILTIN_VCMPGTSW_P },
9086 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9087 ALTIVEC_BUILTIN_VCMPGTUW_P },
9088 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9089 ALTIVEC_BUILTIN_VCMPEQUH_P },
9090 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9091 ALTIVEC_BUILTIN_VCMPGTSH_P },
9092 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9093 ALTIVEC_BUILTIN_VCMPGTUH_P },
9094 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9095 ALTIVEC_BUILTIN_VCMPEQUB_P },
9096 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9097 ALTIVEC_BUILTIN_VCMPGTSB_P },
9098 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9099 ALTIVEC_BUILTIN_VCMPGTUB_P },
9101 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9102 VSX_BUILTIN_XVCMPEQSP_P },
9103 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9104 VSX_BUILTIN_XVCMPGESP_P },
9105 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9106 VSX_BUILTIN_XVCMPGTSP_P },
9107 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9108 VSX_BUILTIN_XVCMPEQDP_P },
9109 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9110 VSX_BUILTIN_XVCMPGEDP_P },
9111 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9112 VSX_BUILTIN_XVCMPGTDP_P },
9114 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9115 ALTIVEC_BUILTIN_VCMPEQ_P },
9116 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9117 ALTIVEC_BUILTIN_VCMPGT_P },
9118 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9119 ALTIVEC_BUILTIN_VCMPGE_P }
9122 /* SPE predicates. */
9123 static struct builtin_description bdesc_spe_predicates[] =
9125 /* Place-holder. Leave as first. */
9126 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9127 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9128 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9129 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9130 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9131 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9132 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9133 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9134 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9135 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9136 /* Place-holder. Leave as last. */
9137 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9140 /* SPE evsel predicates. */
9141 static struct builtin_description bdesc_spe_evsel[] =
9143 /* Place-holder. Leave as first. */
9144 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9145 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9146 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9147 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9148 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9149 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9150 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9151 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9152 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9153 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9154 /* Place-holder. Leave as last. */
9155 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9158 /* PAIRED predicates. */
9159 static const struct builtin_description bdesc_paired_preds[] =
9161 /* Place-holder. Leave as first. */
9162 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9163 /* Place-holder. Leave as last. */
9164 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9167 /* ABS* operations. */
9169 static const struct builtin_description bdesc_abs[] =
9171 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9172 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9173 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9174 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9175 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9176 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9177 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9178 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9179 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9180 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9181 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9184 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9187 static struct builtin_description bdesc_1arg[] =
9189 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9190 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9191 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9192 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9193 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9194 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9195 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9196 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9197 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9198 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9199 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9200 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9201 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9202 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9203 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9204 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9205 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9207 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9208 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9209 { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9210 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9211 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9212 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9214 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9215 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9216 { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9217 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9218 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9219 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9221 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9222 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9223 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9224 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9225 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9226 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9228 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9229 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9230 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9231 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9232 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9233 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9235 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9236 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9237 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9238 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9240 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9241 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9242 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9243 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9244 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9245 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9246 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9247 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9248 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9250 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9251 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9252 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9253 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9254 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9255 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9256 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9257 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9258 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9260 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9261 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9262 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9263 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9264 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9266 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9267 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9268 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9269 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9270 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9271 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9272 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9273 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9274 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9275 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9276 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9277 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9278 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9279 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9280 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9281 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9282 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9283 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9284 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9286 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9287 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9288 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9290 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9291 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9292 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9293 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9295 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9296 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9297 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9298 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9299 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9300 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9301 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9302 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9303 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9304 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9305 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9306 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9307 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9308 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9309 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9310 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9311 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9312 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9313 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9314 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9315 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9316 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9317 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9318 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9319 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9320 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9321 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9322 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9323 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9324 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9326 /* Place-holder. Leave as last unary SPE builtin. */
9327 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9329 { 0, CODE_FOR_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9330 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9331 { 0, CODE_FOR_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9332 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9333 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9337 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9340 tree arg0 = CALL_EXPR_ARG (exp, 0);
9341 rtx op0 = expand_normal (arg0);
9342 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9343 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9345 if (icode == CODE_FOR_nothing)
9346 /* Builtin not supported on this processor. */
9349 /* If we got invalid arguments bail out before generating bad rtl. */
9350 if (arg0 == error_mark_node)
9353 if (icode == CODE_FOR_altivec_vspltisb
9354 || icode == CODE_FOR_altivec_vspltish
9355 || icode == CODE_FOR_altivec_vspltisw
9356 || icode == CODE_FOR_spe_evsplatfi
9357 || icode == CODE_FOR_spe_evsplati)
9359 /* Only allow 5-bit *signed* literals. */
9360 if (GET_CODE (op0) != CONST_INT
9361 || INTVAL (op0) > 15
9362 || INTVAL (op0) < -16)
9364 error ("argument 1 must be a 5-bit signed literal");
9370 || GET_MODE (target) != tmode
9371 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9372 target = gen_reg_rtx (tmode);
9374 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9375 op0 = copy_to_mode_reg (mode0, op0);
9377 pat = GEN_FCN (icode) (target, op0);
9386 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9388 rtx pat, scratch1, scratch2;
9389 tree arg0 = CALL_EXPR_ARG (exp, 0);
9390 rtx op0 = expand_normal (arg0);
9391 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9392 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9394 /* If we have invalid arguments, bail out before generating bad rtl. */
9395 if (arg0 == error_mark_node)
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 scratch1 = gen_reg_rtx (mode0);
9407 scratch2 = gen_reg_rtx (mode0);
9409 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9418 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
9421 tree arg0 = CALL_EXPR_ARG (exp, 0);
9422 tree arg1 = CALL_EXPR_ARG (exp, 1);
9423 rtx op0 = expand_normal (arg0);
9424 rtx op1 = expand_normal (arg1);
9425 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9426 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9427 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9429 if (icode == CODE_FOR_nothing)
9430 /* Builtin not supported on this processor. */
9433 /* If we got invalid arguments bail out before generating bad rtl. */
9434 if (arg0 == error_mark_node || arg1 == error_mark_node)
9437 if (icode == CODE_FOR_altivec_vcfux
9438 || icode == CODE_FOR_altivec_vcfsx
9439 || icode == CODE_FOR_altivec_vctsxs
9440 || icode == CODE_FOR_altivec_vctuxs
9441 || icode == CODE_FOR_altivec_vspltb
9442 || icode == CODE_FOR_altivec_vsplth
9443 || icode == CODE_FOR_altivec_vspltw
9444 || icode == CODE_FOR_spe_evaddiw
9445 || icode == CODE_FOR_spe_evldd
9446 || icode == CODE_FOR_spe_evldh
9447 || icode == CODE_FOR_spe_evldw
9448 || icode == CODE_FOR_spe_evlhhesplat
9449 || icode == CODE_FOR_spe_evlhhossplat
9450 || icode == CODE_FOR_spe_evlhhousplat
9451 || icode == CODE_FOR_spe_evlwhe
9452 || icode == CODE_FOR_spe_evlwhos
9453 || icode == CODE_FOR_spe_evlwhou
9454 || icode == CODE_FOR_spe_evlwhsplat
9455 || icode == CODE_FOR_spe_evlwwsplat
9456 || icode == CODE_FOR_spe_evrlwi
9457 || icode == CODE_FOR_spe_evslwi
9458 || icode == CODE_FOR_spe_evsrwis
9459 || icode == CODE_FOR_spe_evsubifw
9460 || icode == CODE_FOR_spe_evsrwiu)
9462 /* Only allow 5-bit unsigned literals. */
9464 if (TREE_CODE (arg1) != INTEGER_CST
9465 || TREE_INT_CST_LOW (arg1) & ~0x1f)
9467 error ("argument 2 must be a 5-bit unsigned literal");
9473 || GET_MODE (target) != tmode
9474 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9475 target = gen_reg_rtx (tmode);
9477 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9478 op0 = copy_to_mode_reg (mode0, op0);
9479 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9480 op1 = copy_to_mode_reg (mode1, op1);
9482 pat = GEN_FCN (icode) (target, op0, op1);
9491 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
9494 tree cr6_form = CALL_EXPR_ARG (exp, 0);
9495 tree arg0 = CALL_EXPR_ARG (exp, 1);
9496 tree arg1 = CALL_EXPR_ARG (exp, 2);
9497 rtx op0 = expand_normal (arg0);
9498 rtx op1 = expand_normal (arg1);
9499 enum machine_mode tmode = SImode;
9500 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9501 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9504 if (TREE_CODE (cr6_form) != INTEGER_CST)
9506 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9510 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
9512 gcc_assert (mode0 == mode1);
9514 /* If we have invalid arguments, bail out before generating bad rtl. */
9515 if (arg0 == error_mark_node || arg1 == error_mark_node)
9519 || GET_MODE (target) != tmode
9520 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9521 target = gen_reg_rtx (tmode);
9523 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9524 op0 = copy_to_mode_reg (mode0, op0);
9525 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9526 op1 = copy_to_mode_reg (mode1, op1);
9528 scratch = gen_reg_rtx (mode0);
9530 pat = GEN_FCN (icode) (scratch, op0, op1);
9535 /* The vec_any* and vec_all* predicates use the same opcodes for two
9536 different operations, but the bits in CR6 will be different
9537 depending on what information we want. So we have to play tricks
9538 with CR6 to get the right bits out.
9540 If you think this is disgusting, look at the specs for the
9541 AltiVec predicates. */
9543 switch (cr6_form_int)
9546 emit_insn (gen_cr6_test_for_zero (target));
9549 emit_insn (gen_cr6_test_for_zero_reverse (target));
9552 emit_insn (gen_cr6_test_for_lt (target));
9555 emit_insn (gen_cr6_test_for_lt_reverse (target));
9558 error ("argument 1 of __builtin_altivec_predicate is out of range");
9566 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
9569 tree arg0 = CALL_EXPR_ARG (exp, 0);
9570 tree arg1 = CALL_EXPR_ARG (exp, 1);
9571 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9572 enum machine_mode mode0 = Pmode;
9573 enum machine_mode mode1 = Pmode;
9574 rtx op0 = expand_normal (arg0);
9575 rtx op1 = expand_normal (arg1);
9577 if (icode == CODE_FOR_nothing)
9578 /* Builtin not supported on this processor. */
9581 /* If we got invalid arguments bail out before generating bad rtl. */
9582 if (arg0 == error_mark_node || arg1 == error_mark_node)
9586 || GET_MODE (target) != tmode
9587 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9588 target = gen_reg_rtx (tmode);
9590 op1 = copy_to_mode_reg (mode1, op1);
9592 if (op0 == const0_rtx)
9594 addr = gen_rtx_MEM (tmode, op1);
9598 op0 = copy_to_mode_reg (mode0, op0);
9599 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
9602 pat = GEN_FCN (icode) (target, addr);
9612 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
9615 tree arg0 = CALL_EXPR_ARG (exp, 0);
9616 tree arg1 = CALL_EXPR_ARG (exp, 1);
9617 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9618 enum machine_mode mode0 = Pmode;
9619 enum machine_mode mode1 = Pmode;
9620 rtx op0 = expand_normal (arg0);
9621 rtx op1 = expand_normal (arg1);
9623 if (icode == CODE_FOR_nothing)
9624 /* Builtin not supported on this processor. */
9627 /* If we got invalid arguments bail out before generating bad rtl. */
9628 if (arg0 == error_mark_node || arg1 == error_mark_node)
9632 || GET_MODE (target) != tmode
9633 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9634 target = gen_reg_rtx (tmode);
9636 op1 = copy_to_mode_reg (mode1, op1);
9638 if (op0 == const0_rtx)
9640 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
9644 op0 = copy_to_mode_reg (mode0, op0);
9645 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
9648 pat = GEN_FCN (icode) (target, addr);
9658 spe_expand_stv_builtin (enum insn_code icode, tree exp)
9660 tree arg0 = CALL_EXPR_ARG (exp, 0);
9661 tree arg1 = CALL_EXPR_ARG (exp, 1);
9662 tree arg2 = CALL_EXPR_ARG (exp, 2);
9663 rtx op0 = expand_normal (arg0);
9664 rtx op1 = expand_normal (arg1);
9665 rtx op2 = expand_normal (arg2);
9667 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
9668 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
9669 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
9671 /* Invalid arguments. Bail before doing anything stoopid! */
9672 if (arg0 == error_mark_node
9673 || arg1 == error_mark_node
9674 || arg2 == error_mark_node)
9677 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
9678 op0 = copy_to_mode_reg (mode2, op0);
9679 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
9680 op1 = copy_to_mode_reg (mode0, op1);
9681 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
9682 op2 = copy_to_mode_reg (mode1, op2);
9684 pat = GEN_FCN (icode) (op1, op2, op0);
9691 paired_expand_stv_builtin (enum insn_code icode, tree exp)
9693 tree arg0 = CALL_EXPR_ARG (exp, 0);
9694 tree arg1 = CALL_EXPR_ARG (exp, 1);
9695 tree arg2 = CALL_EXPR_ARG (exp, 2);
9696 rtx op0 = expand_normal (arg0);
9697 rtx op1 = expand_normal (arg1);
9698 rtx op2 = expand_normal (arg2);
9700 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9701 enum machine_mode mode1 = Pmode;
9702 enum machine_mode mode2 = Pmode;
9704 /* Invalid arguments. Bail before doing anything stoopid! */
9705 if (arg0 == error_mark_node
9706 || arg1 == error_mark_node
9707 || arg2 == error_mark_node)
9710 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9711 op0 = copy_to_mode_reg (tmode, op0);
9713 op2 = copy_to_mode_reg (mode2, op2);
9715 if (op1 == const0_rtx)
9717 addr = gen_rtx_MEM (tmode, op2);
9721 op1 = copy_to_mode_reg (mode1, op1);
9722 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9725 pat = GEN_FCN (icode) (addr, op0);
9732 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
9734 tree arg0 = CALL_EXPR_ARG (exp, 0);
9735 tree arg1 = CALL_EXPR_ARG (exp, 1);
9736 tree arg2 = CALL_EXPR_ARG (exp, 2);
9737 rtx op0 = expand_normal (arg0);
9738 rtx op1 = expand_normal (arg1);
9739 rtx op2 = expand_normal (arg2);
9741 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9742 enum machine_mode mode1 = Pmode;
9743 enum machine_mode mode2 = Pmode;
9745 /* Invalid arguments. Bail before doing anything stoopid! */
9746 if (arg0 == error_mark_node
9747 || arg1 == error_mark_node
9748 || arg2 == error_mark_node)
9751 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9752 op0 = copy_to_mode_reg (tmode, op0);
9754 op2 = copy_to_mode_reg (mode2, op2);
9756 if (op1 == const0_rtx)
9758 addr = gen_rtx_MEM (tmode, op2);
9762 op1 = copy_to_mode_reg (mode1, op1);
9763 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9766 pat = GEN_FCN (icode) (addr, op0);
9773 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
9776 tree arg0 = CALL_EXPR_ARG (exp, 0);
9777 tree arg1 = CALL_EXPR_ARG (exp, 1);
9778 tree arg2 = CALL_EXPR_ARG (exp, 2);
9779 rtx op0 = expand_normal (arg0);
9780 rtx op1 = expand_normal (arg1);
9781 rtx op2 = expand_normal (arg2);
9782 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9783 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9784 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9785 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
9787 if (icode == CODE_FOR_nothing)
9788 /* Builtin not supported on this processor. */
9791 /* If we got invalid arguments bail out before generating bad rtl. */
9792 if (arg0 == error_mark_node
9793 || arg1 == error_mark_node
9794 || arg2 == error_mark_node)
9799 case CODE_FOR_altivec_vsldoi_v4sf:
9800 case CODE_FOR_altivec_vsldoi_v4si:
9801 case CODE_FOR_altivec_vsldoi_v8hi:
9802 case CODE_FOR_altivec_vsldoi_v16qi:
9803 /* Only allow 4-bit unsigned literals. */
9805 if (TREE_CODE (arg2) != INTEGER_CST
9806 || TREE_INT_CST_LOW (arg2) & ~0xf)
9808 error ("argument 3 must be a 4-bit unsigned literal");
9813 case CODE_FOR_vsx_xxpermdi_v2df:
9814 case CODE_FOR_vsx_xxpermdi_v2di:
9815 case CODE_FOR_vsx_xxsldwi_v16qi:
9816 case CODE_FOR_vsx_xxsldwi_v8hi:
9817 case CODE_FOR_vsx_xxsldwi_v4si:
9818 case CODE_FOR_vsx_xxsldwi_v4sf:
9819 case CODE_FOR_vsx_xxsldwi_v2di:
9820 case CODE_FOR_vsx_xxsldwi_v2df:
9821 /* Only allow 2-bit unsigned literals. */
9823 if (TREE_CODE (arg2) != INTEGER_CST
9824 || TREE_INT_CST_LOW (arg2) & ~0x3)
9826 error ("argument 3 must be a 2-bit unsigned literal");
9831 case CODE_FOR_vsx_set_v2df:
9832 case CODE_FOR_vsx_set_v2di:
9833 /* Only allow 1-bit unsigned literals. */
9835 if (TREE_CODE (arg2) != INTEGER_CST
9836 || TREE_INT_CST_LOW (arg2) & ~0x1)
9838 error ("argument 3 must be a 1-bit unsigned literal");
9848 || GET_MODE (target) != tmode
9849 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9850 target = gen_reg_rtx (tmode);
9852 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9853 op0 = copy_to_mode_reg (mode0, op0);
9854 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9855 op1 = copy_to_mode_reg (mode1, op1);
9856 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
9857 op2 = copy_to_mode_reg (mode2, op2);
9859 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
9860 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
9862 pat = GEN_FCN (icode) (target, op0, op1, op2);
9870 /* Expand the lvx builtins. */
9872 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
9874 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9875 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9877 enum machine_mode tmode, mode0;
9879 enum insn_code icode;
9883 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
9884 icode = CODE_FOR_vector_load_v16qi;
9886 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
9887 icode = CODE_FOR_vector_load_v8hi;
9889 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
9890 icode = CODE_FOR_vector_load_v4si;
9892 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
9893 icode = CODE_FOR_vector_load_v4sf;
9902 arg0 = CALL_EXPR_ARG (exp, 0);
9903 op0 = expand_normal (arg0);
9904 tmode = insn_data[icode].operand[0].mode;
9905 mode0 = insn_data[icode].operand[1].mode;
9908 || GET_MODE (target) != tmode
9909 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9910 target = gen_reg_rtx (tmode);
9912 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9913 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
9915 pat = GEN_FCN (icode) (target, op0);
9922 /* Expand the stvx builtins. */
9924 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
9927 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9928 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9930 enum machine_mode mode0, mode1;
9932 enum insn_code icode;
9936 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
9937 icode = CODE_FOR_vector_store_v16qi;
9939 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
9940 icode = CODE_FOR_vector_store_v8hi;
9942 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
9943 icode = CODE_FOR_vector_store_v4si;
9945 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
9946 icode = CODE_FOR_vector_store_v4sf;
9953 arg0 = CALL_EXPR_ARG (exp, 0);
9954 arg1 = CALL_EXPR_ARG (exp, 1);
9955 op0 = expand_normal (arg0);
9956 op1 = expand_normal (arg1);
9957 mode0 = insn_data[icode].operand[0].mode;
9958 mode1 = insn_data[icode].operand[1].mode;
9960 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
9961 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
9962 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
9963 op1 = copy_to_mode_reg (mode1, op1);
9965 pat = GEN_FCN (icode) (op0, op1);
9973 /* Expand the dst builtins. */
9975 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
9978 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9979 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9980 tree arg0, arg1, arg2;
9981 enum machine_mode mode0, mode1, mode2;
9982 rtx pat, op0, op1, op2;
9983 const struct builtin_description *d;
9988 /* Handle DST variants. */
9990 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
9991 if (d->code == fcode)
9993 arg0 = CALL_EXPR_ARG (exp, 0);
9994 arg1 = CALL_EXPR_ARG (exp, 1);
9995 arg2 = CALL_EXPR_ARG (exp, 2);
9996 op0 = expand_normal (arg0);
9997 op1 = expand_normal (arg1);
9998 op2 = expand_normal (arg2);
9999 mode0 = insn_data[d->icode].operand[0].mode;
10000 mode1 = insn_data[d->icode].operand[1].mode;
10001 mode2 = insn_data[d->icode].operand[2].mode;
10003 /* Invalid arguments, bail out before generating bad rtl. */
10004 if (arg0 == error_mark_node
10005 || arg1 == error_mark_node
10006 || arg2 == error_mark_node)
10011 if (TREE_CODE (arg2) != INTEGER_CST
10012 || TREE_INT_CST_LOW (arg2) & ~0x3)
10014 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10018 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10019 op0 = copy_to_mode_reg (Pmode, op0);
10020 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10021 op1 = copy_to_mode_reg (mode1, op1);
10023 pat = GEN_FCN (d->icode) (op0, op1, op2);
10033 /* Expand vec_init builtin. */
10035 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10037 enum machine_mode tmode = TYPE_MODE (type);
10038 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10039 int i, n_elt = GET_MODE_NUNITS (tmode);
10040 rtvec v = rtvec_alloc (n_elt);
10042 gcc_assert (VECTOR_MODE_P (tmode));
10043 gcc_assert (n_elt == call_expr_nargs (exp));
10045 for (i = 0; i < n_elt; ++i)
10047 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10048 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10051 if (!target || !register_operand (target, tmode))
10052 target = gen_reg_rtx (tmode);
10054 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10058 /* Return the integer constant in ARG. Constrain it to be in the range
10059 of the subparts of VEC_TYPE; issue an error if not. */
10062 get_element_number (tree vec_type, tree arg)
10064 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10066 if (!host_integerp (arg, 1)
10067 || (elt = tree_low_cst (arg, 1), elt > max))
10069 error ("selector must be an integer constant in the range 0..%wi", max);
10076 /* Expand vec_set builtin. */
10078 altivec_expand_vec_set_builtin (tree exp)
10080 enum machine_mode tmode, mode1;
10081 tree arg0, arg1, arg2;
10085 arg0 = CALL_EXPR_ARG (exp, 0);
10086 arg1 = CALL_EXPR_ARG (exp, 1);
10087 arg2 = CALL_EXPR_ARG (exp, 2);
10089 tmode = TYPE_MODE (TREE_TYPE (arg0));
10090 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10091 gcc_assert (VECTOR_MODE_P (tmode));
10093 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10094 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10095 elt = get_element_number (TREE_TYPE (arg0), arg2);
10097 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10098 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10100 op0 = force_reg (tmode, op0);
10101 op1 = force_reg (mode1, op1);
10103 rs6000_expand_vector_set (op0, op1, elt);
10108 /* Expand vec_ext builtin. */
10110 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10112 enum machine_mode tmode, mode0;
10117 arg0 = CALL_EXPR_ARG (exp, 0);
10118 arg1 = CALL_EXPR_ARG (exp, 1);
10120 op0 = expand_normal (arg0);
10121 elt = get_element_number (TREE_TYPE (arg0), arg1);
10123 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10124 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10125 gcc_assert (VECTOR_MODE_P (mode0));
10127 op0 = force_reg (mode0, op0);
10129 if (optimize || !target || !register_operand (target, tmode))
10130 target = gen_reg_rtx (tmode);
10132 rs6000_expand_vector_extract (target, op0, elt);
10137 /* Expand the builtin in EXP and store the result in TARGET. Store
10138 true in *EXPANDEDP if we found a builtin to expand. */
10140 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10142 const struct builtin_description *d;
10143 const struct builtin_description_predicates *dp;
10145 enum insn_code icode;
10146 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10149 enum machine_mode tmode, mode0;
10150 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10152 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10153 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10154 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10155 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10158 error ("unresolved overload for Altivec builtin %qF", fndecl);
10162 target = altivec_expand_ld_builtin (exp, target, expandedp);
10166 target = altivec_expand_st_builtin (exp, target, expandedp);
10170 target = altivec_expand_dst_builtin (exp, target, expandedp);
10178 case ALTIVEC_BUILTIN_STVX:
10179 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10180 case ALTIVEC_BUILTIN_STVEBX:
10181 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10182 case ALTIVEC_BUILTIN_STVEHX:
10183 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10184 case ALTIVEC_BUILTIN_STVEWX:
10185 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10186 case ALTIVEC_BUILTIN_STVXL:
10187 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10189 case ALTIVEC_BUILTIN_STVLX:
10190 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10191 case ALTIVEC_BUILTIN_STVLXL:
10192 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10193 case ALTIVEC_BUILTIN_STVRX:
10194 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10195 case ALTIVEC_BUILTIN_STVRXL:
10196 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10198 case ALTIVEC_BUILTIN_MFVSCR:
10199 icode = CODE_FOR_altivec_mfvscr;
10200 tmode = insn_data[icode].operand[0].mode;
10203 || GET_MODE (target) != tmode
10204 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10205 target = gen_reg_rtx (tmode);
10207 pat = GEN_FCN (icode) (target);
10213 case ALTIVEC_BUILTIN_MTVSCR:
10214 icode = CODE_FOR_altivec_mtvscr;
10215 arg0 = CALL_EXPR_ARG (exp, 0);
10216 op0 = expand_normal (arg0);
10217 mode0 = insn_data[icode].operand[0].mode;
10219 /* If we got invalid arguments bail out before generating bad rtl. */
10220 if (arg0 == error_mark_node)
10223 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10224 op0 = copy_to_mode_reg (mode0, op0);
10226 pat = GEN_FCN (icode) (op0);
10231 case ALTIVEC_BUILTIN_DSSALL:
10232 emit_insn (gen_altivec_dssall ());
10235 case ALTIVEC_BUILTIN_DSS:
10236 icode = CODE_FOR_altivec_dss;
10237 arg0 = CALL_EXPR_ARG (exp, 0);
10239 op0 = expand_normal (arg0);
10240 mode0 = insn_data[icode].operand[0].mode;
10242 /* If we got invalid arguments bail out before generating bad rtl. */
10243 if (arg0 == error_mark_node)
10246 if (TREE_CODE (arg0) != INTEGER_CST
10247 || TREE_INT_CST_LOW (arg0) & ~0x3)
10249 error ("argument to dss must be a 2-bit unsigned literal");
10253 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10254 op0 = copy_to_mode_reg (mode0, op0);
10256 emit_insn (gen_altivec_dss (op0));
10259 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10260 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10261 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10262 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10263 case VSX_BUILTIN_VEC_INIT_V2DF:
10264 case VSX_BUILTIN_VEC_INIT_V2DI:
10265 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10267 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10268 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10269 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10270 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10271 case VSX_BUILTIN_VEC_SET_V2DF:
10272 case VSX_BUILTIN_VEC_SET_V2DI:
10273 return altivec_expand_vec_set_builtin (exp);
10275 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10276 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10277 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10278 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10279 case VSX_BUILTIN_VEC_EXT_V2DF:
10280 case VSX_BUILTIN_VEC_EXT_V2DI:
10281 return altivec_expand_vec_ext_builtin (exp, target);
10285 /* Fall through. */
10288 /* Expand abs* operations. */
10290 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10291 if (d->code == fcode)
10292 return altivec_expand_abs_builtin (d->icode, exp, target);
10294 /* Expand the AltiVec predicates. */
10295 dp = bdesc_altivec_preds;
10296 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10297 if (dp->code == fcode)
10298 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10300 /* LV* are funky. We initialized them differently. */
10303 case ALTIVEC_BUILTIN_LVSL:
10304 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10305 exp, target, false);
10306 case ALTIVEC_BUILTIN_LVSR:
10307 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10308 exp, target, false);
10309 case ALTIVEC_BUILTIN_LVEBX:
10310 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10311 exp, target, false);
10312 case ALTIVEC_BUILTIN_LVEHX:
10313 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10314 exp, target, false);
10315 case ALTIVEC_BUILTIN_LVEWX:
10316 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10317 exp, target, false);
10318 case ALTIVEC_BUILTIN_LVXL:
10319 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10320 exp, target, false);
10321 case ALTIVEC_BUILTIN_LVX:
10322 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10323 exp, target, false);
10324 case ALTIVEC_BUILTIN_LVLX:
10325 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10326 exp, target, true);
10327 case ALTIVEC_BUILTIN_LVLXL:
10328 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10329 exp, target, true);
10330 case ALTIVEC_BUILTIN_LVRX:
10331 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10332 exp, target, true);
10333 case ALTIVEC_BUILTIN_LVRXL:
10334 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10335 exp, target, true);
10338 /* Fall through. */
10341 *expandedp = false;
10345 /* Expand the builtin in EXP and store the result in TARGET. Store
10346 true in *EXPANDEDP if we found a builtin to expand. */
10348 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10350 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10351 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10352 const struct builtin_description *d;
10359 case PAIRED_BUILTIN_STX:
10360 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10361 case PAIRED_BUILTIN_LX:
10362 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10365 /* Fall through. */
10368 /* Expand the paired predicates. */
10369 d = bdesc_paired_preds;
10370 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10371 if (d->code == fcode)
10372 return paired_expand_predicate_builtin (d->icode, exp, target);
10374 *expandedp = false;
10378 /* Binops that need to be initialized manually, but can be expanded
10379 automagically by rs6000_expand_binop_builtin. */
10380 static struct builtin_description bdesc_2arg_spe[] =
10382 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10383 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10384 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10385 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10386 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10387 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10388 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10389 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10390 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10391 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10392 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10393 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10394 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10395 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10396 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10397 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10398 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10399 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10400 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10401 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10402 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10403 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10406 /* Expand the builtin in EXP and store the result in TARGET. Store
10407 true in *EXPANDEDP if we found a builtin to expand.
10409 This expands the SPE builtins that are not simple unary and binary
10412 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10414 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10416 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10417 enum insn_code icode;
10418 enum machine_mode tmode, mode0;
10420 struct builtin_description *d;
10425 /* Syntax check for a 5-bit unsigned immediate. */
10428 case SPE_BUILTIN_EVSTDD:
10429 case SPE_BUILTIN_EVSTDH:
10430 case SPE_BUILTIN_EVSTDW:
10431 case SPE_BUILTIN_EVSTWHE:
10432 case SPE_BUILTIN_EVSTWHO:
10433 case SPE_BUILTIN_EVSTWWE:
10434 case SPE_BUILTIN_EVSTWWO:
10435 arg1 = CALL_EXPR_ARG (exp, 2);
10436 if (TREE_CODE (arg1) != INTEGER_CST
10437 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10439 error ("argument 2 must be a 5-bit unsigned literal");
10447 /* The evsplat*i instructions are not quite generic. */
10450 case SPE_BUILTIN_EVSPLATFI:
10451 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
10453 case SPE_BUILTIN_EVSPLATI:
10454 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
10460 d = (struct builtin_description *) bdesc_2arg_spe;
10461 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
10462 if (d->code == fcode)
10463 return rs6000_expand_binop_builtin (d->icode, exp, target);
10465 d = (struct builtin_description *) bdesc_spe_predicates;
10466 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
10467 if (d->code == fcode)
10468 return spe_expand_predicate_builtin (d->icode, exp, target);
10470 d = (struct builtin_description *) bdesc_spe_evsel;
10471 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
10472 if (d->code == fcode)
10473 return spe_expand_evsel_builtin (d->icode, exp, target);
10477 case SPE_BUILTIN_EVSTDDX:
10478 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
10479 case SPE_BUILTIN_EVSTDHX:
10480 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
10481 case SPE_BUILTIN_EVSTDWX:
10482 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
10483 case SPE_BUILTIN_EVSTWHEX:
10484 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
10485 case SPE_BUILTIN_EVSTWHOX:
10486 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
10487 case SPE_BUILTIN_EVSTWWEX:
10488 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
10489 case SPE_BUILTIN_EVSTWWOX:
10490 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
10491 case SPE_BUILTIN_EVSTDD:
10492 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
10493 case SPE_BUILTIN_EVSTDH:
10494 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
10495 case SPE_BUILTIN_EVSTDW:
10496 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
10497 case SPE_BUILTIN_EVSTWHE:
10498 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
10499 case SPE_BUILTIN_EVSTWHO:
10500 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
10501 case SPE_BUILTIN_EVSTWWE:
10502 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
10503 case SPE_BUILTIN_EVSTWWO:
10504 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
10505 case SPE_BUILTIN_MFSPEFSCR:
10506 icode = CODE_FOR_spe_mfspefscr;
10507 tmode = insn_data[icode].operand[0].mode;
10510 || GET_MODE (target) != tmode
10511 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10512 target = gen_reg_rtx (tmode);
10514 pat = GEN_FCN (icode) (target);
10519 case SPE_BUILTIN_MTSPEFSCR:
10520 icode = CODE_FOR_spe_mtspefscr;
10521 arg0 = CALL_EXPR_ARG (exp, 0);
10522 op0 = expand_normal (arg0);
10523 mode0 = insn_data[icode].operand[0].mode;
10525 if (arg0 == error_mark_node)
10528 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10529 op0 = copy_to_mode_reg (mode0, op0);
10531 pat = GEN_FCN (icode) (op0);
10539 *expandedp = false;
10544 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10546 rtx pat, scratch, tmp;
10547 tree form = CALL_EXPR_ARG (exp, 0);
10548 tree arg0 = CALL_EXPR_ARG (exp, 1);
10549 tree arg1 = CALL_EXPR_ARG (exp, 2);
10550 rtx op0 = expand_normal (arg0);
10551 rtx op1 = expand_normal (arg1);
10552 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10553 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10555 enum rtx_code code;
10557 if (TREE_CODE (form) != INTEGER_CST)
10559 error ("argument 1 of __builtin_paired_predicate must be a constant");
10563 form_int = TREE_INT_CST_LOW (form);
10565 gcc_assert (mode0 == mode1);
10567 if (arg0 == error_mark_node || arg1 == error_mark_node)
10571 || GET_MODE (target) != SImode
10572 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
10573 target = gen_reg_rtx (SImode);
10574 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10575 op0 = copy_to_mode_reg (mode0, op0);
10576 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10577 op1 = copy_to_mode_reg (mode1, op1);
10579 scratch = gen_reg_rtx (CCFPmode);
10581 pat = GEN_FCN (icode) (scratch, op0, op1);
10603 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10606 error ("argument 1 of __builtin_paired_predicate is out of range");
10610 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10611 emit_move_insn (target, tmp);
10616 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10618 rtx pat, scratch, tmp;
10619 tree form = CALL_EXPR_ARG (exp, 0);
10620 tree arg0 = CALL_EXPR_ARG (exp, 1);
10621 tree arg1 = CALL_EXPR_ARG (exp, 2);
10622 rtx op0 = expand_normal (arg0);
10623 rtx op1 = expand_normal (arg1);
10624 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10625 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10627 enum rtx_code code;
10629 if (TREE_CODE (form) != INTEGER_CST)
10631 error ("argument 1 of __builtin_spe_predicate must be a constant");
10635 form_int = TREE_INT_CST_LOW (form);
10637 gcc_assert (mode0 == mode1);
10639 if (arg0 == error_mark_node || arg1 == error_mark_node)
10643 || GET_MODE (target) != SImode
10644 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
10645 target = gen_reg_rtx (SImode);
10647 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10648 op0 = copy_to_mode_reg (mode0, op0);
10649 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10650 op1 = copy_to_mode_reg (mode1, op1);
10652 scratch = gen_reg_rtx (CCmode);
10654 pat = GEN_FCN (icode) (scratch, op0, op1);
10659 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
10660 _lower_. We use one compare, but look in different bits of the
10661 CR for each variant.
10663 There are 2 elements in each SPE simd type (upper/lower). The CR
10664 bits are set as follows:
10666 BIT0 | BIT 1 | BIT 2 | BIT 3
10667 U | L | (U | L) | (U & L)
10669 So, for an "all" relationship, BIT 3 would be set.
10670 For an "any" relationship, BIT 2 would be set. Etc.
10672 Following traditional nomenclature, these bits map to:
10674 BIT0 | BIT 1 | BIT 2 | BIT 3
10677 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
10682 /* All variant. OV bit. */
10684 /* We need to get to the OV bit, which is the ORDERED bit. We
10685 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
10686 that's ugly and will make validate_condition_mode die.
10687 So let's just use another pattern. */
10688 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10690 /* Any variant. EQ bit. */
10694 /* Upper variant. LT bit. */
10698 /* Lower variant. GT bit. */
10703 error ("argument 1 of __builtin_spe_predicate is out of range");
10707 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10708 emit_move_insn (target, tmp);
10713 /* The evsel builtins look like this:
10715 e = __builtin_spe_evsel_OP (a, b, c, d);
10717 and work like this:
10719 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
10720 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
10724 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
10727 tree arg0 = CALL_EXPR_ARG (exp, 0);
10728 tree arg1 = CALL_EXPR_ARG (exp, 1);
10729 tree arg2 = CALL_EXPR_ARG (exp, 2);
10730 tree arg3 = CALL_EXPR_ARG (exp, 3);
10731 rtx op0 = expand_normal (arg0);
10732 rtx op1 = expand_normal (arg1);
10733 rtx op2 = expand_normal (arg2);
10734 rtx op3 = expand_normal (arg3);
10735 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10736 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10738 gcc_assert (mode0 == mode1);
10740 if (arg0 == error_mark_node || arg1 == error_mark_node
10741 || arg2 == error_mark_node || arg3 == error_mark_node)
10745 || GET_MODE (target) != mode0
10746 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
10747 target = gen_reg_rtx (mode0);
10749 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10750 op0 = copy_to_mode_reg (mode0, op0);
10751 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10752 op1 = copy_to_mode_reg (mode0, op1);
10753 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10754 op2 = copy_to_mode_reg (mode0, op2);
10755 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
10756 op3 = copy_to_mode_reg (mode0, op3);
10758 /* Generate the compare. */
10759 scratch = gen_reg_rtx (CCmode);
10760 pat = GEN_FCN (icode) (scratch, op0, op1);
10765 if (mode0 == V2SImode)
10766 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
10768 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
10773 /* Expand an expression EXP that calls a built-in function,
10774 with result going to TARGET if that's convenient
10775 (and in mode MODE if that's convenient).
10776 SUBTARGET may be used as the target for computing one of EXP's operands.
10777 IGNORE is nonzero if the value is to be ignored. */
10780 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10781 enum machine_mode mode ATTRIBUTE_UNUSED,
10782 int ignore ATTRIBUTE_UNUSED)
10784 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10785 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10786 const struct builtin_description *d;
10791 if (fcode == RS6000_BUILTIN_RECIP)
10792 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
10794 if (fcode == RS6000_BUILTIN_RECIPF)
10795 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
10797 if (fcode == RS6000_BUILTIN_RSQRTF)
10798 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
10800 if (fcode == RS6000_BUILTIN_BSWAP_HI)
10801 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
10803 if (fcode == POWER7_BUILTIN_BPERMD)
10804 return rs6000_expand_binop_builtin (((TARGET_64BIT)
10805 ? CODE_FOR_bpermd_di
10806 : CODE_FOR_bpermd_si), exp, target);
10808 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
10809 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10811 int icode = (int) CODE_FOR_altivec_lvsr;
10812 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10813 enum machine_mode mode = insn_data[icode].operand[1].mode;
10817 gcc_assert (TARGET_ALTIVEC);
10819 arg = CALL_EXPR_ARG (exp, 0);
10820 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
10821 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
10822 addr = memory_address (mode, op);
10823 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10827 /* For the load case need to negate the address. */
10828 op = gen_reg_rtx (GET_MODE (addr));
10829 emit_insn (gen_rtx_SET (VOIDmode, op,
10830 gen_rtx_NEG (GET_MODE (addr), addr)));
10832 op = gen_rtx_MEM (mode, op);
10835 || GET_MODE (target) != tmode
10836 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10837 target = gen_reg_rtx (tmode);
10839 /*pat = gen_altivec_lvsr (target, op);*/
10840 pat = GEN_FCN (icode) (target, op);
10848 /* FIXME: There's got to be a nicer way to handle this case than
10849 constructing a new CALL_EXPR. */
10850 if (fcode == ALTIVEC_BUILTIN_VCFUX
10851 || fcode == ALTIVEC_BUILTIN_VCFSX
10852 || fcode == ALTIVEC_BUILTIN_VCTUXS
10853 || fcode == ALTIVEC_BUILTIN_VCTSXS)
10855 if (call_expr_nargs (exp) == 1)
10856 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
10857 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
10860 if (TARGET_ALTIVEC)
10862 ret = altivec_expand_builtin (exp, target, &success);
10869 ret = spe_expand_builtin (exp, target, &success);
10874 if (TARGET_PAIRED_FLOAT)
10876 ret = paired_expand_builtin (exp, target, &success);
10882 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
10884 /* Handle simple unary operations. */
10885 d = (struct builtin_description *) bdesc_1arg;
10886 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
10887 if (d->code == fcode)
10888 return rs6000_expand_unop_builtin (d->icode, exp, target);
10890 /* Handle simple binary operations. */
10891 d = (struct builtin_description *) bdesc_2arg;
10892 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
10893 if (d->code == fcode)
10894 return rs6000_expand_binop_builtin (d->icode, exp, target);
10896 /* Handle simple ternary operations. */
10898 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
10899 if (d->code == fcode)
10900 return rs6000_expand_ternop_builtin (d->icode, exp, target);
10902 gcc_unreachable ();
10906 rs6000_init_builtins (void)
10910 V2SI_type_node = build_vector_type (intSI_type_node, 2);
10911 V2SF_type_node = build_vector_type (float_type_node, 2);
10912 V2DI_type_node = build_vector_type (intDI_type_node, 2);
10913 V2DF_type_node = build_vector_type (double_type_node, 2);
10914 V4HI_type_node = build_vector_type (intHI_type_node, 4);
10915 V4SI_type_node = build_vector_type (intSI_type_node, 4);
10916 V4SF_type_node = build_vector_type (float_type_node, 4);
10917 V8HI_type_node = build_vector_type (intHI_type_node, 8);
10918 V16QI_type_node = build_vector_type (intQI_type_node, 16);
10920 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
10921 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
10922 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
10923 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
10925 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
10926 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
10927 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
10928 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
10930 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
10931 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
10932 'vector unsigned short'. */
10934 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
10935 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
10936 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
10937 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
10938 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
10940 long_integer_type_internal_node = long_integer_type_node;
10941 long_unsigned_type_internal_node = long_unsigned_type_node;
10942 intQI_type_internal_node = intQI_type_node;
10943 uintQI_type_internal_node = unsigned_intQI_type_node;
10944 intHI_type_internal_node = intHI_type_node;
10945 uintHI_type_internal_node = unsigned_intHI_type_node;
10946 intSI_type_internal_node = intSI_type_node;
10947 uintSI_type_internal_node = unsigned_intSI_type_node;
10948 intDI_type_internal_node = intDI_type_node;
10949 uintDI_type_internal_node = unsigned_intDI_type_node;
10950 float_type_internal_node = float_type_node;
10951 double_type_internal_node = float_type_node;
10952 void_type_internal_node = void_type_node;
10954 /* Initialize the modes for builtin_function_type, mapping a machine mode to
10956 builtin_mode_to_type[QImode][0] = integer_type_node;
10957 builtin_mode_to_type[HImode][0] = integer_type_node;
10958 builtin_mode_to_type[SImode][0] = intSI_type_node;
10959 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
10960 builtin_mode_to_type[DImode][0] = intDI_type_node;
10961 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
10962 builtin_mode_to_type[SFmode][0] = float_type_node;
10963 builtin_mode_to_type[DFmode][0] = double_type_node;
10964 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
10965 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
10966 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
10967 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
10968 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
10969 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
10970 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
10971 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
10972 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
10973 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
10974 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
10975 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
10976 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
10978 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10979 get_identifier ("__bool char"),
10980 bool_char_type_node);
10981 TYPE_NAME (bool_char_type_node) = tdecl;
10982 (*lang_hooks.decls.pushdecl) (tdecl);
10983 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10984 get_identifier ("__bool short"),
10985 bool_short_type_node);
10986 TYPE_NAME (bool_short_type_node) = tdecl;
10987 (*lang_hooks.decls.pushdecl) (tdecl);
10988 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10989 get_identifier ("__bool int"),
10990 bool_int_type_node);
10991 TYPE_NAME (bool_int_type_node) = tdecl;
10992 (*lang_hooks.decls.pushdecl) (tdecl);
10993 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
10995 TYPE_NAME (pixel_type_node) = tdecl;
10996 (*lang_hooks.decls.pushdecl) (tdecl);
10998 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
10999 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11000 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11001 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11002 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11004 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11005 get_identifier ("__vector unsigned char"),
11006 unsigned_V16QI_type_node);
11007 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11008 (*lang_hooks.decls.pushdecl) (tdecl);
11009 tdecl = build_decl (BUILTINS_LOCATION,
11010 TYPE_DECL, get_identifier ("__vector signed char"),
11012 TYPE_NAME (V16QI_type_node) = tdecl;
11013 (*lang_hooks.decls.pushdecl) (tdecl);
11014 tdecl = build_decl (BUILTINS_LOCATION,
11015 TYPE_DECL, get_identifier ("__vector __bool char"),
11016 bool_V16QI_type_node);
11017 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11018 (*lang_hooks.decls.pushdecl) (tdecl);
11020 tdecl = build_decl (BUILTINS_LOCATION,
11021 TYPE_DECL, get_identifier ("__vector unsigned short"),
11022 unsigned_V8HI_type_node);
11023 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11024 (*lang_hooks.decls.pushdecl) (tdecl);
11025 tdecl = build_decl (BUILTINS_LOCATION,
11026 TYPE_DECL, get_identifier ("__vector signed short"),
11028 TYPE_NAME (V8HI_type_node) = tdecl;
11029 (*lang_hooks.decls.pushdecl) (tdecl);
11030 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11031 get_identifier ("__vector __bool short"),
11032 bool_V8HI_type_node);
11033 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11034 (*lang_hooks.decls.pushdecl) (tdecl);
11036 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11037 get_identifier ("__vector unsigned int"),
11038 unsigned_V4SI_type_node);
11039 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11040 (*lang_hooks.decls.pushdecl) (tdecl);
11041 tdecl = build_decl (BUILTINS_LOCATION,
11042 TYPE_DECL, get_identifier ("__vector signed int"),
11044 TYPE_NAME (V4SI_type_node) = tdecl;
11045 (*lang_hooks.decls.pushdecl) (tdecl);
11046 tdecl = build_decl (BUILTINS_LOCATION,
11047 TYPE_DECL, get_identifier ("__vector __bool int"),
11048 bool_V4SI_type_node);
11049 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11050 (*lang_hooks.decls.pushdecl) (tdecl);
11052 tdecl = build_decl (BUILTINS_LOCATION,
11053 TYPE_DECL, get_identifier ("__vector float"),
11055 TYPE_NAME (V4SF_type_node) = tdecl;
11056 (*lang_hooks.decls.pushdecl) (tdecl);
11057 tdecl = build_decl (BUILTINS_LOCATION,
11058 TYPE_DECL, get_identifier ("__vector __pixel"),
11059 pixel_V8HI_type_node);
11060 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11061 (*lang_hooks.decls.pushdecl) (tdecl);
11065 tdecl = build_decl (BUILTINS_LOCATION,
11066 TYPE_DECL, get_identifier ("__vector double"),
11068 TYPE_NAME (V2DF_type_node) = tdecl;
11069 (*lang_hooks.decls.pushdecl) (tdecl);
11071 tdecl = build_decl (BUILTINS_LOCATION,
11072 TYPE_DECL, get_identifier ("__vector long"),
11074 TYPE_NAME (V2DI_type_node) = tdecl;
11075 (*lang_hooks.decls.pushdecl) (tdecl);
11077 tdecl = build_decl (BUILTINS_LOCATION,
11078 TYPE_DECL, get_identifier ("__vector unsigned long"),
11079 unsigned_V2DI_type_node);
11080 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11081 (*lang_hooks.decls.pushdecl) (tdecl);
11083 tdecl = build_decl (BUILTINS_LOCATION,
11084 TYPE_DECL, get_identifier ("__vector __bool long"),
11085 bool_V2DI_type_node);
11086 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11087 (*lang_hooks.decls.pushdecl) (tdecl);
11090 if (TARGET_PAIRED_FLOAT)
11091 paired_init_builtins ();
11093 spe_init_builtins ();
11094 if (TARGET_ALTIVEC)
11095 altivec_init_builtins ();
11096 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11097 rs6000_common_init_builtins ();
11098 if (TARGET_PPC_GFXOPT)
11100 tree ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11101 RS6000_BUILTIN_RECIPF,
11102 "__builtin_recipdivf");
11103 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11104 RS6000_BUILTIN_RECIPF);
11106 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11107 RS6000_BUILTIN_RSQRTF,
11108 "__builtin_rsqrtf");
11109 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11110 RS6000_BUILTIN_RSQRTF);
11112 if (TARGET_POPCNTB)
11114 tree ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11115 RS6000_BUILTIN_RECIP,
11116 "__builtin_recipdiv");
11117 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11118 RS6000_BUILTIN_RECIP);
11121 if (TARGET_POPCNTD)
11123 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11124 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11125 POWER7_BUILTIN_BPERMD,
11126 "__builtin_bpermd");
11127 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11128 POWER7_BUILTIN_BPERMD);
11130 if (TARGET_POWERPC)
11132 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11133 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11134 unsigned_intHI_type_node,
11136 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11137 RS6000_BUILTIN_BSWAP_HI);
11141 /* AIX libm provides clog as __clog. */
11142 if (built_in_decls [BUILT_IN_CLOG])
11143 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11146 #ifdef SUBTARGET_INIT_BUILTINS
11147 SUBTARGET_INIT_BUILTINS;
11151 /* Search through a set of builtins and enable the mask bits.
11152 DESC is an array of builtins.
11153 SIZE is the total number of builtins.
11154 START is the builtin enum at which to start.
11155 END is the builtin enum at which to end. */
11157 enable_mask_for_builtins (struct builtin_description *desc, int size,
11158 enum rs6000_builtins start,
11159 enum rs6000_builtins end)
11163 for (i = 0; i < size; ++i)
11164 if (desc[i].code == start)
11170 for (; i < size; ++i)
11172 /* Flip all the bits on. */
11173 desc[i].mask = target_flags;
11174 if (desc[i].code == end)
11180 spe_init_builtins (void)
11182 tree endlink = void_list_node;
11183 tree puint_type_node = build_pointer_type (unsigned_type_node);
11184 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11185 struct builtin_description *d;
11188 tree v2si_ftype_4_v2si
11189 = build_function_type
11190 (opaque_V2SI_type_node,
11191 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11192 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11193 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11194 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11197 tree v2sf_ftype_4_v2sf
11198 = build_function_type
11199 (opaque_V2SF_type_node,
11200 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11201 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11202 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11203 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11206 tree int_ftype_int_v2si_v2si
11207 = build_function_type
11208 (integer_type_node,
11209 tree_cons (NULL_TREE, integer_type_node,
11210 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11211 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11214 tree int_ftype_int_v2sf_v2sf
11215 = build_function_type
11216 (integer_type_node,
11217 tree_cons (NULL_TREE, integer_type_node,
11218 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11219 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11222 tree void_ftype_v2si_puint_int
11223 = build_function_type (void_type_node,
11224 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11225 tree_cons (NULL_TREE, puint_type_node,
11226 tree_cons (NULL_TREE,
11230 tree void_ftype_v2si_puint_char
11231 = build_function_type (void_type_node,
11232 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11233 tree_cons (NULL_TREE, puint_type_node,
11234 tree_cons (NULL_TREE,
11238 tree void_ftype_v2si_pv2si_int
11239 = build_function_type (void_type_node,
11240 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11241 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11242 tree_cons (NULL_TREE,
11246 tree void_ftype_v2si_pv2si_char
11247 = build_function_type (void_type_node,
11248 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11249 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11250 tree_cons (NULL_TREE,
11254 tree void_ftype_int
11255 = build_function_type (void_type_node,
11256 tree_cons (NULL_TREE, integer_type_node, endlink));
11258 tree int_ftype_void
11259 = build_function_type (integer_type_node, endlink);
11261 tree v2si_ftype_pv2si_int
11262 = build_function_type (opaque_V2SI_type_node,
11263 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11264 tree_cons (NULL_TREE, integer_type_node,
11267 tree v2si_ftype_puint_int
11268 = build_function_type (opaque_V2SI_type_node,
11269 tree_cons (NULL_TREE, puint_type_node,
11270 tree_cons (NULL_TREE, integer_type_node,
11273 tree v2si_ftype_pushort_int
11274 = build_function_type (opaque_V2SI_type_node,
11275 tree_cons (NULL_TREE, pushort_type_node,
11276 tree_cons (NULL_TREE, integer_type_node,
11279 tree v2si_ftype_signed_char
11280 = build_function_type (opaque_V2SI_type_node,
11281 tree_cons (NULL_TREE, signed_char_type_node,
11284 /* The initialization of the simple binary and unary builtins is
11285 done in rs6000_common_init_builtins, but we have to enable the
11286 mask bits here manually because we have run out of `target_flags'
11287 bits. We really need to redesign this mask business. */
11289 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11290 ARRAY_SIZE (bdesc_2arg),
11291 SPE_BUILTIN_EVADDW,
11292 SPE_BUILTIN_EVXOR);
11293 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11294 ARRAY_SIZE (bdesc_1arg),
11296 SPE_BUILTIN_EVSUBFUSIAAW);
11297 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11298 ARRAY_SIZE (bdesc_spe_predicates),
11299 SPE_BUILTIN_EVCMPEQ,
11300 SPE_BUILTIN_EVFSTSTLT);
11301 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11302 ARRAY_SIZE (bdesc_spe_evsel),
11303 SPE_BUILTIN_EVSEL_CMPGTS,
11304 SPE_BUILTIN_EVSEL_FSTSTEQ);
11306 (*lang_hooks.decls.pushdecl)
11307 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11308 get_identifier ("__ev64_opaque__"),
11309 opaque_V2SI_type_node));
11311 /* Initialize irregular SPE builtins. */
11313 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11314 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11315 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11316 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11317 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11318 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11319 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11320 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11321 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11322 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11323 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11324 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11325 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11326 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11327 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11328 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11329 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11330 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11333 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11334 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11335 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11336 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11337 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11338 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11339 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11340 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11341 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11342 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11343 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11344 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11345 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11346 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11347 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11348 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11349 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11350 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11351 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11352 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11353 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11354 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11357 d = (struct builtin_description *) bdesc_spe_predicates;
11358 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11362 switch (insn_data[d->icode].operand[1].mode)
11365 type = int_ftype_int_v2si_v2si;
11368 type = int_ftype_int_v2sf_v2sf;
11371 gcc_unreachable ();
11374 def_builtin (d->mask, d->name, type, d->code);
11377 /* Evsel predicates. */
11378 d = (struct builtin_description *) bdesc_spe_evsel;
11379 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11383 switch (insn_data[d->icode].operand[1].mode)
11386 type = v2si_ftype_4_v2si;
11389 type = v2sf_ftype_4_v2sf;
11392 gcc_unreachable ();
11395 def_builtin (d->mask, d->name, type, d->code);
11400 paired_init_builtins (void)
11402 const struct builtin_description *d;
11404 tree endlink = void_list_node;
11406 tree int_ftype_int_v2sf_v2sf
11407 = build_function_type
11408 (integer_type_node,
11409 tree_cons (NULL_TREE, integer_type_node,
11410 tree_cons (NULL_TREE, V2SF_type_node,
11411 tree_cons (NULL_TREE, V2SF_type_node,
11413 tree pcfloat_type_node =
11414 build_pointer_type (build_qualified_type
11415 (float_type_node, TYPE_QUAL_CONST));
11417 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
11418 long_integer_type_node,
11421 tree void_ftype_v2sf_long_pcfloat =
11422 build_function_type_list (void_type_node,
11424 long_integer_type_node,
11429 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
11430 PAIRED_BUILTIN_LX);
11433 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
11434 PAIRED_BUILTIN_STX);
11437 d = bdesc_paired_preds;
11438 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
11442 switch (insn_data[d->icode].operand[1].mode)
11445 type = int_ftype_int_v2sf_v2sf;
11448 gcc_unreachable ();
11451 def_builtin (d->mask, d->name, type, d->code);
11456 altivec_init_builtins (void)
11458 const struct builtin_description *d;
11459 const struct builtin_description_predicates *dp;
11463 tree pfloat_type_node = build_pointer_type (float_type_node);
11464 tree pint_type_node = build_pointer_type (integer_type_node);
11465 tree pshort_type_node = build_pointer_type (short_integer_type_node);
11466 tree pchar_type_node = build_pointer_type (char_type_node);
11468 tree pvoid_type_node = build_pointer_type (void_type_node);
11470 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
11471 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
11472 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
11473 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
11475 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
11477 tree int_ftype_opaque
11478 = build_function_type_list (integer_type_node,
11479 opaque_V4SI_type_node, NULL_TREE);
11480 tree opaque_ftype_opaque
11481 = build_function_type (integer_type_node,
11483 tree opaque_ftype_opaque_int
11484 = build_function_type_list (opaque_V4SI_type_node,
11485 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
11486 tree opaque_ftype_opaque_opaque_int
11487 = build_function_type_list (opaque_V4SI_type_node,
11488 opaque_V4SI_type_node, opaque_V4SI_type_node,
11489 integer_type_node, NULL_TREE);
11490 tree int_ftype_int_opaque_opaque
11491 = build_function_type_list (integer_type_node,
11492 integer_type_node, opaque_V4SI_type_node,
11493 opaque_V4SI_type_node, NULL_TREE);
11494 tree int_ftype_int_v4si_v4si
11495 = build_function_type_list (integer_type_node,
11496 integer_type_node, V4SI_type_node,
11497 V4SI_type_node, NULL_TREE);
11498 tree v4sf_ftype_pcfloat
11499 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
11500 tree void_ftype_pfloat_v4sf
11501 = build_function_type_list (void_type_node,
11502 pfloat_type_node, V4SF_type_node, NULL_TREE);
11503 tree v4si_ftype_pcint
11504 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
11505 tree void_ftype_pint_v4si
11506 = build_function_type_list (void_type_node,
11507 pint_type_node, V4SI_type_node, NULL_TREE);
11508 tree v8hi_ftype_pcshort
11509 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
11510 tree void_ftype_pshort_v8hi
11511 = build_function_type_list (void_type_node,
11512 pshort_type_node, V8HI_type_node, NULL_TREE);
11513 tree v16qi_ftype_pcchar
11514 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
11515 tree void_ftype_pchar_v16qi
11516 = build_function_type_list (void_type_node,
11517 pchar_type_node, V16QI_type_node, NULL_TREE);
11518 tree void_ftype_v4si
11519 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
11520 tree v8hi_ftype_void
11521 = build_function_type (V8HI_type_node, void_list_node);
11522 tree void_ftype_void
11523 = build_function_type (void_type_node, void_list_node);
11524 tree void_ftype_int
11525 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
11527 tree opaque_ftype_long_pcvoid
11528 = build_function_type_list (opaque_V4SI_type_node,
11529 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11530 tree v16qi_ftype_long_pcvoid
11531 = build_function_type_list (V16QI_type_node,
11532 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11533 tree v8hi_ftype_long_pcvoid
11534 = build_function_type_list (V8HI_type_node,
11535 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11536 tree v4si_ftype_long_pcvoid
11537 = build_function_type_list (V4SI_type_node,
11538 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11540 tree void_ftype_opaque_long_pvoid
11541 = build_function_type_list (void_type_node,
11542 opaque_V4SI_type_node, long_integer_type_node,
11543 pvoid_type_node, NULL_TREE);
11544 tree void_ftype_v4si_long_pvoid
11545 = build_function_type_list (void_type_node,
11546 V4SI_type_node, long_integer_type_node,
11547 pvoid_type_node, NULL_TREE);
11548 tree void_ftype_v16qi_long_pvoid
11549 = build_function_type_list (void_type_node,
11550 V16QI_type_node, long_integer_type_node,
11551 pvoid_type_node, NULL_TREE);
11552 tree void_ftype_v8hi_long_pvoid
11553 = build_function_type_list (void_type_node,
11554 V8HI_type_node, long_integer_type_node,
11555 pvoid_type_node, NULL_TREE);
11556 tree int_ftype_int_v8hi_v8hi
11557 = build_function_type_list (integer_type_node,
11558 integer_type_node, V8HI_type_node,
11559 V8HI_type_node, NULL_TREE);
11560 tree int_ftype_int_v16qi_v16qi
11561 = build_function_type_list (integer_type_node,
11562 integer_type_node, V16QI_type_node,
11563 V16QI_type_node, NULL_TREE);
11564 tree int_ftype_int_v4sf_v4sf
11565 = build_function_type_list (integer_type_node,
11566 integer_type_node, V4SF_type_node,
11567 V4SF_type_node, NULL_TREE);
11568 tree int_ftype_int_v2df_v2df
11569 = build_function_type_list (integer_type_node,
11570 integer_type_node, V2DF_type_node,
11571 V2DF_type_node, NULL_TREE);
11572 tree v4si_ftype_v4si
11573 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
11574 tree v8hi_ftype_v8hi
11575 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
11576 tree v16qi_ftype_v16qi
11577 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
11578 tree v4sf_ftype_v4sf
11579 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
11580 tree v2df_ftype_v2df
11581 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
11582 tree void_ftype_pcvoid_int_int
11583 = build_function_type_list (void_type_node,
11584 pcvoid_type_node, integer_type_node,
11585 integer_type_node, NULL_TREE);
11587 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
11588 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
11589 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
11590 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
11591 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
11592 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
11593 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
11594 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
11595 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
11596 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
11597 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
11598 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
11599 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
11600 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
11601 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
11602 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
11603 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
11604 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
11605 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
11606 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
11607 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
11608 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
11609 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
11610 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
11611 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
11612 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
11613 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
11614 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
11615 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
11616 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
11617 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
11618 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
11619 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
11620 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
11621 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
11622 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
11623 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
11624 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
11625 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
11626 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
11627 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
11628 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
11629 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
11630 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
11631 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
11632 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
11634 if (rs6000_cpu == PROCESSOR_CELL)
11636 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
11637 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
11638 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
11639 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
11641 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
11642 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
11643 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
11644 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
11646 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
11647 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
11648 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
11649 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
11651 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
11652 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
11653 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
11654 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
11656 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
11657 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
11658 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
11660 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
11661 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
11662 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
11663 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
11664 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
11665 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
11666 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
11667 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
11668 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
11669 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
11670 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
11671 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
11673 /* Add the DST variants. */
11675 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11676 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
11678 /* Initialize the predicates. */
11679 dp = bdesc_altivec_preds;
11680 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11682 enum machine_mode mode1;
11684 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11685 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11686 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
11687 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
11692 mode1 = insn_data[dp->icode].operand[1].mode;
11697 type = int_ftype_int_opaque_opaque;
11700 type = int_ftype_int_v4si_v4si;
11703 type = int_ftype_int_v8hi_v8hi;
11706 type = int_ftype_int_v16qi_v16qi;
11709 type = int_ftype_int_v4sf_v4sf;
11712 type = int_ftype_int_v2df_v2df;
11715 gcc_unreachable ();
11718 def_builtin (dp->mask, dp->name, type, dp->code);
11721 /* Initialize the abs* operators. */
11723 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11725 enum machine_mode mode0;
11728 mode0 = insn_data[d->icode].operand[0].mode;
11733 type = v4si_ftype_v4si;
11736 type = v8hi_ftype_v8hi;
11739 type = v16qi_ftype_v16qi;
11742 type = v4sf_ftype_v4sf;
11745 type = v2df_ftype_v2df;
11748 gcc_unreachable ();
11751 def_builtin (d->mask, d->name, type, d->code);
11754 if (TARGET_ALTIVEC)
11758 /* Initialize target builtin that implements
11759 targetm.vectorize.builtin_mask_for_load. */
11761 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
11762 v16qi_ftype_long_pcvoid,
11763 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
11764 BUILT_IN_MD, NULL, NULL_TREE);
11765 TREE_READONLY (decl) = 1;
11766 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
11767 altivec_builtin_mask_for_load = decl;
11770 /* Access to the vec_init patterns. */
11771 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
11772 integer_type_node, integer_type_node,
11773 integer_type_node, NULL_TREE);
11774 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
11775 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
11777 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
11778 short_integer_type_node,
11779 short_integer_type_node,
11780 short_integer_type_node,
11781 short_integer_type_node,
11782 short_integer_type_node,
11783 short_integer_type_node,
11784 short_integer_type_node, NULL_TREE);
11785 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
11786 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
11788 ftype = build_function_type_list (V16QI_type_node, char_type_node,
11789 char_type_node, char_type_node,
11790 char_type_node, char_type_node,
11791 char_type_node, char_type_node,
11792 char_type_node, char_type_node,
11793 char_type_node, char_type_node,
11794 char_type_node, char_type_node,
11795 char_type_node, char_type_node,
11796 char_type_node, NULL_TREE);
11797 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
11798 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
11800 ftype = build_function_type_list (V4SF_type_node, float_type_node,
11801 float_type_node, float_type_node,
11802 float_type_node, NULL_TREE);
11803 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
11804 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
11808 ftype = build_function_type_list (V2DF_type_node, double_type_node,
11809 double_type_node, NULL_TREE);
11810 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
11811 VSX_BUILTIN_VEC_INIT_V2DF);
11813 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
11814 intDI_type_node, NULL_TREE);
11815 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
11816 VSX_BUILTIN_VEC_INIT_V2DI);
11819 /* Access to the vec_set patterns. */
11820 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
11822 integer_type_node, NULL_TREE);
11823 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
11824 ALTIVEC_BUILTIN_VEC_SET_V4SI);
11826 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
11828 integer_type_node, NULL_TREE);
11829 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
11830 ALTIVEC_BUILTIN_VEC_SET_V8HI);
11832 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
11834 integer_type_node, NULL_TREE);
11835 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
11836 ALTIVEC_BUILTIN_VEC_SET_V16QI);
11838 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
11840 integer_type_node, NULL_TREE);
11841 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
11842 ALTIVEC_BUILTIN_VEC_SET_V4SF);
11846 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
11848 integer_type_node, NULL_TREE);
11849 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
11850 VSX_BUILTIN_VEC_SET_V2DF);
11852 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
11854 integer_type_node, NULL_TREE);
11855 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
11856 VSX_BUILTIN_VEC_SET_V2DI);
11859 /* Access to the vec_extract patterns. */
11860 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
11861 integer_type_node, NULL_TREE);
11862 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
11863 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
11865 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
11866 integer_type_node, NULL_TREE);
11867 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
11868 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
11870 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
11871 integer_type_node, NULL_TREE);
11872 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
11873 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
11875 ftype = build_function_type_list (float_type_node, V4SF_type_node,
11876 integer_type_node, NULL_TREE);
11877 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
11878 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
11882 ftype = build_function_type_list (double_type_node, V2DF_type_node,
11883 integer_type_node, NULL_TREE);
11884 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
11885 VSX_BUILTIN_VEC_EXT_V2DF);
11887 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
11888 integer_type_node, NULL_TREE);
11889 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
11890 VSX_BUILTIN_VEC_EXT_V2DI);
11894 /* Hash function for builtin functions with up to 3 arguments and a return
11897 builtin_hash_function (const void *hash_entry)
11901 const struct builtin_hash_struct *bh =
11902 (const struct builtin_hash_struct *) hash_entry;
11904 for (i = 0; i < 4; i++)
11906 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
11907 ret = (ret * 2) + bh->uns_p[i];
11913 /* Compare builtin hash entries H1 and H2 for equivalence. */
11915 builtin_hash_eq (const void *h1, const void *h2)
11917 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
11918 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
11920 return ((p1->mode[0] == p2->mode[0])
11921 && (p1->mode[1] == p2->mode[1])
11922 && (p1->mode[2] == p2->mode[2])
11923 && (p1->mode[3] == p2->mode[3])
11924 && (p1->uns_p[0] == p2->uns_p[0])
11925 && (p1->uns_p[1] == p2->uns_p[1])
11926 && (p1->uns_p[2] == p2->uns_p[2])
11927 && (p1->uns_p[3] == p2->uns_p[3]));
11930 /* Map types for builtin functions with an explicit return type and up to 3
11931 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
11932 of the argument. */
11934 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
11935 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
11936 enum rs6000_builtins builtin, const char *name)
11938 struct builtin_hash_struct h;
11939 struct builtin_hash_struct *h2;
11943 tree ret_type = NULL_TREE;
11944 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
11947 /* Create builtin_hash_table. */
11948 if (builtin_hash_table == NULL)
11949 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
11950 builtin_hash_eq, NULL);
11952 h.type = NULL_TREE;
11953 h.mode[0] = mode_ret;
11954 h.mode[1] = mode_arg0;
11955 h.mode[2] = mode_arg1;
11956 h.mode[3] = mode_arg2;
11962 /* If the builtin is a type that produces unsigned results or takes unsigned
11963 arguments, and it is returned as a decl for the vectorizer (such as
11964 widening multiplies, permute), make sure the arguments and return value
11965 are type correct. */
11968 /* unsigned 2 argument functions. */
11969 case ALTIVEC_BUILTIN_VMULEUB_UNS:
11970 case ALTIVEC_BUILTIN_VMULEUH_UNS:
11971 case ALTIVEC_BUILTIN_VMULOUB_UNS:
11972 case ALTIVEC_BUILTIN_VMULOUH_UNS:
11978 /* unsigned 3 argument functions. */
11979 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
11980 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
11981 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
11982 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
11983 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
11984 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
11985 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
11986 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
11987 case VSX_BUILTIN_VPERM_16QI_UNS:
11988 case VSX_BUILTIN_VPERM_8HI_UNS:
11989 case VSX_BUILTIN_VPERM_4SI_UNS:
11990 case VSX_BUILTIN_VPERM_2DI_UNS:
11991 case VSX_BUILTIN_XXSEL_16QI_UNS:
11992 case VSX_BUILTIN_XXSEL_8HI_UNS:
11993 case VSX_BUILTIN_XXSEL_4SI_UNS:
11994 case VSX_BUILTIN_XXSEL_2DI_UNS:
12001 /* signed permute functions with unsigned char mask. */
12002 case ALTIVEC_BUILTIN_VPERM_16QI:
12003 case ALTIVEC_BUILTIN_VPERM_8HI:
12004 case ALTIVEC_BUILTIN_VPERM_4SI:
12005 case ALTIVEC_BUILTIN_VPERM_4SF:
12006 case ALTIVEC_BUILTIN_VPERM_2DI:
12007 case ALTIVEC_BUILTIN_VPERM_2DF:
12008 case VSX_BUILTIN_VPERM_16QI:
12009 case VSX_BUILTIN_VPERM_8HI:
12010 case VSX_BUILTIN_VPERM_4SI:
12011 case VSX_BUILTIN_VPERM_4SF:
12012 case VSX_BUILTIN_VPERM_2DI:
12013 case VSX_BUILTIN_VPERM_2DF:
12017 /* unsigned args, signed return. */
12018 case VSX_BUILTIN_XVCVUXDDP_UNS:
12019 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12023 /* signed args, unsigned return. */
12024 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12025 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12033 /* Figure out how many args are present. */
12034 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12038 fatal_error ("internal error: builtin function %s had no type", name);
12040 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12041 if (!ret_type && h.uns_p[0])
12042 ret_type = builtin_mode_to_type[h.mode[0]][0];
12045 fatal_error ("internal error: builtin function %s had an unexpected "
12046 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12048 for (i = 0; i < num_args; i++)
12050 int m = (int) h.mode[i+1];
12051 int uns_p = h.uns_p[i+1];
12053 arg_type[i] = builtin_mode_to_type[m][uns_p];
12054 if (!arg_type[i] && uns_p)
12055 arg_type[i] = builtin_mode_to_type[m][0];
12058 fatal_error ("internal error: builtin function %s, argument %d "
12059 "had unexpected argument type %s", name, i,
12060 GET_MODE_NAME (m));
12063 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12064 if (*found == NULL)
12066 h2 = GGC_NEW (struct builtin_hash_struct);
12068 *found = (void *)h2;
12069 args = void_list_node;
12071 for (i = num_args - 1; i >= 0; i--)
12072 args = tree_cons (NULL_TREE, arg_type[i], args);
12074 h2->type = build_function_type (ret_type, args);
12077 return ((struct builtin_hash_struct *)(*found))->type;
12081 rs6000_common_init_builtins (void)
12083 const struct builtin_description *d;
12086 tree opaque_ftype_opaque = NULL_TREE;
12087 tree opaque_ftype_opaque_opaque = NULL_TREE;
12088 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12089 tree v2si_ftype_qi = NULL_TREE;
12090 tree v2si_ftype_v2si_qi = NULL_TREE;
12091 tree v2si_ftype_int_qi = NULL_TREE;
12093 if (!TARGET_PAIRED_FLOAT)
12095 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12096 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12099 /* Add the ternary operators. */
12101 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12104 int mask = d->mask;
12106 if ((mask != 0 && (mask & target_flags) == 0)
12107 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12110 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12111 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12112 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12113 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12115 if (! (type = opaque_ftype_opaque_opaque_opaque))
12116 type = opaque_ftype_opaque_opaque_opaque
12117 = build_function_type_list (opaque_V4SI_type_node,
12118 opaque_V4SI_type_node,
12119 opaque_V4SI_type_node,
12120 opaque_V4SI_type_node,
12125 enum insn_code icode = d->icode;
12126 if (d->name == 0 || icode == CODE_FOR_nothing)
12129 type = builtin_function_type (insn_data[icode].operand[0].mode,
12130 insn_data[icode].operand[1].mode,
12131 insn_data[icode].operand[2].mode,
12132 insn_data[icode].operand[3].mode,
12136 def_builtin (d->mask, d->name, type, d->code);
12139 /* Add the binary operators. */
12141 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12143 enum machine_mode mode0, mode1, mode2;
12145 int mask = d->mask;
12147 if ((mask != 0 && (mask & target_flags) == 0)
12148 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12151 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12152 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12153 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12154 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12156 if (! (type = opaque_ftype_opaque_opaque))
12157 type = opaque_ftype_opaque_opaque
12158 = build_function_type_list (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 mode0 = insn_data[icode].operand[0].mode;
12170 mode1 = insn_data[icode].operand[1].mode;
12171 mode2 = insn_data[icode].operand[2].mode;
12173 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12175 if (! (type = v2si_ftype_v2si_qi))
12176 type = v2si_ftype_v2si_qi
12177 = build_function_type_list (opaque_V2SI_type_node,
12178 opaque_V2SI_type_node,
12183 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12184 && mode2 == QImode)
12186 if (! (type = v2si_ftype_int_qi))
12187 type = v2si_ftype_int_qi
12188 = build_function_type_list (opaque_V2SI_type_node,
12195 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12199 def_builtin (d->mask, d->name, type, d->code);
12202 /* Add the simple unary operators. */
12203 d = (struct builtin_description *) bdesc_1arg;
12204 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12206 enum machine_mode mode0, mode1;
12208 int mask = d->mask;
12210 if ((mask != 0 && (mask & target_flags) == 0)
12211 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12214 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12215 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12216 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12217 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12219 if (! (type = opaque_ftype_opaque))
12220 type = opaque_ftype_opaque
12221 = build_function_type_list (opaque_V4SI_type_node,
12222 opaque_V4SI_type_node,
12227 enum insn_code icode = d->icode;
12228 if (d->name == 0 || icode == CODE_FOR_nothing)
12231 mode0 = insn_data[icode].operand[0].mode;
12232 mode1 = insn_data[icode].operand[1].mode;
12234 if (mode0 == V2SImode && mode1 == QImode)
12236 if (! (type = v2si_ftype_qi))
12237 type = v2si_ftype_qi
12238 = build_function_type_list (opaque_V2SI_type_node,
12244 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12248 def_builtin (d->mask, d->name, type, d->code);
12253 rs6000_init_libfuncs (void)
12255 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12256 && !TARGET_POWER2 && !TARGET_POWERPC)
12258 /* AIX library routines for float->int conversion. */
12259 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12260 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12261 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12262 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12265 if (!TARGET_IEEEQUAD)
12266 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12267 if (!TARGET_XL_COMPAT)
12269 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12270 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12271 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12272 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12274 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12276 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12277 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12278 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12279 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12280 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12281 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12282 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12284 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12285 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12286 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12287 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12288 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12289 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12290 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12291 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12294 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12295 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12299 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12300 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12301 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12302 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12306 /* 32-bit SVR4 quad floating point routines. */
12308 set_optab_libfunc (add_optab, TFmode, "_q_add");
12309 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12310 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12311 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12312 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12313 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12314 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12316 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12317 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12318 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12319 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12320 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12321 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12323 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12324 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12325 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12326 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12327 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12328 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12329 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12330 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12335 /* Expand a block clear operation, and return 1 if successful. Return 0
12336 if we should let the compiler generate normal code.
12338 operands[0] is the destination
12339 operands[1] is the length
12340 operands[3] is the alignment */
12343 expand_block_clear (rtx operands[])
12345 rtx orig_dest = operands[0];
12346 rtx bytes_rtx = operands[1];
12347 rtx align_rtx = operands[3];
12348 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12349 HOST_WIDE_INT align;
12350 HOST_WIDE_INT bytes;
12355 /* If this is not a fixed size move, just call memcpy */
12359 /* This must be a fixed size alignment */
12360 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12361 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12363 /* Anything to clear? */
12364 bytes = INTVAL (bytes_rtx);
12368 /* Use the builtin memset after a point, to avoid huge code bloat.
12369 When optimize_size, avoid any significant code bloat; calling
12370 memset is about 4 instructions, so allow for one instruction to
12371 load zero and three to do clearing. */
12372 if (TARGET_ALTIVEC && align >= 128)
12374 else if (TARGET_POWERPC64 && align >= 32)
12376 else if (TARGET_SPE && align >= 64)
12381 if (optimize_size && bytes > 3 * clear_step)
12383 if (! optimize_size && bytes > 8 * clear_step)
12386 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12388 enum machine_mode mode = BLKmode;
12391 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
12396 else if (bytes >= 8 && TARGET_SPE && align >= 64)
12401 else if (bytes >= 8 && TARGET_POWERPC64
12402 /* 64-bit loads and stores require word-aligned
12404 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12409 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12410 { /* move 4 bytes */
12414 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12415 { /* move 2 bytes */
12419 else /* move 1 byte at a time */
12425 dest = adjust_address (orig_dest, mode, offset);
12427 emit_move_insn (dest, CONST0_RTX (mode));
12434 /* Expand a block move operation, and return 1 if successful. Return 0
12435 if we should let the compiler generate normal code.
12437 operands[0] is the destination
12438 operands[1] is the source
12439 operands[2] is the length
12440 operands[3] is the alignment */
12442 #define MAX_MOVE_REG 4
12445 expand_block_move (rtx operands[])
12447 rtx orig_dest = operands[0];
12448 rtx orig_src = operands[1];
12449 rtx bytes_rtx = operands[2];
12450 rtx align_rtx = operands[3];
12451 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
12456 rtx stores[MAX_MOVE_REG];
12459 /* If this is not a fixed size move, just call memcpy */
12463 /* This must be a fixed size alignment */
12464 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12465 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12467 /* Anything to move? */
12468 bytes = INTVAL (bytes_rtx);
12472 /* store_one_arg depends on expand_block_move to handle at least the size of
12473 reg_parm_stack_space. */
12474 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
12477 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
12480 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
12481 rtx (*mov) (rtx, rtx);
12483 enum machine_mode mode = BLKmode;
12486 /* Altivec first, since it will be faster than a string move
12487 when it applies, and usually not significantly larger. */
12488 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
12492 gen_func.mov = gen_movv4si;
12494 else if (TARGET_SPE && bytes >= 8 && align >= 64)
12498 gen_func.mov = gen_movv2si;
12500 else if (TARGET_STRING
12501 && bytes > 24 /* move up to 32 bytes at a time */
12507 && ! fixed_regs[10]
12508 && ! fixed_regs[11]
12509 && ! fixed_regs[12])
12511 move_bytes = (bytes > 32) ? 32 : bytes;
12512 gen_func.movmemsi = gen_movmemsi_8reg;
12514 else if (TARGET_STRING
12515 && bytes > 16 /* move up to 24 bytes at a time */
12521 && ! fixed_regs[10])
12523 move_bytes = (bytes > 24) ? 24 : bytes;
12524 gen_func.movmemsi = gen_movmemsi_6reg;
12526 else if (TARGET_STRING
12527 && bytes > 8 /* move up to 16 bytes at a time */
12531 && ! fixed_regs[8])
12533 move_bytes = (bytes > 16) ? 16 : bytes;
12534 gen_func.movmemsi = gen_movmemsi_4reg;
12536 else if (bytes >= 8 && TARGET_POWERPC64
12537 /* 64-bit loads and stores require word-aligned
12539 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12543 gen_func.mov = gen_movdi;
12545 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
12546 { /* move up to 8 bytes at a time */
12547 move_bytes = (bytes > 8) ? 8 : bytes;
12548 gen_func.movmemsi = gen_movmemsi_2reg;
12550 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12551 { /* move 4 bytes */
12554 gen_func.mov = gen_movsi;
12556 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12557 { /* move 2 bytes */
12560 gen_func.mov = gen_movhi;
12562 else if (TARGET_STRING && bytes > 1)
12563 { /* move up to 4 bytes at a time */
12564 move_bytes = (bytes > 4) ? 4 : bytes;
12565 gen_func.movmemsi = gen_movmemsi_1reg;
12567 else /* move 1 byte at a time */
12571 gen_func.mov = gen_movqi;
12574 src = adjust_address (orig_src, mode, offset);
12575 dest = adjust_address (orig_dest, mode, offset);
12577 if (mode != BLKmode)
12579 rtx tmp_reg = gen_reg_rtx (mode);
12581 emit_insn ((*gen_func.mov) (tmp_reg, src));
12582 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
12585 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
12588 for (i = 0; i < num_reg; i++)
12589 emit_insn (stores[i]);
12593 if (mode == BLKmode)
12595 /* Move the address into scratch registers. The movmemsi
12596 patterns require zero offset. */
12597 if (!REG_P (XEXP (src, 0)))
12599 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
12600 src = replace_equiv_address (src, src_reg);
12602 set_mem_size (src, GEN_INT (move_bytes));
12604 if (!REG_P (XEXP (dest, 0)))
12606 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
12607 dest = replace_equiv_address (dest, dest_reg);
12609 set_mem_size (dest, GEN_INT (move_bytes));
12611 emit_insn ((*gen_func.movmemsi) (dest, src,
12612 GEN_INT (move_bytes & 31),
12621 /* Return a string to perform a load_multiple operation.
12622 operands[0] is the vector.
12623 operands[1] is the source address.
12624 operands[2] is the first destination register. */
12627 rs6000_output_load_multiple (rtx operands[3])
12629 /* We have to handle the case where the pseudo used to contain the address
12630 is assigned to one of the output registers. */
12632 int words = XVECLEN (operands[0], 0);
12635 if (XVECLEN (operands[0], 0) == 1)
12636 return "{l|lwz} %2,0(%1)";
12638 for (i = 0; i < words; i++)
12639 if (refers_to_regno_p (REGNO (operands[2]) + i,
12640 REGNO (operands[2]) + i + 1, operands[1], 0))
12644 xop[0] = GEN_INT (4 * (words-1));
12645 xop[1] = operands[1];
12646 xop[2] = operands[2];
12647 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
12652 xop[0] = GEN_INT (4 * (words-1));
12653 xop[1] = operands[1];
12654 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
12655 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);
12660 for (j = 0; j < words; j++)
12663 xop[0] = GEN_INT (j * 4);
12664 xop[1] = operands[1];
12665 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
12666 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
12668 xop[0] = GEN_INT (i * 4);
12669 xop[1] = operands[1];
12670 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
12675 return "{lsi|lswi} %2,%1,%N0";
12679 /* A validation routine: say whether CODE, a condition code, and MODE
12680 match. The other alternatives either don't make sense or should
12681 never be generated. */
12684 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
12686 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
12687 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
12688 && GET_MODE_CLASS (mode) == MODE_CC);
12690 /* These don't make sense. */
12691 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
12692 || mode != CCUNSmode);
12694 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
12695 || mode == CCUNSmode);
12697 gcc_assert (mode == CCFPmode
12698 || (code != ORDERED && code != UNORDERED
12699 && code != UNEQ && code != LTGT
12700 && code != UNGT && code != UNLT
12701 && code != UNGE && code != UNLE));
12703 /* These should never be generated except for
12704 flag_finite_math_only. */
12705 gcc_assert (mode != CCFPmode
12706 || flag_finite_math_only
12707 || (code != LE && code != GE
12708 && code != UNEQ && code != LTGT
12709 && code != UNGT && code != UNLT));
12711 /* These are invalid; the information is not there. */
12712 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
12716 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
12717 mask required to convert the result of a rotate insn into a shift
12718 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
12721 includes_lshift_p (rtx shiftop, rtx andop)
12723 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12725 shift_mask <<= INTVAL (shiftop);
12727 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12730 /* Similar, but for right shift. */
12733 includes_rshift_p (rtx shiftop, rtx andop)
12735 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12737 shift_mask >>= INTVAL (shiftop);
12739 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12742 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
12743 to perform a left shift. It must have exactly SHIFTOP least
12744 significant 0's, then one or more 1's, then zero or more 0's. */
12747 includes_rldic_lshift_p (rtx shiftop, rtx andop)
12749 if (GET_CODE (andop) == CONST_INT)
12751 HOST_WIDE_INT c, lsb, shift_mask;
12753 c = INTVAL (andop);
12754 if (c == 0 || c == ~0)
12758 shift_mask <<= INTVAL (shiftop);
12760 /* Find the least significant one bit. */
12763 /* It must coincide with the LSB of the shift mask. */
12764 if (-lsb != shift_mask)
12767 /* Invert to look for the next transition (if any). */
12770 /* Remove the low group of ones (originally low group of zeros). */
12773 /* Again find the lsb, and check we have all 1's above. */
12777 else if (GET_CODE (andop) == CONST_DOUBLE
12778 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12780 HOST_WIDE_INT low, high, lsb;
12781 HOST_WIDE_INT shift_mask_low, shift_mask_high;
12783 low = CONST_DOUBLE_LOW (andop);
12784 if (HOST_BITS_PER_WIDE_INT < 64)
12785 high = CONST_DOUBLE_HIGH (andop);
12787 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
12788 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
12791 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12793 shift_mask_high = ~0;
12794 if (INTVAL (shiftop) > 32)
12795 shift_mask_high <<= INTVAL (shiftop) - 32;
12797 lsb = high & -high;
12799 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
12805 lsb = high & -high;
12806 return high == -lsb;
12809 shift_mask_low = ~0;
12810 shift_mask_low <<= INTVAL (shiftop);
12814 if (-lsb != shift_mask_low)
12817 if (HOST_BITS_PER_WIDE_INT < 64)
12822 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12824 lsb = high & -high;
12825 return high == -lsb;
12829 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
12835 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
12836 to perform a left shift. It must have SHIFTOP or more least
12837 significant 0's, with the remainder of the word 1's. */
12840 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
12842 if (GET_CODE (andop) == CONST_INT)
12844 HOST_WIDE_INT c, lsb, shift_mask;
12847 shift_mask <<= INTVAL (shiftop);
12848 c = INTVAL (andop);
12850 /* Find the least significant one bit. */
12853 /* It must be covered by the shift mask.
12854 This test also rejects c == 0. */
12855 if ((lsb & shift_mask) == 0)
12858 /* Check we have all 1's above the transition, and reject all 1's. */
12859 return c == -lsb && lsb != 1;
12861 else if (GET_CODE (andop) == CONST_DOUBLE
12862 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12864 HOST_WIDE_INT low, lsb, shift_mask_low;
12866 low = CONST_DOUBLE_LOW (andop);
12868 if (HOST_BITS_PER_WIDE_INT < 64)
12870 HOST_WIDE_INT high, shift_mask_high;
12872 high = CONST_DOUBLE_HIGH (andop);
12876 shift_mask_high = ~0;
12877 if (INTVAL (shiftop) > 32)
12878 shift_mask_high <<= INTVAL (shiftop) - 32;
12880 lsb = high & -high;
12882 if ((lsb & shift_mask_high) == 0)
12885 return high == -lsb;
12891 shift_mask_low = ~0;
12892 shift_mask_low <<= INTVAL (shiftop);
12896 if ((lsb & shift_mask_low) == 0)
12899 return low == -lsb && lsb != 1;
12905 /* Return 1 if operands will generate a valid arguments to rlwimi
12906 instruction for insert with right shift in 64-bit mode. The mask may
12907 not start on the first bit or stop on the last bit because wrap-around
12908 effects of instruction do not correspond to semantics of RTL insn. */
12911 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
12913 if (INTVAL (startop) > 32
12914 && INTVAL (startop) < 64
12915 && INTVAL (sizeop) > 1
12916 && INTVAL (sizeop) + INTVAL (startop) < 64
12917 && INTVAL (shiftop) > 0
12918 && INTVAL (sizeop) + INTVAL (shiftop) < 32
12919 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
12925 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
12926 for lfq and stfq insns iff the registers are hard registers. */
12929 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
12931 /* We might have been passed a SUBREG. */
12932 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
12935 /* We might have been passed non floating point registers. */
12936 if (!FP_REGNO_P (REGNO (reg1))
12937 || !FP_REGNO_P (REGNO (reg2)))
12940 return (REGNO (reg1) == REGNO (reg2) - 1);
12943 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
12944 addr1 and addr2 must be in consecutive memory locations
12945 (addr2 == addr1 + 8). */
12948 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
12951 unsigned int reg1, reg2;
12952 int offset1, offset2;
12954 /* The mems cannot be volatile. */
12955 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
12958 addr1 = XEXP (mem1, 0);
12959 addr2 = XEXP (mem2, 0);
12961 /* Extract an offset (if used) from the first addr. */
12962 if (GET_CODE (addr1) == PLUS)
12964 /* If not a REG, return zero. */
12965 if (GET_CODE (XEXP (addr1, 0)) != REG)
12969 reg1 = REGNO (XEXP (addr1, 0));
12970 /* The offset must be constant! */
12971 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
12973 offset1 = INTVAL (XEXP (addr1, 1));
12976 else if (GET_CODE (addr1) != REG)
12980 reg1 = REGNO (addr1);
12981 /* This was a simple (mem (reg)) expression. Offset is 0. */
12985 /* And now for the second addr. */
12986 if (GET_CODE (addr2) == PLUS)
12988 /* If not a REG, return zero. */
12989 if (GET_CODE (XEXP (addr2, 0)) != REG)
12993 reg2 = REGNO (XEXP (addr2, 0));
12994 /* The offset must be constant. */
12995 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
12997 offset2 = INTVAL (XEXP (addr2, 1));
13000 else if (GET_CODE (addr2) != REG)
13004 reg2 = REGNO (addr2);
13005 /* This was a simple (mem (reg)) expression. Offset is 0. */
13009 /* Both of these must have the same base register. */
13013 /* The offset for the second addr must be 8 more than the first addr. */
13014 if (offset2 != offset1 + 8)
13017 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13024 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13026 static bool eliminated = false;
13029 if (mode != SDmode)
13030 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13033 rtx mem = cfun->machine->sdmode_stack_slot;
13034 gcc_assert (mem != NULL_RTX);
13038 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13039 cfun->machine->sdmode_stack_slot = mem;
13045 if (TARGET_DEBUG_ADDR)
13047 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13048 GET_MODE_NAME (mode));
13050 fprintf (stderr, "\tNULL_RTX\n");
13059 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13061 /* Don't walk into types. */
13062 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13064 *walk_subtrees = 0;
13068 switch (TREE_CODE (*tp))
13077 case ALIGN_INDIRECT_REF:
13078 case MISALIGNED_INDIRECT_REF:
13079 case VIEW_CONVERT_EXPR:
13080 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13090 enum reload_reg_type {
13092 VECTOR_REGISTER_TYPE,
13093 OTHER_REGISTER_TYPE
13096 static enum reload_reg_type
13097 rs6000_reload_register_type (enum reg_class rclass)
13103 return GPR_REGISTER_TYPE;
13108 return VECTOR_REGISTER_TYPE;
13111 return OTHER_REGISTER_TYPE;
13115 /* Inform reload about cases where moving X with a mode MODE to a register in
13116 RCLASS requires an extra scratch or immediate register. Return the class
13117 needed for the immediate register.
13119 For VSX and Altivec, we may need a register to convert sp+offset into
13122 static enum reg_class
13123 rs6000_secondary_reload (bool in_p,
13125 enum reg_class rclass,
13126 enum machine_mode mode,
13127 secondary_reload_info *sri)
13129 enum reg_class ret = ALL_REGS;
13130 enum insn_code icode;
13131 bool default_p = false;
13133 sri->icode = CODE_FOR_nothing;
13135 /* Convert vector loads and stores into gprs to use an additional base
13137 icode = rs6000_vector_reload[mode][in_p != false];
13138 if (icode != CODE_FOR_nothing)
13141 sri->icode = CODE_FOR_nothing;
13142 sri->extra_cost = 0;
13144 if (GET_CODE (x) == MEM)
13146 rtx addr = XEXP (x, 0);
13148 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13149 an extra register in that case, but it would need an extra
13150 register if the addressing is reg+reg or (reg+reg)&(-16). */
13151 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13153 if (!legitimate_indirect_address_p (addr, false)
13154 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13156 sri->icode = icode;
13157 /* account for splitting the loads, and converting the
13158 address from reg+reg to reg. */
13159 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13160 + ((GET_CODE (addr) == AND) ? 1 : 0));
13163 /* Loads to and stores from vector registers can only do reg+reg
13164 addressing. Altivec registers can also do (reg+reg)&(-16). */
13165 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13166 || rclass == FLOAT_REGS || rclass == NO_REGS)
13168 if (!VECTOR_MEM_ALTIVEC_P (mode)
13169 && GET_CODE (addr) == AND
13170 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13171 && INTVAL (XEXP (addr, 1)) == -16
13172 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13173 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13175 sri->icode = icode;
13176 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13179 else if (!legitimate_indirect_address_p (addr, false)
13180 && (rclass == NO_REGS
13181 || !legitimate_indexed_address_p (addr, false)))
13183 sri->icode = icode;
13184 sri->extra_cost = 1;
13187 icode = CODE_FOR_nothing;
13189 /* Any other loads, including to pseudo registers which haven't been
13190 assigned to a register yet, default to require a scratch
13194 sri->icode = icode;
13195 sri->extra_cost = 2;
13198 else if (REG_P (x))
13200 int regno = true_regnum (x);
13202 icode = CODE_FOR_nothing;
13203 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13207 enum reg_class xclass = REGNO_REG_CLASS (regno);
13208 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13209 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13211 /* If memory is needed, use default_secondary_reload to create the
13213 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13226 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13228 gcc_assert (ret != ALL_REGS);
13230 if (TARGET_DEBUG_ADDR)
13233 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13235 reg_class_names[ret],
13236 in_p ? "true" : "false",
13237 reg_class_names[rclass],
13238 GET_MODE_NAME (mode));
13241 fprintf (stderr, ", default secondary reload");
13243 if (sri->icode != CODE_FOR_nothing)
13244 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13245 insn_data[sri->icode].name, sri->extra_cost);
13247 fprintf (stderr, "\n");
13255 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13256 to SP+reg addressing. */
13259 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13261 int regno = true_regnum (reg);
13262 enum machine_mode mode = GET_MODE (reg);
13263 enum reg_class rclass;
13265 rtx and_op2 = NULL_RTX;
13268 rtx scratch_or_premodify = scratch;
13272 if (TARGET_DEBUG_ADDR)
13274 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13275 store_p ? "store" : "load");
13276 fprintf (stderr, "reg:\n");
13278 fprintf (stderr, "mem:\n");
13280 fprintf (stderr, "scratch:\n");
13281 debug_rtx (scratch);
13284 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13285 gcc_assert (GET_CODE (mem) == MEM);
13286 rclass = REGNO_REG_CLASS (regno);
13287 addr = XEXP (mem, 0);
13291 /* GPRs can handle reg + small constant, all other addresses need to use
13292 the scratch register. */
13295 if (GET_CODE (addr) == AND)
13297 and_op2 = XEXP (addr, 1);
13298 addr = XEXP (addr, 0);
13301 if (GET_CODE (addr) == PRE_MODIFY)
13303 scratch_or_premodify = XEXP (addr, 0);
13304 gcc_assert (REG_P (scratch_or_premodify));
13305 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13306 addr = XEXP (addr, 1);
13309 if (GET_CODE (addr) == PLUS
13310 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13311 || and_op2 != NULL_RTX))
13313 addr_op1 = XEXP (addr, 0);
13314 addr_op2 = XEXP (addr, 1);
13315 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13317 if (!REG_P (addr_op2)
13318 && (GET_CODE (addr_op2) != CONST_INT
13319 || !satisfies_constraint_I (addr_op2)))
13321 if (TARGET_DEBUG_ADDR)
13324 "\nMove plus addr to register %s, mode = %s: ",
13325 rs6000_reg_names[REGNO (scratch)],
13326 GET_MODE_NAME (mode));
13327 debug_rtx (addr_op2);
13329 rs6000_emit_move (scratch, addr_op2, Pmode);
13330 addr_op2 = scratch;
13333 emit_insn (gen_rtx_SET (VOIDmode,
13334 scratch_or_premodify,
13335 gen_rtx_PLUS (Pmode,
13339 addr = scratch_or_premodify;
13340 scratch_or_premodify = scratch;
13342 else if (!legitimate_indirect_address_p (addr, false)
13343 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13345 if (TARGET_DEBUG_ADDR)
13347 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13348 rs6000_reg_names[REGNO (scratch_or_premodify)],
13349 GET_MODE_NAME (mode));
13352 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13353 addr = scratch_or_premodify;
13354 scratch_or_premodify = scratch;
13358 /* Float/Altivec registers can only handle reg+reg addressing. Move
13359 other addresses into a scratch register. */
13364 /* With float regs, we need to handle the AND ourselves, since we can't
13365 use the Altivec instruction with an implicit AND -16. Allow scalar
13366 loads to float registers to use reg+offset even if VSX. */
13367 if (GET_CODE (addr) == AND
13368 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13369 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13370 || INTVAL (XEXP (addr, 1)) != -16
13371 || !VECTOR_MEM_ALTIVEC_P (mode)))
13373 and_op2 = XEXP (addr, 1);
13374 addr = XEXP (addr, 0);
13377 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13378 as the address later. */
13379 if (GET_CODE (addr) == PRE_MODIFY
13380 && (!VECTOR_MEM_VSX_P (mode)
13381 || and_op2 != NULL_RTX
13382 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13384 scratch_or_premodify = XEXP (addr, 0);
13385 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13387 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13388 addr = XEXP (addr, 1);
13391 if (legitimate_indirect_address_p (addr, false) /* reg */
13392 || legitimate_indexed_address_p (addr, false) /* reg+reg */
13393 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
13394 || (GET_CODE (addr) == AND /* Altivec memory */
13395 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13396 && INTVAL (XEXP (addr, 1)) == -16
13397 && VECTOR_MEM_ALTIVEC_P (mode))
13398 || (rclass == FLOAT_REGS /* legacy float mem */
13399 && GET_MODE_SIZE (mode) == 8
13400 && and_op2 == NULL_RTX
13401 && scratch_or_premodify == scratch
13402 && rs6000_legitimate_offset_address_p (mode, addr, false)))
13405 else if (GET_CODE (addr) == PLUS)
13407 addr_op1 = XEXP (addr, 0);
13408 addr_op2 = XEXP (addr, 1);
13409 gcc_assert (REG_P (addr_op1));
13411 if (TARGET_DEBUG_ADDR)
13413 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
13414 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13415 debug_rtx (addr_op2);
13417 rs6000_emit_move (scratch, addr_op2, Pmode);
13418 emit_insn (gen_rtx_SET (VOIDmode,
13419 scratch_or_premodify,
13420 gen_rtx_PLUS (Pmode,
13423 addr = scratch_or_premodify;
13424 scratch_or_premodify = scratch;
13427 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
13428 || GET_CODE (addr) == CONST_INT || REG_P (addr))
13430 if (TARGET_DEBUG_ADDR)
13432 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13433 rs6000_reg_names[REGNO (scratch_or_premodify)],
13434 GET_MODE_NAME (mode));
13438 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13439 addr = scratch_or_premodify;
13440 scratch_or_premodify = scratch;
13444 gcc_unreachable ();
13449 gcc_unreachable ();
13452 /* If the original address involved a pre-modify that we couldn't use the VSX
13453 memory instruction with update, and we haven't taken care of already,
13454 store the address in the pre-modify register and use that as the
13456 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
13458 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
13459 addr = scratch_or_premodify;
13462 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
13463 memory instruction, recreate the AND now, including the clobber which is
13464 generated by the general ANDSI3/ANDDI3 patterns for the
13465 andi. instruction. */
13466 if (and_op2 != NULL_RTX)
13468 if (! legitimate_indirect_address_p (addr, false))
13470 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
13474 if (TARGET_DEBUG_ADDR)
13476 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
13477 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13478 debug_rtx (and_op2);
13481 and_rtx = gen_rtx_SET (VOIDmode,
13483 gen_rtx_AND (Pmode,
13487 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
13488 emit_insn (gen_rtx_PARALLEL (VOIDmode,
13489 gen_rtvec (2, and_rtx, cc_clobber)));
13493 /* Adjust the address if it changed. */
13494 if (addr != XEXP (mem, 0))
13496 mem = change_address (mem, mode, addr);
13497 if (TARGET_DEBUG_ADDR)
13498 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
13501 /* Now create the move. */
13503 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
13505 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
13510 /* Target hook to return the cover classes for Integrated Register Allocator.
13511 Cover classes is a set of non-intersected register classes covering all hard
13512 registers used for register allocation purpose. Any move between two
13513 registers of a cover class should be cheaper than load or store of the
13514 registers. The value is array of register classes with LIM_REG_CLASSES used
13517 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
13518 account for the Altivec and Floating registers being subsets of the VSX
13519 register set under VSX, but distinct register sets on pre-VSX machines. */
13521 static const enum reg_class *
13522 rs6000_ira_cover_classes (void)
13524 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
13525 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
13527 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
13530 /* Allocate a 64-bit stack slot to be used for copying SDmode
13531 values through if this function has any SDmode references. */
13534 rs6000_alloc_sdmode_stack_slot (void)
13538 gimple_stmt_iterator gsi;
13540 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
13543 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
13545 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
13548 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13549 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13555 /* Check for any SDmode parameters of the function. */
13556 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
13558 if (TREE_TYPE (t) == error_mark_node)
13561 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
13562 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
13564 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13565 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13573 rs6000_instantiate_decls (void)
13575 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
13576 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
13579 /* Given an rtx X being reloaded into a reg required to be
13580 in class CLASS, return the class of reg to actually use.
13581 In general this is just CLASS; but on some machines
13582 in some cases it is preferable to use a more restrictive class.
13584 On the RS/6000, we have to return NO_REGS when we want to reload a
13585 floating-point CONST_DOUBLE to force it to be copied to memory.
13587 We also don't want to reload integer values into floating-point
13588 registers if we can at all help it. In fact, this can
13589 cause reload to die, if it tries to generate a reload of CTR
13590 into a FP register and discovers it doesn't have the memory location
13593 ??? Would it be a good idea to have reload do the converse, that is
13594 try to reload floating modes into FP registers if possible?
13597 static enum reg_class
13598 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
13600 enum machine_mode mode = GET_MODE (x);
13602 if (VECTOR_UNIT_VSX_P (mode)
13603 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
13606 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
13607 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
13608 && easy_vector_constant (x, mode))
13609 return ALTIVEC_REGS;
13611 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
13614 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
13615 return GENERAL_REGS;
13617 /* For VSX, prefer the traditional registers for DF if the address is of the
13618 form reg+offset because we can use the non-VSX loads. Prefer the Altivec
13619 registers if Altivec is handling the vector operations (i.e. V16QI, V8HI,
13621 if (rclass == VSX_REGS && VECTOR_MEM_VSX_P (mode))
13623 if (mode == DFmode && GET_CODE (x) == MEM)
13625 rtx addr = XEXP (x, 0);
13627 if (legitimate_indirect_address_p (addr, false)) /* reg */
13630 if (legitimate_indexed_address_p (addr, false)) /* reg+reg */
13633 if (GET_CODE (addr) == PRE_MODIFY
13634 && legitimate_indexed_address_p (XEXP (addr, 0), false))
13640 if (VECTOR_UNIT_ALTIVEC_P (mode))
13641 return ALTIVEC_REGS;
13649 /* Debug version of rs6000_preferred_reload_class. */
13650 static enum reg_class
13651 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
13653 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
13656 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
13658 reg_class_names[ret], reg_class_names[rclass],
13659 GET_MODE_NAME (GET_MODE (x)));
13665 /* If we are copying between FP or AltiVec registers and anything else, we need
13666 a memory location. The exception is when we are targeting ppc64 and the
13667 move to/from fpr to gpr instructions are available. Also, under VSX, you
13668 can copy vector registers from the FP register set to the Altivec register
13669 set and vice versa. */
13672 rs6000_secondary_memory_needed (enum reg_class class1,
13673 enum reg_class class2,
13674 enum machine_mode mode)
13676 if (class1 == class2)
13679 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
13680 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
13681 between these classes. But we need memory for other things that can go in
13682 FLOAT_REGS like SFmode. */
13684 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
13685 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
13686 || class1 == FLOAT_REGS))
13687 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
13688 && class2 != FLOAT_REGS);
13690 if (class1 == VSX_REGS || class2 == VSX_REGS)
13693 if (class1 == FLOAT_REGS
13694 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13695 || ((mode != DFmode)
13696 && (mode != DDmode)
13697 && (mode != DImode))))
13700 if (class2 == FLOAT_REGS
13701 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13702 || ((mode != DFmode)
13703 && (mode != DDmode)
13704 && (mode != DImode))))
13707 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
13713 /* Debug version of rs6000_secondary_memory_needed. */
13715 rs6000_debug_secondary_memory_needed (enum reg_class class1,
13716 enum reg_class class2,
13717 enum machine_mode mode)
13719 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
13722 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
13723 "class2 = %s, mode = %s\n",
13724 ret ? "true" : "false", reg_class_names[class1],
13725 reg_class_names[class2], GET_MODE_NAME (mode));
13730 /* Return the register class of a scratch register needed to copy IN into
13731 or out of a register in RCLASS in MODE. If it can be done directly,
13732 NO_REGS is returned. */
13734 static enum reg_class
13735 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
13740 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
13742 && MACHOPIC_INDIRECT
13746 /* We cannot copy a symbolic operand directly into anything
13747 other than BASE_REGS for TARGET_ELF. So indicate that a
13748 register from BASE_REGS is needed as an intermediate
13751 On Darwin, pic addresses require a load from memory, which
13752 needs a base register. */
13753 if (rclass != BASE_REGS
13754 && (GET_CODE (in) == SYMBOL_REF
13755 || GET_CODE (in) == HIGH
13756 || GET_CODE (in) == LABEL_REF
13757 || GET_CODE (in) == CONST))
13761 if (GET_CODE (in) == REG)
13763 regno = REGNO (in);
13764 if (regno >= FIRST_PSEUDO_REGISTER)
13766 regno = true_regnum (in);
13767 if (regno >= FIRST_PSEUDO_REGISTER)
13771 else if (GET_CODE (in) == SUBREG)
13773 regno = true_regnum (in);
13774 if (regno >= FIRST_PSEUDO_REGISTER)
13780 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
13782 if (rclass == GENERAL_REGS || rclass == BASE_REGS
13783 || (regno >= 0 && INT_REGNO_P (regno)))
13786 /* Constants, memory, and FP registers can go into FP registers. */
13787 if ((regno == -1 || FP_REGNO_P (regno))
13788 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
13789 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
13791 /* Memory, and FP/altivec registers can go into fp/altivec registers under
13794 && (regno == -1 || VSX_REGNO_P (regno))
13795 && VSX_REG_CLASS_P (rclass))
13798 /* Memory, and AltiVec registers can go into AltiVec registers. */
13799 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
13800 && rclass == ALTIVEC_REGS)
13803 /* We can copy among the CR registers. */
13804 if ((rclass == CR_REGS || rclass == CR0_REGS)
13805 && regno >= 0 && CR_REGNO_P (regno))
13808 /* Otherwise, we need GENERAL_REGS. */
13809 return GENERAL_REGS;
13812 /* Debug version of rs6000_secondary_reload_class. */
13813 static enum reg_class
13814 rs6000_debug_secondary_reload_class (enum reg_class rclass,
13815 enum machine_mode mode, rtx in)
13817 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
13819 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
13820 "mode = %s, input rtx:\n",
13821 reg_class_names[ret], reg_class_names[rclass],
13822 GET_MODE_NAME (mode));
13828 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
13831 rs6000_cannot_change_mode_class (enum machine_mode from,
13832 enum machine_mode to,
13833 enum reg_class rclass)
13835 unsigned from_size = GET_MODE_SIZE (from);
13836 unsigned to_size = GET_MODE_SIZE (to);
13838 if (from_size != to_size)
13840 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
13841 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
13842 && reg_classes_intersect_p (xclass, rclass));
13845 if (TARGET_E500_DOUBLE
13846 && ((((to) == DFmode) + ((from) == DFmode)) == 1
13847 || (((to) == TFmode) + ((from) == TFmode)) == 1
13848 || (((to) == DDmode) + ((from) == DDmode)) == 1
13849 || (((to) == TDmode) + ((from) == TDmode)) == 1
13850 || (((to) == DImode) + ((from) == DImode)) == 1))
13853 /* Since the VSX register set includes traditional floating point registers
13854 and altivec registers, just check for the size being different instead of
13855 trying to check whether the modes are vector modes. Otherwise it won't
13856 allow say DF and DI to change classes. */
13857 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
13858 return (from_size != 8 && from_size != 16);
13860 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
13861 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
13864 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
13865 && reg_classes_intersect_p (GENERAL_REGS, rclass))
13871 /* Debug version of rs6000_cannot_change_mode_class. */
13873 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
13874 enum machine_mode to,
13875 enum reg_class rclass)
13877 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
13880 "rs6000_cannot_change_mode_class, return %s, from = %s, "
13881 "to = %s, rclass = %s\n",
13882 ret ? "true" : "false",
13883 GET_MODE_NAME (from), GET_MODE_NAME (to),
13884 reg_class_names[rclass]);
13889 /* Given a comparison operation, return the bit number in CCR to test. We
13890 know this is a valid comparison.
13892 SCC_P is 1 if this is for an scc. That means that %D will have been
13893 used instead of %C, so the bits will be in different places.
13895 Return -1 if OP isn't a valid comparison for some reason. */
13898 ccr_bit (rtx op, int scc_p)
13900 enum rtx_code code = GET_CODE (op);
13901 enum machine_mode cc_mode;
13906 if (!COMPARISON_P (op))
13909 reg = XEXP (op, 0);
13911 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
13913 cc_mode = GET_MODE (reg);
13914 cc_regnum = REGNO (reg);
13915 base_bit = 4 * (cc_regnum - CR0_REGNO);
13917 validate_condition_mode (code, cc_mode);
13919 /* When generating a sCOND operation, only positive conditions are
13922 || code == EQ || code == GT || code == LT || code == UNORDERED
13923 || code == GTU || code == LTU);
13928 return scc_p ? base_bit + 3 : base_bit + 2;
13930 return base_bit + 2;
13931 case GT: case GTU: case UNLE:
13932 return base_bit + 1;
13933 case LT: case LTU: case UNGE:
13935 case ORDERED: case UNORDERED:
13936 return base_bit + 3;
13939 /* If scc, we will have done a cror to put the bit in the
13940 unordered position. So test that bit. For integer, this is ! LT
13941 unless this is an scc insn. */
13942 return scc_p ? base_bit + 3 : base_bit;
13945 return scc_p ? base_bit + 3 : base_bit + 1;
13948 gcc_unreachable ();
13952 /* Return the GOT register. */
13955 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
13957 /* The second flow pass currently (June 1999) can't update
13958 regs_ever_live without disturbing other parts of the compiler, so
13959 update it here to make the prolog/epilogue code happy. */
13960 if (!can_create_pseudo_p ()
13961 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
13962 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
13964 crtl->uses_pic_offset_table = 1;
13966 return pic_offset_table_rtx;
13969 /* Function to init struct machine_function.
13970 This will be called, via a pointer variable,
13971 from push_function_context. */
13973 static struct machine_function *
13974 rs6000_init_machine_status (void)
13976 return GGC_CNEW (machine_function);
13979 /* These macros test for integers and extract the low-order bits. */
13981 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
13982 && GET_MODE (X) == VOIDmode)
13984 #define INT_LOWPART(X) \
13985 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
13988 extract_MB (rtx op)
13991 unsigned long val = INT_LOWPART (op);
13993 /* If the high bit is zero, the value is the first 1 bit we find
13995 if ((val & 0x80000000) == 0)
13997 gcc_assert (val & 0xffffffff);
14000 while (((val <<= 1) & 0x80000000) == 0)
14005 /* If the high bit is set and the low bit is not, or the mask is all
14006 1's, the value is zero. */
14007 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14010 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14013 while (((val >>= 1) & 1) != 0)
14020 extract_ME (rtx op)
14023 unsigned long val = INT_LOWPART (op);
14025 /* If the low bit is zero, the value is the first 1 bit we find from
14027 if ((val & 1) == 0)
14029 gcc_assert (val & 0xffffffff);
14032 while (((val >>= 1) & 1) == 0)
14038 /* If the low bit is set and the high bit is not, or the mask is all
14039 1's, the value is 31. */
14040 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14043 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14046 while (((val <<= 1) & 0x80000000) != 0)
14052 /* Locate some local-dynamic symbol still in use by this function
14053 so that we can print its name in some tls_ld pattern. */
14055 static const char *
14056 rs6000_get_some_local_dynamic_name (void)
14060 if (cfun->machine->some_ld_name)
14061 return cfun->machine->some_ld_name;
14063 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14065 && for_each_rtx (&PATTERN (insn),
14066 rs6000_get_some_local_dynamic_name_1, 0))
14067 return cfun->machine->some_ld_name;
14069 gcc_unreachable ();
14072 /* Helper function for rs6000_get_some_local_dynamic_name. */
14075 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14079 if (GET_CODE (x) == SYMBOL_REF)
14081 const char *str = XSTR (x, 0);
14082 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14084 cfun->machine->some_ld_name = str;
14092 /* Write out a function code label. */
14095 rs6000_output_function_entry (FILE *file, const char *fname)
14097 if (fname[0] != '.')
14099 switch (DEFAULT_ABI)
14102 gcc_unreachable ();
14108 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14117 RS6000_OUTPUT_BASENAME (file, fname);
14119 assemble_name (file, fname);
14122 /* Print an operand. Recognize special options, documented below. */
14125 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14126 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14128 #define SMALL_DATA_RELOC "sda21"
14129 #define SMALL_DATA_REG 0
14133 print_operand (FILE *file, rtx x, int code)
14137 unsigned HOST_WIDE_INT uval;
14142 /* Write out an instruction after the call which may be replaced
14143 with glue code by the loader. This depends on the AIX version. */
14144 asm_fprintf (file, RS6000_CALL_GLUE);
14147 /* %a is output_address. */
14150 /* If X is a constant integer whose low-order 5 bits are zero,
14151 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14152 in the AIX assembler where "sri" with a zero shift count
14153 writes a trash instruction. */
14154 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14161 /* If constant, low-order 16 bits of constant, unsigned.
14162 Otherwise, write normally. */
14164 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14166 print_operand (file, x, 0);
14170 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14171 for 64-bit mask direction. */
14172 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14175 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14179 /* X is a CR register. Print the number of the GT bit of the CR. */
14180 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14181 output_operand_lossage ("invalid %%c value");
14183 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14187 /* Like 'J' but get to the GT bit only. */
14188 gcc_assert (GET_CODE (x) == REG);
14190 /* Bit 1 is GT bit. */
14191 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14193 /* Add one for shift count in rlinm for scc. */
14194 fprintf (file, "%d", i + 1);
14198 /* X is a CR register. Print the number of the EQ bit of the CR */
14199 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14200 output_operand_lossage ("invalid %%E value");
14202 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14206 /* X is a CR register. Print the shift count needed to move it
14207 to the high-order four bits. */
14208 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14209 output_operand_lossage ("invalid %%f value");
14211 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14215 /* Similar, but print the count for the rotate in the opposite
14217 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14218 output_operand_lossage ("invalid %%F value");
14220 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14224 /* X is a constant integer. If it is negative, print "m",
14225 otherwise print "z". This is to make an aze or ame insn. */
14226 if (GET_CODE (x) != CONST_INT)
14227 output_operand_lossage ("invalid %%G value");
14228 else if (INTVAL (x) >= 0)
14235 /* If constant, output low-order five bits. Otherwise, write
14238 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14240 print_operand (file, x, 0);
14244 /* If constant, output low-order six bits. Otherwise, write
14247 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14249 print_operand (file, x, 0);
14253 /* Print `i' if this is a constant, else nothing. */
14259 /* Write the bit number in CCR for jump. */
14260 i = ccr_bit (x, 0);
14262 output_operand_lossage ("invalid %%j code");
14264 fprintf (file, "%d", i);
14268 /* Similar, but add one for shift count in rlinm for scc and pass
14269 scc flag to `ccr_bit'. */
14270 i = ccr_bit (x, 1);
14272 output_operand_lossage ("invalid %%J code");
14274 /* If we want bit 31, write a shift count of zero, not 32. */
14275 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14279 /* X must be a constant. Write the 1's complement of the
14282 output_operand_lossage ("invalid %%k value");
14284 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14288 /* X must be a symbolic constant on ELF. Write an
14289 expression suitable for an 'addi' that adds in the low 16
14290 bits of the MEM. */
14291 if (GET_CODE (x) != CONST)
14293 print_operand_address (file, x);
14294 fputs ("@l", file);
14298 if (GET_CODE (XEXP (x, 0)) != PLUS
14299 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14300 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14301 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14302 output_operand_lossage ("invalid %%K value");
14303 print_operand_address (file, XEXP (XEXP (x, 0), 0));
14304 fputs ("@l", file);
14305 /* For GNU as, there must be a non-alphanumeric character
14306 between 'l' and the number. The '-' is added by
14307 print_operand() already. */
14308 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
14310 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
14314 /* %l is output_asm_label. */
14317 /* Write second word of DImode or DFmode reference. Works on register
14318 or non-indexed memory only. */
14319 if (GET_CODE (x) == REG)
14320 fputs (reg_names[REGNO (x) + 1], file);
14321 else if (GET_CODE (x) == MEM)
14323 /* Handle possible auto-increment. Since it is pre-increment and
14324 we have already done it, we can just use an offset of word. */
14325 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14326 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14327 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14329 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14330 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14333 output_address (XEXP (adjust_address_nv (x, SImode,
14337 if (small_data_operand (x, GET_MODE (x)))
14338 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14339 reg_names[SMALL_DATA_REG]);
14344 /* MB value for a mask operand. */
14345 if (! mask_operand (x, SImode))
14346 output_operand_lossage ("invalid %%m value");
14348 fprintf (file, "%d", extract_MB (x));
14352 /* ME value for a mask operand. */
14353 if (! mask_operand (x, SImode))
14354 output_operand_lossage ("invalid %%M value");
14356 fprintf (file, "%d", extract_ME (x));
14359 /* %n outputs the negative of its operand. */
14362 /* Write the number of elements in the vector times 4. */
14363 if (GET_CODE (x) != PARALLEL)
14364 output_operand_lossage ("invalid %%N value");
14366 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14370 /* Similar, but subtract 1 first. */
14371 if (GET_CODE (x) != PARALLEL)
14372 output_operand_lossage ("invalid %%O value");
14374 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14378 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14380 || INT_LOWPART (x) < 0
14381 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14382 output_operand_lossage ("invalid %%p value");
14384 fprintf (file, "%d", i);
14388 /* The operand must be an indirect memory reference. The result
14389 is the register name. */
14390 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14391 || REGNO (XEXP (x, 0)) >= 32)
14392 output_operand_lossage ("invalid %%P value");
14394 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14398 /* This outputs the logical code corresponding to a boolean
14399 expression. The expression may have one or both operands
14400 negated (if one, only the first one). For condition register
14401 logical operations, it will also treat the negated
14402 CR codes as NOTs, but not handle NOTs of them. */
14404 const char *const *t = 0;
14406 enum rtx_code code = GET_CODE (x);
14407 static const char * const tbl[3][3] = {
14408 { "and", "andc", "nor" },
14409 { "or", "orc", "nand" },
14410 { "xor", "eqv", "xor" } };
14414 else if (code == IOR)
14416 else if (code == XOR)
14419 output_operand_lossage ("invalid %%q value");
14421 if (GET_CODE (XEXP (x, 0)) != NOT)
14425 if (GET_CODE (XEXP (x, 1)) == NOT)
14443 /* X is a CR register. Print the mask for `mtcrf'. */
14444 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14445 output_operand_lossage ("invalid %%R value");
14447 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
14451 /* Low 5 bits of 32 - value */
14453 output_operand_lossage ("invalid %%s value");
14455 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
14459 /* PowerPC64 mask position. All 0's is excluded.
14460 CONST_INT 32-bit mask is considered sign-extended so any
14461 transition must occur within the CONST_INT, not on the boundary. */
14462 if (! mask64_operand (x, DImode))
14463 output_operand_lossage ("invalid %%S value");
14465 uval = INT_LOWPART (x);
14467 if (uval & 1) /* Clear Left */
14469 #if HOST_BITS_PER_WIDE_INT > 64
14470 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14474 else /* Clear Right */
14477 #if HOST_BITS_PER_WIDE_INT > 64
14478 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14484 gcc_assert (i >= 0);
14485 fprintf (file, "%d", i);
14489 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
14490 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
14492 /* Bit 3 is OV bit. */
14493 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
14495 /* If we want bit 31, write a shift count of zero, not 32. */
14496 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14500 /* Print the symbolic name of a branch target register. */
14501 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
14502 && REGNO (x) != CTR_REGNO))
14503 output_operand_lossage ("invalid %%T value");
14504 else if (REGNO (x) == LR_REGNO)
14505 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
14507 fputs ("ctr", file);
14511 /* High-order 16 bits of constant for use in unsigned operand. */
14513 output_operand_lossage ("invalid %%u value");
14515 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14516 (INT_LOWPART (x) >> 16) & 0xffff);
14520 /* High-order 16 bits of constant for use in signed operand. */
14522 output_operand_lossage ("invalid %%v value");
14524 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14525 (INT_LOWPART (x) >> 16) & 0xffff);
14529 /* Print `u' if this has an auto-increment or auto-decrement. */
14530 if (GET_CODE (x) == MEM
14531 && (GET_CODE (XEXP (x, 0)) == PRE_INC
14532 || GET_CODE (XEXP (x, 0)) == PRE_DEC
14533 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
14538 /* Print the trap code for this operand. */
14539 switch (GET_CODE (x))
14542 fputs ("eq", file); /* 4 */
14545 fputs ("ne", file); /* 24 */
14548 fputs ("lt", file); /* 16 */
14551 fputs ("le", file); /* 20 */
14554 fputs ("gt", file); /* 8 */
14557 fputs ("ge", file); /* 12 */
14560 fputs ("llt", file); /* 2 */
14563 fputs ("lle", file); /* 6 */
14566 fputs ("lgt", file); /* 1 */
14569 fputs ("lge", file); /* 5 */
14572 gcc_unreachable ();
14577 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
14580 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
14581 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
14583 print_operand (file, x, 0);
14587 /* MB value for a PowerPC64 rldic operand. */
14588 val = (GET_CODE (x) == CONST_INT
14589 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
14594 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
14595 if ((val <<= 1) < 0)
14598 #if HOST_BITS_PER_WIDE_INT == 32
14599 if (GET_CODE (x) == CONST_INT && i >= 0)
14600 i += 32; /* zero-extend high-part was all 0's */
14601 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
14603 val = CONST_DOUBLE_LOW (x);
14609 for ( ; i < 64; i++)
14610 if ((val <<= 1) < 0)
14615 fprintf (file, "%d", i + 1);
14619 /* X is a FPR or Altivec register used in a VSX context. */
14620 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
14621 output_operand_lossage ("invalid %%x value");
14624 int reg = REGNO (x);
14625 int vsx_reg = (FP_REGNO_P (reg)
14627 : reg - FIRST_ALTIVEC_REGNO + 32);
14629 #ifdef TARGET_REGNAMES
14630 if (TARGET_REGNAMES)
14631 fprintf (file, "%%vs%d", vsx_reg);
14634 fprintf (file, "%d", vsx_reg);
14639 if (GET_CODE (x) == MEM
14640 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
14641 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
14642 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
14647 /* Like 'L', for third word of TImode */
14648 if (GET_CODE (x) == REG)
14649 fputs (reg_names[REGNO (x) + 2], file);
14650 else if (GET_CODE (x) == MEM)
14652 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14653 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14654 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14655 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14656 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14658 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
14659 if (small_data_operand (x, GET_MODE (x)))
14660 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14661 reg_names[SMALL_DATA_REG]);
14666 /* X is a SYMBOL_REF. Write out the name preceded by a
14667 period and without any trailing data in brackets. Used for function
14668 names. If we are configured for System V (or the embedded ABI) on
14669 the PowerPC, do not emit the period, since those systems do not use
14670 TOCs and the like. */
14671 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14673 /* Mark the decl as referenced so that cgraph will output the
14675 if (SYMBOL_REF_DECL (x))
14676 mark_decl_referenced (SYMBOL_REF_DECL (x));
14678 /* For macho, check to see if we need a stub. */
14681 const char *name = XSTR (x, 0);
14683 if (MACHOPIC_INDIRECT
14684 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
14685 name = machopic_indirection_name (x, /*stub_p=*/true);
14687 assemble_name (file, name);
14689 else if (!DOT_SYMBOLS)
14690 assemble_name (file, XSTR (x, 0));
14692 rs6000_output_function_entry (file, XSTR (x, 0));
14696 /* Like 'L', for last word of TImode. */
14697 if (GET_CODE (x) == REG)
14698 fputs (reg_names[REGNO (x) + 3], file);
14699 else if (GET_CODE (x) == MEM)
14701 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14702 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14703 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14704 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14705 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14707 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
14708 if (small_data_operand (x, GET_MODE (x)))
14709 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14710 reg_names[SMALL_DATA_REG]);
14714 /* Print AltiVec or SPE memory operand. */
14719 gcc_assert (GET_CODE (x) == MEM);
14723 /* Ugly hack because %y is overloaded. */
14724 if ((TARGET_SPE || TARGET_E500_DOUBLE)
14725 && (GET_MODE_SIZE (GET_MODE (x)) == 8
14726 || GET_MODE (x) == TFmode
14727 || GET_MODE (x) == TImode))
14729 /* Handle [reg]. */
14730 if (GET_CODE (tmp) == REG)
14732 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
14735 /* Handle [reg+UIMM]. */
14736 else if (GET_CODE (tmp) == PLUS &&
14737 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
14741 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
14743 x = INTVAL (XEXP (tmp, 1));
14744 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
14748 /* Fall through. Must be [reg+reg]. */
14750 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
14751 && GET_CODE (tmp) == AND
14752 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
14753 && INTVAL (XEXP (tmp, 1)) == -16)
14754 tmp = XEXP (tmp, 0);
14755 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
14756 && GET_CODE (tmp) == PRE_MODIFY)
14757 tmp = XEXP (tmp, 1);
14758 if (GET_CODE (tmp) == REG)
14759 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
14762 if (!GET_CODE (tmp) == PLUS
14763 || !REG_P (XEXP (tmp, 0))
14764 || !REG_P (XEXP (tmp, 1)))
14766 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
14770 if (REGNO (XEXP (tmp, 0)) == 0)
14771 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
14772 reg_names[ REGNO (XEXP (tmp, 0)) ]);
14774 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
14775 reg_names[ REGNO (XEXP (tmp, 1)) ]);
14781 if (GET_CODE (x) == REG)
14782 fprintf (file, "%s", reg_names[REGNO (x)]);
14783 else if (GET_CODE (x) == MEM)
14785 /* We need to handle PRE_INC and PRE_DEC here, since we need to
14786 know the width from the mode. */
14787 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
14788 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
14789 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14790 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
14791 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
14792 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14793 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14794 output_address (XEXP (XEXP (x, 0), 1));
14796 output_address (XEXP (x, 0));
14799 output_addr_const (file, x);
14803 assemble_name (file, rs6000_get_some_local_dynamic_name ());
14807 output_operand_lossage ("invalid %%xn code");
14811 /* Print the address of an operand. */
14814 print_operand_address (FILE *file, rtx x)
14816 if (GET_CODE (x) == REG)
14817 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
14818 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
14819 || GET_CODE (x) == LABEL_REF)
14821 output_addr_const (file, x);
14822 if (small_data_operand (x, GET_MODE (x)))
14823 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14824 reg_names[SMALL_DATA_REG]);
14826 gcc_assert (!TARGET_TOC);
14828 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
14830 gcc_assert (REG_P (XEXP (x, 0)));
14831 if (REGNO (XEXP (x, 0)) == 0)
14832 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
14833 reg_names[ REGNO (XEXP (x, 0)) ]);
14835 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
14836 reg_names[ REGNO (XEXP (x, 1)) ]);
14838 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
14839 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
14840 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
14842 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
14843 && CONSTANT_P (XEXP (x, 1)))
14845 output_addr_const (file, XEXP (x, 1));
14846 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
14850 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
14851 && CONSTANT_P (XEXP (x, 1)))
14853 fprintf (file, "lo16(");
14854 output_addr_const (file, XEXP (x, 1));
14855 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
14858 else if (legitimate_constant_pool_address_p (x))
14860 output_addr_const (file, XEXP (x, 1));
14861 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
14864 gcc_unreachable ();
14867 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
14870 rs6000_output_addr_const_extra (FILE *file, rtx x)
14872 if (GET_CODE (x) == UNSPEC)
14873 switch (XINT (x, 1))
14875 case UNSPEC_TOCREL:
14876 x = XVECEXP (x, 0, 0);
14877 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14878 output_addr_const (file, x);
14879 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
14882 assemble_name (file, toc_label_name);
14884 else if (TARGET_ELF)
14885 fputs ("@toc", file);
14889 case UNSPEC_MACHOPIC_OFFSET:
14890 output_addr_const (file, XVECEXP (x, 0, 0));
14892 machopic_output_function_base_name (file);
14899 /* Target hook for assembling integer objects. The PowerPC version has
14900 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
14901 is defined. It also needs to handle DI-mode objects on 64-bit
14905 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
14907 #ifdef RELOCATABLE_NEEDS_FIXUP
14908 /* Special handling for SI values. */
14909 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
14911 static int recurse = 0;
14913 /* For -mrelocatable, we mark all addresses that need to be fixed up
14914 in the .fixup section. */
14915 if (TARGET_RELOCATABLE
14916 && in_section != toc_section
14917 && in_section != text_section
14918 && !unlikely_text_section_p (in_section)
14920 && GET_CODE (x) != CONST_INT
14921 && GET_CODE (x) != CONST_DOUBLE
14927 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
14929 ASM_OUTPUT_LABEL (asm_out_file, buf);
14930 fprintf (asm_out_file, "\t.long\t(");
14931 output_addr_const (asm_out_file, x);
14932 fprintf (asm_out_file, ")@fixup\n");
14933 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
14934 ASM_OUTPUT_ALIGN (asm_out_file, 2);
14935 fprintf (asm_out_file, "\t.long\t");
14936 assemble_name (asm_out_file, buf);
14937 fprintf (asm_out_file, "\n\t.previous\n");
14941 /* Remove initial .'s to turn a -mcall-aixdesc function
14942 address into the address of the descriptor, not the function
14944 else if (GET_CODE (x) == SYMBOL_REF
14945 && XSTR (x, 0)[0] == '.'
14946 && DEFAULT_ABI == ABI_AIX)
14948 const char *name = XSTR (x, 0);
14949 while (*name == '.')
14952 fprintf (asm_out_file, "\t.long\t%s\n", name);
14956 #endif /* RELOCATABLE_NEEDS_FIXUP */
14957 return default_assemble_integer (x, size, aligned_p);
14960 #ifdef HAVE_GAS_HIDDEN
14961 /* Emit an assembler directive to set symbol visibility for DECL to
14962 VISIBILITY_TYPE. */
14965 rs6000_assemble_visibility (tree decl, int vis)
14967 /* Functions need to have their entry point symbol visibility set as
14968 well as their descriptor symbol visibility. */
14969 if (DEFAULT_ABI == ABI_AIX
14971 && TREE_CODE (decl) == FUNCTION_DECL)
14973 static const char * const visibility_types[] = {
14974 NULL, "internal", "hidden", "protected"
14977 const char *name, *type;
14979 name = ((* targetm.strip_name_encoding)
14980 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
14981 type = visibility_types[vis];
14983 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
14984 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
14987 default_assemble_visibility (decl, vis);
14992 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
14994 /* Reversal of FP compares takes care -- an ordered compare
14995 becomes an unordered compare and vice versa. */
14996 if (mode == CCFPmode
14997 && (!flag_finite_math_only
14998 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
14999 || code == UNEQ || code == LTGT))
15000 return reverse_condition_maybe_unordered (code);
15002 return reverse_condition (code);
15005 /* Generate a compare for CODE. Return a brand-new rtx that
15006 represents the result of the compare. */
15009 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15011 enum machine_mode comp_mode;
15012 rtx compare_result;
15013 enum rtx_code code = GET_CODE (cmp);
15014 rtx op0 = XEXP (cmp, 0);
15015 rtx op1 = XEXP (cmp, 1);
15017 if (FLOAT_MODE_P (mode))
15018 comp_mode = CCFPmode;
15019 else if (code == GTU || code == LTU
15020 || code == GEU || code == LEU)
15021 comp_mode = CCUNSmode;
15022 else if ((code == EQ || code == NE)
15023 && GET_CODE (op0) == SUBREG
15024 && GET_CODE (op1) == SUBREG
15025 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15026 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15027 /* These are unsigned values, perhaps there will be a later
15028 ordering compare that can be shared with this one.
15029 Unfortunately we cannot detect the signedness of the operands
15030 for non-subregs. */
15031 comp_mode = CCUNSmode;
15033 comp_mode = CCmode;
15035 /* First, the compare. */
15036 compare_result = gen_reg_rtx (comp_mode);
15038 /* E500 FP compare instructions on the GPRs. Yuck! */
15039 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15040 && FLOAT_MODE_P (mode))
15042 rtx cmp, or_result, compare_result2;
15043 enum machine_mode op_mode = GET_MODE (op0);
15045 if (op_mode == VOIDmode)
15046 op_mode = GET_MODE (op1);
15048 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15049 This explains the following mess. */
15053 case EQ: case UNEQ: case NE: case LTGT:
15057 cmp = (flag_finite_math_only && !flag_trapping_math)
15058 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15059 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15063 cmp = (flag_finite_math_only && !flag_trapping_math)
15064 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15065 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15069 cmp = (flag_finite_math_only && !flag_trapping_math)
15070 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15071 : gen_cmptfeq_gpr (compare_result, op0, op1);
15075 gcc_unreachable ();
15079 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15083 cmp = (flag_finite_math_only && !flag_trapping_math)
15084 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15085 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15089 cmp = (flag_finite_math_only && !flag_trapping_math)
15090 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15091 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15095 cmp = (flag_finite_math_only && !flag_trapping_math)
15096 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15097 : gen_cmptfgt_gpr (compare_result, op0, op1);
15101 gcc_unreachable ();
15105 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15109 cmp = (flag_finite_math_only && !flag_trapping_math)
15110 ? gen_tstsflt_gpr (compare_result, op0, op1)
15111 : gen_cmpsflt_gpr (compare_result, op0, op1);
15115 cmp = (flag_finite_math_only && !flag_trapping_math)
15116 ? gen_tstdflt_gpr (compare_result, op0, op1)
15117 : gen_cmpdflt_gpr (compare_result, op0, op1);
15121 cmp = (flag_finite_math_only && !flag_trapping_math)
15122 ? gen_tsttflt_gpr (compare_result, op0, op1)
15123 : gen_cmptflt_gpr (compare_result, op0, op1);
15127 gcc_unreachable ();
15131 gcc_unreachable ();
15134 /* Synthesize LE and GE from LT/GT || EQ. */
15135 if (code == LE || code == GE || code == LEU || code == GEU)
15141 case LE: code = LT; break;
15142 case GE: code = GT; break;
15143 case LEU: code = LT; break;
15144 case GEU: code = GT; break;
15145 default: gcc_unreachable ();
15148 compare_result2 = gen_reg_rtx (CCFPmode);
15154 cmp = (flag_finite_math_only && !flag_trapping_math)
15155 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15156 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15160 cmp = (flag_finite_math_only && !flag_trapping_math)
15161 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15162 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15166 cmp = (flag_finite_math_only && !flag_trapping_math)
15167 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15168 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15172 gcc_unreachable ();
15176 /* OR them together. */
15177 or_result = gen_reg_rtx (CCFPmode);
15178 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15180 compare_result = or_result;
15185 if (code == NE || code == LTGT)
15195 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15196 CLOBBERs to match cmptf_internal2 pattern. */
15197 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15198 && GET_MODE (op0) == TFmode
15199 && !TARGET_IEEEQUAD
15200 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15201 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15203 gen_rtx_SET (VOIDmode,
15205 gen_rtx_COMPARE (comp_mode, op0, op1)),
15206 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15207 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15208 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15209 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15210 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15211 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15212 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15213 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
15214 else if (GET_CODE (op1) == UNSPEC
15215 && XINT (op1, 1) == UNSPEC_SP_TEST)
15217 rtx op1b = XVECEXP (op1, 0, 0);
15218 comp_mode = CCEQmode;
15219 compare_result = gen_reg_rtx (CCEQmode);
15221 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15223 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15226 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15227 gen_rtx_COMPARE (comp_mode, op0, op1)));
15230 /* Some kinds of FP comparisons need an OR operation;
15231 under flag_finite_math_only we don't bother. */
15232 if (FLOAT_MODE_P (mode)
15233 && !flag_finite_math_only
15234 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15235 && (code == LE || code == GE
15236 || code == UNEQ || code == LTGT
15237 || code == UNGT || code == UNLT))
15239 enum rtx_code or1, or2;
15240 rtx or1_rtx, or2_rtx, compare2_rtx;
15241 rtx or_result = gen_reg_rtx (CCEQmode);
15245 case LE: or1 = LT; or2 = EQ; break;
15246 case GE: or1 = GT; or2 = EQ; break;
15247 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15248 case LTGT: or1 = LT; or2 = GT; break;
15249 case UNGT: or1 = UNORDERED; or2 = GT; break;
15250 case UNLT: or1 = UNORDERED; or2 = LT; break;
15251 default: gcc_unreachable ();
15253 validate_condition_mode (or1, comp_mode);
15254 validate_condition_mode (or2, comp_mode);
15255 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15256 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15257 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15258 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15260 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15262 compare_result = or_result;
15266 validate_condition_mode (code, GET_MODE (compare_result));
15268 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15272 /* Emit the RTL for an sCOND pattern. */
15275 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15278 enum machine_mode op_mode;
15279 enum rtx_code cond_code;
15280 rtx result = operands[0];
15282 condition_rtx = rs6000_generate_compare (operands[1], mode);
15283 cond_code = GET_CODE (condition_rtx);
15285 if (FLOAT_MODE_P (mode)
15286 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15290 PUT_MODE (condition_rtx, SImode);
15291 t = XEXP (condition_rtx, 0);
15293 gcc_assert (cond_code == NE || cond_code == EQ);
15295 if (cond_code == NE)
15296 emit_insn (gen_e500_flip_gt_bit (t, t));
15298 emit_insn (gen_move_from_CR_gt_bit (result, t));
15302 if (cond_code == NE
15303 || cond_code == GE || cond_code == LE
15304 || cond_code == GEU || cond_code == LEU
15305 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15307 rtx not_result = gen_reg_rtx (CCEQmode);
15308 rtx not_op, rev_cond_rtx;
15309 enum machine_mode cc_mode;
15311 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15313 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15314 SImode, XEXP (condition_rtx, 0), const0_rtx);
15315 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15316 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15317 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15320 op_mode = GET_MODE (XEXP (operands[1], 0));
15321 if (op_mode == VOIDmode)
15322 op_mode = GET_MODE (XEXP (operands[1], 1));
15324 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15326 PUT_MODE (condition_rtx, DImode);
15327 convert_move (result, condition_rtx, 0);
15331 PUT_MODE (condition_rtx, SImode);
15332 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15336 /* Emit a branch of kind CODE to location LOC. */
15339 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15341 rtx condition_rtx, loc_ref;
15343 condition_rtx = rs6000_generate_compare (operands[0], mode);
15344 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15345 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15346 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15347 loc_ref, pc_rtx)));
15350 /* Return the string to output a conditional branch to LABEL, which is
15351 the operand number of the label, or -1 if the branch is really a
15352 conditional return.
15354 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15355 condition code register and its mode specifies what kind of
15356 comparison we made.
15358 REVERSED is nonzero if we should reverse the sense of the comparison.
15360 INSN is the insn. */
15363 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
15365 static char string[64];
15366 enum rtx_code code = GET_CODE (op);
15367 rtx cc_reg = XEXP (op, 0);
15368 enum machine_mode mode = GET_MODE (cc_reg);
15369 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
15370 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
15371 int really_reversed = reversed ^ need_longbranch;
15377 validate_condition_mode (code, mode);
15379 /* Work out which way this really branches. We could use
15380 reverse_condition_maybe_unordered here always but this
15381 makes the resulting assembler clearer. */
15382 if (really_reversed)
15384 /* Reversal of FP compares takes care -- an ordered compare
15385 becomes an unordered compare and vice versa. */
15386 if (mode == CCFPmode)
15387 code = reverse_condition_maybe_unordered (code);
15389 code = reverse_condition (code);
15392 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
15394 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
15399 /* Opposite of GT. */
15408 gcc_unreachable ();
15414 /* Not all of these are actually distinct opcodes, but
15415 we distinguish them for clarity of the resulting assembler. */
15416 case NE: case LTGT:
15417 ccode = "ne"; break;
15418 case EQ: case UNEQ:
15419 ccode = "eq"; break;
15421 ccode = "ge"; break;
15422 case GT: case GTU: case UNGT:
15423 ccode = "gt"; break;
15425 ccode = "le"; break;
15426 case LT: case LTU: case UNLT:
15427 ccode = "lt"; break;
15428 case UNORDERED: ccode = "un"; break;
15429 case ORDERED: ccode = "nu"; break;
15430 case UNGE: ccode = "nl"; break;
15431 case UNLE: ccode = "ng"; break;
15433 gcc_unreachable ();
15436 /* Maybe we have a guess as to how likely the branch is.
15437 The old mnemonics don't have a way to specify this information. */
15439 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
15440 if (note != NULL_RTX)
15442 /* PROB is the difference from 50%. */
15443 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
15445 /* Only hint for highly probable/improbable branches on newer
15446 cpus as static prediction overrides processor dynamic
15447 prediction. For older cpus we may as well always hint, but
15448 assume not taken for branches that are very close to 50% as a
15449 mispredicted taken branch is more expensive than a
15450 mispredicted not-taken branch. */
15451 if (rs6000_always_hint
15452 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
15453 && br_prob_note_reliable_p (note)))
15455 if (abs (prob) > REG_BR_PROB_BASE / 20
15456 && ((prob > 0) ^ need_longbranch))
15464 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
15466 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
15468 /* We need to escape any '%' characters in the reg_names string.
15469 Assume they'd only be the first character.... */
15470 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
15472 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
15476 /* If the branch distance was too far, we may have to use an
15477 unconditional branch to go the distance. */
15478 if (need_longbranch)
15479 s += sprintf (s, ",$+8\n\tb %s", label);
15481 s += sprintf (s, ",%s", label);
15487 /* Return the string to flip the GT bit on a CR. */
15489 output_e500_flip_gt_bit (rtx dst, rtx src)
15491 static char string[64];
15494 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
15495 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
15498 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
15499 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
15501 sprintf (string, "crnot %d,%d", a, b);
15505 /* Return insn for VSX or Altivec comparisons. */
15508 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
15511 enum machine_mode mode = GET_MODE (op0);
15519 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
15525 mask = gen_reg_rtx (mode);
15526 emit_insn (gen_rtx_SET (VOIDmode,
15528 gen_rtx_fmt_ee (code, mode, op0, op1)));
15535 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
15536 DMODE is expected destination mode. This is a recursive function. */
15539 rs6000_emit_vector_compare (enum rtx_code rcode,
15541 enum machine_mode dmode)
15544 bool swap_operands = false;
15545 bool try_again = false;
15547 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
15548 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
15550 /* See if the comparison works as is. */
15551 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15559 swap_operands = true;
15564 swap_operands = true;
15572 /* Invert condition and try again.
15573 e.g., A != B becomes ~(A==B). */
15575 enum rtx_code rev_code;
15576 enum insn_code nor_code;
15579 rev_code = reverse_condition_maybe_unordered (rcode);
15580 if (rev_code == UNKNOWN)
15583 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
15584 if (nor_code == CODE_FOR_nothing)
15587 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
15591 mask = gen_reg_rtx (dmode);
15592 emit_insn (GEN_FCN (nor_code) (mask, mask2));
15600 /* Try GT/GTU/LT/LTU OR EQ */
15603 enum insn_code ior_code;
15604 enum rtx_code new_code;
15625 gcc_unreachable ();
15628 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
15629 if (ior_code == CODE_FOR_nothing)
15632 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
15636 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
15640 mask = gen_reg_rtx (dmode);
15641 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
15659 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15664 /* You only get two chances. */
15668 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
15669 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
15670 operands for the relation operation COND. */
15673 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
15674 rtx cond, rtx cc_op0, rtx cc_op1)
15676 enum machine_mode dest_mode = GET_MODE (dest);
15677 enum rtx_code rcode = GET_CODE (cond);
15678 enum machine_mode cc_mode = CCmode;
15682 bool invert_move = false;
15684 if (VECTOR_UNIT_NONE_P (dest_mode))
15689 /* Swap operands if we can, and fall back to doing the operation as
15690 specified, and doing a NOR to invert the test. */
15696 /* Invert condition and try again.
15697 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
15698 invert_move = true;
15699 rcode = reverse_condition_maybe_unordered (rcode);
15700 if (rcode == UNKNOWN)
15704 /* Mark unsigned tests with CCUNSmode. */
15709 cc_mode = CCUNSmode;
15716 /* Get the vector mask for the given relational operations. */
15717 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
15725 op_true = op_false;
15729 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
15730 emit_insn (gen_rtx_SET (VOIDmode,
15732 gen_rtx_IF_THEN_ELSE (dest_mode,
15739 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
15740 operands of the last comparison is nonzero/true, FALSE_COND if it
15741 is zero/false. Return 0 if the hardware has no such operation. */
15744 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15746 enum rtx_code code = GET_CODE (op);
15747 rtx op0 = XEXP (op, 0);
15748 rtx op1 = XEXP (op, 1);
15749 REAL_VALUE_TYPE c1;
15750 enum machine_mode compare_mode = GET_MODE (op0);
15751 enum machine_mode result_mode = GET_MODE (dest);
15753 bool is_against_zero;
15755 /* These modes should always match. */
15756 if (GET_MODE (op1) != compare_mode
15757 /* In the isel case however, we can use a compare immediate, so
15758 op1 may be a small constant. */
15759 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
15761 if (GET_MODE (true_cond) != result_mode)
15763 if (GET_MODE (false_cond) != result_mode)
15766 /* First, work out if the hardware can do this at all, or
15767 if it's too slow.... */
15768 if (!FLOAT_MODE_P (compare_mode))
15771 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
15774 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
15775 && SCALAR_FLOAT_MODE_P (compare_mode))
15778 is_against_zero = op1 == CONST0_RTX (compare_mode);
15780 /* A floating-point subtract might overflow, underflow, or produce
15781 an inexact result, thus changing the floating-point flags, so it
15782 can't be generated if we care about that. It's safe if one side
15783 of the construct is zero, since then no subtract will be
15785 if (SCALAR_FLOAT_MODE_P (compare_mode)
15786 && flag_trapping_math && ! is_against_zero)
15789 /* Eliminate half of the comparisons by switching operands, this
15790 makes the remaining code simpler. */
15791 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
15792 || code == LTGT || code == LT || code == UNLE)
15794 code = reverse_condition_maybe_unordered (code);
15796 true_cond = false_cond;
15800 /* UNEQ and LTGT take four instructions for a comparison with zero,
15801 it'll probably be faster to use a branch here too. */
15802 if (code == UNEQ && HONOR_NANS (compare_mode))
15805 if (GET_CODE (op1) == CONST_DOUBLE)
15806 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
15808 /* We're going to try to implement comparisons by performing
15809 a subtract, then comparing against zero. Unfortunately,
15810 Inf - Inf is NaN which is not zero, and so if we don't
15811 know that the operand is finite and the comparison
15812 would treat EQ different to UNORDERED, we can't do it. */
15813 if (HONOR_INFINITIES (compare_mode)
15814 && code != GT && code != UNGE
15815 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
15816 /* Constructs of the form (a OP b ? a : b) are safe. */
15817 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
15818 || (! rtx_equal_p (op0, true_cond)
15819 && ! rtx_equal_p (op1, true_cond))))
15822 /* At this point we know we can use fsel. */
15824 /* Reduce the comparison to a comparison against zero. */
15825 if (! is_against_zero)
15827 temp = gen_reg_rtx (compare_mode);
15828 emit_insn (gen_rtx_SET (VOIDmode, temp,
15829 gen_rtx_MINUS (compare_mode, op0, op1)));
15831 op1 = CONST0_RTX (compare_mode);
15834 /* If we don't care about NaNs we can reduce some of the comparisons
15835 down to faster ones. */
15836 if (! HONOR_NANS (compare_mode))
15842 true_cond = false_cond;
15855 /* Now, reduce everything down to a GE. */
15862 temp = gen_reg_rtx (compare_mode);
15863 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15868 temp = gen_reg_rtx (compare_mode);
15869 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
15874 temp = gen_reg_rtx (compare_mode);
15875 emit_insn (gen_rtx_SET (VOIDmode, temp,
15876 gen_rtx_NEG (compare_mode,
15877 gen_rtx_ABS (compare_mode, op0))));
15882 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
15883 temp = gen_reg_rtx (result_mode);
15884 emit_insn (gen_rtx_SET (VOIDmode, temp,
15885 gen_rtx_IF_THEN_ELSE (result_mode,
15886 gen_rtx_GE (VOIDmode,
15888 true_cond, false_cond)));
15889 false_cond = true_cond;
15892 temp = gen_reg_rtx (compare_mode);
15893 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15898 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
15899 temp = gen_reg_rtx (result_mode);
15900 emit_insn (gen_rtx_SET (VOIDmode, temp,
15901 gen_rtx_IF_THEN_ELSE (result_mode,
15902 gen_rtx_GE (VOIDmode,
15904 true_cond, false_cond)));
15905 true_cond = false_cond;
15908 temp = gen_reg_rtx (compare_mode);
15909 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15914 gcc_unreachable ();
15917 emit_insn (gen_rtx_SET (VOIDmode, dest,
15918 gen_rtx_IF_THEN_ELSE (result_mode,
15919 gen_rtx_GE (VOIDmode,
15921 true_cond, false_cond)));
15925 /* Same as above, but for ints (isel). */
15928 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15930 rtx condition_rtx, cr;
15931 enum machine_mode mode = GET_MODE (XEXP (op, 0));
15933 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
15936 /* We still have to do the compare, because isel doesn't do a
15937 compare, it just looks at the CRx bits set by a previous compare
15939 condition_rtx = rs6000_generate_compare (op, SImode);
15940 cr = XEXP (condition_rtx, 0);
15942 if (mode == SImode)
15944 if (GET_MODE (cr) == CCmode)
15945 emit_insn (gen_isel_signed_si (dest, condition_rtx,
15946 true_cond, false_cond, cr));
15948 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
15949 true_cond, false_cond, cr));
15953 if (GET_MODE (cr) == CCmode)
15954 emit_insn (gen_isel_signed_di (dest, condition_rtx,
15955 true_cond, false_cond, cr));
15957 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
15958 true_cond, false_cond, cr));
15965 output_isel (rtx *operands)
15967 enum rtx_code code;
15969 code = GET_CODE (operands[1]);
15970 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
15972 PUT_CODE (operands[1], reverse_condition (code));
15973 return "isel %0,%3,%2,%j1";
15976 return "isel %0,%2,%3,%j1";
15980 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
15982 enum machine_mode mode = GET_MODE (op0);
15986 /* VSX/altivec have direct min/max insns. */
15987 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
15989 emit_insn (gen_rtx_SET (VOIDmode,
15991 gen_rtx_fmt_ee (code, mode, op0, op1)));
15995 if (code == SMAX || code == SMIN)
16000 if (code == SMAX || code == UMAX)
16001 target = emit_conditional_move (dest, c, op0, op1, mode,
16002 op0, op1, mode, 0);
16004 target = emit_conditional_move (dest, c, op0, op1, mode,
16005 op1, op0, mode, 0);
16006 gcc_assert (target);
16007 if (target != dest)
16008 emit_move_insn (dest, target);
16011 /* Emit instructions to perform a load-reserved/store-conditional operation.
16012 The operation performed is an atomic
16013 (set M (CODE:MODE M OP))
16014 If not NULL, BEFORE is atomically set to M before the operation, and
16015 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16016 If SYNC_P then a memory barrier is emitted before the operation.
16017 Either OP or M may be wrapped in a NOT operation. */
16020 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16021 rtx m, rtx op, rtx before_param, rtx after_param,
16024 enum machine_mode used_mode;
16025 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16028 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16029 rtx shift = NULL_RTX;
16032 emit_insn (gen_lwsync ());
16036 /* If this is smaller than SImode, we'll have to use SImode with
16038 if (mode == QImode || mode == HImode)
16042 if (MEM_ALIGN (used_m) >= 32)
16045 if (BYTES_BIG_ENDIAN)
16046 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16048 shift = GEN_INT (ishift);
16049 used_m = change_address (used_m, SImode, 0);
16053 rtx addrSI, aligned_addr;
16054 int shift_mask = mode == QImode ? 0x18 : 0x10;
16056 addrSI = gen_lowpart_common (SImode,
16057 force_reg (Pmode, XEXP (used_m, 0)));
16058 addrSI = force_reg (SImode, addrSI);
16059 shift = gen_reg_rtx (SImode);
16061 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16062 GEN_INT (shift_mask)));
16063 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16065 aligned_addr = expand_binop (Pmode, and_optab,
16067 GEN_INT (-4), NULL_RTX,
16068 1, OPTAB_LIB_WIDEN);
16069 used_m = change_address (used_m, SImode, aligned_addr);
16070 set_mem_align (used_m, 32);
16072 /* It's safe to keep the old alias set of USED_M, because
16073 the operation is atomic and only affects the original
16077 if (GET_CODE (op) == NOT)
16079 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16080 oldop = gen_rtx_NOT (SImode, oldop);
16083 oldop = lowpart_subreg (SImode, op, mode);
16089 newop = expand_binop (SImode, and_optab,
16090 oldop, GEN_INT (imask), NULL_RTX,
16091 1, OPTAB_LIB_WIDEN);
16092 emit_insn (gen_ashlsi3 (newop, newop, shift));
16095 case NOT: /* NAND */
16096 newop = expand_binop (SImode, ior_optab,
16097 oldop, GEN_INT (~imask), NULL_RTX,
16098 1, OPTAB_LIB_WIDEN);
16099 emit_insn (gen_rotlsi3 (newop, newop, shift));
16103 newop = expand_binop (SImode, ior_optab,
16104 oldop, GEN_INT (~imask), NULL_RTX,
16105 1, OPTAB_LIB_WIDEN);
16106 emit_insn (gen_rotlsi3 (newop, newop, shift));
16114 newop = expand_binop (SImode, and_optab,
16115 oldop, GEN_INT (imask), NULL_RTX,
16116 1, OPTAB_LIB_WIDEN);
16117 emit_insn (gen_ashlsi3 (newop, newop, shift));
16119 mask = gen_reg_rtx (SImode);
16120 emit_move_insn (mask, GEN_INT (imask));
16121 emit_insn (gen_ashlsi3 (mask, mask, shift));
16124 newop = gen_rtx_PLUS (SImode, m, newop);
16126 newop = gen_rtx_MINUS (SImode, m, newop);
16127 newop = gen_rtx_AND (SImode, newop, mask);
16128 newop = gen_rtx_IOR (SImode, newop,
16129 gen_rtx_AND (SImode,
16130 gen_rtx_NOT (SImode, mask),
16136 gcc_unreachable ();
16140 used_mode = SImode;
16141 before = gen_reg_rtx (used_mode);
16142 after = gen_reg_rtx (used_mode);
16147 before = before_param;
16148 after = after_param;
16150 if (before == NULL_RTX)
16151 before = gen_reg_rtx (used_mode);
16152 if (after == NULL_RTX)
16153 after = gen_reg_rtx (used_mode);
16156 if ((code == PLUS || code == MINUS)
16157 && used_mode != mode)
16158 the_op = op; /* Computed above. */
16159 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16160 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16161 else if (code == NOT)
16162 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16163 gen_rtx_NOT (used_mode, m),
16164 gen_rtx_NOT (used_mode, op));
16166 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16168 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16169 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16170 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16171 gen_rtx_UNSPEC (used_mode,
16172 gen_rtvec (1, the_op),
16174 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16176 if ((code == PLUS || code == MINUS) && used_mode != mode)
16177 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16178 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16180 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16181 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16183 /* Shift and mask the return values properly. */
16184 if (used_mode != mode && before_param)
16186 emit_insn (gen_lshrsi3 (before, before, shift));
16187 convert_move (before_param, before, 1);
16190 if (used_mode != mode && after_param)
16192 emit_insn (gen_lshrsi3 (after, after, shift));
16193 convert_move (after_param, after, 1);
16196 /* The previous sequence will end with a branch that's dependent on
16197 the conditional store, so placing an isync will ensure that no
16198 other instructions (especially, no load or store instructions)
16199 can start before the atomic operation completes. */
16201 emit_insn (gen_isync ());
16204 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16205 COND is true. Mark the jump as unlikely to be taken. */
16208 emit_unlikely_jump (rtx cond, rtx label)
16210 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16213 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16214 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16215 add_reg_note (x, REG_BR_PROB, very_unlikely);
16218 /* A subroutine of the atomic operation splitters. Emit a load-locked
16219 instruction in MODE. */
16222 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16224 rtx (*fn) (rtx, rtx) = NULL;
16225 if (mode == SImode)
16226 fn = gen_load_locked_si;
16227 else if (mode == DImode)
16228 fn = gen_load_locked_di;
16229 emit_insn (fn (reg, mem));
16232 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16233 instruction in MODE. */
16236 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16238 rtx (*fn) (rtx, rtx, rtx) = NULL;
16239 if (mode == SImode)
16240 fn = gen_store_conditional_si;
16241 else if (mode == DImode)
16242 fn = gen_store_conditional_di;
16244 /* Emit sync before stwcx. to address PPC405 Erratum. */
16245 if (PPC405_ERRATUM77)
16246 emit_insn (gen_memory_barrier ());
16248 emit_insn (fn (res, mem, val));
16251 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16252 to perform. MEM is the memory on which to operate. VAL is the second
16253 operand of the binary operator. BEFORE and AFTER are optional locations to
16254 return the value of MEM either before of after the operation. SCRATCH is
16255 a scratch register. */
16258 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16259 rtx before, rtx after, rtx scratch)
16261 enum machine_mode mode = GET_MODE (mem);
16262 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16264 emit_insn (gen_lwsync ());
16266 label = gen_label_rtx ();
16267 emit_label (label);
16268 label = gen_rtx_LABEL_REF (VOIDmode, label);
16270 if (before == NULL_RTX)
16272 emit_load_locked (mode, before, mem);
16275 x = gen_rtx_IOR (mode,
16276 gen_rtx_NOT (mode, before),
16277 gen_rtx_NOT (mode, val));
16278 else if (code == AND)
16279 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16281 x = gen_rtx_fmt_ee (code, mode, before, val);
16283 if (after != NULL_RTX)
16284 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16285 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16287 emit_store_conditional (mode, cond, mem, scratch);
16289 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16290 emit_unlikely_jump (x, label);
16292 emit_insn (gen_isync ());
16295 /* Expand an atomic compare and swap operation. MEM is the memory on which
16296 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16297 value to be stored. SCRATCH is a scratch GPR. */
16300 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16303 enum machine_mode mode = GET_MODE (mem);
16304 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16306 emit_insn (gen_lwsync ());
16308 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16309 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16310 emit_label (XEXP (label1, 0));
16312 emit_load_locked (mode, retval, mem);
16314 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16315 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16317 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16318 emit_unlikely_jump (x, label2);
16320 emit_move_insn (scratch, newval);
16321 emit_store_conditional (mode, cond, mem, scratch);
16323 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16324 emit_unlikely_jump (x, label1);
16326 emit_insn (gen_isync ());
16327 emit_label (XEXP (label2, 0));
16330 /* Expand an atomic test and set operation. MEM is the memory on which
16331 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16334 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16336 enum machine_mode mode = GET_MODE (mem);
16337 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16339 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16340 emit_label (XEXP (label, 0));
16342 emit_load_locked (mode, retval, mem);
16343 emit_move_insn (scratch, val);
16344 emit_store_conditional (mode, cond, mem, scratch);
16346 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16347 emit_unlikely_jump (x, label);
16349 emit_insn (gen_isync ());
16353 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
16355 enum machine_mode mode = GET_MODE (mem);
16356 rtx addrSI, align, wdst, shift, mask;
16357 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
16358 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16360 /* Shift amount for subword relative to aligned word. */
16361 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
16362 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
16363 shift = gen_reg_rtx (SImode);
16364 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16365 GEN_INT (shift_mask)));
16366 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16368 /* Shift and mask old value into position within word. */
16369 oldval = convert_modes (SImode, mode, oldval, 1);
16370 oldval = expand_binop (SImode, and_optab,
16371 oldval, GEN_INT (imask), NULL_RTX,
16372 1, OPTAB_LIB_WIDEN);
16373 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
16375 /* Shift and mask new value into position within word. */
16376 newval = convert_modes (SImode, mode, newval, 1);
16377 newval = expand_binop (SImode, and_optab,
16378 newval, GEN_INT (imask), NULL_RTX,
16379 1, OPTAB_LIB_WIDEN);
16380 emit_insn (gen_ashlsi3 (newval, newval, shift));
16382 /* Mask for insertion. */
16383 mask = gen_reg_rtx (SImode);
16384 emit_move_insn (mask, GEN_INT (imask));
16385 emit_insn (gen_ashlsi3 (mask, mask, shift));
16387 /* Address of aligned word containing subword. */
16388 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
16389 NULL_RTX, 1, OPTAB_LIB_WIDEN);
16390 mem = change_address (mem, SImode, align);
16391 set_mem_align (mem, 32);
16392 MEM_VOLATILE_P (mem) = 1;
16394 wdst = gen_reg_rtx (SImode);
16395 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
16396 oldval, newval, mem));
16398 /* Shift the result back. */
16399 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
16401 emit_move_insn (dst, gen_lowpart (mode, wdst));
16405 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
16406 rtx oldval, rtx newval, rtx mem,
16409 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16411 emit_insn (gen_lwsync ());
16412 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16413 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16414 emit_label (XEXP (label1, 0));
16416 emit_load_locked (SImode, scratch, mem);
16418 /* Mask subword within loaded value for comparison with oldval.
16419 Use UNSPEC_AND to avoid clobber.*/
16420 emit_insn (gen_rtx_SET (SImode, dest,
16421 gen_rtx_UNSPEC (SImode,
16422 gen_rtvec (2, scratch, mask),
16425 x = gen_rtx_COMPARE (CCmode, dest, oldval);
16426 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16428 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16429 emit_unlikely_jump (x, label2);
16431 /* Clear subword within loaded value for insertion of new value. */
16432 emit_insn (gen_rtx_SET (SImode, scratch,
16433 gen_rtx_AND (SImode,
16434 gen_rtx_NOT (SImode, mask), scratch)));
16435 emit_insn (gen_iorsi3 (scratch, scratch, newval));
16436 emit_store_conditional (SImode, cond, mem, scratch);
16438 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16439 emit_unlikely_jump (x, label1);
16441 emit_insn (gen_isync ());
16442 emit_label (XEXP (label2, 0));
16446 /* Emit instructions to move SRC to DST. Called by splitters for
16447 multi-register moves. It will emit at most one instruction for
16448 each register that is accessed; that is, it won't emit li/lis pairs
16449 (or equivalent for 64-bit code). One of SRC or DST must be a hard
16453 rs6000_split_multireg_move (rtx dst, rtx src)
16455 /* The register number of the first register being moved. */
16457 /* The mode that is to be moved. */
16458 enum machine_mode mode;
16459 /* The mode that the move is being done in, and its size. */
16460 enum machine_mode reg_mode;
16462 /* The number of registers that will be moved. */
16465 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
16466 mode = GET_MODE (dst);
16467 nregs = hard_regno_nregs[reg][mode];
16468 if (FP_REGNO_P (reg))
16469 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
16470 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
16471 else if (ALTIVEC_REGNO_P (reg))
16472 reg_mode = V16QImode;
16473 else if (TARGET_E500_DOUBLE && mode == TFmode)
16476 reg_mode = word_mode;
16477 reg_mode_size = GET_MODE_SIZE (reg_mode);
16479 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
16481 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
16483 /* Move register range backwards, if we might have destructive
16486 for (i = nregs - 1; i >= 0; i--)
16487 emit_insn (gen_rtx_SET (VOIDmode,
16488 simplify_gen_subreg (reg_mode, dst, mode,
16489 i * reg_mode_size),
16490 simplify_gen_subreg (reg_mode, src, mode,
16491 i * reg_mode_size)));
16497 bool used_update = false;
16499 if (MEM_P (src) && INT_REGNO_P (reg))
16503 if (GET_CODE (XEXP (src, 0)) == PRE_INC
16504 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
16507 breg = XEXP (XEXP (src, 0), 0);
16508 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
16509 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
16510 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
16511 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16512 src = replace_equiv_address (src, breg);
16514 else if (! rs6000_offsettable_memref_p (src))
16517 basereg = gen_rtx_REG (Pmode, reg);
16518 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
16519 src = replace_equiv_address (src, basereg);
16522 breg = XEXP (src, 0);
16523 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
16524 breg = XEXP (breg, 0);
16526 /* If the base register we are using to address memory is
16527 also a destination reg, then change that register last. */
16529 && REGNO (breg) >= REGNO (dst)
16530 && REGNO (breg) < REGNO (dst) + nregs)
16531 j = REGNO (breg) - REGNO (dst);
16534 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
16538 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
16539 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
16542 breg = XEXP (XEXP (dst, 0), 0);
16543 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
16544 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
16545 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
16547 /* We have to update the breg before doing the store.
16548 Use store with update, if available. */
16552 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16553 emit_insn (TARGET_32BIT
16554 ? (TARGET_POWERPC64
16555 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
16556 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
16557 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
16558 used_update = true;
16561 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16562 dst = replace_equiv_address (dst, breg);
16565 gcc_assert (rs6000_offsettable_memref_p (dst));
16568 for (i = 0; i < nregs; i++)
16570 /* Calculate index to next subword. */
16575 /* If compiler already emitted move of first word by
16576 store with update, no need to do anything. */
16577 if (j == 0 && used_update)
16580 emit_insn (gen_rtx_SET (VOIDmode,
16581 simplify_gen_subreg (reg_mode, dst, mode,
16582 j * reg_mode_size),
16583 simplify_gen_subreg (reg_mode, src, mode,
16584 j * reg_mode_size)));
16590 /* This page contains routines that are used to determine what the
16591 function prologue and epilogue code will do and write them out. */
16593 /* Return the first fixed-point register that is required to be
16594 saved. 32 if none. */
16597 first_reg_to_save (void)
16601 /* Find lowest numbered live register. */
16602 for (first_reg = 13; first_reg <= 31; first_reg++)
16603 if (df_regs_ever_live_p (first_reg)
16604 && (! call_used_regs[first_reg]
16605 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
16606 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
16607 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
16608 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
16613 && crtl->uses_pic_offset_table
16614 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
16615 return RS6000_PIC_OFFSET_TABLE_REGNUM;
16621 /* Similar, for FP regs. */
16624 first_fp_reg_to_save (void)
16628 /* Find lowest numbered live register. */
16629 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
16630 if (df_regs_ever_live_p (first_reg))
16636 /* Similar, for AltiVec regs. */
16639 first_altivec_reg_to_save (void)
16643 /* Stack frame remains as is unless we are in AltiVec ABI. */
16644 if (! TARGET_ALTIVEC_ABI)
16645 return LAST_ALTIVEC_REGNO + 1;
16647 /* On Darwin, the unwind routines are compiled without
16648 TARGET_ALTIVEC, and use save_world to save/restore the
16649 altivec registers when necessary. */
16650 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16651 && ! TARGET_ALTIVEC)
16652 return FIRST_ALTIVEC_REGNO + 20;
16654 /* Find lowest numbered live register. */
16655 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
16656 if (df_regs_ever_live_p (i))
16662 /* Return a 32-bit mask of the AltiVec registers we need to set in
16663 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
16664 the 32-bit word is 0. */
16666 static unsigned int
16667 compute_vrsave_mask (void)
16669 unsigned int i, mask = 0;
16671 /* On Darwin, the unwind routines are compiled without
16672 TARGET_ALTIVEC, and use save_world to save/restore the
16673 call-saved altivec registers when necessary. */
16674 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16675 && ! TARGET_ALTIVEC)
16678 /* First, find out if we use _any_ altivec registers. */
16679 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
16680 if (df_regs_ever_live_p (i))
16681 mask |= ALTIVEC_REG_BIT (i);
16686 /* Next, remove the argument registers from the set. These must
16687 be in the VRSAVE mask set by the caller, so we don't need to add
16688 them in again. More importantly, the mask we compute here is
16689 used to generate CLOBBERs in the set_vrsave insn, and we do not
16690 wish the argument registers to die. */
16691 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
16692 mask &= ~ALTIVEC_REG_BIT (i);
16694 /* Similarly, remove the return value from the set. */
16697 diddle_return_value (is_altivec_return_reg, &yes);
16699 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
16705 /* For a very restricted set of circumstances, we can cut down the
16706 size of prologues/epilogues by calling our own save/restore-the-world
16710 compute_save_world_info (rs6000_stack_t *info_ptr)
16712 info_ptr->world_save_p = 1;
16713 info_ptr->world_save_p
16714 = (WORLD_SAVE_P (info_ptr)
16715 && DEFAULT_ABI == ABI_DARWIN
16716 && ! (cfun->calls_setjmp && flag_exceptions)
16717 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
16718 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
16719 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
16720 && info_ptr->cr_save_p);
16722 /* This will not work in conjunction with sibcalls. Make sure there
16723 are none. (This check is expensive, but seldom executed.) */
16724 if (WORLD_SAVE_P (info_ptr))
16727 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
16728 if ( GET_CODE (insn) == CALL_INSN
16729 && SIBLING_CALL_P (insn))
16731 info_ptr->world_save_p = 0;
16736 if (WORLD_SAVE_P (info_ptr))
16738 /* Even if we're not touching VRsave, make sure there's room on the
16739 stack for it, if it looks like we're calling SAVE_WORLD, which
16740 will attempt to save it. */
16741 info_ptr->vrsave_size = 4;
16743 /* If we are going to save the world, we need to save the link register too. */
16744 info_ptr->lr_save_p = 1;
16746 /* "Save" the VRsave register too if we're saving the world. */
16747 if (info_ptr->vrsave_mask == 0)
16748 info_ptr->vrsave_mask = compute_vrsave_mask ();
16750 /* Because the Darwin register save/restore routines only handle
16751 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
16753 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
16754 && (info_ptr->first_altivec_reg_save
16755 >= FIRST_SAVED_ALTIVEC_REGNO));
16762 is_altivec_return_reg (rtx reg, void *xyes)
16764 bool *yes = (bool *) xyes;
16765 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
16770 /* Calculate the stack information for the current function. This is
16771 complicated by having two separate calling sequences, the AIX calling
16772 sequence and the V.4 calling sequence.
16774 AIX (and Darwin/Mac OS X) stack frames look like:
16776 SP----> +---------------------------------------+
16777 | back chain to caller | 0 0
16778 +---------------------------------------+
16779 | saved CR | 4 8 (8-11)
16780 +---------------------------------------+
16782 +---------------------------------------+
16783 | reserved for compilers | 12 24
16784 +---------------------------------------+
16785 | reserved for binders | 16 32
16786 +---------------------------------------+
16787 | saved TOC pointer | 20 40
16788 +---------------------------------------+
16789 | Parameter save area (P) | 24 48
16790 +---------------------------------------+
16791 | Alloca space (A) | 24+P etc.
16792 +---------------------------------------+
16793 | Local variable space (L) | 24+P+A
16794 +---------------------------------------+
16795 | Float/int conversion temporary (X) | 24+P+A+L
16796 +---------------------------------------+
16797 | Save area for AltiVec registers (W) | 24+P+A+L+X
16798 +---------------------------------------+
16799 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
16800 +---------------------------------------+
16801 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
16802 +---------------------------------------+
16803 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
16804 +---------------------------------------+
16805 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
16806 +---------------------------------------+
16807 old SP->| back chain to caller's caller |
16808 +---------------------------------------+
16810 The required alignment for AIX configurations is two words (i.e., 8
16814 V.4 stack frames look like:
16816 SP----> +---------------------------------------+
16817 | back chain to caller | 0
16818 +---------------------------------------+
16819 | caller's saved LR | 4
16820 +---------------------------------------+
16821 | Parameter save area (P) | 8
16822 +---------------------------------------+
16823 | Alloca space (A) | 8+P
16824 +---------------------------------------+
16825 | Varargs save area (V) | 8+P+A
16826 +---------------------------------------+
16827 | Local variable space (L) | 8+P+A+V
16828 +---------------------------------------+
16829 | Float/int conversion temporary (X) | 8+P+A+V+L
16830 +---------------------------------------+
16831 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
16832 +---------------------------------------+
16833 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
16834 +---------------------------------------+
16835 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
16836 +---------------------------------------+
16837 | SPE: area for 64-bit GP registers |
16838 +---------------------------------------+
16839 | SPE alignment padding |
16840 +---------------------------------------+
16841 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
16842 +---------------------------------------+
16843 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
16844 +---------------------------------------+
16845 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
16846 +---------------------------------------+
16847 old SP->| back chain to caller's caller |
16848 +---------------------------------------+
16850 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
16851 given. (But note below and in sysv4.h that we require only 8 and
16852 may round up the size of our stack frame anyways. The historical
16853 reason is early versions of powerpc-linux which didn't properly
16854 align the stack at program startup. A happy side-effect is that
16855 -mno-eabi libraries can be used with -meabi programs.)
16857 The EABI configuration defaults to the V.4 layout. However,
16858 the stack alignment requirements may differ. If -mno-eabi is not
16859 given, the required stack alignment is 8 bytes; if -mno-eabi is
16860 given, the required alignment is 16 bytes. (But see V.4 comment
16863 #ifndef ABI_STACK_BOUNDARY
16864 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
16867 static rs6000_stack_t *
16868 rs6000_stack_info (void)
16870 static rs6000_stack_t info;
16871 rs6000_stack_t *info_ptr = &info;
16872 int reg_size = TARGET_32BIT ? 4 : 8;
16876 HOST_WIDE_INT non_fixed_size;
16878 memset (&info, 0, sizeof (info));
16882 /* Cache value so we don't rescan instruction chain over and over. */
16883 if (cfun->machine->insn_chain_scanned_p == 0)
16884 cfun->machine->insn_chain_scanned_p
16885 = spe_func_has_64bit_regs_p () + 1;
16886 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
16889 /* Select which calling sequence. */
16890 info_ptr->abi = DEFAULT_ABI;
16892 /* Calculate which registers need to be saved & save area size. */
16893 info_ptr->first_gp_reg_save = first_reg_to_save ();
16894 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
16895 even if it currently looks like we won't. Reload may need it to
16896 get at a constant; if so, it will have already created a constant
16897 pool entry for it. */
16898 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
16899 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
16900 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
16901 && crtl->uses_const_pool
16902 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
16903 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
16905 first_gp = info_ptr->first_gp_reg_save;
16907 info_ptr->gp_size = reg_size * (32 - first_gp);
16909 /* For the SPE, we have an additional upper 32-bits on each GPR.
16910 Ideally we should save the entire 64-bits only when the upper
16911 half is used in SIMD instructions. Since we only record
16912 registers live (not the size they are used in), this proves
16913 difficult because we'd have to traverse the instruction chain at
16914 the right time, taking reload into account. This is a real pain,
16915 so we opt to save the GPRs in 64-bits always if but one register
16916 gets used in 64-bits. Otherwise, all the registers in the frame
16917 get saved in 32-bits.
16919 So... since when we save all GPRs (except the SP) in 64-bits, the
16920 traditional GP save area will be empty. */
16921 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
16922 info_ptr->gp_size = 0;
16924 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
16925 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
16927 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
16928 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
16929 - info_ptr->first_altivec_reg_save);
16931 /* Does this function call anything? */
16932 info_ptr->calls_p = (! current_function_is_leaf
16933 || cfun->machine->ra_needs_full_frame);
16935 /* Determine if we need to save the link register. */
16936 if ((DEFAULT_ABI == ABI_AIX
16938 && !TARGET_PROFILE_KERNEL)
16939 #ifdef TARGET_RELOCATABLE
16940 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
16942 || (info_ptr->first_fp_reg_save != 64
16943 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
16944 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
16945 || info_ptr->calls_p
16946 || rs6000_ra_ever_killed ())
16948 info_ptr->lr_save_p = 1;
16949 df_set_regs_ever_live (LR_REGNO, true);
16952 /* Determine if we need to save the condition code registers. */
16953 if (df_regs_ever_live_p (CR2_REGNO)
16954 || df_regs_ever_live_p (CR3_REGNO)
16955 || df_regs_ever_live_p (CR4_REGNO))
16957 info_ptr->cr_save_p = 1;
16958 if (DEFAULT_ABI == ABI_V4)
16959 info_ptr->cr_size = reg_size;
16962 /* If the current function calls __builtin_eh_return, then we need
16963 to allocate stack space for registers that will hold data for
16964 the exception handler. */
16965 if (crtl->calls_eh_return)
16968 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
16971 /* SPE saves EH registers in 64-bits. */
16972 ehrd_size = i * (TARGET_SPE_ABI
16973 && info_ptr->spe_64bit_regs_used != 0
16974 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
16979 /* Determine various sizes. */
16980 info_ptr->reg_size = reg_size;
16981 info_ptr->fixed_size = RS6000_SAVE_AREA;
16982 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
16983 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
16984 TARGET_ALTIVEC ? 16 : 8);
16985 if (FRAME_GROWS_DOWNWARD)
16986 info_ptr->vars_size
16987 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
16988 + info_ptr->parm_size,
16989 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
16990 - (info_ptr->fixed_size + info_ptr->vars_size
16991 + info_ptr->parm_size);
16993 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
16994 info_ptr->spe_gp_size = 8 * (32 - first_gp);
16996 info_ptr->spe_gp_size = 0;
16998 if (TARGET_ALTIVEC_ABI)
16999 info_ptr->vrsave_mask = compute_vrsave_mask ();
17001 info_ptr->vrsave_mask = 0;
17003 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17004 info_ptr->vrsave_size = 4;
17006 info_ptr->vrsave_size = 0;
17008 compute_save_world_info (info_ptr);
17010 /* Calculate the offsets. */
17011 switch (DEFAULT_ABI)
17015 gcc_unreachable ();
17019 info_ptr->fp_save_offset = - info_ptr->fp_size;
17020 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17022 if (TARGET_ALTIVEC_ABI)
17024 info_ptr->vrsave_save_offset
17025 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17027 /* Align stack so vector save area is on a quadword boundary.
17028 The padding goes above the vectors. */
17029 if (info_ptr->altivec_size != 0)
17030 info_ptr->altivec_padding_size
17031 = info_ptr->vrsave_save_offset & 0xF;
17033 info_ptr->altivec_padding_size = 0;
17035 info_ptr->altivec_save_offset
17036 = info_ptr->vrsave_save_offset
17037 - info_ptr->altivec_padding_size
17038 - info_ptr->altivec_size;
17039 gcc_assert (info_ptr->altivec_size == 0
17040 || info_ptr->altivec_save_offset % 16 == 0);
17042 /* Adjust for AltiVec case. */
17043 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17046 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17047 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17048 info_ptr->lr_save_offset = 2*reg_size;
17052 info_ptr->fp_save_offset = - info_ptr->fp_size;
17053 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17054 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17056 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17058 /* Align stack so SPE GPR save area is aligned on a
17059 double-word boundary. */
17060 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17061 info_ptr->spe_padding_size
17062 = 8 - (-info_ptr->cr_save_offset % 8);
17064 info_ptr->spe_padding_size = 0;
17066 info_ptr->spe_gp_save_offset
17067 = info_ptr->cr_save_offset
17068 - info_ptr->spe_padding_size
17069 - info_ptr->spe_gp_size;
17071 /* Adjust for SPE case. */
17072 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17074 else if (TARGET_ALTIVEC_ABI)
17076 info_ptr->vrsave_save_offset
17077 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17079 /* Align stack so vector save area is on a quadword boundary. */
17080 if (info_ptr->altivec_size != 0)
17081 info_ptr->altivec_padding_size
17082 = 16 - (-info_ptr->vrsave_save_offset % 16);
17084 info_ptr->altivec_padding_size = 0;
17086 info_ptr->altivec_save_offset
17087 = info_ptr->vrsave_save_offset
17088 - info_ptr->altivec_padding_size
17089 - info_ptr->altivec_size;
17091 /* Adjust for AltiVec case. */
17092 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17095 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17096 info_ptr->ehrd_offset -= ehrd_size;
17097 info_ptr->lr_save_offset = reg_size;
17101 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17102 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17103 + info_ptr->gp_size
17104 + info_ptr->altivec_size
17105 + info_ptr->altivec_padding_size
17106 + info_ptr->spe_gp_size
17107 + info_ptr->spe_padding_size
17109 + info_ptr->cr_size
17110 + info_ptr->vrsave_size,
17113 non_fixed_size = (info_ptr->vars_size
17114 + info_ptr->parm_size
17115 + info_ptr->save_size);
17117 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17118 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17120 /* Determine if we need to allocate any stack frame:
17122 For AIX we need to push the stack if a frame pointer is needed
17123 (because the stack might be dynamically adjusted), if we are
17124 debugging, if we make calls, or if the sum of fp_save, gp_save,
17125 and local variables are more than the space needed to save all
17126 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17127 + 18*8 = 288 (GPR13 reserved).
17129 For V.4 we don't have the stack cushion that AIX uses, but assume
17130 that the debugger can handle stackless frames. */
17132 if (info_ptr->calls_p)
17133 info_ptr->push_p = 1;
17135 else if (DEFAULT_ABI == ABI_V4)
17136 info_ptr->push_p = non_fixed_size != 0;
17138 else if (frame_pointer_needed)
17139 info_ptr->push_p = 1;
17141 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17142 info_ptr->push_p = 1;
17145 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17147 /* Zero offsets if we're not saving those registers. */
17148 if (info_ptr->fp_size == 0)
17149 info_ptr->fp_save_offset = 0;
17151 if (info_ptr->gp_size == 0)
17152 info_ptr->gp_save_offset = 0;
17154 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17155 info_ptr->altivec_save_offset = 0;
17157 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17158 info_ptr->vrsave_save_offset = 0;
17160 if (! TARGET_SPE_ABI
17161 || info_ptr->spe_64bit_regs_used == 0
17162 || info_ptr->spe_gp_size == 0)
17163 info_ptr->spe_gp_save_offset = 0;
17165 if (! info_ptr->lr_save_p)
17166 info_ptr->lr_save_offset = 0;
17168 if (! info_ptr->cr_save_p)
17169 info_ptr->cr_save_offset = 0;
17174 /* Return true if the current function uses any GPRs in 64-bit SIMD
17178 spe_func_has_64bit_regs_p (void)
17182 /* Functions that save and restore all the call-saved registers will
17183 need to save/restore the registers in 64-bits. */
17184 if (crtl->calls_eh_return
17185 || cfun->calls_setjmp
17186 || crtl->has_nonlocal_goto)
17189 insns = get_insns ();
17191 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17197 /* FIXME: This should be implemented with attributes...
17199 (set_attr "spe64" "true")....then,
17200 if (get_spe64(insn)) return true;
17202 It's the only reliable way to do the stuff below. */
17204 i = PATTERN (insn);
17205 if (GET_CODE (i) == SET)
17207 enum machine_mode mode = GET_MODE (SET_SRC (i));
17209 if (SPE_VECTOR_MODE (mode))
17211 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17221 debug_stack_info (rs6000_stack_t *info)
17223 const char *abi_string;
17226 info = rs6000_stack_info ();
17228 fprintf (stderr, "\nStack information for function %s:\n",
17229 ((current_function_decl && DECL_NAME (current_function_decl))
17230 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17235 default: abi_string = "Unknown"; break;
17236 case ABI_NONE: abi_string = "NONE"; break;
17237 case ABI_AIX: abi_string = "AIX"; break;
17238 case ABI_DARWIN: abi_string = "Darwin"; break;
17239 case ABI_V4: abi_string = "V.4"; break;
17242 fprintf (stderr, "\tABI = %5s\n", abi_string);
17244 if (TARGET_ALTIVEC_ABI)
17245 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17247 if (TARGET_SPE_ABI)
17248 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17250 if (info->first_gp_reg_save != 32)
17251 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17253 if (info->first_fp_reg_save != 64)
17254 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17256 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17257 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17258 info->first_altivec_reg_save);
17260 if (info->lr_save_p)
17261 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17263 if (info->cr_save_p)
17264 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17266 if (info->vrsave_mask)
17267 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17270 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17273 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17275 if (info->gp_save_offset)
17276 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17278 if (info->fp_save_offset)
17279 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17281 if (info->altivec_save_offset)
17282 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17283 info->altivec_save_offset);
17285 if (info->spe_gp_save_offset)
17286 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17287 info->spe_gp_save_offset);
17289 if (info->vrsave_save_offset)
17290 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17291 info->vrsave_save_offset);
17293 if (info->lr_save_offset)
17294 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
17296 if (info->cr_save_offset)
17297 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
17299 if (info->varargs_save_offset)
17300 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
17302 if (info->total_size)
17303 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17306 if (info->vars_size)
17307 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17310 if (info->parm_size)
17311 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
17313 if (info->fixed_size)
17314 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
17317 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
17319 if (info->spe_gp_size)
17320 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
17323 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
17325 if (info->altivec_size)
17326 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
17328 if (info->vrsave_size)
17329 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
17331 if (info->altivec_padding_size)
17332 fprintf (stderr, "\taltivec_padding_size= %5d\n",
17333 info->altivec_padding_size);
17335 if (info->spe_padding_size)
17336 fprintf (stderr, "\tspe_padding_size = %5d\n",
17337 info->spe_padding_size);
17340 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
17342 if (info->save_size)
17343 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
17345 if (info->reg_size != 4)
17346 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
17348 fprintf (stderr, "\n");
17352 rs6000_return_addr (int count, rtx frame)
17354 /* Currently we don't optimize very well between prolog and body
17355 code and for PIC code the code can be actually quite bad, so
17356 don't try to be too clever here. */
17357 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
17359 cfun->machine->ra_needs_full_frame = 1;
17366 plus_constant (copy_to_reg
17367 (gen_rtx_MEM (Pmode,
17368 memory_address (Pmode, frame))),
17369 RETURN_ADDRESS_OFFSET)));
17372 cfun->machine->ra_need_lr = 1;
17373 return get_hard_reg_initial_val (Pmode, LR_REGNO);
17376 /* Say whether a function is a candidate for sibcall handling or not.
17377 We do not allow indirect calls to be optimized into sibling calls.
17378 Also, we can't do it if there are any vector parameters; there's
17379 nowhere to put the VRsave code so it works; note that functions with
17380 vector parameters are required to have a prototype, so the argument
17381 type info must be available here. (The tail recursion case can work
17382 with vector parameters, but there's no way to distinguish here.) */
17384 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
17389 if (TARGET_ALTIVEC_VRSAVE)
17391 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
17392 type; type = TREE_CHAIN (type))
17394 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
17398 if (DEFAULT_ABI == ABI_DARWIN
17399 || ((*targetm.binds_local_p) (decl)
17400 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
17402 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
17404 if (!lookup_attribute ("longcall", attr_list)
17405 || lookup_attribute ("shortcall", attr_list))
17412 /* NULL if INSN insn is valid within a low-overhead loop.
17413 Otherwise return why doloop cannot be applied.
17414 PowerPC uses the COUNT register for branch on table instructions. */
17416 static const char *
17417 rs6000_invalid_within_doloop (const_rtx insn)
17420 return "Function call in the loop.";
17423 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
17424 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
17425 return "Computed branch in the loop.";
17431 rs6000_ra_ever_killed (void)
17437 if (cfun->is_thunk)
17440 /* regs_ever_live has LR marked as used if any sibcalls are present,
17441 but this should not force saving and restoring in the
17442 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
17443 clobbers LR, so that is inappropriate. */
17445 /* Also, the prologue can generate a store into LR that
17446 doesn't really count, like this:
17449 bcl to set PIC register
17453 When we're called from the epilogue, we need to avoid counting
17454 this as a store. */
17456 push_topmost_sequence ();
17457 top = get_insns ();
17458 pop_topmost_sequence ();
17459 reg = gen_rtx_REG (Pmode, LR_REGNO);
17461 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
17467 if (!SIBLING_CALL_P (insn))
17470 else if (find_regno_note (insn, REG_INC, LR_REGNO))
17472 else if (set_of (reg, insn) != NULL_RTX
17473 && !prologue_epilogue_contains (insn))
17480 /* Emit instructions needed to load the TOC register.
17481 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
17482 a constant pool; or for SVR4 -fpic. */
17485 rs6000_emit_load_toc_table (int fromprolog)
17488 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
17490 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
17493 rtx lab, tmp1, tmp2, got;
17495 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17496 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17498 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17500 got = rs6000_got_sym ();
17501 tmp1 = tmp2 = dest;
17504 tmp1 = gen_reg_rtx (Pmode);
17505 tmp2 = gen_reg_rtx (Pmode);
17507 emit_insn (gen_load_toc_v4_PIC_1 (lab));
17508 emit_move_insn (tmp1,
17509 gen_rtx_REG (Pmode, LR_REGNO));
17510 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
17511 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
17513 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
17515 emit_insn (gen_load_toc_v4_pic_si ());
17516 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
17518 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
17521 rtx temp0 = (fromprolog
17522 ? gen_rtx_REG (Pmode, 0)
17523 : gen_reg_rtx (Pmode));
17529 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17530 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17532 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
17533 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17535 emit_insn (gen_load_toc_v4_PIC_1 (symF));
17536 emit_move_insn (dest,
17537 gen_rtx_REG (Pmode, LR_REGNO));
17538 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
17544 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17545 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
17546 emit_move_insn (dest,
17547 gen_rtx_REG (Pmode, LR_REGNO));
17548 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
17550 emit_insn (gen_addsi3 (dest, temp0, dest));
17552 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
17554 /* This is for AIX code running in non-PIC ELF32. */
17557 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
17558 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17560 emit_insn (gen_elf_high (dest, realsym));
17561 emit_insn (gen_elf_low (dest, dest, realsym));
17565 gcc_assert (DEFAULT_ABI == ABI_AIX);
17568 emit_insn (gen_load_toc_aix_si (dest));
17570 emit_insn (gen_load_toc_aix_di (dest));
17574 /* Emit instructions to restore the link register after determining where
17575 its value has been stored. */
17578 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
17580 rs6000_stack_t *info = rs6000_stack_info ();
17583 operands[0] = source;
17584 operands[1] = scratch;
17586 if (info->lr_save_p)
17588 rtx frame_rtx = stack_pointer_rtx;
17589 HOST_WIDE_INT sp_offset = 0;
17592 if (frame_pointer_needed
17593 || cfun->calls_alloca
17594 || info->total_size > 32767)
17596 tmp = gen_frame_mem (Pmode, frame_rtx);
17597 emit_move_insn (operands[1], tmp);
17598 frame_rtx = operands[1];
17600 else if (info->push_p)
17601 sp_offset = info->total_size;
17603 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
17604 tmp = gen_frame_mem (Pmode, tmp);
17605 emit_move_insn (tmp, operands[0]);
17608 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
17611 static GTY(()) alias_set_type set = -1;
17614 get_TOC_alias_set (void)
17617 set = new_alias_set ();
17621 /* This returns nonzero if the current function uses the TOC. This is
17622 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
17623 is generated by the ABI_V4 load_toc_* patterns. */
17630 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
17633 rtx pat = PATTERN (insn);
17636 if (GET_CODE (pat) == PARALLEL)
17637 for (i = 0; i < XVECLEN (pat, 0); i++)
17639 rtx sub = XVECEXP (pat, 0, i);
17640 if (GET_CODE (sub) == USE)
17642 sub = XEXP (sub, 0);
17643 if (GET_CODE (sub) == UNSPEC
17644 && XINT (sub, 1) == UNSPEC_TOC)
17654 create_TOC_reference (rtx symbol)
17656 if (TARGET_DEBUG_ADDR)
17658 if (GET_CODE (symbol) == SYMBOL_REF)
17659 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
17663 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
17664 GET_RTX_NAME (GET_CODE (symbol)));
17665 debug_rtx (symbol);
17669 if (!can_create_pseudo_p ())
17670 df_set_regs_ever_live (TOC_REGISTER, true);
17671 return gen_rtx_PLUS (Pmode,
17672 gen_rtx_REG (Pmode, TOC_REGISTER),
17673 gen_rtx_CONST (Pmode,
17674 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL)));
17677 /* Issue assembly directives that create a reference to the given DWARF
17678 FRAME_TABLE_LABEL from the current function section. */
17680 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
17682 fprintf (asm_out_file, "\t.ref %s\n",
17683 TARGET_STRIP_NAME_ENCODING (frame_table_label));
17686 /* If _Unwind_* has been called from within the same module,
17687 toc register is not guaranteed to be saved to 40(1) on function
17688 entry. Save it there in that case. */
17691 rs6000_aix_emit_builtin_unwind_init (void)
17694 rtx stack_top = gen_reg_rtx (Pmode);
17695 rtx opcode_addr = gen_reg_rtx (Pmode);
17696 rtx opcode = gen_reg_rtx (SImode);
17697 rtx tocompare = gen_reg_rtx (SImode);
17698 rtx no_toc_save_needed = gen_label_rtx ();
17700 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
17701 emit_move_insn (stack_top, mem);
17703 mem = gen_frame_mem (Pmode,
17704 gen_rtx_PLUS (Pmode, stack_top,
17705 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
17706 emit_move_insn (opcode_addr, mem);
17707 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
17708 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
17709 : 0xE8410028, SImode));
17711 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
17712 SImode, NULL_RTX, NULL_RTX,
17713 no_toc_save_needed);
17715 mem = gen_frame_mem (Pmode,
17716 gen_rtx_PLUS (Pmode, stack_top,
17717 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
17718 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
17719 emit_label (no_toc_save_needed);
17722 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
17723 and the change to the stack pointer. */
17726 rs6000_emit_stack_tie (void)
17728 rtx mem = gen_frame_mem (BLKmode,
17729 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
17731 emit_insn (gen_stack_tie (mem));
17734 /* Emit the correct code for allocating stack space, as insns.
17735 If COPY_R12, make sure a copy of the old frame is left in r12.
17736 If COPY_R11, make sure a copy of the old frame is left in r11,
17737 in preference to r12 if COPY_R12.
17738 The generated code may use hard register 0 as a temporary. */
17741 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
17744 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
17745 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
17746 rtx todec = gen_int_mode (-size, Pmode);
17749 if (INTVAL (todec) != -size)
17751 warning (0, "stack frame too large");
17752 emit_insn (gen_trap ());
17756 if (crtl->limit_stack)
17758 if (REG_P (stack_limit_rtx)
17759 && REGNO (stack_limit_rtx) > 1
17760 && REGNO (stack_limit_rtx) <= 31)
17762 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
17763 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
17766 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
17768 && DEFAULT_ABI == ABI_V4)
17770 rtx toload = gen_rtx_CONST (VOIDmode,
17771 gen_rtx_PLUS (Pmode,
17775 emit_insn (gen_elf_high (tmp_reg, toload));
17776 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
17777 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
17781 warning (0, "stack limit expression is not supported");
17784 if (copy_r12 || copy_r11)
17785 emit_move_insn (copy_r11
17786 ? gen_rtx_REG (Pmode, 11)
17787 : gen_rtx_REG (Pmode, 12),
17792 /* Need a note here so that try_split doesn't get confused. */
17793 if (get_last_insn () == NULL_RTX)
17794 emit_note (NOTE_INSN_DELETED);
17795 insn = emit_move_insn (tmp_reg, todec);
17796 try_split (PATTERN (insn), insn, 0);
17800 insn = emit_insn (TARGET_32BIT
17801 ? gen_movsi_update_stack (stack_reg, stack_reg,
17803 : gen_movdi_di_update_stack (stack_reg, stack_reg,
17804 todec, stack_reg));
17805 /* Since we didn't use gen_frame_mem to generate the MEM, grab
17806 it now and set the alias set/attributes. The above gen_*_update
17807 calls will generate a PARALLEL with the MEM set being the first
17809 par = PATTERN (insn);
17810 gcc_assert (GET_CODE (par) == PARALLEL);
17811 set = XVECEXP (par, 0, 0);
17812 gcc_assert (GET_CODE (set) == SET);
17813 mem = SET_DEST (set);
17814 gcc_assert (MEM_P (mem));
17815 MEM_NOTRAP_P (mem) = 1;
17816 set_mem_alias_set (mem, get_frame_alias_set ());
17818 RTX_FRAME_RELATED_P (insn) = 1;
17819 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
17820 gen_rtx_SET (VOIDmode, stack_reg,
17821 gen_rtx_PLUS (Pmode, stack_reg,
17822 GEN_INT (-size))));
17825 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
17826 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
17827 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
17828 deduce these equivalences by itself so it wasn't necessary to hold
17829 its hand so much. */
17832 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
17833 rtx reg2, rtx rreg)
17837 /* copy_rtx will not make unique copies of registers, so we need to
17838 ensure we don't have unwanted sharing here. */
17840 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
17843 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
17845 real = copy_rtx (PATTERN (insn));
17847 if (reg2 != NULL_RTX)
17848 real = replace_rtx (real, reg2, rreg);
17850 real = replace_rtx (real, reg,
17851 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
17852 STACK_POINTER_REGNUM),
17855 /* We expect that 'real' is either a SET or a PARALLEL containing
17856 SETs (and possibly other stuff). In a PARALLEL, all the SETs
17857 are important so they all have to be marked RTX_FRAME_RELATED_P. */
17859 if (GET_CODE (real) == SET)
17863 temp = simplify_rtx (SET_SRC (set));
17865 SET_SRC (set) = temp;
17866 temp = simplify_rtx (SET_DEST (set));
17868 SET_DEST (set) = temp;
17869 if (GET_CODE (SET_DEST (set)) == MEM)
17871 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
17873 XEXP (SET_DEST (set), 0) = temp;
17880 gcc_assert (GET_CODE (real) == PARALLEL);
17881 for (i = 0; i < XVECLEN (real, 0); i++)
17882 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
17884 rtx set = XVECEXP (real, 0, i);
17886 temp = simplify_rtx (SET_SRC (set));
17888 SET_SRC (set) = temp;
17889 temp = simplify_rtx (SET_DEST (set));
17891 SET_DEST (set) = temp;
17892 if (GET_CODE (SET_DEST (set)) == MEM)
17894 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
17896 XEXP (SET_DEST (set), 0) = temp;
17898 RTX_FRAME_RELATED_P (set) = 1;
17902 RTX_FRAME_RELATED_P (insn) = 1;
17903 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
17906 /* Returns an insn that has a vrsave set operation with the
17907 appropriate CLOBBERs. */
17910 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
17913 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
17914 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
17917 = gen_rtx_SET (VOIDmode,
17919 gen_rtx_UNSPEC_VOLATILE (SImode,
17920 gen_rtvec (2, reg, vrsave),
17921 UNSPECV_SET_VRSAVE));
17925 /* We need to clobber the registers in the mask so the scheduler
17926 does not move sets to VRSAVE before sets of AltiVec registers.
17928 However, if the function receives nonlocal gotos, reload will set
17929 all call saved registers live. We will end up with:
17931 (set (reg 999) (mem))
17932 (parallel [ (set (reg vrsave) (unspec blah))
17933 (clobber (reg 999))])
17935 The clobber will cause the store into reg 999 to be dead, and
17936 flow will attempt to delete an epilogue insn. In this case, we
17937 need an unspec use/set of the register. */
17939 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17940 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
17942 if (!epiloguep || call_used_regs [i])
17943 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
17944 gen_rtx_REG (V4SImode, i));
17947 rtx reg = gen_rtx_REG (V4SImode, i);
17950 = gen_rtx_SET (VOIDmode,
17952 gen_rtx_UNSPEC (V4SImode,
17953 gen_rtvec (1, reg), 27));
17957 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
17959 for (i = 0; i < nclobs; ++i)
17960 XVECEXP (insn, 0, i) = clobs[i];
17965 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
17966 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
17969 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
17970 unsigned int regno, int offset, HOST_WIDE_INT total_size)
17972 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
17973 rtx replacea, replaceb;
17975 int_rtx = GEN_INT (offset);
17977 /* Some cases that need register indexed addressing. */
17978 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
17979 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
17980 || (TARGET_E500_DOUBLE && mode == DFmode)
17982 && SPE_VECTOR_MODE (mode)
17983 && !SPE_CONST_OFFSET_OK (offset)))
17985 /* Whomever calls us must make sure r11 is available in the
17986 flow path of instructions in the prologue. */
17987 offset_rtx = gen_rtx_REG (Pmode, 11);
17988 emit_move_insn (offset_rtx, int_rtx);
17990 replacea = offset_rtx;
17991 replaceb = int_rtx;
17995 offset_rtx = int_rtx;
17996 replacea = NULL_RTX;
17997 replaceb = NULL_RTX;
18000 reg = gen_rtx_REG (mode, regno);
18001 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18002 mem = gen_frame_mem (mode, addr);
18004 insn = emit_move_insn (mem, reg);
18006 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18009 /* Emit an offset memory reference suitable for a frame store, while
18010 converting to a valid addressing mode. */
18013 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18015 rtx int_rtx, offset_rtx;
18017 int_rtx = GEN_INT (offset);
18019 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18020 || (TARGET_E500_DOUBLE && mode == DFmode))
18022 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18023 emit_move_insn (offset_rtx, int_rtx);
18026 offset_rtx = int_rtx;
18028 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18031 /* Look for user-defined global regs. We should not save and restore these,
18032 and cannot use stmw/lmw if there are any in its range. */
18035 no_global_regs_above (int first, bool gpr)
18038 int last = gpr ? 32 : 64;
18039 for (i = first; i < last; i++)
18040 if (global_regs[i])
18045 #ifndef TARGET_FIX_AND_CONTINUE
18046 #define TARGET_FIX_AND_CONTINUE 0
18049 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18050 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18051 #define LAST_SAVRES_REGISTER 31
18052 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18054 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18056 /* Temporary holding space for an out-of-line register save/restore
18058 static char savres_routine_name[30];
18060 /* Return the name for an out-of-line register save/restore routine.
18061 We are saving/restoring GPRs if GPR is true. */
18064 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18065 bool savep, bool gpr, bool lr)
18067 const char *prefix = "";
18068 const char *suffix = "";
18070 /* Different targets are supposed to define
18071 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18072 routine name could be defined with:
18074 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18076 This is a nice idea in practice, but in reality, things are
18077 complicated in several ways:
18079 - ELF targets have save/restore routines for GPRs.
18081 - SPE targets use different prefixes for 32/64-bit registers, and
18082 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18084 - PPC64 ELF targets have routines for save/restore of GPRs that
18085 differ in what they do with the link register, so having a set
18086 prefix doesn't work. (We only use one of the save routines at
18087 the moment, though.)
18089 - PPC32 elf targets have "exit" versions of the restore routines
18090 that restore the link register and can save some extra space.
18091 These require an extra suffix. (There are also "tail" versions
18092 of the restore routines and "GOT" versions of the save routines,
18093 but we don't generate those at present. Same problems apply,
18096 We deal with all this by synthesizing our own prefix/suffix and
18097 using that for the simple sprintf call shown above. */
18100 /* No floating point saves on the SPE. */
18104 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
18106 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
18111 else if (DEFAULT_ABI == ABI_V4)
18117 prefix = savep ? "_savegpr_" : "_restgpr_";
18119 prefix = savep ? "_savefpr_" : "_restfpr_";
18124 else if (DEFAULT_ABI == ABI_AIX)
18126 #ifndef POWERPC_LINUX
18127 /* No out-of-line save/restore routines for GPRs on AIX. */
18128 gcc_assert (!TARGET_AIX || !gpr);
18134 ? (lr ? "_savegpr0_" : "_savegpr1_")
18135 : (lr ? "_restgpr0_" : "_restgpr1_"));
18136 #ifdef POWERPC_LINUX
18138 prefix = (savep ? "_savefpr_" : "_restfpr_");
18142 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
18143 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
18146 else if (DEFAULT_ABI == ABI_DARWIN)
18147 sorry ("Out-of-line save/restore routines not supported on Darwin");
18149 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
18151 return savres_routine_name;
18154 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18155 We are saving/restoring GPRs if GPR is true. */
18158 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
18161 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18163 int select = ((savep ? 1 : 0) << 2
18165 /* On the SPE, we never have any FPRs, but we do have
18166 32/64-bit versions of the routines. */
18167 ? (info->spe_64bit_regs_used ? 1 : 0)
18168 : (gpr ? 1 : 0)) << 1)
18171 /* Don't generate bogus routine names. */
18172 gcc_assert (FIRST_SAVRES_REGISTER <= regno
18173 && regno <= LAST_SAVRES_REGISTER);
18175 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18181 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
18183 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18184 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18185 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
18191 /* Emit a sequence of insns, including a stack tie if needed, for
18192 resetting the stack pointer. If SAVRES is true, then don't reset the
18193 stack pointer, but move the base of the frame into r11 for use by
18194 out-of-line register restore routines. */
18197 rs6000_emit_stack_reset (rs6000_stack_t *info,
18198 rtx sp_reg_rtx, rtx frame_reg_rtx,
18199 int sp_offset, bool savres)
18201 /* This blockage is needed so that sched doesn't decide to move
18202 the sp change before the register restores. */
18203 if (frame_reg_rtx != sp_reg_rtx
18205 && info->spe_64bit_regs_used != 0
18206 && info->first_gp_reg_save != 32))
18207 rs6000_emit_stack_tie ();
18209 if (frame_reg_rtx != sp_reg_rtx)
18211 if (sp_offset != 0)
18213 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
18214 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
18215 GEN_INT (sp_offset)));
18218 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18220 else if (sp_offset != 0)
18222 /* If we are restoring registers out-of-line, we will be using the
18223 "exit" variants of the restore routines, which will reset the
18224 stack for us. But we do need to point r11 into the right place
18225 for those routines. */
18226 rtx dest_reg = (savres
18227 ? gen_rtx_REG (Pmode, 11)
18230 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18231 GEN_INT (sp_offset)));
18238 /* Construct a parallel rtx describing the effect of a call to an
18239 out-of-line register save/restore routine. */
18242 rs6000_make_savres_rtx (rs6000_stack_t *info,
18243 rtx frame_reg_rtx, int save_area_offset,
18244 enum machine_mode reg_mode,
18245 bool savep, bool gpr, bool lr)
18248 int offset, start_reg, end_reg, n_regs;
18249 int reg_size = GET_MODE_SIZE (reg_mode);
18255 ? info->first_gp_reg_save
18256 : info->first_fp_reg_save);
18257 end_reg = gpr ? 32 : 64;
18258 n_regs = end_reg - start_reg;
18259 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
18262 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18264 RTVEC_ELT (p, offset++)
18265 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18267 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
18268 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18269 RTVEC_ELT (p, offset++)
18270 = gen_rtx_USE (VOIDmode,
18271 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
18275 for (i = 0; i < end_reg - start_reg; i++)
18277 rtx addr, reg, mem;
18278 reg = gen_rtx_REG (reg_mode, start_reg + i);
18279 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18280 GEN_INT (save_area_offset + reg_size*i));
18281 mem = gen_frame_mem (reg_mode, addr);
18283 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
18285 savep ? reg : mem);
18290 rtx addr, reg, mem;
18291 reg = gen_rtx_REG (Pmode, 0);
18292 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18293 GEN_INT (info->lr_save_offset));
18294 mem = gen_frame_mem (Pmode, addr);
18295 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
18298 return gen_rtx_PARALLEL (VOIDmode, p);
18301 /* Determine whether the gp REG is really used. */
18304 rs6000_reg_live_or_pic_offset_p (int reg)
18306 return ((df_regs_ever_live_p (reg)
18307 && (!call_used_regs[reg]
18308 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18309 && TARGET_TOC && TARGET_MINIMAL_TOC)))
18310 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18311 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18312 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
18316 SAVRES_MULTIPLE = 0x1,
18317 SAVRES_INLINE_FPRS = 0x2,
18318 SAVRES_INLINE_GPRS = 0x4,
18319 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
18320 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
18321 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
18324 /* Determine the strategy for savings/restoring registers. */
18327 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
18328 int using_static_chain_p, int sibcall)
18330 bool using_multiple_p;
18332 bool savres_fprs_inline;
18333 bool savres_gprs_inline;
18334 bool noclobber_global_gprs
18335 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
18338 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
18339 && (!TARGET_SPE_ABI
18340 || info->spe_64bit_regs_used == 0)
18341 && info->first_gp_reg_save < 31
18342 && noclobber_global_gprs);
18343 /* Don't bother to try to save things out-of-line if r11 is occupied
18344 by the static chain. It would require too much fiddling and the
18345 static chain is rarely used anyway. */
18346 common = (using_static_chain_p
18348 || crtl->calls_eh_return
18349 || !info->lr_save_p
18350 || cfun->machine->ra_need_lr
18351 || info->total_size > 32767);
18352 savres_fprs_inline = (common
18353 || info->first_fp_reg_save == 64
18354 || !no_global_regs_above (info->first_fp_reg_save,
18356 /* The out-of-line FP routines use
18357 double-precision stores; we can't use those
18358 routines if we don't have such stores. */
18359 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18360 || FP_SAVE_INLINE (info->first_fp_reg_save));
18361 savres_gprs_inline = (common
18362 /* Saving CR interferes with the exit routines
18363 used on the SPE, so just punt here. */
18366 && info->spe_64bit_regs_used != 0
18367 && info->cr_save_p != 0)
18368 || info->first_gp_reg_save == 32
18369 || !noclobber_global_gprs
18370 || GP_SAVE_INLINE (info->first_gp_reg_save));
18373 /* If we are going to use store multiple, then don't even bother
18374 with the out-of-line routines, since the store-multiple instruction
18375 will always be smaller. */
18376 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18379 /* The situation is more complicated with load multiple. We'd
18380 prefer to use the out-of-line routines for restores, since the
18381 "exit" out-of-line routines can handle the restore of LR and
18382 the frame teardown. But we can only use the out-of-line
18383 routines if we know that we've used store multiple or
18384 out-of-line routines in the prologue, i.e. if we've saved all
18385 the registers from first_gp_reg_save. Otherwise, we risk
18386 loading garbage from the stack. Furthermore, we can only use
18387 the "exit" out-of-line gpr restore if we haven't saved any
18389 bool saved_all = !savres_gprs_inline || using_multiple_p;
18391 if (saved_all && info->first_fp_reg_save != 64)
18392 /* We can't use the exit routine; use load multiple if it's
18394 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18397 strategy = (using_multiple_p
18398 | (savres_fprs_inline << 1)
18399 | (savres_gprs_inline << 2));
18400 #ifdef POWERPC_LINUX
18403 if (!savres_fprs_inline)
18404 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
18405 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
18406 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
18409 if (TARGET_AIX && !savres_fprs_inline)
18410 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18415 /* Emit function prologue as insns. */
18418 rs6000_emit_prologue (void)
18420 rs6000_stack_t *info = rs6000_stack_info ();
18421 enum machine_mode reg_mode = Pmode;
18422 int reg_size = TARGET_32BIT ? 4 : 8;
18423 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18424 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
18425 rtx frame_reg_rtx = sp_reg_rtx;
18426 rtx cr_save_rtx = NULL_RTX;
18429 int saving_FPRs_inline;
18430 int saving_GPRs_inline;
18431 int using_store_multiple;
18432 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18433 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18434 && call_used_regs[STATIC_CHAIN_REGNUM]);
18435 HOST_WIDE_INT sp_offset = 0;
18437 if (TARGET_FIX_AND_CONTINUE)
18439 /* gdb on darwin arranges to forward a function from the old
18440 address by modifying the first 5 instructions of the function
18441 to branch to the overriding function. This is necessary to
18442 permit function pointers that point to the old function to
18443 actually forward to the new function. */
18444 emit_insn (gen_nop ());
18445 emit_insn (gen_nop ());
18446 emit_insn (gen_nop ());
18447 emit_insn (gen_nop ());
18448 emit_insn (gen_nop ());
18451 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
18453 reg_mode = V2SImode;
18457 strategy = rs6000_savres_strategy (info, /*savep=*/true,
18458 /*static_chain_p=*/using_static_chain_p,
18460 using_store_multiple = strategy & SAVRES_MULTIPLE;
18461 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
18462 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
18464 /* For V.4, update stack before we do any saving and set back pointer. */
18465 if (! WORLD_SAVE_P (info)
18467 && (DEFAULT_ABI == ABI_V4
18468 || crtl->calls_eh_return))
18470 bool need_r11 = (TARGET_SPE
18471 ? (!saving_GPRs_inline
18472 && info->spe_64bit_regs_used == 0)
18473 : (!saving_FPRs_inline || !saving_GPRs_inline));
18474 if (info->total_size < 32767)
18475 sp_offset = info->total_size;
18477 frame_reg_rtx = (need_r11
18478 ? gen_rtx_REG (Pmode, 11)
18480 rs6000_emit_allocate_stack (info->total_size,
18481 (frame_reg_rtx != sp_reg_rtx
18482 && (info->cr_save_p
18484 || info->first_fp_reg_save < 64
18485 || info->first_gp_reg_save < 32
18488 if (frame_reg_rtx != sp_reg_rtx)
18489 rs6000_emit_stack_tie ();
18492 /* Handle world saves specially here. */
18493 if (WORLD_SAVE_P (info))
18500 /* save_world expects lr in r0. */
18501 reg0 = gen_rtx_REG (Pmode, 0);
18502 if (info->lr_save_p)
18504 insn = emit_move_insn (reg0,
18505 gen_rtx_REG (Pmode, LR_REGNO));
18506 RTX_FRAME_RELATED_P (insn) = 1;
18509 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
18510 assumptions about the offsets of various bits of the stack
18512 gcc_assert (info->gp_save_offset == -220
18513 && info->fp_save_offset == -144
18514 && info->lr_save_offset == 8
18515 && info->cr_save_offset == 4
18518 && (!crtl->calls_eh_return
18519 || info->ehrd_offset == -432)
18520 && info->vrsave_save_offset == -224
18521 && info->altivec_save_offset == -416);
18523 treg = gen_rtx_REG (SImode, 11);
18524 emit_move_insn (treg, GEN_INT (-info->total_size));
18526 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
18527 in R11. It also clobbers R12, so beware! */
18529 /* Preserve CR2 for save_world prologues */
18531 sz += 32 - info->first_gp_reg_save;
18532 sz += 64 - info->first_fp_reg_save;
18533 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
18534 p = rtvec_alloc (sz);
18536 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
18537 gen_rtx_REG (SImode,
18539 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
18540 gen_rtx_SYMBOL_REF (Pmode,
18542 /* We do floats first so that the instruction pattern matches
18544 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18546 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18547 ? DFmode : SFmode),
18548 info->first_fp_reg_save + i);
18549 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18550 GEN_INT (info->fp_save_offset
18551 + sp_offset + 8 * i));
18552 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18553 ? DFmode : SFmode), addr);
18555 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18557 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
18559 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
18560 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18561 GEN_INT (info->altivec_save_offset
18562 + sp_offset + 16 * i));
18563 rtx mem = gen_frame_mem (V4SImode, addr);
18565 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18567 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18569 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18570 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18571 GEN_INT (info->gp_save_offset
18572 + sp_offset + reg_size * i));
18573 rtx mem = gen_frame_mem (reg_mode, addr);
18575 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18579 /* CR register traditionally saved as CR2. */
18580 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
18581 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18582 GEN_INT (info->cr_save_offset
18584 rtx mem = gen_frame_mem (reg_mode, addr);
18586 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18588 /* Explain about use of R0. */
18589 if (info->lr_save_p)
18591 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18592 GEN_INT (info->lr_save_offset
18594 rtx mem = gen_frame_mem (reg_mode, addr);
18596 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
18598 /* Explain what happens to the stack pointer. */
18600 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
18601 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
18604 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18605 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18606 treg, GEN_INT (-info->total_size));
18607 sp_offset = info->total_size;
18610 /* If we use the link register, get it into r0. */
18611 if (!WORLD_SAVE_P (info) && info->lr_save_p)
18613 rtx addr, reg, mem;
18615 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
18616 gen_rtx_REG (Pmode, LR_REGNO));
18617 RTX_FRAME_RELATED_P (insn) = 1;
18619 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
18620 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
18622 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18623 GEN_INT (info->lr_save_offset + sp_offset));
18624 reg = gen_rtx_REG (Pmode, 0);
18625 mem = gen_rtx_MEM (Pmode, addr);
18626 /* This should not be of rs6000_sr_alias_set, because of
18627 __builtin_return_address. */
18629 insn = emit_move_insn (mem, reg);
18630 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18631 NULL_RTX, NULL_RTX);
18635 /* If we need to save CR, put it into r12 or r11. */
18636 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
18641 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
18643 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18644 RTX_FRAME_RELATED_P (insn) = 1;
18645 /* Now, there's no way that dwarf2out_frame_debug_expr is going
18646 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
18647 But that's OK. All we have to do is specify that _one_ condition
18648 code register is saved in this stack slot. The thrower's epilogue
18649 will then restore all the call-saved registers.
18650 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
18651 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
18652 gen_rtx_REG (SImode, CR2_REGNO));
18653 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18656 /* Do any required saving of fpr's. If only one or two to save, do
18657 it ourselves. Otherwise, call function. */
18658 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
18661 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18662 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
18663 && ! call_used_regs[info->first_fp_reg_save+i]))
18664 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
18665 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18667 info->first_fp_reg_save + i,
18668 info->fp_save_offset + sp_offset + 8 * i,
18671 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
18675 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18676 info->fp_save_offset + sp_offset,
18678 /*savep=*/true, /*gpr=*/false,
18680 & SAVRES_NOINLINE_FPRS_SAVES_LR)
18682 insn = emit_insn (par);
18683 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18684 NULL_RTX, NULL_RTX);
18687 /* Save GPRs. This is done as a PARALLEL if we are using
18688 the store-multiple instructions. */
18689 if (!WORLD_SAVE_P (info)
18691 && info->spe_64bit_regs_used != 0
18692 && info->first_gp_reg_save != 32)
18695 rtx spe_save_area_ptr;
18697 /* Determine whether we can address all of the registers that need
18698 to be saved with an offset from the stack pointer that fits in
18699 the small const field for SPE memory instructions. */
18700 int spe_regs_addressable_via_sp
18701 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
18702 + (32 - info->first_gp_reg_save - 1) * reg_size)
18703 && saving_GPRs_inline);
18706 if (spe_regs_addressable_via_sp)
18708 spe_save_area_ptr = frame_reg_rtx;
18709 spe_offset = info->spe_gp_save_offset + sp_offset;
18713 /* Make r11 point to the start of the SPE save area. We need
18714 to be careful here if r11 is holding the static chain. If
18715 it is, then temporarily save it in r0. We would use r0 as
18716 our base register here, but using r0 as a base register in
18717 loads and stores means something different from what we
18719 int ool_adjust = (saving_GPRs_inline
18721 : (info->first_gp_reg_save
18722 - (FIRST_SAVRES_REGISTER+1))*8);
18723 HOST_WIDE_INT offset = (info->spe_gp_save_offset
18724 + sp_offset - ool_adjust);
18726 if (using_static_chain_p)
18728 rtx r0 = gen_rtx_REG (Pmode, 0);
18729 gcc_assert (info->first_gp_reg_save > 11);
18731 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
18734 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
18735 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
18737 GEN_INT (offset)));
18738 /* We need to make sure the move to r11 gets noted for
18739 properly outputting unwind information. */
18740 if (!saving_GPRs_inline)
18741 rs6000_frame_related (insn, frame_reg_rtx, offset,
18742 NULL_RTX, NULL_RTX);
18746 if (saving_GPRs_inline)
18748 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18749 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
18751 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18752 rtx offset, addr, mem;
18754 /* We're doing all this to ensure that the offset fits into
18755 the immediate offset of 'evstdd'. */
18756 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
18758 offset = GEN_INT (reg_size * i + spe_offset);
18759 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
18760 mem = gen_rtx_MEM (V2SImode, addr);
18762 insn = emit_move_insn (mem, reg);
18764 rs6000_frame_related (insn, spe_save_area_ptr,
18765 info->spe_gp_save_offset
18766 + sp_offset + reg_size * i,
18767 offset, const0_rtx);
18774 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
18776 /*savep=*/true, /*gpr=*/true,
18778 insn = emit_insn (par);
18779 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18780 NULL_RTX, NULL_RTX);
18784 /* Move the static chain pointer back. */
18785 if (using_static_chain_p && !spe_regs_addressable_via_sp)
18786 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
18788 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
18792 /* Need to adjust r11 (r12) if we saved any FPRs. */
18793 if (info->first_fp_reg_save != 64)
18795 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
18797 rtx offset = GEN_INT (sp_offset
18798 + (-8 * (64-info->first_fp_reg_save)));
18799 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
18802 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18803 info->gp_save_offset + sp_offset,
18805 /*savep=*/true, /*gpr=*/true,
18807 & SAVRES_NOINLINE_GPRS_SAVES_LR)
18809 insn = emit_insn (par);
18810 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18811 NULL_RTX, NULL_RTX);
18813 else if (!WORLD_SAVE_P (info) && using_store_multiple)
18817 p = rtvec_alloc (32 - info->first_gp_reg_save);
18818 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18820 rtx addr, reg, mem;
18821 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18822 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18823 GEN_INT (info->gp_save_offset
18826 mem = gen_frame_mem (reg_mode, addr);
18828 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
18830 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18831 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18832 NULL_RTX, NULL_RTX);
18834 else if (!WORLD_SAVE_P (info))
18837 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18838 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
18840 rtx addr, reg, mem;
18841 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18843 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18844 GEN_INT (info->gp_save_offset
18847 mem = gen_frame_mem (reg_mode, addr);
18849 insn = emit_move_insn (mem, reg);
18850 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18851 NULL_RTX, NULL_RTX);
18855 /* ??? There's no need to emit actual instructions here, but it's the
18856 easiest way to get the frame unwind information emitted. */
18857 if (crtl->calls_eh_return)
18859 unsigned int i, regno;
18861 /* In AIX ABI we need to pretend we save r2 here. */
18864 rtx addr, reg, mem;
18866 reg = gen_rtx_REG (reg_mode, 2);
18867 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18868 GEN_INT (sp_offset + 5 * reg_size));
18869 mem = gen_frame_mem (reg_mode, addr);
18871 insn = emit_move_insn (mem, reg);
18872 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18873 NULL_RTX, NULL_RTX);
18874 PATTERN (insn) = gen_blockage ();
18879 regno = EH_RETURN_DATA_REGNO (i);
18880 if (regno == INVALID_REGNUM)
18883 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
18884 info->ehrd_offset + sp_offset
18885 + reg_size * (int) i,
18890 /* Save CR if we use any that must be preserved. */
18891 if (!WORLD_SAVE_P (info) && info->cr_save_p)
18893 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18894 GEN_INT (info->cr_save_offset + sp_offset));
18895 rtx mem = gen_frame_mem (SImode, addr);
18896 /* See the large comment above about why CR2_REGNO is used. */
18897 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
18899 /* If r12 was used to hold the original sp, copy cr into r0 now
18901 if (REGNO (frame_reg_rtx) == 12)
18905 cr_save_rtx = gen_rtx_REG (SImode, 0);
18906 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18907 RTX_FRAME_RELATED_P (insn) = 1;
18908 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
18909 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18911 insn = emit_move_insn (mem, cr_save_rtx);
18913 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18914 NULL_RTX, NULL_RTX);
18917 /* Update stack and set back pointer unless this is V.4,
18918 for which it was done previously. */
18919 if (!WORLD_SAVE_P (info) && info->push_p
18920 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
18922 if (info->total_size < 32767)
18923 sp_offset = info->total_size;
18925 frame_reg_rtx = frame_ptr_rtx;
18926 rs6000_emit_allocate_stack (info->total_size,
18927 (frame_reg_rtx != sp_reg_rtx
18928 && ((info->altivec_size != 0)
18929 || (info->vrsave_mask != 0)
18932 if (frame_reg_rtx != sp_reg_rtx)
18933 rs6000_emit_stack_tie ();
18936 /* Set frame pointer, if needed. */
18937 if (frame_pointer_needed)
18939 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
18941 RTX_FRAME_RELATED_P (insn) = 1;
18944 /* Save AltiVec registers if needed. Save here because the red zone does
18945 not include AltiVec registers. */
18946 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
18950 /* There should be a non inline version of this, for when we
18951 are saving lots of vector registers. */
18952 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
18953 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18955 rtx areg, savereg, mem;
18958 offset = info->altivec_save_offset + sp_offset
18959 + 16 * (i - info->first_altivec_reg_save);
18961 savereg = gen_rtx_REG (V4SImode, i);
18963 areg = gen_rtx_REG (Pmode, 0);
18964 emit_move_insn (areg, GEN_INT (offset));
18966 /* AltiVec addressing mode is [reg+reg]. */
18967 mem = gen_frame_mem (V4SImode,
18968 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
18970 insn = emit_move_insn (mem, savereg);
18972 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18973 areg, GEN_INT (offset));
18977 /* VRSAVE is a bit vector representing which AltiVec registers
18978 are used. The OS uses this to determine which vector
18979 registers to save on a context switch. We need to save
18980 VRSAVE on the stack frame, add whatever AltiVec registers we
18981 used in this function, and do the corresponding magic in the
18984 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
18985 && info->vrsave_mask != 0)
18987 rtx reg, mem, vrsave;
18990 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
18991 as frame_reg_rtx and r11 as the static chain pointer for
18992 nested functions. */
18993 reg = gen_rtx_REG (SImode, 0);
18994 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18996 emit_insn (gen_get_vrsave_internal (reg));
18998 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19000 if (!WORLD_SAVE_P (info))
19003 offset = info->vrsave_save_offset + sp_offset;
19004 mem = gen_frame_mem (SImode,
19005 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19006 GEN_INT (offset)));
19007 insn = emit_move_insn (mem, reg);
19010 /* Include the registers in the mask. */
19011 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19013 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19016 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19017 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19018 || (DEFAULT_ABI == ABI_V4
19019 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19020 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19022 /* If emit_load_toc_table will use the link register, we need to save
19023 it. We use R12 for this purpose because emit_load_toc_table
19024 can use register 0. This allows us to use a plain 'blr' to return
19025 from the procedure more often. */
19026 int save_LR_around_toc_setup = (TARGET_ELF
19027 && DEFAULT_ABI != ABI_AIX
19029 && ! info->lr_save_p
19030 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19031 if (save_LR_around_toc_setup)
19033 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19035 insn = emit_move_insn (frame_ptr_rtx, lr);
19036 RTX_FRAME_RELATED_P (insn) = 1;
19038 rs6000_emit_load_toc_table (TRUE);
19040 insn = emit_move_insn (lr, frame_ptr_rtx);
19041 RTX_FRAME_RELATED_P (insn) = 1;
19044 rs6000_emit_load_toc_table (TRUE);
19048 if (DEFAULT_ABI == ABI_DARWIN
19049 && flag_pic && crtl->uses_pic_offset_table)
19051 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19052 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19054 /* Save and restore LR locally around this call (in R0). */
19055 if (!info->lr_save_p)
19056 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19058 emit_insn (gen_load_macho_picbase (src));
19060 emit_move_insn (gen_rtx_REG (Pmode,
19061 RS6000_PIC_OFFSET_TABLE_REGNUM),
19064 if (!info->lr_save_p)
19065 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19070 /* Write function prologue. */
19073 rs6000_output_function_prologue (FILE *file,
19074 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19076 rs6000_stack_t *info = rs6000_stack_info ();
19078 if (TARGET_DEBUG_STACK)
19079 debug_stack_info (info);
19081 /* Write .extern for any function we will call to save and restore
19083 if (info->first_fp_reg_save < 64
19084 && !FP_SAVE_INLINE (info->first_fp_reg_save))
19087 int regno = info->first_fp_reg_save - 32;
19089 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
19090 /*gpr=*/false, /*lr=*/false);
19091 fprintf (file, "\t.extern %s\n", name);
19093 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
19094 /*gpr=*/false, /*lr=*/true);
19095 fprintf (file, "\t.extern %s\n", name);
19098 /* Write .extern for AIX common mode routines, if needed. */
19099 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
19101 fputs ("\t.extern __mulh\n", file);
19102 fputs ("\t.extern __mull\n", file);
19103 fputs ("\t.extern __divss\n", file);
19104 fputs ("\t.extern __divus\n", file);
19105 fputs ("\t.extern __quoss\n", file);
19106 fputs ("\t.extern __quous\n", file);
19107 common_mode_defined = 1;
19110 if (! HAVE_prologue)
19116 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19117 the "toplevel" insn chain. */
19118 emit_note (NOTE_INSN_DELETED);
19119 rs6000_emit_prologue ();
19120 emit_note (NOTE_INSN_DELETED);
19122 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19126 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19128 INSN_ADDRESSES_NEW (insn, addr);
19133 prologue = get_insns ();
19136 if (TARGET_DEBUG_STACK)
19137 debug_rtx_list (prologue, 100);
19139 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
19143 rs6000_pic_labelno++;
19146 /* Non-zero if vmx regs are restored before the frame pop, zero if
19147 we restore after the pop when possible. */
19148 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19150 /* Reload CR from REG. */
19153 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
19158 if (using_mfcr_multiple)
19160 for (i = 0; i < 8; i++)
19161 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19163 gcc_assert (count);
19166 if (using_mfcr_multiple && count > 1)
19171 p = rtvec_alloc (count);
19174 for (i = 0; i < 8; i++)
19175 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19177 rtvec r = rtvec_alloc (2);
19178 RTVEC_ELT (r, 0) = reg;
19179 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19180 RTVEC_ELT (p, ndx) =
19181 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19182 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19185 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19186 gcc_assert (ndx == count);
19189 for (i = 0; i < 8; i++)
19190 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19192 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19198 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19199 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19200 below stack pointer not cloberred by signals. */
19203 offset_below_red_zone_p (HOST_WIDE_INT offset)
19205 return offset < (DEFAULT_ABI == ABI_V4
19207 : TARGET_32BIT ? -220 : -288);
19210 /* Emit function epilogue as insns. */
19213 rs6000_emit_epilogue (int sibcall)
19215 rs6000_stack_t *info;
19216 int restoring_GPRs_inline;
19217 int restoring_FPRs_inline;
19218 int using_load_multiple;
19219 int using_mtcr_multiple;
19220 int use_backchain_to_restore_sp;
19224 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19225 rtx frame_reg_rtx = sp_reg_rtx;
19226 rtx cfa_restores = NULL_RTX;
19228 rtx cr_save_reg = NULL_RTX;
19229 enum machine_mode reg_mode = Pmode;
19230 int reg_size = TARGET_32BIT ? 4 : 8;
19233 info = rs6000_stack_info ();
19235 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19237 reg_mode = V2SImode;
19241 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19242 /*static_chain_p=*/0, sibcall);
19243 using_load_multiple = strategy & SAVRES_MULTIPLE;
19244 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19245 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19246 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19247 || rs6000_cpu == PROCESSOR_PPC603
19248 || rs6000_cpu == PROCESSOR_PPC750
19250 /* Restore via the backchain when we have a large frame, since this
19251 is more efficient than an addis, addi pair. The second condition
19252 here will not trigger at the moment; We don't actually need a
19253 frame pointer for alloca, but the generic parts of the compiler
19254 give us one anyway. */
19255 use_backchain_to_restore_sp = (info->total_size > 32767
19256 || info->total_size
19257 + (info->lr_save_p ? info->lr_save_offset : 0)
19259 || (cfun->calls_alloca
19260 && !frame_pointer_needed));
19261 restore_lr = (info->lr_save_p
19262 && (restoring_FPRs_inline
19263 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
19264 && (restoring_GPRs_inline
19265 || info->first_fp_reg_save < 64));
19267 if (WORLD_SAVE_P (info))
19271 const char *alloc_rname;
19274 /* eh_rest_world_r10 will return to the location saved in the LR
19275 stack slot (which is not likely to be our caller.)
19276 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19277 rest_world is similar, except any R10 parameter is ignored.
19278 The exception-handling stuff that was here in 2.95 is no
19279 longer necessary. */
19283 + 32 - info->first_gp_reg_save
19284 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
19285 + 63 + 1 - info->first_fp_reg_save);
19287 strcpy (rname, ((crtl->calls_eh_return) ?
19288 "*eh_rest_world_r10" : "*rest_world"));
19289 alloc_rname = ggc_strdup (rname);
19292 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
19293 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19294 gen_rtx_REG (Pmode,
19297 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
19298 /* The instruction pattern requires a clobber here;
19299 it is shared with the restVEC helper. */
19301 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
19304 /* CR register traditionally saved as CR2. */
19305 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19306 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19307 GEN_INT (info->cr_save_offset));
19308 rtx mem = gen_frame_mem (reg_mode, addr);
19310 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19313 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19315 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19316 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19317 GEN_INT (info->gp_save_offset
19319 rtx mem = gen_frame_mem (reg_mode, addr);
19321 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19323 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19325 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19326 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19327 GEN_INT (info->altivec_save_offset
19329 rtx mem = gen_frame_mem (V4SImode, addr);
19331 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19333 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
19335 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19336 ? DFmode : SFmode),
19337 info->first_fp_reg_save + i);
19338 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19339 GEN_INT (info->fp_save_offset
19341 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19342 ? DFmode : SFmode), addr);
19344 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19347 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
19349 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
19351 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
19353 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
19355 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
19356 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19361 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
19363 sp_offset = info->total_size;
19365 /* Restore AltiVec registers if we must do so before adjusting the
19367 if (TARGET_ALTIVEC_ABI
19368 && info->altivec_size != 0
19369 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19370 || (DEFAULT_ABI != ABI_V4
19371 && offset_below_red_zone_p (info->altivec_save_offset))))
19375 if (use_backchain_to_restore_sp)
19377 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19378 emit_move_insn (frame_reg_rtx,
19379 gen_rtx_MEM (Pmode, sp_reg_rtx));
19382 else if (frame_pointer_needed)
19383 frame_reg_rtx = hard_frame_pointer_rtx;
19385 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19386 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19388 rtx addr, areg, mem, reg;
19390 areg = gen_rtx_REG (Pmode, 0);
19392 (areg, GEN_INT (info->altivec_save_offset
19394 + 16 * (i - info->first_altivec_reg_save)));
19396 /* AltiVec addressing mode is [reg+reg]. */
19397 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19398 mem = gen_frame_mem (V4SImode, addr);
19400 reg = gen_rtx_REG (V4SImode, i);
19401 emit_move_insn (reg, mem);
19402 if (offset_below_red_zone_p (info->altivec_save_offset
19403 + (i - info->first_altivec_reg_save)
19405 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19410 /* Restore VRSAVE if we must do so before adjusting the stack. */
19412 && TARGET_ALTIVEC_VRSAVE
19413 && info->vrsave_mask != 0
19414 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19415 || (DEFAULT_ABI != ABI_V4
19416 && offset_below_red_zone_p (info->vrsave_save_offset))))
19418 rtx addr, mem, reg;
19420 if (frame_reg_rtx == sp_reg_rtx)
19422 if (use_backchain_to_restore_sp)
19424 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19425 emit_move_insn (frame_reg_rtx,
19426 gen_rtx_MEM (Pmode, sp_reg_rtx));
19429 else if (frame_pointer_needed)
19430 frame_reg_rtx = hard_frame_pointer_rtx;
19433 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19434 GEN_INT (info->vrsave_save_offset + sp_offset));
19435 mem = gen_frame_mem (SImode, addr);
19436 reg = gen_rtx_REG (SImode, 12);
19437 emit_move_insn (reg, mem);
19439 emit_insn (generate_set_vrsave (reg, info, 1));
19443 /* If we have a large stack frame, restore the old stack pointer
19444 using the backchain. */
19445 if (use_backchain_to_restore_sp)
19447 if (frame_reg_rtx == sp_reg_rtx)
19449 /* Under V.4, don't reset the stack pointer until after we're done
19450 loading the saved registers. */
19451 if (DEFAULT_ABI == ABI_V4)
19452 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19454 insn = emit_move_insn (frame_reg_rtx,
19455 gen_rtx_MEM (Pmode, sp_reg_rtx));
19458 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19459 && DEFAULT_ABI == ABI_V4)
19460 /* frame_reg_rtx has been set up by the altivec restore. */
19464 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19465 frame_reg_rtx = sp_reg_rtx;
19468 /* If we have a frame pointer, we can restore the old stack pointer
19470 else if (frame_pointer_needed)
19472 frame_reg_rtx = sp_reg_rtx;
19473 if (DEFAULT_ABI == ABI_V4)
19474 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19476 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
19477 GEN_INT (info->total_size)));
19480 else if (info->push_p
19481 && DEFAULT_ABI != ABI_V4
19482 && !crtl->calls_eh_return)
19484 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
19485 GEN_INT (info->total_size)));
19488 if (insn && frame_reg_rtx == sp_reg_rtx)
19492 REG_NOTES (insn) = cfa_restores;
19493 cfa_restores = NULL_RTX;
19495 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19496 RTX_FRAME_RELATED_P (insn) = 1;
19499 /* Restore AltiVec registers if we have not done so already. */
19500 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19501 && TARGET_ALTIVEC_ABI
19502 && info->altivec_size != 0
19503 && (DEFAULT_ABI == ABI_V4
19504 || !offset_below_red_zone_p (info->altivec_save_offset)))
19508 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19509 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19511 rtx addr, areg, mem, reg;
19513 areg = gen_rtx_REG (Pmode, 0);
19515 (areg, GEN_INT (info->altivec_save_offset
19517 + 16 * (i - info->first_altivec_reg_save)));
19519 /* AltiVec addressing mode is [reg+reg]. */
19520 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19521 mem = gen_frame_mem (V4SImode, addr);
19523 reg = gen_rtx_REG (V4SImode, i);
19524 emit_move_insn (reg, mem);
19525 if (DEFAULT_ABI == ABI_V4)
19526 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19531 /* Restore VRSAVE if we have not done so already. */
19532 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19534 && TARGET_ALTIVEC_VRSAVE
19535 && info->vrsave_mask != 0
19536 && (DEFAULT_ABI == ABI_V4
19537 || !offset_below_red_zone_p (info->vrsave_save_offset)))
19539 rtx addr, mem, reg;
19541 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19542 GEN_INT (info->vrsave_save_offset + sp_offset));
19543 mem = gen_frame_mem (SImode, addr);
19544 reg = gen_rtx_REG (SImode, 12);
19545 emit_move_insn (reg, mem);
19547 emit_insn (generate_set_vrsave (reg, info, 1));
19550 /* Get the old lr if we saved it. If we are restoring registers
19551 out-of-line, then the out-of-line routines can do this for us. */
19552 if (restore_lr && restoring_GPRs_inline)
19554 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19555 info->lr_save_offset + sp_offset);
19557 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19560 /* Get the old cr if we saved it. */
19561 if (info->cr_save_p)
19563 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19564 GEN_INT (info->cr_save_offset + sp_offset));
19565 rtx mem = gen_frame_mem (SImode, addr);
19567 cr_save_reg = gen_rtx_REG (SImode,
19568 DEFAULT_ABI == ABI_AIX
19569 && !restoring_GPRs_inline
19570 && info->first_fp_reg_save < 64
19572 emit_move_insn (cr_save_reg, mem);
19575 /* Set LR here to try to overlap restores below. LR is always saved
19576 above incoming stack, so it never needs REG_CFA_RESTORE. */
19577 if (restore_lr && restoring_GPRs_inline)
19578 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19579 gen_rtx_REG (Pmode, 0));
19581 /* Load exception handler data registers, if needed. */
19582 if (crtl->calls_eh_return)
19584 unsigned int i, regno;
19588 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19589 GEN_INT (sp_offset + 5 * reg_size));
19590 rtx mem = gen_frame_mem (reg_mode, addr);
19592 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
19599 regno = EH_RETURN_DATA_REGNO (i);
19600 if (regno == INVALID_REGNUM)
19603 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
19604 info->ehrd_offset + sp_offset
19605 + reg_size * (int) i);
19607 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
19611 /* Restore GPRs. This is done as a PARALLEL if we are using
19612 the load-multiple instructions. */
19614 && info->spe_64bit_regs_used != 0
19615 && info->first_gp_reg_save != 32)
19617 /* Determine whether we can address all of the registers that need
19618 to be saved with an offset from the stack pointer that fits in
19619 the small const field for SPE memory instructions. */
19620 int spe_regs_addressable_via_sp
19621 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19622 + (32 - info->first_gp_reg_save - 1) * reg_size)
19623 && restoring_GPRs_inline);
19626 if (spe_regs_addressable_via_sp)
19627 spe_offset = info->spe_gp_save_offset + sp_offset;
19630 rtx old_frame_reg_rtx = frame_reg_rtx;
19631 /* Make r11 point to the start of the SPE save area. We worried about
19632 not clobbering it when we were saving registers in the prologue.
19633 There's no need to worry here because the static chain is passed
19634 anew to every function. */
19635 int ool_adjust = (restoring_GPRs_inline
19637 : (info->first_gp_reg_save
19638 - (FIRST_SAVRES_REGISTER+1))*8);
19640 if (frame_reg_rtx == sp_reg_rtx)
19641 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19642 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
19643 GEN_INT (info->spe_gp_save_offset
19646 /* Keep the invariant that frame_reg_rtx + sp_offset points
19647 at the top of the stack frame. */
19648 sp_offset = -info->spe_gp_save_offset;
19653 if (restoring_GPRs_inline)
19655 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19656 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19658 rtx offset, addr, mem, reg;
19660 /* We're doing all this to ensure that the immediate offset
19661 fits into the immediate field of 'evldd'. */
19662 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
19664 offset = GEN_INT (spe_offset + reg_size * i);
19665 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
19666 mem = gen_rtx_MEM (V2SImode, addr);
19667 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19669 insn = emit_move_insn (reg, mem);
19670 if (DEFAULT_ABI == ABI_V4)
19672 if (frame_pointer_needed
19673 && info->first_gp_reg_save + i
19674 == HARD_FRAME_POINTER_REGNUM)
19676 add_reg_note (insn, REG_CFA_DEF_CFA,
19677 plus_constant (frame_reg_rtx,
19679 RTX_FRAME_RELATED_P (insn) = 1;
19682 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19691 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19693 /*savep=*/false, /*gpr=*/true,
19695 emit_jump_insn (par);
19696 /* We don't want anybody else emitting things after we jumped
19701 else if (!restoring_GPRs_inline)
19703 /* We are jumping to an out-of-line function. */
19704 bool can_use_exit = info->first_fp_reg_save == 64;
19707 /* Emit stack reset code if we need it. */
19709 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19710 sp_offset, can_use_exit);
19713 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
19716 GEN_INT (sp_offset - info->fp_size)));
19717 if (REGNO (frame_reg_rtx) == 11)
19718 sp_offset += info->fp_size;
19721 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19722 info->gp_save_offset, reg_mode,
19723 /*savep=*/false, /*gpr=*/true,
19724 /*lr=*/can_use_exit);
19728 if (info->cr_save_p)
19730 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
19731 if (DEFAULT_ABI == ABI_V4)
19733 = alloc_reg_note (REG_CFA_RESTORE,
19734 gen_rtx_REG (SImode, CR2_REGNO),
19738 emit_jump_insn (par);
19740 /* We don't want anybody else emitting things after we jumped
19745 insn = emit_insn (par);
19746 if (DEFAULT_ABI == ABI_V4)
19748 if (frame_pointer_needed)
19750 add_reg_note (insn, REG_CFA_DEF_CFA,
19751 plus_constant (frame_reg_rtx, sp_offset));
19752 RTX_FRAME_RELATED_P (insn) = 1;
19755 for (i = info->first_gp_reg_save; i < 32; i++)
19757 = alloc_reg_note (REG_CFA_RESTORE,
19758 gen_rtx_REG (reg_mode, i), cfa_restores);
19761 else if (using_load_multiple)
19764 p = rtvec_alloc (32 - info->first_gp_reg_save);
19765 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19767 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19768 GEN_INT (info->gp_save_offset
19771 rtx mem = gen_frame_mem (reg_mode, addr);
19772 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19774 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
19775 if (DEFAULT_ABI == ABI_V4)
19776 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19779 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19780 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
19782 add_reg_note (insn, REG_CFA_DEF_CFA,
19783 plus_constant (frame_reg_rtx, sp_offset));
19784 RTX_FRAME_RELATED_P (insn) = 1;
19789 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19790 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19792 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19793 GEN_INT (info->gp_save_offset
19796 rtx mem = gen_frame_mem (reg_mode, addr);
19797 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19799 insn = emit_move_insn (reg, mem);
19800 if (DEFAULT_ABI == ABI_V4)
19802 if (frame_pointer_needed
19803 && info->first_gp_reg_save + i
19804 == HARD_FRAME_POINTER_REGNUM)
19806 add_reg_note (insn, REG_CFA_DEF_CFA,
19807 plus_constant (frame_reg_rtx, sp_offset));
19808 RTX_FRAME_RELATED_P (insn) = 1;
19811 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19817 if (restore_lr && !restoring_GPRs_inline)
19819 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19820 info->lr_save_offset + sp_offset);
19822 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19823 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19824 gen_rtx_REG (Pmode, 0));
19827 /* Restore fpr's if we need to do it without calling a function. */
19828 if (restoring_FPRs_inline)
19829 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19830 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
19831 && ! call_used_regs[info->first_fp_reg_save+i]))
19833 rtx addr, mem, reg;
19834 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19835 GEN_INT (info->fp_save_offset
19838 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19839 ? DFmode : SFmode), addr);
19840 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19841 ? DFmode : SFmode),
19842 info->first_fp_reg_save + i);
19844 emit_move_insn (reg, mem);
19845 if (DEFAULT_ABI == ABI_V4)
19846 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19850 /* If we saved cr, restore it here. Just those that were used. */
19851 if (info->cr_save_p)
19853 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
19854 if (DEFAULT_ABI == ABI_V4)
19856 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
19860 /* If this is V.4, unwind the stack pointer after all of the loads
19862 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19863 sp_offset, !restoring_FPRs_inline);
19868 REG_NOTES (insn) = cfa_restores;
19869 cfa_restores = NULL_RTX;
19871 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19872 RTX_FRAME_RELATED_P (insn) = 1;
19875 if (crtl->calls_eh_return)
19877 rtx sa = EH_RETURN_STACKADJ_RTX;
19878 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
19884 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
19885 if (! restoring_FPRs_inline)
19886 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
19888 p = rtvec_alloc (2);
19890 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
19891 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
19892 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
19893 : gen_rtx_CLOBBER (VOIDmode,
19894 gen_rtx_REG (Pmode, 65)));
19896 /* If we have to restore more than two FP registers, branch to the
19897 restore function. It will return to our caller. */
19898 if (! restoring_FPRs_inline)
19903 sym = rs6000_savres_routine_sym (info,
19907 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
19908 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
19909 gen_rtx_REG (Pmode,
19910 DEFAULT_ABI == ABI_AIX
19912 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19915 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
19916 GEN_INT (info->fp_save_offset + 8*i));
19917 mem = gen_frame_mem (DFmode, addr);
19919 RTVEC_ELT (p, i+4) =
19920 gen_rtx_SET (VOIDmode,
19921 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
19926 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19930 /* Write function epilogue. */
19933 rs6000_output_function_epilogue (FILE *file,
19934 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19936 if (! HAVE_epilogue)
19938 rtx insn = get_last_insn ();
19939 /* If the last insn was a BARRIER, we don't have to write anything except
19940 the trace table. */
19941 if (GET_CODE (insn) == NOTE)
19942 insn = prev_nonnote_insn (insn);
19943 if (insn == 0 || GET_CODE (insn) != BARRIER)
19945 /* This is slightly ugly, but at least we don't have two
19946 copies of the epilogue-emitting code. */
19949 /* A NOTE_INSN_DELETED is supposed to be at the start
19950 and end of the "toplevel" insn chain. */
19951 emit_note (NOTE_INSN_DELETED);
19952 rs6000_emit_epilogue (FALSE);
19953 emit_note (NOTE_INSN_DELETED);
19955 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19959 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19961 INSN_ADDRESSES_NEW (insn, addr);
19966 if (TARGET_DEBUG_STACK)
19967 debug_rtx_list (get_insns (), 100);
19968 final (get_insns (), file, FALSE);
19974 macho_branch_islands ();
19975 /* Mach-O doesn't support labels at the end of objects, so if
19976 it looks like we might want one, insert a NOP. */
19978 rtx insn = get_last_insn ();
19981 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
19982 insn = PREV_INSN (insn);
19986 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
19987 fputs ("\tnop\n", file);
19991 /* Output a traceback table here. See /usr/include/sys/debug.h for info
19994 We don't output a traceback table if -finhibit-size-directive was
19995 used. The documentation for -finhibit-size-directive reads
19996 ``don't output a @code{.size} assembler directive, or anything
19997 else that would cause trouble if the function is split in the
19998 middle, and the two halves are placed at locations far apart in
19999 memory.'' The traceback table has this property, since it
20000 includes the offset from the start of the function to the
20001 traceback table itself.
20003 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20004 different traceback table. */
20005 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20006 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20008 const char *fname = NULL;
20009 const char *language_string = lang_hooks.name;
20010 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20012 int optional_tbtab;
20013 rs6000_stack_t *info = rs6000_stack_info ();
20015 if (rs6000_traceback == traceback_full)
20016 optional_tbtab = 1;
20017 else if (rs6000_traceback == traceback_part)
20018 optional_tbtab = 0;
20020 optional_tbtab = !optimize_size && !TARGET_ELF;
20022 if (optional_tbtab)
20024 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20025 while (*fname == '.') /* V.4 encodes . in the name */
20028 /* Need label immediately before tbtab, so we can compute
20029 its offset from the function start. */
20030 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20031 ASM_OUTPUT_LABEL (file, fname);
20034 /* The .tbtab pseudo-op can only be used for the first eight
20035 expressions, since it can't handle the possibly variable
20036 length fields that follow. However, if you omit the optional
20037 fields, the assembler outputs zeros for all optional fields
20038 anyways, giving each variable length field is minimum length
20039 (as defined in sys/debug.h). Thus we can not use the .tbtab
20040 pseudo-op at all. */
20042 /* An all-zero word flags the start of the tbtab, for debuggers
20043 that have to find it by searching forward from the entry
20044 point or from the current pc. */
20045 fputs ("\t.long 0\n", file);
20047 /* Tbtab format type. Use format type 0. */
20048 fputs ("\t.byte 0,", file);
20050 /* Language type. Unfortunately, there does not seem to be any
20051 official way to discover the language being compiled, so we
20052 use language_string.
20053 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20054 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20055 a number, so for now use 9. */
20056 if (! strcmp (language_string, "GNU C"))
20058 else if (! strcmp (language_string, "GNU F77")
20059 || ! strcmp (language_string, "GNU Fortran"))
20061 else if (! strcmp (language_string, "GNU Pascal"))
20063 else if (! strcmp (language_string, "GNU Ada"))
20065 else if (! strcmp (language_string, "GNU C++")
20066 || ! strcmp (language_string, "GNU Objective-C++"))
20068 else if (! strcmp (language_string, "GNU Java"))
20070 else if (! strcmp (language_string, "GNU Objective-C"))
20073 gcc_unreachable ();
20074 fprintf (file, "%d,", i);
20076 /* 8 single bit fields: global linkage (not set for C extern linkage,
20077 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20078 from start of procedure stored in tbtab, internal function, function
20079 has controlled storage, function has no toc, function uses fp,
20080 function logs/aborts fp operations. */
20081 /* Assume that fp operations are used if any fp reg must be saved. */
20082 fprintf (file, "%d,",
20083 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
20085 /* 6 bitfields: function is interrupt handler, name present in
20086 proc table, function calls alloca, on condition directives
20087 (controls stack walks, 3 bits), saves condition reg, saves
20089 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20090 set up as a frame pointer, even when there is no alloca call. */
20091 fprintf (file, "%d,",
20092 ((optional_tbtab << 6)
20093 | ((optional_tbtab & frame_pointer_needed) << 5)
20094 | (info->cr_save_p << 1)
20095 | (info->lr_save_p)));
20097 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20099 fprintf (file, "%d,",
20100 (info->push_p << 7) | (64 - info->first_fp_reg_save));
20102 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20103 fprintf (file, "%d,", (32 - first_reg_to_save ()));
20105 if (optional_tbtab)
20107 /* Compute the parameter info from the function decl argument
20110 int next_parm_info_bit = 31;
20112 for (decl = DECL_ARGUMENTS (current_function_decl);
20113 decl; decl = TREE_CHAIN (decl))
20115 rtx parameter = DECL_INCOMING_RTL (decl);
20116 enum machine_mode mode = GET_MODE (parameter);
20118 if (GET_CODE (parameter) == REG)
20120 if (SCALAR_FLOAT_MODE_P (mode))
20141 gcc_unreachable ();
20144 /* If only one bit will fit, don't or in this entry. */
20145 if (next_parm_info_bit > 0)
20146 parm_info |= (bits << (next_parm_info_bit - 1));
20147 next_parm_info_bit -= 2;
20151 fixed_parms += ((GET_MODE_SIZE (mode)
20152 + (UNITS_PER_WORD - 1))
20154 next_parm_info_bit -= 1;
20160 /* Number of fixed point parameters. */
20161 /* This is actually the number of words of fixed point parameters; thus
20162 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20163 fprintf (file, "%d,", fixed_parms);
20165 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20167 /* This is actually the number of fp registers that hold parameters;
20168 and thus the maximum value is 13. */
20169 /* Set parameters on stack bit if parameters are not in their original
20170 registers, regardless of whether they are on the stack? Xlc
20171 seems to set the bit when not optimizing. */
20172 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
20174 if (! optional_tbtab)
20177 /* Optional fields follow. Some are variable length. */
20179 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20180 11 double float. */
20181 /* There is an entry for each parameter in a register, in the order that
20182 they occur in the parameter list. Any intervening arguments on the
20183 stack are ignored. If the list overflows a long (max possible length
20184 34 bits) then completely leave off all elements that don't fit. */
20185 /* Only emit this long if there was at least one parameter. */
20186 if (fixed_parms || float_parms)
20187 fprintf (file, "\t.long %d\n", parm_info);
20189 /* Offset from start of code to tb table. */
20190 fputs ("\t.long ", file);
20191 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20193 RS6000_OUTPUT_BASENAME (file, fname);
20195 assemble_name (file, fname);
20197 rs6000_output_function_entry (file, fname);
20200 /* Interrupt handler mask. */
20201 /* Omit this long, since we never set the interrupt handler bit
20204 /* Number of CTL (controlled storage) anchors. */
20205 /* Omit this long, since the has_ctl bit is never set above. */
20207 /* Displacement into stack of each CTL anchor. */
20208 /* Omit this list of longs, because there are no CTL anchors. */
20210 /* Length of function name. */
20213 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20215 /* Function name. */
20216 assemble_string (fname, strlen (fname));
20218 /* Register for alloca automatic storage; this is always reg 31.
20219 Only emit this if the alloca bit was set above. */
20220 if (frame_pointer_needed)
20221 fputs ("\t.byte 31\n", file);
20223 fputs ("\t.align 2\n", file);
20227 /* A C compound statement that outputs the assembler code for a thunk
20228 function, used to implement C++ virtual function calls with
20229 multiple inheritance. The thunk acts as a wrapper around a virtual
20230 function, adjusting the implicit object parameter before handing
20231 control off to the real function.
20233 First, emit code to add the integer DELTA to the location that
20234 contains the incoming first argument. Assume that this argument
20235 contains a pointer, and is the one used to pass the `this' pointer
20236 in C++. This is the incoming argument *before* the function
20237 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20238 values of all other incoming arguments.
20240 After the addition, emit code to jump to FUNCTION, which is a
20241 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20242 not touch the return address. Hence returning from FUNCTION will
20243 return to whoever called the current `thunk'.
20245 The effect must be as if FUNCTION had been called directly with the
20246 adjusted first argument. This macro is responsible for emitting
20247 all of the code for a thunk function; output_function_prologue()
20248 and output_function_epilogue() are not invoked.
20250 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20251 been extracted from it.) It might possibly be useful on some
20252 targets, but probably not.
20254 If you do not define this macro, the target-independent code in the
20255 C++ frontend will generate a less efficient heavyweight thunk that
20256 calls FUNCTION instead of jumping to it. The generic approach does
20257 not support varargs. */
20260 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
20261 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
20264 rtx this_rtx, insn, funexp;
20266 reload_completed = 1;
20267 epilogue_completed = 1;
20269 /* Mark the end of the (empty) prologue. */
20270 emit_note (NOTE_INSN_PROLOGUE_END);
20272 /* Find the "this" pointer. If the function returns a structure,
20273 the structure return pointer is in r3. */
20274 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
20275 this_rtx = gen_rtx_REG (Pmode, 4);
20277 this_rtx = gen_rtx_REG (Pmode, 3);
20279 /* Apply the constant offset, if required. */
20281 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
20283 /* Apply the offset from the vtable, if required. */
20286 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
20287 rtx tmp = gen_rtx_REG (Pmode, 12);
20289 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
20290 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
20292 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
20293 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
20297 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
20299 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
20301 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
20304 /* Generate a tail call to the target function. */
20305 if (!TREE_USED (function))
20307 assemble_external (function);
20308 TREE_USED (function) = 1;
20310 funexp = XEXP (DECL_RTL (function), 0);
20311 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
20314 if (MACHOPIC_INDIRECT)
20315 funexp = machopic_indirect_call_target (funexp);
20318 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
20319 generate sibcall RTL explicitly. */
20320 insn = emit_call_insn (
20321 gen_rtx_PARALLEL (VOIDmode,
20323 gen_rtx_CALL (VOIDmode,
20324 funexp, const0_rtx),
20325 gen_rtx_USE (VOIDmode, const0_rtx),
20326 gen_rtx_USE (VOIDmode,
20327 gen_rtx_REG (SImode,
20329 gen_rtx_RETURN (VOIDmode))));
20330 SIBLING_CALL_P (insn) = 1;
20333 /* Run just enough of rest_of_compilation to get the insns emitted.
20334 There's not really enough bulk here to make other passes such as
20335 instruction scheduling worth while. Note that use_thunk calls
20336 assemble_start_function and assemble_end_function. */
20337 insn = get_insns ();
20338 insn_locators_alloc ();
20339 shorten_branches (insn);
20340 final_start_function (insn, file, 1);
20341 final (insn, file, 1);
20342 final_end_function ();
20344 reload_completed = 0;
20345 epilogue_completed = 0;
20348 /* A quick summary of the various types of 'constant-pool tables'
20351 Target Flags Name One table per
20352 AIX (none) AIX TOC object file
20353 AIX -mfull-toc AIX TOC object file
20354 AIX -mminimal-toc AIX minimal TOC translation unit
20355 SVR4/EABI (none) SVR4 SDATA object file
20356 SVR4/EABI -fpic SVR4 pic object file
20357 SVR4/EABI -fPIC SVR4 PIC translation unit
20358 SVR4/EABI -mrelocatable EABI TOC function
20359 SVR4/EABI -maix AIX TOC object file
20360 SVR4/EABI -maix -mminimal-toc
20361 AIX minimal TOC translation unit
20363 Name Reg. Set by entries contains:
20364 made by addrs? fp? sum?
20366 AIX TOC 2 crt0 as Y option option
20367 AIX minimal TOC 30 prolog gcc Y Y option
20368 SVR4 SDATA 13 crt0 gcc N Y N
20369 SVR4 pic 30 prolog ld Y not yet N
20370 SVR4 PIC 30 prolog gcc Y option option
20371 EABI TOC 30 prolog gcc Y option option
20375 /* Hash functions for the hash table. */
20378 rs6000_hash_constant (rtx k)
20380 enum rtx_code code = GET_CODE (k);
20381 enum machine_mode mode = GET_MODE (k);
20382 unsigned result = (code << 3) ^ mode;
20383 const char *format;
20386 format = GET_RTX_FORMAT (code);
20387 flen = strlen (format);
20393 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
20396 if (mode != VOIDmode)
20397 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
20409 for (; fidx < flen; fidx++)
20410 switch (format[fidx])
20415 const char *str = XSTR (k, fidx);
20416 len = strlen (str);
20417 result = result * 613 + len;
20418 for (i = 0; i < len; i++)
20419 result = result * 613 + (unsigned) str[i];
20424 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
20428 result = result * 613 + (unsigned) XINT (k, fidx);
20431 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
20432 result = result * 613 + (unsigned) XWINT (k, fidx);
20436 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
20437 result = result * 613 + (unsigned) (XWINT (k, fidx)
20444 gcc_unreachable ();
20451 toc_hash_function (const void *hash_entry)
20453 const struct toc_hash_struct *thc =
20454 (const struct toc_hash_struct *) hash_entry;
20455 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
20458 /* Compare H1 and H2 for equivalence. */
20461 toc_hash_eq (const void *h1, const void *h2)
20463 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
20464 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
20466 if (((const struct toc_hash_struct *) h1)->key_mode
20467 != ((const struct toc_hash_struct *) h2)->key_mode)
20470 return rtx_equal_p (r1, r2);
20473 /* These are the names given by the C++ front-end to vtables, and
20474 vtable-like objects. Ideally, this logic should not be here;
20475 instead, there should be some programmatic way of inquiring as
20476 to whether or not an object is a vtable. */
20478 #define VTABLE_NAME_P(NAME) \
20479 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
20480 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
20481 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
20482 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
20483 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
20485 #ifdef NO_DOLLAR_IN_LABEL
20486 /* Return a GGC-allocated character string translating dollar signs in
20487 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
20490 rs6000_xcoff_strip_dollar (const char *name)
20495 p = strchr (name, '$');
20497 if (p == 0 || p == name)
20500 len = strlen (name);
20501 strip = (char *) alloca (len + 1);
20502 strcpy (strip, name);
20503 p = strchr (strip, '$');
20507 p = strchr (p + 1, '$');
20510 return ggc_alloc_string (strip, len);
20515 rs6000_output_symbol_ref (FILE *file, rtx x)
20517 /* Currently C++ toc references to vtables can be emitted before it
20518 is decided whether the vtable is public or private. If this is
20519 the case, then the linker will eventually complain that there is
20520 a reference to an unknown section. Thus, for vtables only,
20521 we emit the TOC reference to reference the symbol and not the
20523 const char *name = XSTR (x, 0);
20525 if (VTABLE_NAME_P (name))
20527 RS6000_OUTPUT_BASENAME (file, name);
20530 assemble_name (file, name);
20533 /* Output a TOC entry. We derive the entry name from what is being
20537 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
20540 const char *name = buf;
20542 HOST_WIDE_INT offset = 0;
20544 gcc_assert (!TARGET_NO_TOC);
20546 /* When the linker won't eliminate them, don't output duplicate
20547 TOC entries (this happens on AIX if there is any kind of TOC,
20548 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
20550 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
20552 struct toc_hash_struct *h;
20555 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
20556 time because GGC is not initialized at that point. */
20557 if (toc_hash_table == NULL)
20558 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
20559 toc_hash_eq, NULL);
20561 h = GGC_NEW (struct toc_hash_struct);
20563 h->key_mode = mode;
20564 h->labelno = labelno;
20566 found = htab_find_slot (toc_hash_table, h, INSERT);
20567 if (*found == NULL)
20569 else /* This is indeed a duplicate.
20570 Set this label equal to that label. */
20572 fputs ("\t.set ", file);
20573 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20574 fprintf (file, "%d,", labelno);
20575 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20576 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
20582 /* If we're going to put a double constant in the TOC, make sure it's
20583 aligned properly when strict alignment is on. */
20584 if (GET_CODE (x) == CONST_DOUBLE
20585 && STRICT_ALIGNMENT
20586 && GET_MODE_BITSIZE (mode) >= 64
20587 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
20588 ASM_OUTPUT_ALIGN (file, 3);
20591 (*targetm.asm_out.internal_label) (file, "LC", labelno);
20593 /* Handle FP constants specially. Note that if we have a minimal
20594 TOC, things we put here aren't actually in the TOC, so we can allow
20596 if (GET_CODE (x) == CONST_DOUBLE &&
20597 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
20599 REAL_VALUE_TYPE rv;
20602 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20603 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20604 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
20606 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
20610 if (TARGET_MINIMAL_TOC)
20611 fputs (DOUBLE_INT_ASM_OP, file);
20613 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20614 k[0] & 0xffffffff, k[1] & 0xffffffff,
20615 k[2] & 0xffffffff, k[3] & 0xffffffff);
20616 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
20617 k[0] & 0xffffffff, k[1] & 0xffffffff,
20618 k[2] & 0xffffffff, k[3] & 0xffffffff);
20623 if (TARGET_MINIMAL_TOC)
20624 fputs ("\t.long ", file);
20626 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20627 k[0] & 0xffffffff, k[1] & 0xffffffff,
20628 k[2] & 0xffffffff, k[3] & 0xffffffff);
20629 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
20630 k[0] & 0xffffffff, k[1] & 0xffffffff,
20631 k[2] & 0xffffffff, k[3] & 0xffffffff);
20635 else if (GET_CODE (x) == CONST_DOUBLE &&
20636 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
20638 REAL_VALUE_TYPE rv;
20641 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20643 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20644 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
20646 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
20650 if (TARGET_MINIMAL_TOC)
20651 fputs (DOUBLE_INT_ASM_OP, file);
20653 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20654 k[0] & 0xffffffff, k[1] & 0xffffffff);
20655 fprintf (file, "0x%lx%08lx\n",
20656 k[0] & 0xffffffff, k[1] & 0xffffffff);
20661 if (TARGET_MINIMAL_TOC)
20662 fputs ("\t.long ", file);
20664 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20665 k[0] & 0xffffffff, k[1] & 0xffffffff);
20666 fprintf (file, "0x%lx,0x%lx\n",
20667 k[0] & 0xffffffff, k[1] & 0xffffffff);
20671 else if (GET_CODE (x) == CONST_DOUBLE &&
20672 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
20674 REAL_VALUE_TYPE rv;
20677 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20678 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20679 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
20681 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
20685 if (TARGET_MINIMAL_TOC)
20686 fputs (DOUBLE_INT_ASM_OP, file);
20688 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20689 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
20694 if (TARGET_MINIMAL_TOC)
20695 fputs ("\t.long ", file);
20697 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20698 fprintf (file, "0x%lx\n", l & 0xffffffff);
20702 else if (GET_MODE (x) == VOIDmode
20703 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
20705 unsigned HOST_WIDE_INT low;
20706 HOST_WIDE_INT high;
20708 if (GET_CODE (x) == CONST_DOUBLE)
20710 low = CONST_DOUBLE_LOW (x);
20711 high = CONST_DOUBLE_HIGH (x);
20714 #if HOST_BITS_PER_WIDE_INT == 32
20717 high = (low & 0x80000000) ? ~0 : 0;
20721 low = INTVAL (x) & 0xffffffff;
20722 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
20726 /* TOC entries are always Pmode-sized, but since this
20727 is a bigendian machine then if we're putting smaller
20728 integer constants in the TOC we have to pad them.
20729 (This is still a win over putting the constants in
20730 a separate constant pool, because then we'd have
20731 to have both a TOC entry _and_ the actual constant.)
20733 For a 32-bit target, CONST_INT values are loaded and shifted
20734 entirely within `low' and can be stored in one TOC entry. */
20736 /* It would be easy to make this work, but it doesn't now. */
20737 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
20739 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
20741 #if HOST_BITS_PER_WIDE_INT == 32
20742 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
20743 POINTER_SIZE, &low, &high, 0);
20746 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
20747 high = (HOST_WIDE_INT) low >> 32;
20754 if (TARGET_MINIMAL_TOC)
20755 fputs (DOUBLE_INT_ASM_OP, file);
20757 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
20758 (long) high & 0xffffffff, (long) low & 0xffffffff);
20759 fprintf (file, "0x%lx%08lx\n",
20760 (long) high & 0xffffffff, (long) low & 0xffffffff);
20765 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
20767 if (TARGET_MINIMAL_TOC)
20768 fputs ("\t.long ", file);
20770 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
20771 (long) high & 0xffffffff, (long) low & 0xffffffff);
20772 fprintf (file, "0x%lx,0x%lx\n",
20773 (long) high & 0xffffffff, (long) low & 0xffffffff);
20777 if (TARGET_MINIMAL_TOC)
20778 fputs ("\t.long ", file);
20780 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
20781 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
20787 if (GET_CODE (x) == CONST)
20789 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
20790 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
20792 base = XEXP (XEXP (x, 0), 0);
20793 offset = INTVAL (XEXP (XEXP (x, 0), 1));
20796 switch (GET_CODE (base))
20799 name = XSTR (base, 0);
20803 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
20804 CODE_LABEL_NUMBER (XEXP (base, 0)));
20808 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
20812 gcc_unreachable ();
20815 if (TARGET_MINIMAL_TOC)
20816 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
20819 fputs ("\t.tc ", file);
20820 RS6000_OUTPUT_BASENAME (file, name);
20823 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
20825 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
20827 fputs ("[TC],", file);
20830 /* Currently C++ toc references to vtables can be emitted before it
20831 is decided whether the vtable is public or private. If this is
20832 the case, then the linker will eventually complain that there is
20833 a TOC reference to an unknown section. Thus, for vtables only,
20834 we emit the TOC reference to reference the symbol and not the
20836 if (VTABLE_NAME_P (name))
20838 RS6000_OUTPUT_BASENAME (file, name);
20840 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
20841 else if (offset > 0)
20842 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
20845 output_addr_const (file, x);
20849 /* Output an assembler pseudo-op to write an ASCII string of N characters
20850 starting at P to FILE.
20852 On the RS/6000, we have to do this using the .byte operation and
20853 write out special characters outside the quoted string.
20854 Also, the assembler is broken; very long strings are truncated,
20855 so we must artificially break them up early. */
20858 output_ascii (FILE *file, const char *p, int n)
20861 int i, count_string;
20862 const char *for_string = "\t.byte \"";
20863 const char *for_decimal = "\t.byte ";
20864 const char *to_close = NULL;
20867 for (i = 0; i < n; i++)
20870 if (c >= ' ' && c < 0177)
20873 fputs (for_string, file);
20876 /* Write two quotes to get one. */
20884 for_decimal = "\"\n\t.byte ";
20888 if (count_string >= 512)
20890 fputs (to_close, file);
20892 for_string = "\t.byte \"";
20893 for_decimal = "\t.byte ";
20901 fputs (for_decimal, file);
20902 fprintf (file, "%d", c);
20904 for_string = "\n\t.byte \"";
20905 for_decimal = ", ";
20911 /* Now close the string if we have written one. Then end the line. */
20913 fputs (to_close, file);
20916 /* Generate a unique section name for FILENAME for a section type
20917 represented by SECTION_DESC. Output goes into BUF.
20919 SECTION_DESC can be any string, as long as it is different for each
20920 possible section type.
20922 We name the section in the same manner as xlc. The name begins with an
20923 underscore followed by the filename (after stripping any leading directory
20924 names) with the last period replaced by the string SECTION_DESC. If
20925 FILENAME does not contain a period, SECTION_DESC is appended to the end of
20929 rs6000_gen_section_name (char **buf, const char *filename,
20930 const char *section_desc)
20932 const char *q, *after_last_slash, *last_period = 0;
20936 after_last_slash = filename;
20937 for (q = filename; *q; q++)
20940 after_last_slash = q + 1;
20941 else if (*q == '.')
20945 len = strlen (after_last_slash) + strlen (section_desc) + 2;
20946 *buf = (char *) xmalloc (len);
20951 for (q = after_last_slash; *q; q++)
20953 if (q == last_period)
20955 strcpy (p, section_desc);
20956 p += strlen (section_desc);
20960 else if (ISALNUM (*q))
20964 if (last_period == 0)
20965 strcpy (p, section_desc);
20970 /* Emit profile function. */
20973 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
20975 /* Non-standard profiling for kernels, which just saves LR then calls
20976 _mcount without worrying about arg saves. The idea is to change
20977 the function prologue as little as possible as it isn't easy to
20978 account for arg save/restore code added just for _mcount. */
20979 if (TARGET_PROFILE_KERNEL)
20982 if (DEFAULT_ABI == ABI_AIX)
20984 #ifndef NO_PROFILE_COUNTERS
20985 # define NO_PROFILE_COUNTERS 0
20987 if (NO_PROFILE_COUNTERS)
20988 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
20989 LCT_NORMAL, VOIDmode, 0);
20993 const char *label_name;
20996 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
20997 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
20998 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21000 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21001 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21004 else if (DEFAULT_ABI == ABI_DARWIN)
21006 const char *mcount_name = RS6000_MCOUNT;
21007 int caller_addr_regno = LR_REGNO;
21009 /* Be conservative and always set this, at least for now. */
21010 crtl->uses_pic_offset_table = 1;
21013 /* For PIC code, set up a stub and collect the caller's address
21014 from r0, which is where the prologue puts it. */
21015 if (MACHOPIC_INDIRECT
21016 && crtl->uses_pic_offset_table)
21017 caller_addr_regno = 0;
21019 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21020 LCT_NORMAL, VOIDmode, 1,
21021 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21025 /* Write function profiler code. */
21028 output_function_profiler (FILE *file, int labelno)
21032 switch (DEFAULT_ABI)
21035 gcc_unreachable ();
21040 warning (0, "no profiling of 64-bit code for this ABI");
21043 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21044 fprintf (file, "\tmflr %s\n", reg_names[0]);
21045 if (NO_PROFILE_COUNTERS)
21047 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21048 reg_names[0], reg_names[1]);
21050 else if (TARGET_SECURE_PLT && flag_pic)
21052 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21053 reg_names[0], reg_names[1]);
21054 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21055 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21056 reg_names[12], reg_names[12]);
21057 assemble_name (file, buf);
21058 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21059 assemble_name (file, buf);
21060 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21062 else if (flag_pic == 1)
21064 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21065 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21066 reg_names[0], reg_names[1]);
21067 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21068 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
21069 assemble_name (file, buf);
21070 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
21072 else if (flag_pic > 1)
21074 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21075 reg_names[0], reg_names[1]);
21076 /* Now, we need to get the address of the label. */
21077 fputs ("\tbcl 20,31,1f\n\t.long ", file);
21078 assemble_name (file, buf);
21079 fputs ("-.\n1:", file);
21080 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
21081 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
21082 reg_names[0], reg_names[11]);
21083 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
21084 reg_names[0], reg_names[0], reg_names[11]);
21088 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
21089 assemble_name (file, buf);
21090 fputs ("@ha\n", file);
21091 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21092 reg_names[0], reg_names[1]);
21093 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
21094 assemble_name (file, buf);
21095 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
21098 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21099 fprintf (file, "\tbl %s%s\n",
21100 RS6000_MCOUNT, flag_pic ? "@plt" : "");
21105 if (!TARGET_PROFILE_KERNEL)
21107 /* Don't do anything, done in output_profile_hook (). */
21111 gcc_assert (!TARGET_32BIT);
21113 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
21114 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
21116 if (cfun->static_chain_decl != NULL)
21118 asm_fprintf (file, "\tstd %s,24(%s)\n",
21119 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21120 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21121 asm_fprintf (file, "\tld %s,24(%s)\n",
21122 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21125 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21133 /* The following variable value is the last issued insn. */
21135 static rtx last_scheduled_insn;
21137 /* The following variable helps to balance issuing of load and
21138 store instructions */
21140 static int load_store_pendulum;
21142 /* Power4 load update and store update instructions are cracked into a
21143 load or store and an integer insn which are executed in the same cycle.
21144 Branches have their own dispatch slot which does not count against the
21145 GCC issue rate, but it changes the program flow so there are no other
21146 instructions to issue in this cycle. */
21149 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
21150 int verbose ATTRIBUTE_UNUSED,
21151 rtx insn, int more)
21153 last_scheduled_insn = insn;
21154 if (GET_CODE (PATTERN (insn)) == USE
21155 || GET_CODE (PATTERN (insn)) == CLOBBER)
21157 cached_can_issue_more = more;
21158 return cached_can_issue_more;
21161 if (insn_terminates_group_p (insn, current_group))
21163 cached_can_issue_more = 0;
21164 return cached_can_issue_more;
21167 /* If no reservation, but reach here */
21168 if (recog_memoized (insn) < 0)
21171 if (rs6000_sched_groups)
21173 if (is_microcoded_insn (insn))
21174 cached_can_issue_more = 0;
21175 else if (is_cracked_insn (insn))
21176 cached_can_issue_more = more > 2 ? more - 2 : 0;
21178 cached_can_issue_more = more - 1;
21180 return cached_can_issue_more;
21183 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21186 cached_can_issue_more = more - 1;
21187 return cached_can_issue_more;
21190 /* Adjust the cost of a scheduling dependency. Return the new cost of
21191 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21194 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21196 enum attr_type attr_type;
21198 if (! recog_memoized (insn))
21201 switch (REG_NOTE_KIND (link))
21205 /* Data dependency; DEP_INSN writes a register that INSN reads
21206 some cycles later. */
21208 /* Separate a load from a narrower, dependent store. */
21209 if (rs6000_sched_groups
21210 && GET_CODE (PATTERN (insn)) == SET
21211 && GET_CODE (PATTERN (dep_insn)) == SET
21212 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21213 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21214 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21215 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21218 attr_type = get_attr_type (insn);
21223 /* Tell the first scheduling pass about the latency between
21224 a mtctr and bctr (and mtlr and br/blr). The first
21225 scheduling pass will not know about this latency since
21226 the mtctr instruction, which has the latency associated
21227 to it, will be generated by reload. */
21228 return TARGET_POWER ? 5 : 4;
21230 /* Leave some extra cycles between a compare and its
21231 dependent branch, to inhibit expensive mispredicts. */
21232 if ((rs6000_cpu_attr == CPU_PPC603
21233 || rs6000_cpu_attr == CPU_PPC604
21234 || rs6000_cpu_attr == CPU_PPC604E
21235 || rs6000_cpu_attr == CPU_PPC620
21236 || rs6000_cpu_attr == CPU_PPC630
21237 || rs6000_cpu_attr == CPU_PPC750
21238 || rs6000_cpu_attr == CPU_PPC7400
21239 || rs6000_cpu_attr == CPU_PPC7450
21240 || rs6000_cpu_attr == CPU_POWER4
21241 || rs6000_cpu_attr == CPU_POWER5
21242 || rs6000_cpu_attr == CPU_POWER7
21243 || rs6000_cpu_attr == CPU_CELL)
21244 && recog_memoized (dep_insn)
21245 && (INSN_CODE (dep_insn) >= 0))
21247 switch (get_attr_type (dep_insn))
21251 case TYPE_DELAYED_COMPARE:
21252 case TYPE_IMUL_COMPARE:
21253 case TYPE_LMUL_COMPARE:
21254 case TYPE_FPCOMPARE:
21255 case TYPE_CR_LOGICAL:
21256 case TYPE_DELAYED_CR:
21265 case TYPE_STORE_UX:
21267 case TYPE_FPSTORE_U:
21268 case TYPE_FPSTORE_UX:
21269 if ((rs6000_cpu == PROCESSOR_POWER6)
21270 && recog_memoized (dep_insn)
21271 && (INSN_CODE (dep_insn) >= 0))
21274 if (GET_CODE (PATTERN (insn)) != SET)
21275 /* If this happens, we have to extend this to schedule
21276 optimally. Return default for now. */
21279 /* Adjust the cost for the case where the value written
21280 by a fixed point operation is used as the address
21281 gen value on a store. */
21282 switch (get_attr_type (dep_insn))
21289 if (! store_data_bypass_p (dep_insn, insn))
21293 case TYPE_LOAD_EXT:
21294 case TYPE_LOAD_EXT_U:
21295 case TYPE_LOAD_EXT_UX:
21296 case TYPE_VAR_SHIFT_ROTATE:
21297 case TYPE_VAR_DELAYED_COMPARE:
21299 if (! store_data_bypass_p (dep_insn, insn))
21305 case TYPE_FAST_COMPARE:
21308 case TYPE_INSERT_WORD:
21309 case TYPE_INSERT_DWORD:
21310 case TYPE_FPLOAD_U:
21311 case TYPE_FPLOAD_UX:
21313 case TYPE_STORE_UX:
21314 case TYPE_FPSTORE_U:
21315 case TYPE_FPSTORE_UX:
21317 if (! store_data_bypass_p (dep_insn, insn))
21325 case TYPE_IMUL_COMPARE:
21326 case TYPE_LMUL_COMPARE:
21328 if (! store_data_bypass_p (dep_insn, insn))
21334 if (! store_data_bypass_p (dep_insn, insn))
21340 if (! store_data_bypass_p (dep_insn, insn))
21353 case TYPE_LOAD_EXT:
21354 case TYPE_LOAD_EXT_U:
21355 case TYPE_LOAD_EXT_UX:
21356 if ((rs6000_cpu == PROCESSOR_POWER6)
21357 && recog_memoized (dep_insn)
21358 && (INSN_CODE (dep_insn) >= 0))
21361 /* Adjust the cost for the case where the value written
21362 by a fixed point instruction is used within the address
21363 gen portion of a subsequent load(u)(x) */
21364 switch (get_attr_type (dep_insn))
21371 if (set_to_load_agen (dep_insn, insn))
21375 case TYPE_LOAD_EXT:
21376 case TYPE_LOAD_EXT_U:
21377 case TYPE_LOAD_EXT_UX:
21378 case TYPE_VAR_SHIFT_ROTATE:
21379 case TYPE_VAR_DELAYED_COMPARE:
21381 if (set_to_load_agen (dep_insn, insn))
21387 case TYPE_FAST_COMPARE:
21390 case TYPE_INSERT_WORD:
21391 case TYPE_INSERT_DWORD:
21392 case TYPE_FPLOAD_U:
21393 case TYPE_FPLOAD_UX:
21395 case TYPE_STORE_UX:
21396 case TYPE_FPSTORE_U:
21397 case TYPE_FPSTORE_UX:
21399 if (set_to_load_agen (dep_insn, insn))
21407 case TYPE_IMUL_COMPARE:
21408 case TYPE_LMUL_COMPARE:
21410 if (set_to_load_agen (dep_insn, insn))
21416 if (set_to_load_agen (dep_insn, insn))
21422 if (set_to_load_agen (dep_insn, insn))
21433 if ((rs6000_cpu == PROCESSOR_POWER6)
21434 && recog_memoized (dep_insn)
21435 && (INSN_CODE (dep_insn) >= 0)
21436 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
21443 /* Fall out to return default cost. */
21447 case REG_DEP_OUTPUT:
21448 /* Output dependency; DEP_INSN writes a register that INSN writes some
21450 if ((rs6000_cpu == PROCESSOR_POWER6)
21451 && recog_memoized (dep_insn)
21452 && (INSN_CODE (dep_insn) >= 0))
21454 attr_type = get_attr_type (insn);
21459 if (get_attr_type (dep_insn) == TYPE_FP)
21463 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
21471 /* Anti dependency; DEP_INSN reads a register that INSN writes some
21476 gcc_unreachable ();
21482 /* Debug version of rs6000_adjust_cost. */
21485 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21487 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
21493 switch (REG_NOTE_KIND (link))
21495 default: dep = "unknown depencency"; break;
21496 case REG_DEP_TRUE: dep = "data dependency"; break;
21497 case REG_DEP_OUTPUT: dep = "output dependency"; break;
21498 case REG_DEP_ANTI: dep = "anti depencency"; break;
21502 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
21503 "%s, insn:\n", ret, cost, dep);
21511 /* The function returns a true if INSN is microcoded.
21512 Return false otherwise. */
21515 is_microcoded_insn (rtx insn)
21517 if (!insn || !NONDEBUG_INSN_P (insn)
21518 || GET_CODE (PATTERN (insn)) == USE
21519 || GET_CODE (PATTERN (insn)) == CLOBBER)
21522 if (rs6000_cpu_attr == CPU_CELL)
21523 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
21525 if (rs6000_sched_groups)
21527 enum attr_type type = get_attr_type (insn);
21528 if (type == TYPE_LOAD_EXT_U
21529 || type == TYPE_LOAD_EXT_UX
21530 || type == TYPE_LOAD_UX
21531 || type == TYPE_STORE_UX
21532 || type == TYPE_MFCR)
21539 /* The function returns true if INSN is cracked into 2 instructions
21540 by the processor (and therefore occupies 2 issue slots). */
21543 is_cracked_insn (rtx insn)
21545 if (!insn || !NONDEBUG_INSN_P (insn)
21546 || GET_CODE (PATTERN (insn)) == USE
21547 || GET_CODE (PATTERN (insn)) == CLOBBER)
21550 if (rs6000_sched_groups)
21552 enum attr_type type = get_attr_type (insn);
21553 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
21554 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
21555 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
21556 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
21557 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
21558 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
21559 || type == TYPE_IDIV || type == TYPE_LDIV
21560 || type == TYPE_INSERT_WORD)
21567 /* The function returns true if INSN can be issued only from
21568 the branch slot. */
21571 is_branch_slot_insn (rtx insn)
21573 if (!insn || !NONDEBUG_INSN_P (insn)
21574 || GET_CODE (PATTERN (insn)) == USE
21575 || GET_CODE (PATTERN (insn)) == CLOBBER)
21578 if (rs6000_sched_groups)
21580 enum attr_type type = get_attr_type (insn);
21581 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
21589 /* The function returns true if out_inst sets a value that is
21590 used in the address generation computation of in_insn */
21592 set_to_load_agen (rtx out_insn, rtx in_insn)
21594 rtx out_set, in_set;
21596 /* For performance reasons, only handle the simple case where
21597 both loads are a single_set. */
21598 out_set = single_set (out_insn);
21601 in_set = single_set (in_insn);
21603 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
21609 /* The function returns true if the target storage location of
21610 out_insn is adjacent to the target storage location of in_insn */
21611 /* Return 1 if memory locations are adjacent. */
21614 adjacent_mem_locations (rtx insn1, rtx insn2)
21617 rtx a = get_store_dest (PATTERN (insn1));
21618 rtx b = get_store_dest (PATTERN (insn2));
21620 if ((GET_CODE (XEXP (a, 0)) == REG
21621 || (GET_CODE (XEXP (a, 0)) == PLUS
21622 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
21623 && (GET_CODE (XEXP (b, 0)) == REG
21624 || (GET_CODE (XEXP (b, 0)) == PLUS
21625 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
21627 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
21630 if (GET_CODE (XEXP (a, 0)) == PLUS)
21632 reg0 = XEXP (XEXP (a, 0), 0);
21633 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
21636 reg0 = XEXP (a, 0);
21638 if (GET_CODE (XEXP (b, 0)) == PLUS)
21640 reg1 = XEXP (XEXP (b, 0), 0);
21641 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
21644 reg1 = XEXP (b, 0);
21646 val_diff = val1 - val0;
21648 return ((REGNO (reg0) == REGNO (reg1))
21649 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
21650 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
21656 /* A C statement (sans semicolon) to update the integer scheduling
21657 priority INSN_PRIORITY (INSN). Increase the priority to execute the
21658 INSN earlier, reduce the priority to execute INSN later. Do not
21659 define this macro if you do not need to adjust the scheduling
21660 priorities of insns. */
21663 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
21665 /* On machines (like the 750) which have asymmetric integer units,
21666 where one integer unit can do multiply and divides and the other
21667 can't, reduce the priority of multiply/divide so it is scheduled
21668 before other integer operations. */
21671 if (! INSN_P (insn))
21674 if (GET_CODE (PATTERN (insn)) == USE)
21677 switch (rs6000_cpu_attr) {
21679 switch (get_attr_type (insn))
21686 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
21687 priority, priority);
21688 if (priority >= 0 && priority < 0x01000000)
21695 if (insn_must_be_first_in_group (insn)
21696 && reload_completed
21697 && current_sched_info->sched_max_insns_priority
21698 && rs6000_sched_restricted_insns_priority)
21701 /* Prioritize insns that can be dispatched only in the first
21703 if (rs6000_sched_restricted_insns_priority == 1)
21704 /* Attach highest priority to insn. This means that in
21705 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
21706 precede 'priority' (critical path) considerations. */
21707 return current_sched_info->sched_max_insns_priority;
21708 else if (rs6000_sched_restricted_insns_priority == 2)
21709 /* Increase priority of insn by a minimal amount. This means that in
21710 haifa-sched.c:ready_sort(), only 'priority' (critical path)
21711 considerations precede dispatch-slot restriction considerations. */
21712 return (priority + 1);
21715 if (rs6000_cpu == PROCESSOR_POWER6
21716 && ((load_store_pendulum == -2 && is_load_insn (insn))
21717 || (load_store_pendulum == 2 && is_store_insn (insn))))
21718 /* Attach highest priority to insn if the scheduler has just issued two
21719 stores and this instruction is a load, or two loads and this instruction
21720 is a store. Power6 wants loads and stores scheduled alternately
21722 return current_sched_info->sched_max_insns_priority;
21727 /* Return true if the instruction is nonpipelined on the Cell. */
21729 is_nonpipeline_insn (rtx insn)
21731 enum attr_type type;
21732 if (!insn || !NONDEBUG_INSN_P (insn)
21733 || GET_CODE (PATTERN (insn)) == USE
21734 || GET_CODE (PATTERN (insn)) == CLOBBER)
21737 type = get_attr_type (insn);
21738 if (type == TYPE_IMUL
21739 || type == TYPE_IMUL2
21740 || type == TYPE_IMUL3
21741 || type == TYPE_LMUL
21742 || type == TYPE_IDIV
21743 || type == TYPE_LDIV
21744 || type == TYPE_SDIV
21745 || type == TYPE_DDIV
21746 || type == TYPE_SSQRT
21747 || type == TYPE_DSQRT
21748 || type == TYPE_MFCR
21749 || type == TYPE_MFCRF
21750 || type == TYPE_MFJMPR)
21758 /* Return how many instructions the machine can issue per cycle. */
21761 rs6000_issue_rate (void)
21763 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
21764 if (!reload_completed)
21767 switch (rs6000_cpu_attr) {
21768 case CPU_RIOS1: /* ? */
21770 case CPU_PPC601: /* ? */
21779 case CPU_PPCE300C2:
21780 case CPU_PPCE300C3:
21781 case CPU_PPCE500MC:
21799 /* Return how many instructions to look ahead for better insn
21803 rs6000_use_sched_lookahead (void)
21805 if (rs6000_cpu_attr == CPU_PPC8540)
21807 if (rs6000_cpu_attr == CPU_CELL)
21808 return (reload_completed ? 8 : 0);
21812 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
21814 rs6000_use_sched_lookahead_guard (rtx insn)
21816 if (rs6000_cpu_attr != CPU_CELL)
21819 if (insn == NULL_RTX || !INSN_P (insn))
21822 if (!reload_completed
21823 || is_nonpipeline_insn (insn)
21824 || is_microcoded_insn (insn))
21830 /* Determine is PAT refers to memory. */
21833 is_mem_ref (rtx pat)
21839 /* stack_tie does not produce any real memory traffic. */
21840 if (GET_CODE (pat) == UNSPEC
21841 && XINT (pat, 1) == UNSPEC_TIE)
21844 if (GET_CODE (pat) == MEM)
21847 /* Recursively process the pattern. */
21848 fmt = GET_RTX_FORMAT (GET_CODE (pat));
21850 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
21853 ret |= is_mem_ref (XEXP (pat, i));
21854 else if (fmt[i] == 'E')
21855 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
21856 ret |= is_mem_ref (XVECEXP (pat, i, j));
21862 /* Determine if PAT is a PATTERN of a load insn. */
21865 is_load_insn1 (rtx pat)
21867 if (!pat || pat == NULL_RTX)
21870 if (GET_CODE (pat) == SET)
21871 return is_mem_ref (SET_SRC (pat));
21873 if (GET_CODE (pat) == PARALLEL)
21877 for (i = 0; i < XVECLEN (pat, 0); i++)
21878 if (is_load_insn1 (XVECEXP (pat, 0, i)))
21885 /* Determine if INSN loads from memory. */
21888 is_load_insn (rtx insn)
21890 if (!insn || !INSN_P (insn))
21893 if (GET_CODE (insn) == CALL_INSN)
21896 return is_load_insn1 (PATTERN (insn));
21899 /* Determine if PAT is a PATTERN of a store insn. */
21902 is_store_insn1 (rtx pat)
21904 if (!pat || pat == NULL_RTX)
21907 if (GET_CODE (pat) == SET)
21908 return is_mem_ref (SET_DEST (pat));
21910 if (GET_CODE (pat) == PARALLEL)
21914 for (i = 0; i < XVECLEN (pat, 0); i++)
21915 if (is_store_insn1 (XVECEXP (pat, 0, i)))
21922 /* Determine if INSN stores to memory. */
21925 is_store_insn (rtx insn)
21927 if (!insn || !INSN_P (insn))
21930 return is_store_insn1 (PATTERN (insn));
21933 /* Return the dest of a store insn. */
21936 get_store_dest (rtx pat)
21938 gcc_assert (is_store_insn1 (pat));
21940 if (GET_CODE (pat) == SET)
21941 return SET_DEST (pat);
21942 else if (GET_CODE (pat) == PARALLEL)
21946 for (i = 0; i < XVECLEN (pat, 0); i++)
21948 rtx inner_pat = XVECEXP (pat, 0, i);
21949 if (GET_CODE (inner_pat) == SET
21950 && is_mem_ref (SET_DEST (inner_pat)))
21954 /* We shouldn't get here, because we should have either a simple
21955 store insn or a store with update which are covered above. */
21959 /* Returns whether the dependence between INSN and NEXT is considered
21960 costly by the given target. */
21963 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
21968 /* If the flag is not enabled - no dependence is considered costly;
21969 allow all dependent insns in the same group.
21970 This is the most aggressive option. */
21971 if (rs6000_sched_costly_dep == no_dep_costly)
21974 /* If the flag is set to 1 - a dependence is always considered costly;
21975 do not allow dependent instructions in the same group.
21976 This is the most conservative option. */
21977 if (rs6000_sched_costly_dep == all_deps_costly)
21980 insn = DEP_PRO (dep);
21981 next = DEP_CON (dep);
21983 if (rs6000_sched_costly_dep == store_to_load_dep_costly
21984 && is_load_insn (next)
21985 && is_store_insn (insn))
21986 /* Prevent load after store in the same group. */
21989 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
21990 && is_load_insn (next)
21991 && is_store_insn (insn)
21992 && DEP_TYPE (dep) == REG_DEP_TRUE)
21993 /* Prevent load after store in the same group if it is a true
21997 /* The flag is set to X; dependences with latency >= X are considered costly,
21998 and will not be scheduled in the same group. */
21999 if (rs6000_sched_costly_dep <= max_dep_latency
22000 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22006 /* Return the next insn after INSN that is found before TAIL is reached,
22007 skipping any "non-active" insns - insns that will not actually occupy
22008 an issue slot. Return NULL_RTX if such an insn is not found. */
22011 get_next_active_insn (rtx insn, rtx tail)
22013 if (insn == NULL_RTX || insn == tail)
22018 insn = NEXT_INSN (insn);
22019 if (insn == NULL_RTX || insn == tail)
22024 || (NONJUMP_INSN_P (insn)
22025 && GET_CODE (PATTERN (insn)) != USE
22026 && GET_CODE (PATTERN (insn)) != CLOBBER
22027 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22033 /* We are about to begin issuing insns for this clock cycle. */
22036 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22037 rtx *ready ATTRIBUTE_UNUSED,
22038 int *pn_ready ATTRIBUTE_UNUSED,
22039 int clock_var ATTRIBUTE_UNUSED)
22041 int n_ready = *pn_ready;
22044 fprintf (dump, "// rs6000_sched_reorder :\n");
22046 /* Reorder the ready list, if the second to last ready insn
22047 is a nonepipeline insn. */
22048 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22050 if (is_nonpipeline_insn (ready[n_ready - 1])
22051 && (recog_memoized (ready[n_ready - 2]) > 0))
22052 /* Simply swap first two insns. */
22054 rtx tmp = ready[n_ready - 1];
22055 ready[n_ready - 1] = ready[n_ready - 2];
22056 ready[n_ready - 2] = tmp;
22060 if (rs6000_cpu == PROCESSOR_POWER6)
22061 load_store_pendulum = 0;
22063 return rs6000_issue_rate ();
22066 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22069 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
22070 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
22073 fprintf (dump, "// rs6000_sched_reorder2 :\n");
22075 /* For Power6, we need to handle some special cases to try and keep the
22076 store queue from overflowing and triggering expensive flushes.
22078 This code monitors how load and store instructions are being issued
22079 and skews the ready list one way or the other to increase the likelihood
22080 that a desired instruction is issued at the proper time.
22082 A couple of things are done. First, we maintain a "load_store_pendulum"
22083 to track the current state of load/store issue.
22085 - If the pendulum is at zero, then no loads or stores have been
22086 issued in the current cycle so we do nothing.
22088 - If the pendulum is 1, then a single load has been issued in this
22089 cycle and we attempt to locate another load in the ready list to
22092 - If the pendulum is -2, then two stores have already been
22093 issued in this cycle, so we increase the priority of the first load
22094 in the ready list to increase it's likelihood of being chosen first
22097 - If the pendulum is -1, then a single store has been issued in this
22098 cycle and we attempt to locate another store in the ready list to
22099 issue with it, preferring a store to an adjacent memory location to
22100 facilitate store pairing in the store queue.
22102 - If the pendulum is 2, then two loads have already been
22103 issued in this cycle, so we increase the priority of the first store
22104 in the ready list to increase it's likelihood of being chosen first
22107 - If the pendulum < -2 or > 2, then do nothing.
22109 Note: This code covers the most common scenarios. There exist non
22110 load/store instructions which make use of the LSU and which
22111 would need to be accounted for to strictly model the behavior
22112 of the machine. Those instructions are currently unaccounted
22113 for to help minimize compile time overhead of this code.
22115 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
22121 if (is_store_insn (last_scheduled_insn))
22122 /* Issuing a store, swing the load_store_pendulum to the left */
22123 load_store_pendulum--;
22124 else if (is_load_insn (last_scheduled_insn))
22125 /* Issuing a load, swing the load_store_pendulum to the right */
22126 load_store_pendulum++;
22128 return cached_can_issue_more;
22130 /* If the pendulum is balanced, or there is only one instruction on
22131 the ready list, then all is well, so return. */
22132 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
22133 return cached_can_issue_more;
22135 if (load_store_pendulum == 1)
22137 /* A load has been issued in this cycle. Scan the ready list
22138 for another load to issue with it */
22143 if (is_load_insn (ready[pos]))
22145 /* Found a load. Move it to the head of the ready list,
22146 and adjust it's priority so that it is more likely to
22149 for (i=pos; i<*pn_ready-1; i++)
22150 ready[i] = ready[i + 1];
22151 ready[*pn_ready-1] = tmp;
22153 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22154 INSN_PRIORITY (tmp)++;
22160 else if (load_store_pendulum == -2)
22162 /* Two stores have been issued in this cycle. Increase the
22163 priority of the first load in the ready list to favor it for
22164 issuing in the next cycle. */
22169 if (is_load_insn (ready[pos])
22171 && INSN_PRIORITY_KNOWN (ready[pos]))
22173 INSN_PRIORITY (ready[pos])++;
22175 /* Adjust the pendulum to account for the fact that a load
22176 was found and increased in priority. This is to prevent
22177 increasing the priority of multiple loads */
22178 load_store_pendulum--;
22185 else if (load_store_pendulum == -1)
22187 /* A store has been issued in this cycle. Scan the ready list for
22188 another store to issue with it, preferring a store to an adjacent
22190 int first_store_pos = -1;
22196 if (is_store_insn (ready[pos]))
22198 /* Maintain the index of the first store found on the
22200 if (first_store_pos == -1)
22201 first_store_pos = pos;
22203 if (is_store_insn (last_scheduled_insn)
22204 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22206 /* Found an adjacent store. Move it to the head of the
22207 ready list, and adjust it's priority so that it is
22208 more likely to stay there */
22210 for (i=pos; i<*pn_ready-1; i++)
22211 ready[i] = ready[i + 1];
22212 ready[*pn_ready-1] = tmp;
22214 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22215 INSN_PRIORITY (tmp)++;
22217 first_store_pos = -1;
22225 if (first_store_pos >= 0)
22227 /* An adjacent store wasn't found, but a non-adjacent store was,
22228 so move the non-adjacent store to the front of the ready
22229 list, and adjust its priority so that it is more likely to
22231 tmp = ready[first_store_pos];
22232 for (i=first_store_pos; i<*pn_ready-1; i++)
22233 ready[i] = ready[i + 1];
22234 ready[*pn_ready-1] = tmp;
22235 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22236 INSN_PRIORITY (tmp)++;
22239 else if (load_store_pendulum == 2)
22241 /* Two loads have been issued in this cycle. Increase the priority
22242 of the first store in the ready list to favor it for issuing in
22248 if (is_store_insn (ready[pos])
22250 && INSN_PRIORITY_KNOWN (ready[pos]))
22252 INSN_PRIORITY (ready[pos])++;
22254 /* Adjust the pendulum to account for the fact that a store
22255 was found and increased in priority. This is to prevent
22256 increasing the priority of multiple stores */
22257 load_store_pendulum++;
22266 return cached_can_issue_more;
22269 /* Return whether the presence of INSN causes a dispatch group termination
22270 of group WHICH_GROUP.
22272 If WHICH_GROUP == current_group, this function will return true if INSN
22273 causes the termination of the current group (i.e, the dispatch group to
22274 which INSN belongs). This means that INSN will be the last insn in the
22275 group it belongs to.
22277 If WHICH_GROUP == previous_group, this function will return true if INSN
22278 causes the termination of the previous group (i.e, the dispatch group that
22279 precedes the group to which INSN belongs). This means that INSN will be
22280 the first insn in the group it belongs to). */
22283 insn_terminates_group_p (rtx insn, enum group_termination which_group)
22290 first = insn_must_be_first_in_group (insn);
22291 last = insn_must_be_last_in_group (insn);
22296 if (which_group == current_group)
22298 else if (which_group == previous_group)
22306 insn_must_be_first_in_group (rtx insn)
22308 enum attr_type type;
22311 || GET_CODE (insn) == NOTE
22312 || DEBUG_INSN_P (insn)
22313 || GET_CODE (PATTERN (insn)) == USE
22314 || GET_CODE (PATTERN (insn)) == CLOBBER)
22317 switch (rs6000_cpu)
22319 case PROCESSOR_POWER5:
22320 if (is_cracked_insn (insn))
22322 case PROCESSOR_POWER4:
22323 if (is_microcoded_insn (insn))
22326 if (!rs6000_sched_groups)
22329 type = get_attr_type (insn);
22336 case TYPE_DELAYED_CR:
22337 case TYPE_CR_LOGICAL:
22351 case PROCESSOR_POWER6:
22352 type = get_attr_type (insn);
22356 case TYPE_INSERT_DWORD:
22360 case TYPE_VAR_SHIFT_ROTATE:
22367 case TYPE_INSERT_WORD:
22368 case TYPE_DELAYED_COMPARE:
22369 case TYPE_IMUL_COMPARE:
22370 case TYPE_LMUL_COMPARE:
22371 case TYPE_FPCOMPARE:
22382 case TYPE_LOAD_EXT_UX:
22384 case TYPE_STORE_UX:
22385 case TYPE_FPLOAD_U:
22386 case TYPE_FPLOAD_UX:
22387 case TYPE_FPSTORE_U:
22388 case TYPE_FPSTORE_UX:
22394 case PROCESSOR_POWER7:
22395 type = get_attr_type (insn);
22399 case TYPE_CR_LOGICAL:
22406 case TYPE_DELAYED_COMPARE:
22407 case TYPE_VAR_DELAYED_COMPARE:
22413 case TYPE_LOAD_EXT:
22414 case TYPE_LOAD_EXT_U:
22415 case TYPE_LOAD_EXT_UX:
22417 case TYPE_STORE_UX:
22418 case TYPE_FPLOAD_U:
22419 case TYPE_FPLOAD_UX:
22420 case TYPE_FPSTORE_U:
22421 case TYPE_FPSTORE_UX:
22437 insn_must_be_last_in_group (rtx insn)
22439 enum attr_type type;
22442 || GET_CODE (insn) == NOTE
22443 || DEBUG_INSN_P (insn)
22444 || GET_CODE (PATTERN (insn)) == USE
22445 || GET_CODE (PATTERN (insn)) == CLOBBER)
22448 switch (rs6000_cpu) {
22449 case PROCESSOR_POWER4:
22450 case PROCESSOR_POWER5:
22451 if (is_microcoded_insn (insn))
22454 if (is_branch_slot_insn (insn))
22458 case PROCESSOR_POWER6:
22459 type = get_attr_type (insn);
22466 case TYPE_VAR_SHIFT_ROTATE:
22473 case TYPE_DELAYED_COMPARE:
22474 case TYPE_IMUL_COMPARE:
22475 case TYPE_LMUL_COMPARE:
22476 case TYPE_FPCOMPARE:
22490 case PROCESSOR_POWER7:
22491 type = get_attr_type (insn);
22499 case TYPE_LOAD_EXT_U:
22500 case TYPE_LOAD_EXT_UX:
22501 case TYPE_STORE_UX:
22514 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
22515 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
22518 is_costly_group (rtx *group_insns, rtx next_insn)
22521 int issue_rate = rs6000_issue_rate ();
22523 for (i = 0; i < issue_rate; i++)
22525 sd_iterator_def sd_it;
22527 rtx insn = group_insns[i];
22532 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
22534 rtx next = DEP_CON (dep);
22536 if (next == next_insn
22537 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
22545 /* Utility of the function redefine_groups.
22546 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
22547 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
22548 to keep it "far" (in a separate group) from GROUP_INSNS, following
22549 one of the following schemes, depending on the value of the flag
22550 -minsert_sched_nops = X:
22551 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
22552 in order to force NEXT_INSN into a separate group.
22553 (2) X < sched_finish_regroup_exact: insert exactly X nops.
22554 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
22555 insertion (has a group just ended, how many vacant issue slots remain in the
22556 last group, and how many dispatch groups were encountered so far). */
22559 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
22560 rtx next_insn, bool *group_end, int can_issue_more,
22565 int issue_rate = rs6000_issue_rate ();
22566 bool end = *group_end;
22569 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
22570 return can_issue_more;
22572 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
22573 return can_issue_more;
22575 force = is_costly_group (group_insns, next_insn);
22577 return can_issue_more;
22579 if (sched_verbose > 6)
22580 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
22581 *group_count ,can_issue_more);
22583 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
22586 can_issue_more = 0;
22588 /* Since only a branch can be issued in the last issue_slot, it is
22589 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
22590 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
22591 in this case the last nop will start a new group and the branch
22592 will be forced to the new group. */
22593 if (can_issue_more && !is_branch_slot_insn (next_insn))
22596 while (can_issue_more > 0)
22599 emit_insn_before (nop, next_insn);
22607 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
22609 int n_nops = rs6000_sched_insert_nops;
22611 /* Nops can't be issued from the branch slot, so the effective
22612 issue_rate for nops is 'issue_rate - 1'. */
22613 if (can_issue_more == 0)
22614 can_issue_more = issue_rate;
22616 if (can_issue_more == 0)
22618 can_issue_more = issue_rate - 1;
22621 for (i = 0; i < issue_rate; i++)
22623 group_insns[i] = 0;
22630 emit_insn_before (nop, next_insn);
22631 if (can_issue_more == issue_rate - 1) /* new group begins */
22634 if (can_issue_more == 0)
22636 can_issue_more = issue_rate - 1;
22639 for (i = 0; i < issue_rate; i++)
22641 group_insns[i] = 0;
22647 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
22650 /* Is next_insn going to start a new group? */
22653 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22654 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22655 || (can_issue_more < issue_rate &&
22656 insn_terminates_group_p (next_insn, previous_group)));
22657 if (*group_end && end)
22660 if (sched_verbose > 6)
22661 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
22662 *group_count, can_issue_more);
22663 return can_issue_more;
22666 return can_issue_more;
22669 /* This function tries to synch the dispatch groups that the compiler "sees"
22670 with the dispatch groups that the processor dispatcher is expected to
22671 form in practice. It tries to achieve this synchronization by forcing the
22672 estimated processor grouping on the compiler (as opposed to the function
22673 'pad_goups' which tries to force the scheduler's grouping on the processor).
22675 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
22676 examines the (estimated) dispatch groups that will be formed by the processor
22677 dispatcher. It marks these group boundaries to reflect the estimated
22678 processor grouping, overriding the grouping that the scheduler had marked.
22679 Depending on the value of the flag '-minsert-sched-nops' this function can
22680 force certain insns into separate groups or force a certain distance between
22681 them by inserting nops, for example, if there exists a "costly dependence"
22684 The function estimates the group boundaries that the processor will form as
22685 follows: It keeps track of how many vacant issue slots are available after
22686 each insn. A subsequent insn will start a new group if one of the following
22688 - no more vacant issue slots remain in the current dispatch group.
22689 - only the last issue slot, which is the branch slot, is vacant, but the next
22690 insn is not a branch.
22691 - only the last 2 or less issue slots, including the branch slot, are vacant,
22692 which means that a cracked insn (which occupies two issue slots) can't be
22693 issued in this group.
22694 - less than 'issue_rate' slots are vacant, and the next insn always needs to
22695 start a new group. */
22698 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22700 rtx insn, next_insn;
22702 int can_issue_more;
22705 int group_count = 0;
22709 issue_rate = rs6000_issue_rate ();
22710 group_insns = XALLOCAVEC (rtx, issue_rate);
22711 for (i = 0; i < issue_rate; i++)
22713 group_insns[i] = 0;
22715 can_issue_more = issue_rate;
22717 insn = get_next_active_insn (prev_head_insn, tail);
22720 while (insn != NULL_RTX)
22722 slot = (issue_rate - can_issue_more);
22723 group_insns[slot] = insn;
22725 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
22726 if (insn_terminates_group_p (insn, current_group))
22727 can_issue_more = 0;
22729 next_insn = get_next_active_insn (insn, tail);
22730 if (next_insn == NULL_RTX)
22731 return group_count + 1;
22733 /* Is next_insn going to start a new group? */
22735 = (can_issue_more == 0
22736 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22737 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22738 || (can_issue_more < issue_rate &&
22739 insn_terminates_group_p (next_insn, previous_group)));
22741 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
22742 next_insn, &group_end, can_issue_more,
22748 can_issue_more = 0;
22749 for (i = 0; i < issue_rate; i++)
22751 group_insns[i] = 0;
22755 if (GET_MODE (next_insn) == TImode && can_issue_more)
22756 PUT_MODE (next_insn, VOIDmode);
22757 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
22758 PUT_MODE (next_insn, TImode);
22761 if (can_issue_more == 0)
22762 can_issue_more = issue_rate;
22765 return group_count;
22768 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
22769 dispatch group boundaries that the scheduler had marked. Pad with nops
22770 any dispatch groups which have vacant issue slots, in order to force the
22771 scheduler's grouping on the processor dispatcher. The function
22772 returns the number of dispatch groups found. */
22775 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22777 rtx insn, next_insn;
22780 int can_issue_more;
22782 int group_count = 0;
22784 /* Initialize issue_rate. */
22785 issue_rate = rs6000_issue_rate ();
22786 can_issue_more = issue_rate;
22788 insn = get_next_active_insn (prev_head_insn, tail);
22789 next_insn = get_next_active_insn (insn, tail);
22791 while (insn != NULL_RTX)
22794 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
22796 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
22798 if (next_insn == NULL_RTX)
22803 /* If the scheduler had marked group termination at this location
22804 (between insn and next_insn), and neither insn nor next_insn will
22805 force group termination, pad the group with nops to force group
22808 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
22809 && !insn_terminates_group_p (insn, current_group)
22810 && !insn_terminates_group_p (next_insn, previous_group))
22812 if (!is_branch_slot_insn (next_insn))
22815 while (can_issue_more)
22818 emit_insn_before (nop, next_insn);
22823 can_issue_more = issue_rate;
22828 next_insn = get_next_active_insn (insn, tail);
22831 return group_count;
22834 /* We're beginning a new block. Initialize data structures as necessary. */
22837 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
22838 int sched_verbose ATTRIBUTE_UNUSED,
22839 int max_ready ATTRIBUTE_UNUSED)
22841 last_scheduled_insn = NULL_RTX;
22842 load_store_pendulum = 0;
22845 /* The following function is called at the end of scheduling BB.
22846 After reload, it inserts nops at insn group bundling. */
22849 rs6000_sched_finish (FILE *dump, int sched_verbose)
22854 fprintf (dump, "=== Finishing schedule.\n");
22856 if (reload_completed && rs6000_sched_groups)
22858 /* Do not run sched_finish hook when selective scheduling enabled. */
22859 if (sel_sched_p ())
22862 if (rs6000_sched_insert_nops == sched_finish_none)
22865 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
22866 n_groups = pad_groups (dump, sched_verbose,
22867 current_sched_info->prev_head,
22868 current_sched_info->next_tail);
22870 n_groups = redefine_groups (dump, sched_verbose,
22871 current_sched_info->prev_head,
22872 current_sched_info->next_tail);
22874 if (sched_verbose >= 6)
22876 fprintf (dump, "ngroups = %d\n", n_groups);
22877 print_rtl (dump, current_sched_info->prev_head);
22878 fprintf (dump, "Done finish_sched\n");
22883 struct _rs6000_sched_context
22885 short cached_can_issue_more;
22886 rtx last_scheduled_insn;
22887 int load_store_pendulum;
22890 typedef struct _rs6000_sched_context rs6000_sched_context_def;
22891 typedef rs6000_sched_context_def *rs6000_sched_context_t;
22893 /* Allocate store for new scheduling context. */
22895 rs6000_alloc_sched_context (void)
22897 return xmalloc (sizeof (rs6000_sched_context_def));
22900 /* If CLEAN_P is true then initializes _SC with clean data,
22901 and from the global context otherwise. */
22903 rs6000_init_sched_context (void *_sc, bool clean_p)
22905 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
22909 sc->cached_can_issue_more = 0;
22910 sc->last_scheduled_insn = NULL_RTX;
22911 sc->load_store_pendulum = 0;
22915 sc->cached_can_issue_more = cached_can_issue_more;
22916 sc->last_scheduled_insn = last_scheduled_insn;
22917 sc->load_store_pendulum = load_store_pendulum;
22921 /* Sets the global scheduling context to the one pointed to by _SC. */
22923 rs6000_set_sched_context (void *_sc)
22925 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
22927 gcc_assert (sc != NULL);
22929 cached_can_issue_more = sc->cached_can_issue_more;
22930 last_scheduled_insn = sc->last_scheduled_insn;
22931 load_store_pendulum = sc->load_store_pendulum;
22936 rs6000_free_sched_context (void *_sc)
22938 gcc_assert (_sc != NULL);
22944 /* Length in units of the trampoline for entering a nested function. */
22947 rs6000_trampoline_size (void)
22951 switch (DEFAULT_ABI)
22954 gcc_unreachable ();
22957 ret = (TARGET_32BIT) ? 12 : 24;
22962 ret = (TARGET_32BIT) ? 40 : 48;
22969 /* Emit RTL insns to initialize the variable parts of a trampoline.
22970 FNADDR is an RTX for the address of the function's pure code.
22971 CXT is an RTX for the static chain value for the function. */
22974 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
22976 int regsize = (TARGET_32BIT) ? 4 : 8;
22977 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
22978 rtx ctx_reg = force_reg (Pmode, cxt);
22979 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
22981 switch (DEFAULT_ABI)
22984 gcc_unreachable ();
22986 /* Under AIX, just build the 3 word function descriptor */
22989 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
22990 rtx fn_reg = gen_reg_rtx (Pmode);
22991 rtx toc_reg = gen_reg_rtx (Pmode);
22993 /* Macro to shorten the code expansions below. */
22994 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
22996 m_tramp = replace_equiv_address (m_tramp, addr);
22998 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
22999 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23000 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23001 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23002 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23008 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23011 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23012 LCT_NORMAL, VOIDmode, 4,
23014 GEN_INT (rs6000_trampoline_size ()), SImode,
23022 /* Handle the "altivec" attribute. The attribute may have
23023 arguments as follows:
23025 __attribute__((altivec(vector__)))
23026 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23027 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23029 and may appear more than once (e.g., 'vector bool char') in a
23030 given declaration. */
23033 rs6000_handle_altivec_attribute (tree *node,
23034 tree name ATTRIBUTE_UNUSED,
23036 int flags ATTRIBUTE_UNUSED,
23037 bool *no_add_attrs)
23039 tree type = *node, result = NULL_TREE;
23040 enum machine_mode mode;
23043 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23044 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23045 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23048 while (POINTER_TYPE_P (type)
23049 || TREE_CODE (type) == FUNCTION_TYPE
23050 || TREE_CODE (type) == METHOD_TYPE
23051 || TREE_CODE (type) == ARRAY_TYPE)
23052 type = TREE_TYPE (type);
23054 mode = TYPE_MODE (type);
23056 /* Check for invalid AltiVec type qualifiers. */
23057 if (type == long_double_type_node)
23058 error ("use of %<long double%> in AltiVec types is invalid");
23059 else if (type == boolean_type_node)
23060 error ("use of boolean types in AltiVec types is invalid");
23061 else if (TREE_CODE (type) == COMPLEX_TYPE)
23062 error ("use of %<complex%> in AltiVec types is invalid");
23063 else if (DECIMAL_FLOAT_MODE_P (mode))
23064 error ("use of decimal floating point types in AltiVec types is invalid");
23065 else if (!TARGET_VSX)
23067 if (type == long_unsigned_type_node || type == long_integer_type_node)
23070 error ("use of %<long%> in AltiVec types is invalid for "
23071 "64-bit code without -mvsx");
23072 else if (rs6000_warn_altivec_long)
23073 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23076 else if (type == long_long_unsigned_type_node
23077 || type == long_long_integer_type_node)
23078 error ("use of %<long long%> in AltiVec types is invalid without "
23080 else if (type == double_type_node)
23081 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23084 switch (altivec_type)
23087 unsigned_p = TYPE_UNSIGNED (type);
23091 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
23094 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
23097 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
23100 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
23102 case SFmode: result = V4SF_type_node; break;
23103 case DFmode: result = V2DF_type_node; break;
23104 /* If the user says 'vector int bool', we may be handed the 'bool'
23105 attribute _before_ the 'vector' attribute, and so select the
23106 proper type in the 'b' case below. */
23107 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
23108 case V2DImode: case V2DFmode:
23116 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
23117 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
23118 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
23119 case QImode: case V16QImode: result = bool_V16QI_type_node;
23126 case V8HImode: result = pixel_V8HI_type_node;
23132 /* Propagate qualifiers attached to the element type
23133 onto the vector type. */
23134 if (result && result != type && TYPE_QUALS (type))
23135 result = build_qualified_type (result, TYPE_QUALS (type));
23137 *no_add_attrs = true; /* No need to hang on to the attribute. */
23140 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
23145 /* AltiVec defines four built-in scalar types that serve as vector
23146 elements; we must teach the compiler how to mangle them. */
23148 static const char *
23149 rs6000_mangle_type (const_tree type)
23151 type = TYPE_MAIN_VARIANT (type);
23153 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
23154 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
23157 if (type == bool_char_type_node) return "U6__boolc";
23158 if (type == bool_short_type_node) return "U6__bools";
23159 if (type == pixel_type_node) return "u7__pixel";
23160 if (type == bool_int_type_node) return "U6__booli";
23161 if (type == bool_long_type_node) return "U6__booll";
23163 /* Mangle IBM extended float long double as `g' (__float128) on
23164 powerpc*-linux where long-double-64 previously was the default. */
23165 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
23167 && TARGET_LONG_DOUBLE_128
23168 && !TARGET_IEEEQUAD)
23171 /* For all other types, use normal C++ mangling. */
23175 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23176 struct attribute_spec.handler. */
23179 rs6000_handle_longcall_attribute (tree *node, tree name,
23180 tree args ATTRIBUTE_UNUSED,
23181 int flags ATTRIBUTE_UNUSED,
23182 bool *no_add_attrs)
23184 if (TREE_CODE (*node) != FUNCTION_TYPE
23185 && TREE_CODE (*node) != FIELD_DECL
23186 && TREE_CODE (*node) != TYPE_DECL)
23188 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23190 *no_add_attrs = true;
23196 /* Set longcall attributes on all functions declared when
23197 rs6000_default_long_calls is true. */
23199 rs6000_set_default_type_attributes (tree type)
23201 if (rs6000_default_long_calls
23202 && (TREE_CODE (type) == FUNCTION_TYPE
23203 || TREE_CODE (type) == METHOD_TYPE))
23204 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23206 TYPE_ATTRIBUTES (type));
23209 darwin_set_default_type_attributes (type);
23213 /* Return a reference suitable for calling a function with the
23214 longcall attribute. */
23217 rs6000_longcall_ref (rtx call_ref)
23219 const char *call_name;
23222 if (GET_CODE (call_ref) != SYMBOL_REF)
23225 /* System V adds '.' to the internal name, so skip them. */
23226 call_name = XSTR (call_ref, 0);
23227 if (*call_name == '.')
23229 while (*call_name == '.')
23232 node = get_identifier (call_name);
23233 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
23236 return force_reg (Pmode, call_ref);
23239 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23240 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23243 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23244 struct attribute_spec.handler. */
23246 rs6000_handle_struct_attribute (tree *node, tree name,
23247 tree args ATTRIBUTE_UNUSED,
23248 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
23251 if (DECL_P (*node))
23253 if (TREE_CODE (*node) == TYPE_DECL)
23254 type = &TREE_TYPE (*node);
23259 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
23260 || TREE_CODE (*type) == UNION_TYPE)))
23262 warning (OPT_Wattributes, "%qE attribute ignored", name);
23263 *no_add_attrs = true;
23266 else if ((is_attribute_p ("ms_struct", name)
23267 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
23268 || ((is_attribute_p ("gcc_struct", name)
23269 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
23271 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
23273 *no_add_attrs = true;
23280 rs6000_ms_bitfield_layout_p (const_tree record_type)
23282 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
23283 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
23284 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
23287 #ifdef USING_ELFOS_H
23289 /* A get_unnamed_section callback, used for switching to toc_section. */
23292 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23294 if (DEFAULT_ABI == ABI_AIX
23295 && TARGET_MINIMAL_TOC
23296 && !TARGET_RELOCATABLE)
23298 if (!toc_initialized)
23300 toc_initialized = 1;
23301 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23302 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
23303 fprintf (asm_out_file, "\t.tc ");
23304 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
23305 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23306 fprintf (asm_out_file, "\n");
23308 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23309 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23310 fprintf (asm_out_file, " = .+32768\n");
23313 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23315 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
23316 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23319 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23320 if (!toc_initialized)
23322 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23323 fprintf (asm_out_file, " = .+32768\n");
23324 toc_initialized = 1;
23329 /* Implement TARGET_ASM_INIT_SECTIONS. */
23332 rs6000_elf_asm_init_sections (void)
23335 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
23338 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
23339 SDATA2_SECTION_ASM_OP);
23342 /* Implement TARGET_SELECT_RTX_SECTION. */
23345 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
23346 unsigned HOST_WIDE_INT align)
23348 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23349 return toc_section;
23351 return default_elf_select_rtx_section (mode, x, align);
23354 /* For a SYMBOL_REF, set generic flags and then perform some
23355 target-specific processing.
23357 When the AIX ABI is requested on a non-AIX system, replace the
23358 function name with the real name (with a leading .) rather than the
23359 function descriptor name. This saves a lot of overriding code to
23360 read the prefixes. */
23363 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
23365 default_encode_section_info (decl, rtl, first);
23368 && TREE_CODE (decl) == FUNCTION_DECL
23370 && DEFAULT_ABI == ABI_AIX)
23372 rtx sym_ref = XEXP (rtl, 0);
23373 size_t len = strlen (XSTR (sym_ref, 0));
23374 char *str = XALLOCAVEC (char, len + 2);
23376 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
23377 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
23382 compare_section_name (const char *section, const char *templ)
23386 len = strlen (templ);
23387 return (strncmp (section, templ, len) == 0
23388 && (section[len] == 0 || section[len] == '.'));
23392 rs6000_elf_in_small_data_p (const_tree decl)
23394 if (rs6000_sdata == SDATA_NONE)
23397 /* We want to merge strings, so we never consider them small data. */
23398 if (TREE_CODE (decl) == STRING_CST)
23401 /* Functions are never in the small data area. */
23402 if (TREE_CODE (decl) == FUNCTION_DECL)
23405 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
23407 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
23408 if (compare_section_name (section, ".sdata")
23409 || compare_section_name (section, ".sdata2")
23410 || compare_section_name (section, ".gnu.linkonce.s")
23411 || compare_section_name (section, ".sbss")
23412 || compare_section_name (section, ".sbss2")
23413 || compare_section_name (section, ".gnu.linkonce.sb")
23414 || strcmp (section, ".PPC.EMB.sdata0") == 0
23415 || strcmp (section, ".PPC.EMB.sbss0") == 0)
23420 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
23423 && (unsigned HOST_WIDE_INT) size <= g_switch_value
23424 /* If it's not public, and we're not going to reference it there,
23425 there's no need to put it in the small data section. */
23426 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
23433 #endif /* USING_ELFOS_H */
23435 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
23438 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
23440 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
23443 /* Return a REG that occurs in ADDR with coefficient 1.
23444 ADDR can be effectively incremented by incrementing REG.
23446 r0 is special and we must not select it as an address
23447 register by this routine since our caller will try to
23448 increment the returned register via an "la" instruction. */
23451 find_addr_reg (rtx addr)
23453 while (GET_CODE (addr) == PLUS)
23455 if (GET_CODE (XEXP (addr, 0)) == REG
23456 && REGNO (XEXP (addr, 0)) != 0)
23457 addr = XEXP (addr, 0);
23458 else if (GET_CODE (XEXP (addr, 1)) == REG
23459 && REGNO (XEXP (addr, 1)) != 0)
23460 addr = XEXP (addr, 1);
23461 else if (CONSTANT_P (XEXP (addr, 0)))
23462 addr = XEXP (addr, 1);
23463 else if (CONSTANT_P (XEXP (addr, 1)))
23464 addr = XEXP (addr, 0);
23466 gcc_unreachable ();
23468 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
23473 rs6000_fatal_bad_address (rtx op)
23475 fatal_insn ("bad address", op);
23480 static tree branch_island_list = 0;
23482 /* Remember to generate a branch island for far calls to the given
23486 add_compiler_branch_island (tree label_name, tree function_name,
23489 tree branch_island = build_tree_list (function_name, label_name);
23490 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
23491 TREE_CHAIN (branch_island) = branch_island_list;
23492 branch_island_list = branch_island;
23495 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
23496 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
23497 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
23498 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
23500 /* Generate far-jump branch islands for everything on the
23501 branch_island_list. Invoked immediately after the last instruction
23502 of the epilogue has been emitted; the branch-islands must be
23503 appended to, and contiguous with, the function body. Mach-O stubs
23504 are generated in machopic_output_stub(). */
23507 macho_branch_islands (void)
23510 tree branch_island;
23512 for (branch_island = branch_island_list;
23514 branch_island = TREE_CHAIN (branch_island))
23516 const char *label =
23517 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
23519 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
23520 char name_buf[512];
23521 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
23522 if (name[0] == '*' || name[0] == '&')
23523 strcpy (name_buf, name+1);
23527 strcpy (name_buf+1, name);
23529 strcpy (tmp_buf, "\n");
23530 strcat (tmp_buf, label);
23531 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23532 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23533 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23534 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23537 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
23538 strcat (tmp_buf, label);
23539 strcat (tmp_buf, "_pic\n");
23540 strcat (tmp_buf, label);
23541 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
23543 strcat (tmp_buf, "\taddis r11,r11,ha16(");
23544 strcat (tmp_buf, name_buf);
23545 strcat (tmp_buf, " - ");
23546 strcat (tmp_buf, label);
23547 strcat (tmp_buf, "_pic)\n");
23549 strcat (tmp_buf, "\tmtlr r0\n");
23551 strcat (tmp_buf, "\taddi r12,r11,lo16(");
23552 strcat (tmp_buf, name_buf);
23553 strcat (tmp_buf, " - ");
23554 strcat (tmp_buf, label);
23555 strcat (tmp_buf, "_pic)\n");
23557 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
23561 strcat (tmp_buf, ":\nlis r12,hi16(");
23562 strcat (tmp_buf, name_buf);
23563 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
23564 strcat (tmp_buf, name_buf);
23565 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
23567 output_asm_insn (tmp_buf, 0);
23568 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23569 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23570 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23571 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23574 branch_island_list = 0;
23577 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
23578 already there or not. */
23581 no_previous_def (tree function_name)
23583 tree branch_island;
23584 for (branch_island = branch_island_list;
23586 branch_island = TREE_CHAIN (branch_island))
23587 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23592 /* GET_PREV_LABEL gets the label name from the previous definition of
23596 get_prev_label (tree function_name)
23598 tree branch_island;
23599 for (branch_island = branch_island_list;
23601 branch_island = TREE_CHAIN (branch_island))
23602 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23603 return BRANCH_ISLAND_LABEL_NAME (branch_island);
23607 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
23608 #define DARWIN_LINKER_GENERATES_ISLANDS 0
23611 /* KEXTs still need branch islands. */
23612 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
23613 || flag_mkernel || flag_apple_kext)
23615 /* INSN is either a function call or a millicode call. It may have an
23616 unconditional jump in its delay slot.
23618 CALL_DEST is the routine we are calling. */
23621 output_call (rtx insn, rtx *operands, int dest_operand_number,
23622 int cookie_operand_number)
23624 static char buf[256];
23625 if (DARWIN_GENERATE_ISLANDS
23626 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
23627 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
23630 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
23632 if (no_previous_def (funname))
23634 rtx label_rtx = gen_label_rtx ();
23635 char *label_buf, temp_buf[256];
23636 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
23637 CODE_LABEL_NUMBER (label_rtx));
23638 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
23639 labelname = get_identifier (label_buf);
23640 add_compiler_branch_island (labelname, funname, insn_line (insn));
23643 labelname = get_prev_label (funname);
23645 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
23646 instruction will reach 'foo', otherwise link as 'bl L42'".
23647 "L42" should be a 'branch island', that will do a far jump to
23648 'foo'. Branch islands are generated in
23649 macho_branch_islands(). */
23650 sprintf (buf, "jbsr %%z%d,%.246s",
23651 dest_operand_number, IDENTIFIER_POINTER (labelname));
23654 sprintf (buf, "bl %%z%d", dest_operand_number);
23658 /* Generate PIC and indirect symbol stubs. */
23661 machopic_output_stub (FILE *file, const char *symb, const char *stub)
23663 unsigned int length;
23664 char *symbol_name, *lazy_ptr_name;
23665 char *local_label_0;
23666 static int label = 0;
23668 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
23669 symb = (*targetm.strip_name_encoding) (symb);
23672 length = strlen (symb);
23673 symbol_name = XALLOCAVEC (char, length + 32);
23674 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
23676 lazy_ptr_name = XALLOCAVEC (char, length + 32);
23677 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
23680 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
23682 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
23686 fprintf (file, "\t.align 5\n");
23688 fprintf (file, "%s:\n", stub);
23689 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23692 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
23693 sprintf (local_label_0, "\"L%011d$spb\"", label);
23695 fprintf (file, "\tmflr r0\n");
23696 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
23697 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
23698 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
23699 lazy_ptr_name, local_label_0);
23700 fprintf (file, "\tmtlr r0\n");
23701 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
23702 (TARGET_64BIT ? "ldu" : "lwzu"),
23703 lazy_ptr_name, local_label_0);
23704 fprintf (file, "\tmtctr r12\n");
23705 fprintf (file, "\tbctr\n");
23709 fprintf (file, "\t.align 4\n");
23711 fprintf (file, "%s:\n", stub);
23712 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23714 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
23715 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
23716 (TARGET_64BIT ? "ldu" : "lwzu"),
23718 fprintf (file, "\tmtctr r12\n");
23719 fprintf (file, "\tbctr\n");
23722 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
23723 fprintf (file, "%s:\n", lazy_ptr_name);
23724 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23725 fprintf (file, "%sdyld_stub_binding_helper\n",
23726 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
23729 /* Legitimize PIC addresses. If the address is already
23730 position-independent, we return ORIG. Newly generated
23731 position-independent addresses go into a reg. This is REG if non
23732 zero, otherwise we allocate register(s) as necessary. */
23734 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
23737 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
23742 if (reg == NULL && ! reload_in_progress && ! reload_completed)
23743 reg = gen_reg_rtx (Pmode);
23745 if (GET_CODE (orig) == CONST)
23749 if (GET_CODE (XEXP (orig, 0)) == PLUS
23750 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
23753 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
23755 /* Use a different reg for the intermediate value, as
23756 it will be marked UNCHANGING. */
23757 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
23758 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
23761 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
23764 if (GET_CODE (offset) == CONST_INT)
23766 if (SMALL_INT (offset))
23767 return plus_constant (base, INTVAL (offset));
23768 else if (! reload_in_progress && ! reload_completed)
23769 offset = force_reg (Pmode, offset);
23772 rtx mem = force_const_mem (Pmode, orig);
23773 return machopic_legitimize_pic_address (mem, Pmode, reg);
23776 return gen_rtx_PLUS (Pmode, base, offset);
23779 /* Fall back on generic machopic code. */
23780 return machopic_legitimize_pic_address (orig, mode, reg);
23783 /* Output a .machine directive for the Darwin assembler, and call
23784 the generic start_file routine. */
23787 rs6000_darwin_file_start (void)
23789 static const struct
23795 { "ppc64", "ppc64", MASK_64BIT },
23796 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
23797 { "power4", "ppc970", 0 },
23798 { "G5", "ppc970", 0 },
23799 { "7450", "ppc7450", 0 },
23800 { "7400", "ppc7400", MASK_ALTIVEC },
23801 { "G4", "ppc7400", 0 },
23802 { "750", "ppc750", 0 },
23803 { "740", "ppc750", 0 },
23804 { "G3", "ppc750", 0 },
23805 { "604e", "ppc604e", 0 },
23806 { "604", "ppc604", 0 },
23807 { "603e", "ppc603", 0 },
23808 { "603", "ppc603", 0 },
23809 { "601", "ppc601", 0 },
23810 { NULL, "ppc", 0 } };
23811 const char *cpu_id = "";
23814 rs6000_file_start ();
23815 darwin_file_start ();
23817 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
23818 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
23819 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
23820 && rs6000_select[i].string[0] != '\0')
23821 cpu_id = rs6000_select[i].string;
23823 /* Look through the mapping array. Pick the first name that either
23824 matches the argument, has a bit set in IF_SET that is also set
23825 in the target flags, or has a NULL name. */
23828 while (mapping[i].arg != NULL
23829 && strcmp (mapping[i].arg, cpu_id) != 0
23830 && (mapping[i].if_set & target_flags) == 0)
23833 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
23836 #endif /* TARGET_MACHO */
23840 rs6000_elf_reloc_rw_mask (void)
23844 else if (DEFAULT_ABI == ABI_AIX)
23850 /* Record an element in the table of global constructors. SYMBOL is
23851 a SYMBOL_REF of the function to be called; PRIORITY is a number
23852 between 0 and MAX_INIT_PRIORITY.
23854 This differs from default_named_section_asm_out_constructor in
23855 that we have special handling for -mrelocatable. */
23858 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
23860 const char *section = ".ctors";
23863 if (priority != DEFAULT_INIT_PRIORITY)
23865 sprintf (buf, ".ctors.%.5u",
23866 /* Invert the numbering so the linker puts us in the proper
23867 order; constructors are run from right to left, and the
23868 linker sorts in increasing order. */
23869 MAX_INIT_PRIORITY - priority);
23873 switch_to_section (get_section (section, SECTION_WRITE, NULL));
23874 assemble_align (POINTER_SIZE);
23876 if (TARGET_RELOCATABLE)
23878 fputs ("\t.long (", asm_out_file);
23879 output_addr_const (asm_out_file, symbol);
23880 fputs (")@fixup\n", asm_out_file);
23883 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
23887 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
23889 const char *section = ".dtors";
23892 if (priority != DEFAULT_INIT_PRIORITY)
23894 sprintf (buf, ".dtors.%.5u",
23895 /* Invert the numbering so the linker puts us in the proper
23896 order; constructors are run from right to left, and the
23897 linker sorts in increasing order. */
23898 MAX_INIT_PRIORITY - priority);
23902 switch_to_section (get_section (section, SECTION_WRITE, NULL));
23903 assemble_align (POINTER_SIZE);
23905 if (TARGET_RELOCATABLE)
23907 fputs ("\t.long (", asm_out_file);
23908 output_addr_const (asm_out_file, symbol);
23909 fputs (")@fixup\n", asm_out_file);
23912 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
23916 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
23920 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
23921 ASM_OUTPUT_LABEL (file, name);
23922 fputs (DOUBLE_INT_ASM_OP, file);
23923 rs6000_output_function_entry (file, name);
23924 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
23927 fputs ("\t.size\t", file);
23928 assemble_name (file, name);
23929 fputs (",24\n\t.type\t.", file);
23930 assemble_name (file, name);
23931 fputs (",@function\n", file);
23932 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
23934 fputs ("\t.globl\t.", file);
23935 assemble_name (file, name);
23940 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
23941 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
23942 rs6000_output_function_entry (file, name);
23943 fputs (":\n", file);
23947 if (TARGET_RELOCATABLE
23948 && !TARGET_SECURE_PLT
23949 && (get_pool_size () != 0 || crtl->profile)
23954 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
23956 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
23957 fprintf (file, "\t.long ");
23958 assemble_name (file, buf);
23960 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
23961 assemble_name (file, buf);
23965 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
23966 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
23968 if (DEFAULT_ABI == ABI_AIX)
23970 const char *desc_name, *orig_name;
23972 orig_name = (*targetm.strip_name_encoding) (name);
23973 desc_name = orig_name;
23974 while (*desc_name == '.')
23977 if (TREE_PUBLIC (decl))
23978 fprintf (file, "\t.globl %s\n", desc_name);
23980 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23981 fprintf (file, "%s:\n", desc_name);
23982 fprintf (file, "\t.long %s\n", orig_name);
23983 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
23984 if (DEFAULT_ABI == ABI_AIX)
23985 fputs ("\t.long 0\n", file);
23986 fprintf (file, "\t.previous\n");
23988 ASM_OUTPUT_LABEL (file, name);
23992 rs6000_elf_end_indicate_exec_stack (void)
23995 file_end_indicate_exec_stack ();
24001 rs6000_xcoff_asm_output_anchor (rtx symbol)
24005 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24006 SYMBOL_REF_BLOCK_OFFSET (symbol));
24007 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24011 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24013 fputs (GLOBAL_ASM_OP, stream);
24014 RS6000_OUTPUT_BASENAME (stream, name);
24015 putc ('\n', stream);
24018 /* A get_unnamed_decl callback, used for read-only sections. PTR
24019 points to the section string variable. */
24022 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24024 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24025 *(const char *const *) directive,
24026 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24029 /* Likewise for read-write sections. */
24032 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24034 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24035 *(const char *const *) directive,
24036 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24039 /* A get_unnamed_section callback, used for switching to toc_section. */
24042 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24044 if (TARGET_MINIMAL_TOC)
24046 /* toc_section is always selected at least once from
24047 rs6000_xcoff_file_start, so this is guaranteed to
24048 always be defined once and only once in each file. */
24049 if (!toc_initialized)
24051 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24052 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24053 toc_initialized = 1;
24055 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
24056 (TARGET_32BIT ? "" : ",3"));
24059 fputs ("\t.toc\n", asm_out_file);
24062 /* Implement TARGET_ASM_INIT_SECTIONS. */
24065 rs6000_xcoff_asm_init_sections (void)
24067 read_only_data_section
24068 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24069 &xcoff_read_only_section_name);
24071 private_data_section
24072 = get_unnamed_section (SECTION_WRITE,
24073 rs6000_xcoff_output_readwrite_section_asm_op,
24074 &xcoff_private_data_section_name);
24076 read_only_private_data_section
24077 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24078 &xcoff_private_data_section_name);
24081 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
24083 readonly_data_section = read_only_data_section;
24084 exception_section = data_section;
24088 rs6000_xcoff_reloc_rw_mask (void)
24094 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
24095 tree decl ATTRIBUTE_UNUSED)
24098 static const char * const suffix[3] = { "PR", "RO", "RW" };
24100 if (flags & SECTION_CODE)
24102 else if (flags & SECTION_WRITE)
24107 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
24108 (flags & SECTION_CODE) ? "." : "",
24109 name, suffix[smclass], flags & SECTION_ENTSIZE);
24113 rs6000_xcoff_select_section (tree decl, int reloc,
24114 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24116 if (decl_readonly_section (decl, reloc))
24118 if (TREE_PUBLIC (decl))
24119 return read_only_data_section;
24121 return read_only_private_data_section;
24125 if (TREE_PUBLIC (decl))
24126 return data_section;
24128 return private_data_section;
24133 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
24137 /* Use select_section for private and uninitialized data. */
24138 if (!TREE_PUBLIC (decl)
24139 || DECL_COMMON (decl)
24140 || DECL_INITIAL (decl) == NULL_TREE
24141 || DECL_INITIAL (decl) == error_mark_node
24142 || (flag_zero_initialized_in_bss
24143 && initializer_zerop (DECL_INITIAL (decl))))
24146 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
24147 name = (*targetm.strip_name_encoding) (name);
24148 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
24151 /* Select section for constant in constant pool.
24153 On RS/6000, all constants are in the private read-only data area.
24154 However, if this is being placed in the TOC it must be output as a
24158 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
24159 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24161 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24162 return toc_section;
24164 return read_only_private_data_section;
24167 /* Remove any trailing [DS] or the like from the symbol name. */
24169 static const char *
24170 rs6000_xcoff_strip_name_encoding (const char *name)
24175 len = strlen (name);
24176 if (name[len - 1] == ']')
24177 return ggc_alloc_string (name, len - 4);
24182 /* Section attributes. AIX is always PIC. */
24184 static unsigned int
24185 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24187 unsigned int align;
24188 unsigned int flags = default_section_type_flags (decl, name, reloc);
24190 /* Align to at least UNIT size. */
24191 if (flags & SECTION_CODE)
24192 align = MIN_UNITS_PER_WORD;
24194 /* Increase alignment of large objects if not already stricter. */
24195 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24196 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24197 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24199 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24202 /* Output at beginning of assembler file.
24204 Initialize the section names for the RS/6000 at this point.
24206 Specify filename, including full path, to assembler.
24208 We want to go into the TOC section so at least one .toc will be emitted.
24209 Also, in order to output proper .bs/.es pairs, we need at least one static
24210 [RW] section emitted.
24212 Finally, declare mcount when profiling to make the assembler happy. */
24215 rs6000_xcoff_file_start (void)
24217 rs6000_gen_section_name (&xcoff_bss_section_name,
24218 main_input_filename, ".bss_");
24219 rs6000_gen_section_name (&xcoff_private_data_section_name,
24220 main_input_filename, ".rw_");
24221 rs6000_gen_section_name (&xcoff_read_only_section_name,
24222 main_input_filename, ".ro_");
24224 fputs ("\t.file\t", asm_out_file);
24225 output_quoted_string (asm_out_file, main_input_filename);
24226 fputc ('\n', asm_out_file);
24227 if (write_symbols != NO_DEBUG)
24228 switch_to_section (private_data_section);
24229 switch_to_section (text_section);
24231 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
24232 rs6000_file_start ();
24235 /* Output at end of assembler file.
24236 On the RS/6000, referencing data should automatically pull in text. */
24239 rs6000_xcoff_file_end (void)
24241 switch_to_section (text_section);
24242 fputs ("_section_.text:\n", asm_out_file);
24243 switch_to_section (data_section);
24244 fputs (TARGET_32BIT
24245 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24248 #endif /* TARGET_XCOFF */
24250 /* Compute a (partial) cost for rtx X. Return true if the complete
24251 cost has been computed, and false if subexpressions should be
24252 scanned. In either case, *TOTAL contains the cost result. */
24255 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
24258 enum machine_mode mode = GET_MODE (x);
24262 /* On the RS/6000, if it is valid in the insn, it is free. */
24264 if (((outer_code == SET
24265 || outer_code == PLUS
24266 || outer_code == MINUS)
24267 && (satisfies_constraint_I (x)
24268 || satisfies_constraint_L (x)))
24269 || (outer_code == AND
24270 && (satisfies_constraint_K (x)
24272 ? satisfies_constraint_L (x)
24273 : satisfies_constraint_J (x))
24274 || mask_operand (x, mode)
24276 && mask64_operand (x, DImode))))
24277 || ((outer_code == IOR || outer_code == XOR)
24278 && (satisfies_constraint_K (x)
24280 ? satisfies_constraint_L (x)
24281 : satisfies_constraint_J (x))))
24282 || outer_code == ASHIFT
24283 || outer_code == ASHIFTRT
24284 || outer_code == LSHIFTRT
24285 || outer_code == ROTATE
24286 || outer_code == ROTATERT
24287 || outer_code == ZERO_EXTRACT
24288 || (outer_code == MULT
24289 && satisfies_constraint_I (x))
24290 || ((outer_code == DIV || outer_code == UDIV
24291 || outer_code == MOD || outer_code == UMOD)
24292 && exact_log2 (INTVAL (x)) >= 0)
24293 || (outer_code == COMPARE
24294 && (satisfies_constraint_I (x)
24295 || satisfies_constraint_K (x)))
24296 || (outer_code == EQ
24297 && (satisfies_constraint_I (x)
24298 || satisfies_constraint_K (x)
24300 ? satisfies_constraint_L (x)
24301 : satisfies_constraint_J (x))))
24302 || (outer_code == GTU
24303 && satisfies_constraint_I (x))
24304 || (outer_code == LTU
24305 && satisfies_constraint_P (x)))
24310 else if ((outer_code == PLUS
24311 && reg_or_add_cint_operand (x, VOIDmode))
24312 || (outer_code == MINUS
24313 && reg_or_sub_cint_operand (x, VOIDmode))
24314 || ((outer_code == SET
24315 || outer_code == IOR
24316 || outer_code == XOR)
24318 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
24320 *total = COSTS_N_INSNS (1);
24326 if (mode == DImode && code == CONST_DOUBLE)
24328 if ((outer_code == IOR || outer_code == XOR)
24329 && CONST_DOUBLE_HIGH (x) == 0
24330 && (CONST_DOUBLE_LOW (x)
24331 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
24336 else if ((outer_code == AND && and64_2_operand (x, DImode))
24337 || ((outer_code == SET
24338 || outer_code == IOR
24339 || outer_code == XOR)
24340 && CONST_DOUBLE_HIGH (x) == 0))
24342 *total = COSTS_N_INSNS (1);
24352 /* When optimizing for size, MEM should be slightly more expensive
24353 than generating address, e.g., (plus (reg) (const)).
24354 L1 cache latency is about two instructions. */
24355 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
24363 if (mode == DFmode)
24365 if (GET_CODE (XEXP (x, 0)) == MULT)
24367 /* FNMA accounted in outer NEG. */
24368 if (outer_code == NEG)
24369 *total = rs6000_cost->dmul - rs6000_cost->fp;
24371 *total = rs6000_cost->dmul;
24374 *total = rs6000_cost->fp;
24376 else if (mode == SFmode)
24378 /* FNMA accounted in outer NEG. */
24379 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24382 *total = rs6000_cost->fp;
24385 *total = COSTS_N_INSNS (1);
24389 if (mode == DFmode)
24391 if (GET_CODE (XEXP (x, 0)) == MULT
24392 || GET_CODE (XEXP (x, 1)) == MULT)
24394 /* FNMA accounted in outer NEG. */
24395 if (outer_code == NEG)
24396 *total = rs6000_cost->dmul - rs6000_cost->fp;
24398 *total = rs6000_cost->dmul;
24401 *total = rs6000_cost->fp;
24403 else if (mode == SFmode)
24405 /* FNMA accounted in outer NEG. */
24406 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24409 *total = rs6000_cost->fp;
24412 *total = COSTS_N_INSNS (1);
24416 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24417 && satisfies_constraint_I (XEXP (x, 1)))
24419 if (INTVAL (XEXP (x, 1)) >= -256
24420 && INTVAL (XEXP (x, 1)) <= 255)
24421 *total = rs6000_cost->mulsi_const9;
24423 *total = rs6000_cost->mulsi_const;
24425 /* FMA accounted in outer PLUS/MINUS. */
24426 else if ((mode == DFmode || mode == SFmode)
24427 && (outer_code == PLUS || outer_code == MINUS))
24429 else if (mode == DFmode)
24430 *total = rs6000_cost->dmul;
24431 else if (mode == SFmode)
24432 *total = rs6000_cost->fp;
24433 else if (mode == DImode)
24434 *total = rs6000_cost->muldi;
24436 *total = rs6000_cost->mulsi;
24441 if (FLOAT_MODE_P (mode))
24443 *total = mode == DFmode ? rs6000_cost->ddiv
24444 : rs6000_cost->sdiv;
24451 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24452 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
24454 if (code == DIV || code == MOD)
24456 *total = COSTS_N_INSNS (2);
24459 *total = COSTS_N_INSNS (1);
24463 if (GET_MODE (XEXP (x, 1)) == DImode)
24464 *total = rs6000_cost->divdi;
24466 *total = rs6000_cost->divsi;
24468 /* Add in shift and subtract for MOD. */
24469 if (code == MOD || code == UMOD)
24470 *total += COSTS_N_INSNS (2);
24475 *total = COSTS_N_INSNS (4);
24479 *total = COSTS_N_INSNS (6);
24483 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
24495 *total = COSTS_N_INSNS (1);
24503 /* Handle mul_highpart. */
24504 if (outer_code == TRUNCATE
24505 && GET_CODE (XEXP (x, 0)) == MULT)
24507 if (mode == DImode)
24508 *total = rs6000_cost->muldi;
24510 *total = rs6000_cost->mulsi;
24513 else if (outer_code == AND)
24516 *total = COSTS_N_INSNS (1);
24521 if (GET_CODE (XEXP (x, 0)) == MEM)
24524 *total = COSTS_N_INSNS (1);
24530 if (!FLOAT_MODE_P (mode))
24532 *total = COSTS_N_INSNS (1);
24538 case UNSIGNED_FLOAT:
24541 case FLOAT_TRUNCATE:
24542 *total = rs6000_cost->fp;
24546 if (mode == DFmode)
24549 *total = rs6000_cost->fp;
24553 switch (XINT (x, 1))
24556 *total = rs6000_cost->fp;
24568 *total = COSTS_N_INSNS (1);
24571 else if (FLOAT_MODE_P (mode)
24572 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
24574 *total = rs6000_cost->fp;
24582 /* Carry bit requires mode == Pmode.
24583 NEG or PLUS already counted so only add one. */
24585 && (outer_code == NEG || outer_code == PLUS))
24587 *total = COSTS_N_INSNS (1);
24590 if (outer_code == SET)
24592 if (XEXP (x, 1) == const0_rtx)
24594 *total = COSTS_N_INSNS (2);
24597 else if (mode == Pmode)
24599 *total = COSTS_N_INSNS (3);
24608 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
24610 *total = COSTS_N_INSNS (2);
24614 if (outer_code == COMPARE)
24628 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
24631 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
24634 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
24637 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
24638 "total = %d, speed = %s, x:\n",
24639 ret ? "complete" : "scan inner",
24640 GET_RTX_NAME (code),
24641 GET_RTX_NAME (outer_code),
24643 speed ? "true" : "false");
24650 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
24653 rs6000_debug_address_cost (rtx x, bool speed)
24655 int ret = TARGET_ADDRESS_COST (x, speed);
24657 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
24658 ret, speed ? "true" : "false");
24665 /* A C expression returning the cost of moving data from a register of class
24666 CLASS1 to one of CLASS2. */
24669 rs6000_register_move_cost (enum machine_mode mode,
24670 enum reg_class from, enum reg_class to)
24674 /* Moves from/to GENERAL_REGS. */
24675 if (reg_classes_intersect_p (to, GENERAL_REGS)
24676 || reg_classes_intersect_p (from, GENERAL_REGS))
24678 if (! reg_classes_intersect_p (to, GENERAL_REGS))
24681 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
24682 ret = (rs6000_memory_move_cost (mode, from, 0)
24683 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
24685 /* It's more expensive to move CR_REGS than CR0_REGS because of the
24687 else if (from == CR_REGS)
24690 /* Power6 has slower LR/CTR moves so make them more expensive than
24691 memory in order to bias spills to memory .*/
24692 else if (rs6000_cpu == PROCESSOR_POWER6
24693 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
24694 ret = 6 * hard_regno_nregs[0][mode];
24697 /* A move will cost one instruction per GPR moved. */
24698 ret = 2 * hard_regno_nregs[0][mode];
24701 /* If we have VSX, we can easily move between FPR or Altivec registers. */
24702 else if (VECTOR_UNIT_VSX_P (mode)
24703 && reg_classes_intersect_p (to, VSX_REGS)
24704 && reg_classes_intersect_p (from, VSX_REGS))
24705 ret = 2 * hard_regno_nregs[32][mode];
24707 /* Moving between two similar registers is just one instruction. */
24708 else if (reg_classes_intersect_p (to, from))
24709 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
24711 /* Everything else has to go through GENERAL_REGS. */
24713 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
24714 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
24716 if (TARGET_DEBUG_COST)
24718 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
24719 ret, GET_MODE_NAME (mode), reg_class_names[from],
24720 reg_class_names[to]);
24725 /* A C expressions returning the cost of moving data of MODE from a register to
24729 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
24730 int in ATTRIBUTE_UNUSED)
24734 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
24735 ret = 4 * hard_regno_nregs[0][mode];
24736 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
24737 ret = 4 * hard_regno_nregs[32][mode];
24738 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
24739 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
24741 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
24743 if (TARGET_DEBUG_COST)
24745 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
24746 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
24751 /* Returns a code for a target-specific builtin that implements
24752 reciprocal of the function, or NULL_TREE if not available. */
24755 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
24756 bool sqrt ATTRIBUTE_UNUSED)
24758 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
24759 && flag_finite_math_only && !flag_trapping_math
24760 && flag_unsafe_math_optimizations))
24768 case BUILT_IN_SQRTF:
24769 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
24776 /* Newton-Raphson approximation of single-precision floating point divide n/d.
24777 Assumes no trapping math and finite arguments. */
24780 rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
24782 rtx x0, e0, e1, y1, u0, v0, one;
24784 x0 = gen_reg_rtx (SFmode);
24785 e0 = gen_reg_rtx (SFmode);
24786 e1 = gen_reg_rtx (SFmode);
24787 y1 = gen_reg_rtx (SFmode);
24788 u0 = gen_reg_rtx (SFmode);
24789 v0 = gen_reg_rtx (SFmode);
24790 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
24792 /* x0 = 1./d estimate */
24793 emit_insn (gen_rtx_SET (VOIDmode, x0,
24794 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
24796 /* e0 = 1. - d * x0 */
24797 emit_insn (gen_rtx_SET (VOIDmode, e0,
24798 gen_rtx_MINUS (SFmode, one,
24799 gen_rtx_MULT (SFmode, d, x0))));
24800 /* e1 = e0 + e0 * e0 */
24801 emit_insn (gen_rtx_SET (VOIDmode, e1,
24802 gen_rtx_PLUS (SFmode,
24803 gen_rtx_MULT (SFmode, e0, e0), e0)));
24804 /* y1 = x0 + e1 * x0 */
24805 emit_insn (gen_rtx_SET (VOIDmode, y1,
24806 gen_rtx_PLUS (SFmode,
24807 gen_rtx_MULT (SFmode, e1, x0), x0)));
24809 emit_insn (gen_rtx_SET (VOIDmode, u0,
24810 gen_rtx_MULT (SFmode, n, y1)));
24811 /* v0 = n - d * u0 */
24812 emit_insn (gen_rtx_SET (VOIDmode, v0,
24813 gen_rtx_MINUS (SFmode, n,
24814 gen_rtx_MULT (SFmode, d, u0))));
24815 /* dst = u0 + v0 * y1 */
24816 emit_insn (gen_rtx_SET (VOIDmode, dst,
24817 gen_rtx_PLUS (SFmode,
24818 gen_rtx_MULT (SFmode, v0, y1), u0)));
24821 /* Newton-Raphson approximation of double-precision floating point divide n/d.
24822 Assumes no trapping math and finite arguments. */
24825 rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
24827 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
24829 x0 = gen_reg_rtx (DFmode);
24830 e0 = gen_reg_rtx (DFmode);
24831 e1 = gen_reg_rtx (DFmode);
24832 e2 = gen_reg_rtx (DFmode);
24833 y1 = gen_reg_rtx (DFmode);
24834 y2 = gen_reg_rtx (DFmode);
24835 y3 = gen_reg_rtx (DFmode);
24836 u0 = gen_reg_rtx (DFmode);
24837 v0 = gen_reg_rtx (DFmode);
24838 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
24840 /* x0 = 1./d estimate */
24841 emit_insn (gen_rtx_SET (VOIDmode, x0,
24842 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
24844 /* e0 = 1. - d * x0 */
24845 emit_insn (gen_rtx_SET (VOIDmode, e0,
24846 gen_rtx_MINUS (DFmode, one,
24847 gen_rtx_MULT (SFmode, d, x0))));
24848 /* y1 = x0 + e0 * x0 */
24849 emit_insn (gen_rtx_SET (VOIDmode, y1,
24850 gen_rtx_PLUS (DFmode,
24851 gen_rtx_MULT (DFmode, e0, x0), x0)));
24853 emit_insn (gen_rtx_SET (VOIDmode, e1,
24854 gen_rtx_MULT (DFmode, e0, e0)));
24855 /* y2 = y1 + e1 * y1 */
24856 emit_insn (gen_rtx_SET (VOIDmode, y2,
24857 gen_rtx_PLUS (DFmode,
24858 gen_rtx_MULT (DFmode, e1, y1), y1)));
24860 emit_insn (gen_rtx_SET (VOIDmode, e2,
24861 gen_rtx_MULT (DFmode, e1, e1)));
24862 /* y3 = y2 + e2 * y2 */
24863 emit_insn (gen_rtx_SET (VOIDmode, y3,
24864 gen_rtx_PLUS (DFmode,
24865 gen_rtx_MULT (DFmode, e2, y2), y2)));
24867 emit_insn (gen_rtx_SET (VOIDmode, u0,
24868 gen_rtx_MULT (DFmode, n, y3)));
24869 /* v0 = n - d * u0 */
24870 emit_insn (gen_rtx_SET (VOIDmode, v0,
24871 gen_rtx_MINUS (DFmode, n,
24872 gen_rtx_MULT (DFmode, d, u0))));
24873 /* dst = u0 + v0 * y3 */
24874 emit_insn (gen_rtx_SET (VOIDmode, dst,
24875 gen_rtx_PLUS (DFmode,
24876 gen_rtx_MULT (DFmode, v0, y3), u0)));
24880 /* Newton-Raphson approximation of single-precision floating point rsqrt.
24881 Assumes no trapping math and finite arguments. */
24884 rs6000_emit_swrsqrtsf (rtx dst, rtx src)
24886 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
24887 half, one, halfthree, c1, cond, label;
24889 x0 = gen_reg_rtx (SFmode);
24890 x1 = gen_reg_rtx (SFmode);
24891 x2 = gen_reg_rtx (SFmode);
24892 y1 = gen_reg_rtx (SFmode);
24893 u0 = gen_reg_rtx (SFmode);
24894 u1 = gen_reg_rtx (SFmode);
24895 u2 = gen_reg_rtx (SFmode);
24896 v0 = gen_reg_rtx (SFmode);
24897 v1 = gen_reg_rtx (SFmode);
24898 v2 = gen_reg_rtx (SFmode);
24899 t0 = gen_reg_rtx (SFmode);
24900 halfthree = gen_reg_rtx (SFmode);
24901 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
24902 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
24904 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
24905 emit_insn (gen_rtx_SET (VOIDmode, t0,
24906 gen_rtx_MULT (SFmode, src, src)));
24908 emit_insn (gen_rtx_SET (VOIDmode, cond,
24909 gen_rtx_COMPARE (CCFPmode, t0, src)));
24910 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
24911 emit_unlikely_jump (c1, label);
24913 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
24914 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
24916 /* halfthree = 1.5 = 1.0 + 0.5 */
24917 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
24918 gen_rtx_PLUS (SFmode, one, half)));
24920 /* x0 = rsqrt estimate */
24921 emit_insn (gen_rtx_SET (VOIDmode, x0,
24922 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
24925 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
24926 emit_insn (gen_rtx_SET (VOIDmode, y1,
24927 gen_rtx_MINUS (SFmode,
24928 gen_rtx_MULT (SFmode, src, halfthree),
24931 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
24932 emit_insn (gen_rtx_SET (VOIDmode, u0,
24933 gen_rtx_MULT (SFmode, x0, x0)));
24934 emit_insn (gen_rtx_SET (VOIDmode, v0,
24935 gen_rtx_MINUS (SFmode,
24937 gen_rtx_MULT (SFmode, y1, u0))));
24938 emit_insn (gen_rtx_SET (VOIDmode, x1,
24939 gen_rtx_MULT (SFmode, x0, v0)));
24941 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
24942 emit_insn (gen_rtx_SET (VOIDmode, u1,
24943 gen_rtx_MULT (SFmode, x1, x1)));
24944 emit_insn (gen_rtx_SET (VOIDmode, v1,
24945 gen_rtx_MINUS (SFmode,
24947 gen_rtx_MULT (SFmode, y1, u1))));
24948 emit_insn (gen_rtx_SET (VOIDmode, x2,
24949 gen_rtx_MULT (SFmode, x1, v1)));
24951 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
24952 emit_insn (gen_rtx_SET (VOIDmode, u2,
24953 gen_rtx_MULT (SFmode, x2, x2)));
24954 emit_insn (gen_rtx_SET (VOIDmode, v2,
24955 gen_rtx_MINUS (SFmode,
24957 gen_rtx_MULT (SFmode, y1, u2))));
24958 emit_insn (gen_rtx_SET (VOIDmode, dst,
24959 gen_rtx_MULT (SFmode, x2, v2)));
24961 emit_label (XEXP (label, 0));
24964 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
24965 (Power7) targets. DST is the target, and SRC is the argument operand. */
24968 rs6000_emit_popcount (rtx dst, rtx src)
24970 enum machine_mode mode = GET_MODE (dst);
24973 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
24974 if (TARGET_POPCNTD)
24976 if (mode == SImode)
24977 emit_insn (gen_popcntwsi2 (dst, src));
24979 emit_insn (gen_popcntddi2 (dst, src));
24983 tmp1 = gen_reg_rtx (mode);
24985 if (mode == SImode)
24987 emit_insn (gen_popcntbsi2 (tmp1, src));
24988 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
24990 tmp2 = force_reg (SImode, tmp2);
24991 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
24995 emit_insn (gen_popcntbdi2 (tmp1, src));
24996 tmp2 = expand_mult (DImode, tmp1,
24997 GEN_INT ((HOST_WIDE_INT)
24998 0x01010101 << 32 | 0x01010101),
25000 tmp2 = force_reg (DImode, tmp2);
25001 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
25006 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25007 target, and SRC is the argument operand. */
25010 rs6000_emit_parity (rtx dst, rtx src)
25012 enum machine_mode mode = GET_MODE (dst);
25015 tmp = gen_reg_rtx (mode);
25016 if (mode == SImode)
25018 /* Is mult+shift >= shift+xor+shift+xor? */
25019 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
25021 rtx tmp1, tmp2, tmp3, tmp4;
25023 tmp1 = gen_reg_rtx (SImode);
25024 emit_insn (gen_popcntbsi2 (tmp1, src));
25026 tmp2 = gen_reg_rtx (SImode);
25027 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
25028 tmp3 = gen_reg_rtx (SImode);
25029 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
25031 tmp4 = gen_reg_rtx (SImode);
25032 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
25033 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
25036 rs6000_emit_popcount (tmp, src);
25037 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
25041 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25042 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
25044 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
25046 tmp1 = gen_reg_rtx (DImode);
25047 emit_insn (gen_popcntbdi2 (tmp1, src));
25049 tmp2 = gen_reg_rtx (DImode);
25050 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
25051 tmp3 = gen_reg_rtx (DImode);
25052 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
25054 tmp4 = gen_reg_rtx (DImode);
25055 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
25056 tmp5 = gen_reg_rtx (DImode);
25057 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
25059 tmp6 = gen_reg_rtx (DImode);
25060 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
25061 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
25064 rs6000_emit_popcount (tmp, src);
25065 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
25069 /* Return an RTX representing where to find the function value of a
25070 function returning MODE. */
25072 rs6000_complex_function_value (enum machine_mode mode)
25074 unsigned int regno;
25076 enum machine_mode inner = GET_MODE_INNER (mode);
25077 unsigned int inner_bytes = GET_MODE_SIZE (inner);
25079 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25080 regno = FP_ARG_RETURN;
25083 regno = GP_ARG_RETURN;
25085 /* 32-bit is OK since it'll go in r3/r4. */
25086 if (TARGET_32BIT && inner_bytes >= 4)
25087 return gen_rtx_REG (mode, regno);
25090 if (inner_bytes >= 8)
25091 return gen_rtx_REG (mode, regno);
25093 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
25095 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
25096 GEN_INT (inner_bytes));
25097 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
25100 /* Target hook for TARGET_FUNCTION_VALUE.
25102 On the SPE, both FPs and vectors are returned in r3.
25104 On RS/6000 an integer value is in r3 and a floating-point value is in
25105 fp1, unless -msoft-float. */
25108 rs6000_function_value (const_tree valtype,
25109 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
25110 bool outgoing ATTRIBUTE_UNUSED)
25112 enum machine_mode mode;
25113 unsigned int regno;
25115 /* Special handling for structs in darwin64. */
25116 if (rs6000_darwin64_abi
25117 && TYPE_MODE (valtype) == BLKmode
25118 && TREE_CODE (valtype) == RECORD_TYPE
25119 && int_size_in_bytes (valtype) > 0)
25121 CUMULATIVE_ARGS valcum;
25125 valcum.fregno = FP_ARG_MIN_REG;
25126 valcum.vregno = ALTIVEC_ARG_MIN_REG;
25127 /* Do a trial code generation as if this were going to be passed as
25128 an argument; if any part goes in memory, we return NULL. */
25129 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
25132 /* Otherwise fall through to standard ABI rules. */
25135 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
25137 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25138 return gen_rtx_PARALLEL (DImode,
25140 gen_rtx_EXPR_LIST (VOIDmode,
25141 gen_rtx_REG (SImode, GP_ARG_RETURN),
25143 gen_rtx_EXPR_LIST (VOIDmode,
25144 gen_rtx_REG (SImode,
25145 GP_ARG_RETURN + 1),
25148 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
25150 return gen_rtx_PARALLEL (DCmode,
25152 gen_rtx_EXPR_LIST (VOIDmode,
25153 gen_rtx_REG (SImode, GP_ARG_RETURN),
25155 gen_rtx_EXPR_LIST (VOIDmode,
25156 gen_rtx_REG (SImode,
25157 GP_ARG_RETURN + 1),
25159 gen_rtx_EXPR_LIST (VOIDmode,
25160 gen_rtx_REG (SImode,
25161 GP_ARG_RETURN + 2),
25163 gen_rtx_EXPR_LIST (VOIDmode,
25164 gen_rtx_REG (SImode,
25165 GP_ARG_RETURN + 3),
25169 mode = TYPE_MODE (valtype);
25170 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
25171 || POINTER_TYPE_P (valtype))
25172 mode = TARGET_32BIT ? SImode : DImode;
25174 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25175 /* _Decimal128 must use an even/odd register pair. */
25176 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25177 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
25178 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
25179 regno = FP_ARG_RETURN;
25180 else if (TREE_CODE (valtype) == COMPLEX_TYPE
25181 && targetm.calls.split_complex_arg)
25182 return rs6000_complex_function_value (mode);
25183 else if (TREE_CODE (valtype) == VECTOR_TYPE
25184 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
25185 && ALTIVEC_VECTOR_MODE (mode))
25186 regno = ALTIVEC_ARG_RETURN;
25187 else if (TREE_CODE (valtype) == VECTOR_TYPE
25188 && TARGET_VSX && TARGET_ALTIVEC_ABI
25189 && VSX_VECTOR_MODE (mode))
25190 regno = ALTIVEC_ARG_RETURN;
25191 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25192 && (mode == DFmode || mode == DCmode
25193 || mode == TFmode || mode == TCmode))
25194 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25196 regno = GP_ARG_RETURN;
25198 return gen_rtx_REG (mode, regno);
25201 /* Define how to find the value returned by a library function
25202 assuming the value has mode MODE. */
25204 rs6000_libcall_value (enum machine_mode mode)
25206 unsigned int regno;
25208 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
25210 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25211 return gen_rtx_PARALLEL (DImode,
25213 gen_rtx_EXPR_LIST (VOIDmode,
25214 gen_rtx_REG (SImode, GP_ARG_RETURN),
25216 gen_rtx_EXPR_LIST (VOIDmode,
25217 gen_rtx_REG (SImode,
25218 GP_ARG_RETURN + 1),
25222 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25223 /* _Decimal128 must use an even/odd register pair. */
25224 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25225 else if (SCALAR_FLOAT_MODE_P (mode)
25226 && TARGET_HARD_FLOAT && TARGET_FPRS
25227 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
25228 regno = FP_ARG_RETURN;
25229 else if (ALTIVEC_VECTOR_MODE (mode)
25230 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
25231 regno = ALTIVEC_ARG_RETURN;
25232 else if (VSX_VECTOR_MODE (mode)
25233 && TARGET_VSX && TARGET_ALTIVEC_ABI)
25234 regno = ALTIVEC_ARG_RETURN;
25235 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
25236 return rs6000_complex_function_value (mode);
25237 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25238 && (mode == DFmode || mode == DCmode
25239 || mode == TFmode || mode == TCmode))
25240 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25242 regno = GP_ARG_RETURN;
25244 return gen_rtx_REG (mode, regno);
25248 /* Given FROM and TO register numbers, say whether this elimination is allowed.
25249 Frame pointer elimination is automatically handled.
25251 For the RS/6000, if frame pointer elimination is being done, we would like
25252 to convert ap into fp, not sp.
25254 We need r30 if -mminimal-toc was specified, and there are constant pool
25258 rs6000_can_eliminate (const int from, const int to)
25260 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
25261 ? ! frame_pointer_needed
25262 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
25263 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
25267 /* Define the offset between two registers, FROM to be eliminated and its
25268 replacement TO, at the start of a routine. */
25270 rs6000_initial_elimination_offset (int from, int to)
25272 rs6000_stack_t *info = rs6000_stack_info ();
25273 HOST_WIDE_INT offset;
25275 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25276 offset = info->push_p ? 0 : -info->total_size;
25277 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25279 offset = info->push_p ? 0 : -info->total_size;
25280 if (FRAME_GROWS_DOWNWARD)
25281 offset += info->fixed_size + info->vars_size + info->parm_size;
25283 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25284 offset = FRAME_GROWS_DOWNWARD
25285 ? info->fixed_size + info->vars_size + info->parm_size
25287 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25288 offset = info->total_size;
25289 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25290 offset = info->push_p ? info->total_size : 0;
25291 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
25294 gcc_unreachable ();
25300 rs6000_dwarf_register_span (rtx reg)
25304 unsigned regno = REGNO (reg);
25305 enum machine_mode mode = GET_MODE (reg);
25309 && (SPE_VECTOR_MODE (GET_MODE (reg))
25310 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
25311 && mode != SFmode && mode != SDmode && mode != SCmode)))
25316 regno = REGNO (reg);
25318 /* The duality of the SPE register size wreaks all kinds of havoc.
25319 This is a way of distinguishing r0 in 32-bits from r0 in
25321 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
25322 gcc_assert (words <= 4);
25323 for (i = 0; i < words; i++, regno++)
25325 if (BYTES_BIG_ENDIAN)
25327 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
25328 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
25332 parts[2 * i] = gen_rtx_REG (SImode, regno);
25333 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
25337 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
25340 /* Fill in sizes for SPE register high parts in table used by unwinder. */
25343 rs6000_init_dwarf_reg_sizes_extra (tree address)
25348 enum machine_mode mode = TYPE_MODE (char_type_node);
25349 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
25350 rtx mem = gen_rtx_MEM (BLKmode, addr);
25351 rtx value = gen_int_mode (4, mode);
25353 for (i = 1201; i < 1232; i++)
25355 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
25356 HOST_WIDE_INT offset
25357 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
25359 emit_move_insn (adjust_address (mem, mode, offset), value);
25364 /* Map internal gcc register numbers to DWARF2 register numbers. */
25367 rs6000_dbx_register_number (unsigned int regno)
25369 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
25371 if (regno == MQ_REGNO)
25373 if (regno == LR_REGNO)
25375 if (regno == CTR_REGNO)
25377 if (CR_REGNO_P (regno))
25378 return regno - CR0_REGNO + 86;
25379 if (regno == XER_REGNO)
25381 if (ALTIVEC_REGNO_P (regno))
25382 return regno - FIRST_ALTIVEC_REGNO + 1124;
25383 if (regno == VRSAVE_REGNO)
25385 if (regno == VSCR_REGNO)
25387 if (regno == SPE_ACC_REGNO)
25389 if (regno == SPEFSCR_REGNO)
25391 /* SPE high reg number. We get these values of regno from
25392 rs6000_dwarf_register_span. */
25393 gcc_assert (regno >= 1200 && regno < 1232);
25397 /* target hook eh_return_filter_mode */
25398 static enum machine_mode
25399 rs6000_eh_return_filter_mode (void)
25401 return TARGET_32BIT ? SImode : word_mode;
25404 /* Target hook for scalar_mode_supported_p. */
25406 rs6000_scalar_mode_supported_p (enum machine_mode mode)
25408 if (DECIMAL_FLOAT_MODE_P (mode))
25409 return default_decimal_float_supported_p ();
25411 return default_scalar_mode_supported_p (mode);
25414 /* Target hook for vector_mode_supported_p. */
25416 rs6000_vector_mode_supported_p (enum machine_mode mode)
25419 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
25422 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
25425 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
25432 /* Target hook for invalid_arg_for_unprototyped_fn. */
25433 static const char *
25434 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
25436 return (!rs6000_darwin64_abi
25438 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
25439 && (funcdecl == NULL_TREE
25440 || (TREE_CODE (funcdecl) == FUNCTION_DECL
25441 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
25442 ? N_("AltiVec argument passed to unprototyped function")
25446 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
25447 setup by using __stack_chk_fail_local hidden function instead of
25448 calling __stack_chk_fail directly. Otherwise it is better to call
25449 __stack_chk_fail directly. */
25452 rs6000_stack_protect_fail (void)
25454 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
25455 ? default_hidden_stack_protect_fail ()
25456 : default_external_stack_protect_fail ();
25460 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
25461 int num_operands ATTRIBUTE_UNUSED)
25463 if (rs6000_warn_cell_microcode)
25466 int insn_code_number = recog_memoized (insn);
25467 location_t location = locator_location (INSN_LOCATOR (insn));
25469 /* Punt on insns we cannot recognize. */
25470 if (insn_code_number < 0)
25473 temp = get_insn_template (insn_code_number, insn);
25475 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
25476 warning_at (location, OPT_mwarn_cell_microcode,
25477 "emitting microcode insn %s\t[%s] #%d",
25478 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25479 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
25480 warning_at (location, OPT_mwarn_cell_microcode,
25481 "emitting conditional microcode insn %s\t[%s] #%d",
25482 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25486 #include "gt-rs6000.h"