1 /* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
29 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-attr.h"
43 #include "basic-block.h"
44 #include "integrate.h"
50 #include "target-def.h"
51 #include "langhooks.h"
53 #include "cfglayout.h"
54 #include "sched-int.h"
56 #include "tree-flow.h"
59 #include "tm-constrs.h"
61 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
64 #include "gstab.h" /* for N_SLINE */
67 #ifndef TARGET_NO_PROTOTYPE
68 #define TARGET_NO_PROTOTYPE 0
71 #define min(A,B) ((A) < (B) ? (A) : (B))
72 #define max(A,B) ((A) > (B) ? (A) : (B))
74 /* Structure used to define the rs6000 stack */
75 typedef struct rs6000_stack {
76 int first_gp_reg_save; /* first callee saved GP register used */
77 int first_fp_reg_save; /* first callee saved FP register used */
78 int first_altivec_reg_save; /* first callee saved AltiVec register used */
79 int lr_save_p; /* true if the link reg needs to be saved */
80 int cr_save_p; /* true if the CR reg needs to be saved */
81 unsigned int vrsave_mask; /* mask of vec registers to save */
82 int push_p; /* true if we need to allocate stack space */
83 int calls_p; /* true if the function makes any calls */
84 int world_save_p; /* true if we're saving *everything*:
85 r13-r31, cr, f14-f31, vrsave, v20-v31 */
86 enum rs6000_abi abi; /* which ABI to use */
87 int gp_save_offset; /* offset to save GP regs from initial SP */
88 int fp_save_offset; /* offset to save FP regs from initial SP */
89 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
90 int lr_save_offset; /* offset to save LR from initial SP */
91 int cr_save_offset; /* offset to save CR from initial SP */
92 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
93 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
94 int varargs_save_offset; /* offset to save the varargs registers */
95 int ehrd_offset; /* offset to EH return data */
96 int reg_size; /* register size (4 or 8) */
97 HOST_WIDE_INT vars_size; /* variable save area size */
98 int parm_size; /* outgoing parameter size */
99 int save_size; /* save area size */
100 int fixed_size; /* fixed size of stack frame */
101 int gp_size; /* size of saved GP registers */
102 int fp_size; /* size of saved FP registers */
103 int altivec_size; /* size of saved AltiVec registers */
104 int cr_size; /* size to hold CR if not in save_size */
105 int vrsave_size; /* size to hold VRSAVE if not in save_size */
106 int altivec_padding_size; /* size of altivec alignment padding if
108 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
109 int spe_padding_size;
110 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
111 int spe_64bit_regs_used;
114 /* A C structure for machine-specific, per-function data.
115 This is added to the cfun structure. */
116 typedef struct GTY(()) machine_function
118 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
119 int ra_needs_full_frame;
120 /* Some local-dynamic symbol. */
121 const char *some_ld_name;
122 /* Whether the instruction chain has been scanned already. */
123 int insn_chain_scanned_p;
124 /* Flags if __builtin_return_address (0) was used. */
126 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
127 varargs save area. */
128 HOST_WIDE_INT varargs_save_offset;
129 /* Temporary stack slot to use for SDmode copies. This slot is
130 64-bits wide and is allocated early enough so that the offset
131 does not overflow the 16-bit load/store offset field. */
132 rtx sdmode_stack_slot;
135 /* Target cpu type */
137 enum processor_type rs6000_cpu;
138 struct rs6000_cpu_select rs6000_select[3] =
140 /* switch name, tune arch */
141 { (const char *)0, "--with-cpu=", 1, 1 },
142 { (const char *)0, "-mcpu=", 1, 1 },
143 { (const char *)0, "-mtune=", 1, 0 },
146 /* Always emit branch hint bits. */
147 static GTY(()) bool rs6000_always_hint;
149 /* Schedule instructions for group formation. */
150 static GTY(()) bool rs6000_sched_groups;
152 /* Align branch targets. */
153 static GTY(()) bool rs6000_align_branch_targets;
155 /* Support for -msched-costly-dep option. */
156 const char *rs6000_sched_costly_dep_str;
157 enum rs6000_dependence_cost rs6000_sched_costly_dep;
159 /* Support for -minsert-sched-nops option. */
160 const char *rs6000_sched_insert_nops_str;
161 enum rs6000_nop_insertion rs6000_sched_insert_nops;
163 /* Support targetm.vectorize.builtin_mask_for_load. */
164 static GTY(()) tree altivec_builtin_mask_for_load;
166 /* Size of long double. */
167 int rs6000_long_double_type_size;
169 /* IEEE quad extended precision long double. */
172 /* Nonzero to use AltiVec ABI. */
173 int rs6000_altivec_abi;
175 /* Nonzero if we want SPE SIMD instructions. */
178 /* Nonzero if we want SPE ABI extensions. */
181 /* Nonzero if floating point operations are done in the GPRs. */
182 int rs6000_float_gprs = 0;
184 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
185 int rs6000_darwin64_abi;
187 /* Set to nonzero once AIX common-mode calls have been defined. */
188 static GTY(()) int common_mode_defined;
190 /* Label number of label created for -mrelocatable, to call to so we can
191 get the address of the GOT section */
192 int rs6000_pic_labelno;
195 /* Which abi to adhere to */
196 const char *rs6000_abi_name;
198 /* Semantics of the small data area */
199 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
201 /* Which small data model to use */
202 const char *rs6000_sdata_name = (char *)0;
204 /* Counter for labels which are to be placed in .fixup. */
205 int fixuplabelno = 0;
208 /* Bit size of immediate TLS offsets and string from which it is decoded. */
209 int rs6000_tls_size = 32;
210 const char *rs6000_tls_size_string;
212 /* ABI enumeration available for subtarget to use. */
213 enum rs6000_abi rs6000_current_abi;
215 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
219 const char *rs6000_debug_name;
220 int rs6000_debug_stack; /* debug stack applications */
221 int rs6000_debug_arg; /* debug argument handling */
222 int rs6000_debug_reg; /* debug register classes */
223 int rs6000_debug_addr; /* debug memory addressing */
224 int rs6000_debug_cost; /* debug rtx_costs */
226 /* Specify the machine mode that pointers have. After generation of rtl, the
227 compiler makes no further distinction between pointers and any other objects
228 of this machine mode. The type is unsigned since not all things that
229 include rs6000.h also include machmode.h. */
230 unsigned rs6000_pmode;
232 /* Width in bits of a pointer. */
233 unsigned rs6000_pointer_size;
236 /* Value is TRUE if register/mode pair is acceptable. */
237 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
239 /* Maximum number of registers needed for a given register class and mode. */
240 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
242 /* How many registers are needed for a given register and mode. */
243 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
245 /* Map register number to register class. */
246 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
248 /* Reload functions based on the type and the vector unit. */
249 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
251 /* Built in types. */
252 tree rs6000_builtin_types[RS6000_BTI_MAX];
253 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
255 const char *rs6000_traceback_name;
257 traceback_default = 0,
263 /* Flag to say the TOC is initialized */
265 char toc_label_name[10];
267 /* Cached value of rs6000_variable_issue. This is cached in
268 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
269 static short cached_can_issue_more;
271 static GTY(()) section *read_only_data_section;
272 static GTY(()) section *private_data_section;
273 static GTY(()) section *read_only_private_data_section;
274 static GTY(()) section *sdata2_section;
275 static GTY(()) section *toc_section;
277 /* Control alignment for fields within structures. */
278 /* String from -malign-XXXXX. */
279 int rs6000_alignment_flags;
281 /* True for any options that were explicitly set. */
283 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
284 bool alignment; /* True if -malign- was used. */
285 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
286 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
287 bool spe; /* True if -mspe= was used. */
288 bool float_gprs; /* True if -mfloat-gprs= was used. */
289 bool long_double; /* True if -mlong-double- was used. */
290 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
291 bool vrsave; /* True if -mvrsave was used. */
292 } rs6000_explicit_options;
294 struct builtin_description
296 /* mask is not const because we're going to alter it below. This
297 nonsense will go away when we rewrite the -march infrastructure
298 to give us more target flag bits. */
300 const enum insn_code icode;
301 const char *const name;
302 const enum rs6000_builtins code;
305 /* Describe the vector unit used for modes. */
306 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
307 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
309 /* Register classes for various constraints that are based on the target
311 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
313 /* Describe the alignment of a vector. */
314 int rs6000_vector_align[NUM_MACHINE_MODES];
316 /* Map selected modes to types for builtins. */
317 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
319 /* Target cpu costs. */
321 struct processor_costs {
322 const int mulsi; /* cost of SImode multiplication. */
323 const int mulsi_const; /* cost of SImode multiplication by constant. */
324 const int mulsi_const9; /* cost of SImode mult by short constant. */
325 const int muldi; /* cost of DImode multiplication. */
326 const int divsi; /* cost of SImode division. */
327 const int divdi; /* cost of DImode division. */
328 const int fp; /* cost of simple SFmode and DFmode insns. */
329 const int dmul; /* cost of DFmode multiplication (and fmadd). */
330 const int sdiv; /* cost of SFmode division (fdivs). */
331 const int ddiv; /* cost of DFmode division (fdiv). */
332 const int cache_line_size; /* cache line size in bytes. */
333 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
334 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
335 const int simultaneous_prefetches; /* number of parallel prefetch
339 const struct processor_costs *rs6000_cost;
341 /* Processor costs (relative to an add) */
343 /* Instruction size costs on 32bit processors. */
345 struct processor_costs size32_cost = {
346 COSTS_N_INSNS (1), /* mulsi */
347 COSTS_N_INSNS (1), /* mulsi_const */
348 COSTS_N_INSNS (1), /* mulsi_const9 */
349 COSTS_N_INSNS (1), /* muldi */
350 COSTS_N_INSNS (1), /* divsi */
351 COSTS_N_INSNS (1), /* divdi */
352 COSTS_N_INSNS (1), /* fp */
353 COSTS_N_INSNS (1), /* dmul */
354 COSTS_N_INSNS (1), /* sdiv */
355 COSTS_N_INSNS (1), /* ddiv */
362 /* Instruction size costs on 64bit processors. */
364 struct processor_costs size64_cost = {
365 COSTS_N_INSNS (1), /* mulsi */
366 COSTS_N_INSNS (1), /* mulsi_const */
367 COSTS_N_INSNS (1), /* mulsi_const9 */
368 COSTS_N_INSNS (1), /* muldi */
369 COSTS_N_INSNS (1), /* divsi */
370 COSTS_N_INSNS (1), /* divdi */
371 COSTS_N_INSNS (1), /* fp */
372 COSTS_N_INSNS (1), /* dmul */
373 COSTS_N_INSNS (1), /* sdiv */
374 COSTS_N_INSNS (1), /* ddiv */
381 /* Instruction costs on RIOS1 processors. */
383 struct processor_costs rios1_cost = {
384 COSTS_N_INSNS (5), /* mulsi */
385 COSTS_N_INSNS (4), /* mulsi_const */
386 COSTS_N_INSNS (3), /* mulsi_const9 */
387 COSTS_N_INSNS (5), /* muldi */
388 COSTS_N_INSNS (19), /* divsi */
389 COSTS_N_INSNS (19), /* divdi */
390 COSTS_N_INSNS (2), /* fp */
391 COSTS_N_INSNS (2), /* dmul */
392 COSTS_N_INSNS (19), /* sdiv */
393 COSTS_N_INSNS (19), /* ddiv */
394 128, /* cache line size */
400 /* Instruction costs on RIOS2 processors. */
402 struct processor_costs rios2_cost = {
403 COSTS_N_INSNS (2), /* mulsi */
404 COSTS_N_INSNS (2), /* mulsi_const */
405 COSTS_N_INSNS (2), /* mulsi_const9 */
406 COSTS_N_INSNS (2), /* muldi */
407 COSTS_N_INSNS (13), /* divsi */
408 COSTS_N_INSNS (13), /* divdi */
409 COSTS_N_INSNS (2), /* fp */
410 COSTS_N_INSNS (2), /* dmul */
411 COSTS_N_INSNS (17), /* sdiv */
412 COSTS_N_INSNS (17), /* ddiv */
413 256, /* cache line size */
419 /* Instruction costs on RS64A processors. */
421 struct processor_costs rs64a_cost = {
422 COSTS_N_INSNS (20), /* mulsi */
423 COSTS_N_INSNS (12), /* mulsi_const */
424 COSTS_N_INSNS (8), /* mulsi_const9 */
425 COSTS_N_INSNS (34), /* muldi */
426 COSTS_N_INSNS (65), /* divsi */
427 COSTS_N_INSNS (67), /* divdi */
428 COSTS_N_INSNS (4), /* fp */
429 COSTS_N_INSNS (4), /* dmul */
430 COSTS_N_INSNS (31), /* sdiv */
431 COSTS_N_INSNS (31), /* ddiv */
432 128, /* cache line size */
438 /* Instruction costs on MPCCORE processors. */
440 struct processor_costs mpccore_cost = {
441 COSTS_N_INSNS (2), /* mulsi */
442 COSTS_N_INSNS (2), /* mulsi_const */
443 COSTS_N_INSNS (2), /* mulsi_const9 */
444 COSTS_N_INSNS (2), /* muldi */
445 COSTS_N_INSNS (6), /* divsi */
446 COSTS_N_INSNS (6), /* divdi */
447 COSTS_N_INSNS (4), /* fp */
448 COSTS_N_INSNS (5), /* dmul */
449 COSTS_N_INSNS (10), /* sdiv */
450 COSTS_N_INSNS (17), /* ddiv */
451 32, /* cache line size */
457 /* Instruction costs on PPC403 processors. */
459 struct processor_costs ppc403_cost = {
460 COSTS_N_INSNS (4), /* mulsi */
461 COSTS_N_INSNS (4), /* mulsi_const */
462 COSTS_N_INSNS (4), /* mulsi_const9 */
463 COSTS_N_INSNS (4), /* muldi */
464 COSTS_N_INSNS (33), /* divsi */
465 COSTS_N_INSNS (33), /* divdi */
466 COSTS_N_INSNS (11), /* fp */
467 COSTS_N_INSNS (11), /* dmul */
468 COSTS_N_INSNS (11), /* sdiv */
469 COSTS_N_INSNS (11), /* ddiv */
470 32, /* cache line size */
476 /* Instruction costs on PPC405 processors. */
478 struct processor_costs ppc405_cost = {
479 COSTS_N_INSNS (5), /* mulsi */
480 COSTS_N_INSNS (4), /* mulsi_const */
481 COSTS_N_INSNS (3), /* mulsi_const9 */
482 COSTS_N_INSNS (5), /* muldi */
483 COSTS_N_INSNS (35), /* divsi */
484 COSTS_N_INSNS (35), /* divdi */
485 COSTS_N_INSNS (11), /* fp */
486 COSTS_N_INSNS (11), /* dmul */
487 COSTS_N_INSNS (11), /* sdiv */
488 COSTS_N_INSNS (11), /* ddiv */
489 32, /* cache line size */
495 /* Instruction costs on PPC440 processors. */
497 struct processor_costs ppc440_cost = {
498 COSTS_N_INSNS (3), /* mulsi */
499 COSTS_N_INSNS (2), /* mulsi_const */
500 COSTS_N_INSNS (2), /* mulsi_const9 */
501 COSTS_N_INSNS (3), /* muldi */
502 COSTS_N_INSNS (34), /* divsi */
503 COSTS_N_INSNS (34), /* divdi */
504 COSTS_N_INSNS (5), /* fp */
505 COSTS_N_INSNS (5), /* dmul */
506 COSTS_N_INSNS (19), /* sdiv */
507 COSTS_N_INSNS (33), /* ddiv */
508 32, /* cache line size */
514 /* Instruction costs on PPC476 processors. */
516 struct processor_costs ppc476_cost = {
517 COSTS_N_INSNS (4), /* mulsi */
518 COSTS_N_INSNS (4), /* mulsi_const */
519 COSTS_N_INSNS (4), /* mulsi_const9 */
520 COSTS_N_INSNS (4), /* muldi */
521 COSTS_N_INSNS (11), /* divsi */
522 COSTS_N_INSNS (11), /* divdi */
523 COSTS_N_INSNS (6), /* fp */
524 COSTS_N_INSNS (6), /* dmul */
525 COSTS_N_INSNS (19), /* sdiv */
526 COSTS_N_INSNS (33), /* ddiv */
527 32, /* l1 cache line size */
533 /* Instruction costs on PPC601 processors. */
535 struct processor_costs ppc601_cost = {
536 COSTS_N_INSNS (5), /* mulsi */
537 COSTS_N_INSNS (5), /* mulsi_const */
538 COSTS_N_INSNS (5), /* mulsi_const9 */
539 COSTS_N_INSNS (5), /* muldi */
540 COSTS_N_INSNS (36), /* divsi */
541 COSTS_N_INSNS (36), /* divdi */
542 COSTS_N_INSNS (4), /* fp */
543 COSTS_N_INSNS (5), /* dmul */
544 COSTS_N_INSNS (17), /* sdiv */
545 COSTS_N_INSNS (31), /* ddiv */
546 32, /* cache line size */
552 /* Instruction costs on PPC603 processors. */
554 struct processor_costs ppc603_cost = {
555 COSTS_N_INSNS (5), /* mulsi */
556 COSTS_N_INSNS (3), /* mulsi_const */
557 COSTS_N_INSNS (2), /* mulsi_const9 */
558 COSTS_N_INSNS (5), /* muldi */
559 COSTS_N_INSNS (37), /* divsi */
560 COSTS_N_INSNS (37), /* divdi */
561 COSTS_N_INSNS (3), /* fp */
562 COSTS_N_INSNS (4), /* dmul */
563 COSTS_N_INSNS (18), /* sdiv */
564 COSTS_N_INSNS (33), /* ddiv */
565 32, /* cache line size */
571 /* Instruction costs on PPC604 processors. */
573 struct processor_costs ppc604_cost = {
574 COSTS_N_INSNS (4), /* mulsi */
575 COSTS_N_INSNS (4), /* mulsi_const */
576 COSTS_N_INSNS (4), /* mulsi_const9 */
577 COSTS_N_INSNS (4), /* muldi */
578 COSTS_N_INSNS (20), /* divsi */
579 COSTS_N_INSNS (20), /* divdi */
580 COSTS_N_INSNS (3), /* fp */
581 COSTS_N_INSNS (3), /* dmul */
582 COSTS_N_INSNS (18), /* sdiv */
583 COSTS_N_INSNS (32), /* ddiv */
584 32, /* cache line size */
590 /* Instruction costs on PPC604e processors. */
592 struct processor_costs ppc604e_cost = {
593 COSTS_N_INSNS (2), /* mulsi */
594 COSTS_N_INSNS (2), /* mulsi_const */
595 COSTS_N_INSNS (2), /* mulsi_const9 */
596 COSTS_N_INSNS (2), /* muldi */
597 COSTS_N_INSNS (20), /* divsi */
598 COSTS_N_INSNS (20), /* divdi */
599 COSTS_N_INSNS (3), /* fp */
600 COSTS_N_INSNS (3), /* dmul */
601 COSTS_N_INSNS (18), /* sdiv */
602 COSTS_N_INSNS (32), /* ddiv */
603 32, /* cache line size */
609 /* Instruction costs on PPC620 processors. */
611 struct processor_costs ppc620_cost = {
612 COSTS_N_INSNS (5), /* mulsi */
613 COSTS_N_INSNS (4), /* mulsi_const */
614 COSTS_N_INSNS (3), /* mulsi_const9 */
615 COSTS_N_INSNS (7), /* muldi */
616 COSTS_N_INSNS (21), /* divsi */
617 COSTS_N_INSNS (37), /* divdi */
618 COSTS_N_INSNS (3), /* fp */
619 COSTS_N_INSNS (3), /* dmul */
620 COSTS_N_INSNS (18), /* sdiv */
621 COSTS_N_INSNS (32), /* ddiv */
622 128, /* cache line size */
628 /* Instruction costs on PPC630 processors. */
630 struct processor_costs ppc630_cost = {
631 COSTS_N_INSNS (5), /* mulsi */
632 COSTS_N_INSNS (4), /* mulsi_const */
633 COSTS_N_INSNS (3), /* mulsi_const9 */
634 COSTS_N_INSNS (7), /* muldi */
635 COSTS_N_INSNS (21), /* divsi */
636 COSTS_N_INSNS (37), /* divdi */
637 COSTS_N_INSNS (3), /* fp */
638 COSTS_N_INSNS (3), /* dmul */
639 COSTS_N_INSNS (17), /* sdiv */
640 COSTS_N_INSNS (21), /* ddiv */
641 128, /* cache line size */
647 /* Instruction costs on Cell processor. */
648 /* COSTS_N_INSNS (1) ~ one add. */
650 struct processor_costs ppccell_cost = {
651 COSTS_N_INSNS (9/2)+2, /* mulsi */
652 COSTS_N_INSNS (6/2), /* mulsi_const */
653 COSTS_N_INSNS (6/2), /* mulsi_const9 */
654 COSTS_N_INSNS (15/2)+2, /* muldi */
655 COSTS_N_INSNS (38/2), /* divsi */
656 COSTS_N_INSNS (70/2), /* divdi */
657 COSTS_N_INSNS (10/2), /* fp */
658 COSTS_N_INSNS (10/2), /* dmul */
659 COSTS_N_INSNS (74/2), /* sdiv */
660 COSTS_N_INSNS (74/2), /* ddiv */
661 128, /* cache line size */
667 /* Instruction costs on PPC750 and PPC7400 processors. */
669 struct processor_costs ppc750_cost = {
670 COSTS_N_INSNS (5), /* mulsi */
671 COSTS_N_INSNS (3), /* mulsi_const */
672 COSTS_N_INSNS (2), /* mulsi_const9 */
673 COSTS_N_INSNS (5), /* muldi */
674 COSTS_N_INSNS (17), /* divsi */
675 COSTS_N_INSNS (17), /* divdi */
676 COSTS_N_INSNS (3), /* fp */
677 COSTS_N_INSNS (3), /* dmul */
678 COSTS_N_INSNS (17), /* sdiv */
679 COSTS_N_INSNS (31), /* ddiv */
680 32, /* cache line size */
686 /* Instruction costs on PPC7450 processors. */
688 struct processor_costs ppc7450_cost = {
689 COSTS_N_INSNS (4), /* mulsi */
690 COSTS_N_INSNS (3), /* mulsi_const */
691 COSTS_N_INSNS (3), /* mulsi_const9 */
692 COSTS_N_INSNS (4), /* muldi */
693 COSTS_N_INSNS (23), /* divsi */
694 COSTS_N_INSNS (23), /* divdi */
695 COSTS_N_INSNS (5), /* fp */
696 COSTS_N_INSNS (5), /* dmul */
697 COSTS_N_INSNS (21), /* sdiv */
698 COSTS_N_INSNS (35), /* ddiv */
699 32, /* cache line size */
705 /* Instruction costs on PPC8540 processors. */
707 struct processor_costs ppc8540_cost = {
708 COSTS_N_INSNS (4), /* mulsi */
709 COSTS_N_INSNS (4), /* mulsi_const */
710 COSTS_N_INSNS (4), /* mulsi_const9 */
711 COSTS_N_INSNS (4), /* muldi */
712 COSTS_N_INSNS (19), /* divsi */
713 COSTS_N_INSNS (19), /* divdi */
714 COSTS_N_INSNS (4), /* fp */
715 COSTS_N_INSNS (4), /* dmul */
716 COSTS_N_INSNS (29), /* sdiv */
717 COSTS_N_INSNS (29), /* ddiv */
718 32, /* cache line size */
721 1, /* prefetch streams /*/
724 /* Instruction costs on E300C2 and E300C3 cores. */
726 struct processor_costs ppce300c2c3_cost = {
727 COSTS_N_INSNS (4), /* mulsi */
728 COSTS_N_INSNS (4), /* mulsi_const */
729 COSTS_N_INSNS (4), /* mulsi_const9 */
730 COSTS_N_INSNS (4), /* muldi */
731 COSTS_N_INSNS (19), /* divsi */
732 COSTS_N_INSNS (19), /* divdi */
733 COSTS_N_INSNS (3), /* fp */
734 COSTS_N_INSNS (4), /* dmul */
735 COSTS_N_INSNS (18), /* sdiv */
736 COSTS_N_INSNS (33), /* ddiv */
740 1, /* prefetch streams /*/
743 /* Instruction costs on PPCE500MC processors. */
745 struct processor_costs ppce500mc_cost = {
746 COSTS_N_INSNS (4), /* mulsi */
747 COSTS_N_INSNS (4), /* mulsi_const */
748 COSTS_N_INSNS (4), /* mulsi_const9 */
749 COSTS_N_INSNS (4), /* muldi */
750 COSTS_N_INSNS (14), /* divsi */
751 COSTS_N_INSNS (14), /* divdi */
752 COSTS_N_INSNS (8), /* fp */
753 COSTS_N_INSNS (10), /* dmul */
754 COSTS_N_INSNS (36), /* sdiv */
755 COSTS_N_INSNS (66), /* ddiv */
756 64, /* cache line size */
759 1, /* prefetch streams /*/
762 /* Instruction costs on POWER4 and POWER5 processors. */
764 struct processor_costs power4_cost = {
765 COSTS_N_INSNS (3), /* mulsi */
766 COSTS_N_INSNS (2), /* mulsi_const */
767 COSTS_N_INSNS (2), /* mulsi_const9 */
768 COSTS_N_INSNS (4), /* muldi */
769 COSTS_N_INSNS (18), /* divsi */
770 COSTS_N_INSNS (34), /* divdi */
771 COSTS_N_INSNS (3), /* fp */
772 COSTS_N_INSNS (3), /* dmul */
773 COSTS_N_INSNS (17), /* sdiv */
774 COSTS_N_INSNS (17), /* ddiv */
775 128, /* cache line size */
778 8, /* prefetch streams /*/
781 /* Instruction costs on POWER6 processors. */
783 struct processor_costs power6_cost = {
784 COSTS_N_INSNS (8), /* mulsi */
785 COSTS_N_INSNS (8), /* mulsi_const */
786 COSTS_N_INSNS (8), /* mulsi_const9 */
787 COSTS_N_INSNS (8), /* muldi */
788 COSTS_N_INSNS (22), /* divsi */
789 COSTS_N_INSNS (28), /* divdi */
790 COSTS_N_INSNS (3), /* fp */
791 COSTS_N_INSNS (3), /* dmul */
792 COSTS_N_INSNS (13), /* sdiv */
793 COSTS_N_INSNS (16), /* ddiv */
794 128, /* cache line size */
797 16, /* prefetch streams */
800 /* Instruction costs on POWER7 processors. */
802 struct processor_costs power7_cost = {
803 COSTS_N_INSNS (2), /* mulsi */
804 COSTS_N_INSNS (2), /* mulsi_const */
805 COSTS_N_INSNS (2), /* mulsi_const9 */
806 COSTS_N_INSNS (2), /* muldi */
807 COSTS_N_INSNS (18), /* divsi */
808 COSTS_N_INSNS (34), /* divdi */
809 COSTS_N_INSNS (3), /* fp */
810 COSTS_N_INSNS (3), /* dmul */
811 COSTS_N_INSNS (13), /* sdiv */
812 COSTS_N_INSNS (16), /* ddiv */
813 128, /* cache line size */
816 12, /* prefetch streams */
819 /* Instruction costs on POWER A2 processors. */
821 struct processor_costs ppca2_cost = {
822 COSTS_N_INSNS (16), /* mulsi */
823 COSTS_N_INSNS (16), /* mulsi_const */
824 COSTS_N_INSNS (16), /* mulsi_const9 */
825 COSTS_N_INSNS (16), /* muldi */
826 COSTS_N_INSNS (22), /* divsi */
827 COSTS_N_INSNS (28), /* divdi */
828 COSTS_N_INSNS (3), /* fp */
829 COSTS_N_INSNS (3), /* dmul */
830 COSTS_N_INSNS (59), /* sdiv */
831 COSTS_N_INSNS (72), /* ddiv */
835 16, /* prefetch streams */
839 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
840 #undef RS6000_BUILTIN
841 #undef RS6000_BUILTIN_EQUATE
842 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
843 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
845 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
847 #include "rs6000-builtin.def"
850 #undef RS6000_BUILTIN
851 #undef RS6000_BUILTIN_EQUATE
854 static bool rs6000_function_ok_for_sibcall (tree, tree);
855 static const char *rs6000_invalid_within_doloop (const_rtx);
856 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
857 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
858 static rtx rs6000_generate_compare (rtx, enum machine_mode);
859 static void rs6000_emit_stack_tie (void);
860 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
861 static bool spe_func_has_64bit_regs_p (void);
862 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
864 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
865 static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int, int);
866 static unsigned rs6000_hash_constant (rtx);
867 static unsigned toc_hash_function (const void *);
868 static int toc_hash_eq (const void *, const void *);
869 static bool reg_offset_addressing_ok_p (enum machine_mode);
870 static bool virtual_stack_registers_memory_p (rtx);
871 static bool constant_pool_expr_p (rtx);
872 static bool legitimate_small_data_p (enum machine_mode, rtx);
873 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
874 static struct machine_function * rs6000_init_machine_status (void);
875 static bool rs6000_assemble_integer (rtx, unsigned int, int);
876 static bool no_global_regs_above (int, bool);
877 #ifdef HAVE_GAS_HIDDEN
878 static void rs6000_assemble_visibility (tree, int);
880 static int rs6000_ra_ever_killed (void);
881 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
882 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
883 static bool rs6000_ms_bitfield_layout_p (const_tree);
884 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
885 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
886 static const char *rs6000_mangle_type (const_tree);
887 static void rs6000_set_default_type_attributes (tree);
888 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
889 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
890 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
891 enum machine_mode, bool, bool, bool);
892 static bool rs6000_reg_live_or_pic_offset_p (int);
893 static tree rs6000_builtin_vectorized_function (unsigned int, tree, tree);
894 static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
895 static void rs6000_restore_saved_cr (rtx, int);
896 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
897 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
898 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
900 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
901 static bool rs6000_return_in_memory (const_tree, const_tree);
902 static rtx rs6000_function_value (const_tree, const_tree, bool);
903 static void rs6000_file_start (void);
905 static int rs6000_elf_reloc_rw_mask (void);
906 static void rs6000_elf_asm_out_constructor (rtx, int);
907 static void rs6000_elf_asm_out_destructor (rtx, int);
908 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
909 static void rs6000_elf_asm_init_sections (void);
910 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
911 unsigned HOST_WIDE_INT);
912 static void rs6000_elf_encode_section_info (tree, rtx, int)
915 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
916 static void rs6000_alloc_sdmode_stack_slot (void);
917 static void rs6000_instantiate_decls (void);
919 static void rs6000_xcoff_asm_output_anchor (rtx);
920 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
921 static void rs6000_xcoff_asm_init_sections (void);
922 static int rs6000_xcoff_reloc_rw_mask (void);
923 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
924 static section *rs6000_xcoff_select_section (tree, int,
925 unsigned HOST_WIDE_INT);
926 static void rs6000_xcoff_unique_section (tree, int);
927 static section *rs6000_xcoff_select_rtx_section
928 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
929 static const char * rs6000_xcoff_strip_name_encoding (const char *);
930 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
931 static void rs6000_xcoff_file_start (void);
932 static void rs6000_xcoff_file_end (void);
934 static int rs6000_variable_issue (FILE *, int, rtx, int);
935 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
936 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
937 static int rs6000_debug_address_cost (rtx, bool);
938 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
939 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
940 static void rs6000_sched_init (FILE *, int, int);
941 static bool is_microcoded_insn (rtx);
942 static bool is_nonpipeline_insn (rtx);
943 static bool is_cracked_insn (rtx);
944 static bool is_branch_slot_insn (rtx);
945 static bool is_load_insn (rtx);
946 static rtx get_store_dest (rtx pat);
947 static bool is_store_insn (rtx);
948 static bool set_to_load_agen (rtx,rtx);
949 static bool adjacent_mem_locations (rtx,rtx);
950 static int rs6000_adjust_priority (rtx, int);
951 static int rs6000_issue_rate (void);
952 static bool rs6000_is_costly_dependence (dep_t, int, int);
953 static rtx get_next_active_insn (rtx, rtx);
954 static bool insn_terminates_group_p (rtx , enum group_termination);
955 static bool insn_must_be_first_in_group (rtx);
956 static bool insn_must_be_last_in_group (rtx);
957 static bool is_costly_group (rtx *, rtx);
958 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
959 static int redefine_groups (FILE *, int, rtx, rtx);
960 static int pad_groups (FILE *, int, rtx, rtx);
961 static void rs6000_sched_finish (FILE *, int);
962 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
963 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
964 static int rs6000_use_sched_lookahead (void);
965 static int rs6000_use_sched_lookahead_guard (rtx);
966 static void * rs6000_alloc_sched_context (void);
967 static void rs6000_init_sched_context (void *, bool);
968 static void rs6000_set_sched_context (void *);
969 static void rs6000_free_sched_context (void *);
970 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
971 static tree rs6000_builtin_mask_for_load (void);
972 static tree rs6000_builtin_mul_widen_even (tree);
973 static tree rs6000_builtin_mul_widen_odd (tree);
974 static tree rs6000_builtin_conversion (unsigned int, tree);
975 static tree rs6000_builtin_vec_perm (tree, tree *);
976 static bool rs6000_builtin_support_vector_misalignment (enum
981 static void def_builtin (int, const char *, tree, int);
982 static bool rs6000_vector_alignment_reachable (const_tree, bool);
983 static void rs6000_init_builtins (void);
984 static tree rs6000_builtin_decl (unsigned, bool);
986 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
987 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
988 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
989 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
990 static void altivec_init_builtins (void);
991 static unsigned builtin_hash_function (const void *);
992 static int builtin_hash_eq (const void *, const void *);
993 static tree builtin_function_type (enum machine_mode, enum machine_mode,
994 enum machine_mode, enum machine_mode,
995 enum rs6000_builtins, const char *name);
996 static void rs6000_common_init_builtins (void);
997 static void rs6000_init_libfuncs (void);
999 static void paired_init_builtins (void);
1000 static rtx paired_expand_builtin (tree, rtx, bool *);
1001 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1002 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1003 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1005 static void enable_mask_for_builtins (struct builtin_description *, int,
1006 enum rs6000_builtins,
1007 enum rs6000_builtins);
1008 static void spe_init_builtins (void);
1009 static rtx spe_expand_builtin (tree, rtx, bool *);
1010 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1011 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1012 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1013 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1014 static rs6000_stack_t *rs6000_stack_info (void);
1015 static void debug_stack_info (rs6000_stack_t *);
1017 static rtx altivec_expand_builtin (tree, rtx, bool *);
1018 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1019 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1020 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1021 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1022 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1023 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1024 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1025 static rtx altivec_expand_vec_set_builtin (tree);
1026 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1027 static int get_element_number (tree, tree);
1028 static bool rs6000_handle_option (size_t, const char *, int);
1029 static void rs6000_parse_tls_size_option (void);
1030 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1031 static int first_altivec_reg_to_save (void);
1032 static unsigned int compute_vrsave_mask (void);
1033 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1034 static void is_altivec_return_reg (rtx, void *);
1035 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1036 int easy_vector_constant (rtx, enum machine_mode);
1037 static rtx rs6000_dwarf_register_span (rtx);
1038 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1039 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1040 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1041 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1042 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1043 static rtx rs6000_tls_get_addr (void);
1044 static rtx rs6000_got_sym (void);
1045 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1046 static const char *rs6000_get_some_local_dynamic_name (void);
1047 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1048 static rtx rs6000_complex_function_value (enum machine_mode);
1049 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
1050 enum machine_mode, tree);
1051 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1053 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1054 tree, HOST_WIDE_INT);
1055 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1058 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1059 const_tree, HOST_WIDE_INT,
1061 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
1062 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
1063 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1064 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1065 enum machine_mode, tree,
1067 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1069 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1071 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1073 static void macho_branch_islands (void);
1074 static int no_previous_def (tree function_name);
1075 static tree get_prev_label (tree function_name);
1076 static void rs6000_darwin_file_start (void);
1079 static tree rs6000_build_builtin_va_list (void);
1080 static void rs6000_va_start (tree, rtx);
1081 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1082 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1083 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1084 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1085 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1086 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1088 static tree rs6000_stack_protect_fail (void);
1090 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1093 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1096 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1098 = rs6000_legitimize_reload_address;
1100 static bool rs6000_mode_dependent_address (rtx);
1101 static bool rs6000_debug_mode_dependent_address (rtx);
1102 bool (*rs6000_mode_dependent_address_ptr) (rtx)
1103 = rs6000_mode_dependent_address;
1105 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1106 enum machine_mode, rtx);
1107 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1110 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1111 enum machine_mode, rtx)
1112 = rs6000_secondary_reload_class;
1114 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1115 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1117 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1118 = rs6000_preferred_reload_class;
1120 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1123 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1127 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1129 = rs6000_secondary_memory_needed;
1131 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1134 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1138 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1141 = rs6000_cannot_change_mode_class;
1143 static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class,
1145 struct secondary_reload_info *);
1147 static const enum reg_class *rs6000_ira_cover_classes (void);
1149 const int INSN_NOT_AVAILABLE = -1;
1150 static enum machine_mode rs6000_eh_return_filter_mode (void);
1151 static bool rs6000_can_eliminate (const int, const int);
1152 static void rs6000_trampoline_init (rtx, tree, rtx);
1154 /* Hash table stuff for keeping track of TOC entries. */
1156 struct GTY(()) toc_hash_struct
1158 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1159 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1161 enum machine_mode key_mode;
1165 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1167 /* Hash table to keep track of the argument types for builtin functions. */
1169 struct GTY(()) builtin_hash_struct
1172 enum machine_mode mode[4]; /* return value + 3 arguments. */
1173 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1176 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1178 /* Default register names. */
1179 char rs6000_reg_names[][8] =
1181 "0", "1", "2", "3", "4", "5", "6", "7",
1182 "8", "9", "10", "11", "12", "13", "14", "15",
1183 "16", "17", "18", "19", "20", "21", "22", "23",
1184 "24", "25", "26", "27", "28", "29", "30", "31",
1185 "0", "1", "2", "3", "4", "5", "6", "7",
1186 "8", "9", "10", "11", "12", "13", "14", "15",
1187 "16", "17", "18", "19", "20", "21", "22", "23",
1188 "24", "25", "26", "27", "28", "29", "30", "31",
1189 "mq", "lr", "ctr","ap",
1190 "0", "1", "2", "3", "4", "5", "6", "7",
1192 /* AltiVec registers. */
1193 "0", "1", "2", "3", "4", "5", "6", "7",
1194 "8", "9", "10", "11", "12", "13", "14", "15",
1195 "16", "17", "18", "19", "20", "21", "22", "23",
1196 "24", "25", "26", "27", "28", "29", "30", "31",
1198 /* SPE registers. */
1199 "spe_acc", "spefscr",
1200 /* Soft frame pointer. */
1204 #ifdef TARGET_REGNAMES
1205 static const char alt_reg_names[][8] =
1207 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1208 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1209 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1210 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1211 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1212 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1213 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1214 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1215 "mq", "lr", "ctr", "ap",
1216 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1218 /* AltiVec registers. */
1219 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1220 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1221 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1222 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1224 /* SPE registers. */
1225 "spe_acc", "spefscr",
1226 /* Soft frame pointer. */
1231 /* Table of valid machine attributes. */
1233 static const struct attribute_spec rs6000_attribute_table[] =
1235 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1236 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1237 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1238 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1239 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1240 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1241 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1242 SUBTARGET_ATTRIBUTE_TABLE,
1244 { NULL, 0, 0, false, false, false, NULL }
1247 #ifndef MASK_STRICT_ALIGN
1248 #define MASK_STRICT_ALIGN 0
1250 #ifndef TARGET_PROFILE_KERNEL
1251 #define TARGET_PROFILE_KERNEL 0
1252 #define SET_PROFILE_KERNEL(N)
1254 #define SET_PROFILE_KERNEL(N) TARGET_PROFILE_KERNEL = (N)
1257 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1258 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1260 /* Initialize the GCC target structure. */
1261 #undef TARGET_ATTRIBUTE_TABLE
1262 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1263 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1264 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1266 #undef TARGET_ASM_ALIGNED_DI_OP
1267 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1269 /* Default unaligned ops are only provided for ELF. Find the ops needed
1270 for non-ELF systems. */
1271 #ifndef OBJECT_FORMAT_ELF
1273 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1275 #undef TARGET_ASM_UNALIGNED_HI_OP
1276 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1277 #undef TARGET_ASM_UNALIGNED_SI_OP
1278 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1279 #undef TARGET_ASM_UNALIGNED_DI_OP
1280 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1283 #undef TARGET_ASM_UNALIGNED_HI_OP
1284 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1285 #undef TARGET_ASM_UNALIGNED_SI_OP
1286 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1287 #undef TARGET_ASM_UNALIGNED_DI_OP
1288 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1289 #undef TARGET_ASM_ALIGNED_DI_OP
1290 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1294 /* This hook deals with fixups for relocatable code and DI-mode objects
1296 #undef TARGET_ASM_INTEGER
1297 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1299 #ifdef HAVE_GAS_HIDDEN
1300 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1301 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1304 #undef TARGET_HAVE_TLS
1305 #define TARGET_HAVE_TLS HAVE_AS_TLS
1307 #undef TARGET_CANNOT_FORCE_CONST_MEM
1308 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1310 #undef TARGET_ASM_FUNCTION_PROLOGUE
1311 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1312 #undef TARGET_ASM_FUNCTION_EPILOGUE
1313 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1315 #undef TARGET_LEGITIMIZE_ADDRESS
1316 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1318 #undef TARGET_SCHED_VARIABLE_ISSUE
1319 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1321 #undef TARGET_SCHED_ISSUE_RATE
1322 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1323 #undef TARGET_SCHED_ADJUST_COST
1324 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1325 #undef TARGET_SCHED_ADJUST_PRIORITY
1326 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1327 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1328 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1329 #undef TARGET_SCHED_INIT
1330 #define TARGET_SCHED_INIT rs6000_sched_init
1331 #undef TARGET_SCHED_FINISH
1332 #define TARGET_SCHED_FINISH rs6000_sched_finish
1333 #undef TARGET_SCHED_REORDER
1334 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1335 #undef TARGET_SCHED_REORDER2
1336 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1338 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1339 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1341 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1342 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1344 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1345 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1346 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1347 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1348 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1349 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1350 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1351 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1353 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1354 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1355 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1356 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1357 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1358 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1359 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1360 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1361 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1362 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1363 #undef TARGET_SUPPORT_VECTOR_MISALIGNMENT
1364 #define TARGET_SUPPORT_VECTOR_MISALIGNMENT \
1365 rs6000_builtin_support_vector_misalignment
1366 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1367 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1369 #undef TARGET_INIT_BUILTINS
1370 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1371 #undef TARGET_BUILTIN_DECL
1372 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1374 #undef TARGET_EXPAND_BUILTIN
1375 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1377 #undef TARGET_MANGLE_TYPE
1378 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1380 #undef TARGET_INIT_LIBFUNCS
1381 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1384 #undef TARGET_BINDS_LOCAL_P
1385 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1388 #undef TARGET_MS_BITFIELD_LAYOUT_P
1389 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1391 #undef TARGET_ASM_OUTPUT_MI_THUNK
1392 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1394 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1395 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1397 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1398 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1400 #undef TARGET_INVALID_WITHIN_DOLOOP
1401 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1403 #undef TARGET_RTX_COSTS
1404 #define TARGET_RTX_COSTS rs6000_rtx_costs
1405 #undef TARGET_ADDRESS_COST
1406 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1408 #undef TARGET_DWARF_REGISTER_SPAN
1409 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1411 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1412 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1414 /* On rs6000, function arguments are promoted, as are function return
1416 #undef TARGET_PROMOTE_FUNCTION_MODE
1417 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1419 #undef TARGET_RETURN_IN_MEMORY
1420 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1422 #undef TARGET_SETUP_INCOMING_VARARGS
1423 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1425 /* Always strict argument naming on rs6000. */
1426 #undef TARGET_STRICT_ARGUMENT_NAMING
1427 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1428 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1429 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1430 #undef TARGET_SPLIT_COMPLEX_ARG
1431 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1432 #undef TARGET_MUST_PASS_IN_STACK
1433 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1434 #undef TARGET_PASS_BY_REFERENCE
1435 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1436 #undef TARGET_ARG_PARTIAL_BYTES
1437 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1439 #undef TARGET_BUILD_BUILTIN_VA_LIST
1440 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1442 #undef TARGET_EXPAND_BUILTIN_VA_START
1443 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1445 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1446 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1448 #undef TARGET_EH_RETURN_FILTER_MODE
1449 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1451 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1452 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1454 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1455 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1457 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1458 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1460 #undef TARGET_HANDLE_OPTION
1461 #define TARGET_HANDLE_OPTION rs6000_handle_option
1463 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1464 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1465 rs6000_builtin_vectorized_function
1467 #undef TARGET_DEFAULT_TARGET_FLAGS
1468 #define TARGET_DEFAULT_TARGET_FLAGS \
1471 #undef TARGET_STACK_PROTECT_FAIL
1472 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1474 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1475 The PowerPC architecture requires only weak consistency among
1476 processors--that is, memory accesses between processors need not be
1477 sequentially consistent and memory accesses among processors can occur
1478 in any order. The ability to order memory accesses weakly provides
1479 opportunities for more efficient use of the system bus. Unless a
1480 dependency exists, the 604e allows read operations to precede store
1482 #undef TARGET_RELAXED_ORDERING
1483 #define TARGET_RELAXED_ORDERING true
1486 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1487 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1490 /* Use a 32-bit anchor range. This leads to sequences like:
1492 addis tmp,anchor,high
1495 where tmp itself acts as an anchor, and can be shared between
1496 accesses to the same 64k page. */
1497 #undef TARGET_MIN_ANCHOR_OFFSET
1498 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1499 #undef TARGET_MAX_ANCHOR_OFFSET
1500 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1501 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1502 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1504 #undef TARGET_BUILTIN_RECIPROCAL
1505 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1507 #undef TARGET_EXPAND_TO_RTL_HOOK
1508 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1510 #undef TARGET_INSTANTIATE_DECLS
1511 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1513 #undef TARGET_SECONDARY_RELOAD
1514 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1516 #undef TARGET_IRA_COVER_CLASSES
1517 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1519 #undef TARGET_LEGITIMATE_ADDRESS_P
1520 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1522 #undef TARGET_CAN_ELIMINATE
1523 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1525 #undef TARGET_TRAMPOLINE_INIT
1526 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1528 #undef TARGET_FUNCTION_VALUE
1529 #define TARGET_FUNCTION_VALUE rs6000_function_value
1531 struct gcc_target targetm = TARGET_INITIALIZER;
1533 /* Return number of consecutive hard regs needed starting at reg REGNO
1534 to hold something of mode MODE.
1535 This is ordinarily the length in words of a value of mode MODE
1536 but can be less for certain modes in special long registers.
1538 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1539 scalar instructions. The upper 32 bits are only available to the
1542 POWER and PowerPC GPRs hold 32 bits worth;
1543 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1546 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1548 unsigned HOST_WIDE_INT reg_size;
1550 if (FP_REGNO_P (regno))
1551 reg_size = (VECTOR_MEM_VSX_P (mode)
1552 ? UNITS_PER_VSX_WORD
1553 : UNITS_PER_FP_WORD);
1555 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1556 reg_size = UNITS_PER_SPE_WORD;
1558 else if (ALTIVEC_REGNO_P (regno))
1559 reg_size = UNITS_PER_ALTIVEC_WORD;
1561 /* The value returned for SCmode in the E500 double case is 2 for
1562 ABI compatibility; storing an SCmode value in a single register
1563 would require function_arg and rs6000_spe_function_arg to handle
1564 SCmode so as to pass the value correctly in a pair of
1566 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1567 && !DECIMAL_FLOAT_MODE_P (mode))
1568 reg_size = UNITS_PER_FP_WORD;
1571 reg_size = UNITS_PER_WORD;
1573 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1576 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1579 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1581 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1583 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1584 implementations. Don't allow an item to be split between a FP register
1585 and an Altivec register. */
1586 if (VECTOR_MEM_VSX_P (mode))
1588 if (FP_REGNO_P (regno))
1589 return FP_REGNO_P (last_regno);
1591 if (ALTIVEC_REGNO_P (regno))
1592 return ALTIVEC_REGNO_P (last_regno);
1595 /* The GPRs can hold any mode, but values bigger than one register
1596 cannot go past R31. */
1597 if (INT_REGNO_P (regno))
1598 return INT_REGNO_P (last_regno);
1600 /* The float registers (except for VSX vector modes) can only hold floating
1601 modes and DImode. This excludes the 32-bit decimal float mode for
1603 if (FP_REGNO_P (regno))
1605 if (SCALAR_FLOAT_MODE_P (mode)
1606 && (mode != TDmode || (regno % 2) == 0)
1607 && FP_REGNO_P (last_regno))
1610 if (GET_MODE_CLASS (mode) == MODE_INT
1611 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1614 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1615 && PAIRED_VECTOR_MODE (mode))
1621 /* The CR register can only hold CC modes. */
1622 if (CR_REGNO_P (regno))
1623 return GET_MODE_CLASS (mode) == MODE_CC;
1625 if (XER_REGNO_P (regno))
1626 return mode == PSImode;
1628 /* AltiVec only in AldyVec registers. */
1629 if (ALTIVEC_REGNO_P (regno))
1630 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1632 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1633 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1636 /* We cannot put TImode anywhere except general register and it must be able
1637 to fit within the register set. In the future, allow TImode in the
1638 Altivec or VSX registers. */
1640 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1643 /* Print interesting facts about registers. */
1645 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1649 for (r = first_regno; r <= last_regno; ++r)
1651 const char *comma = "";
1654 if (first_regno == last_regno)
1655 fprintf (stderr, "%s:\t", reg_name);
1657 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1660 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1661 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1665 fprintf (stderr, ",\n\t");
1670 if (rs6000_hard_regno_nregs[m][r] > 1)
1671 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1672 rs6000_hard_regno_nregs[m][r]);
1674 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1679 if (call_used_regs[r])
1683 fprintf (stderr, ",\n\t");
1688 len += fprintf (stderr, "%s%s", comma, "call-used");
1696 fprintf (stderr, ",\n\t");
1701 len += fprintf (stderr, "%s%s", comma, "fixed");
1707 fprintf (stderr, ",\n\t");
1711 fprintf (stderr, "%sregno = %d\n", comma, r);
1715 /* Print various interesting information with -mdebug=reg. */
1717 rs6000_debug_reg_global (void)
1719 const char *nl = (const char *)0;
1721 char costly_num[20];
1723 const char *costly_str;
1724 const char *nop_str;
1726 /* Map enum rs6000_vector to string. */
1727 static const char *rs6000_debug_vector_unit[] = {
1736 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1737 LAST_VIRTUAL_REGISTER);
1738 rs6000_debug_reg_print (0, 31, "gr");
1739 rs6000_debug_reg_print (32, 63, "fp");
1740 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1743 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1744 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1745 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1746 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1747 rs6000_debug_reg_print (XER_REGNO, XER_REGNO, "xer");
1748 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1749 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1750 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1751 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1755 "d reg_class = %s\n"
1756 "f reg_class = %s\n"
1757 "v reg_class = %s\n"
1758 "wa reg_class = %s\n"
1759 "wd reg_class = %s\n"
1760 "wf reg_class = %s\n"
1761 "ws reg_class = %s\n\n",
1762 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1763 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1764 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1765 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1766 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1767 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1768 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1770 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1771 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1774 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1776 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1777 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1783 switch (rs6000_sched_costly_dep)
1785 case max_dep_latency:
1786 costly_str = "max_dep_latency";
1790 costly_str = "no_dep_costly";
1793 case all_deps_costly:
1794 costly_str = "all_deps_costly";
1797 case true_store_to_load_dep_costly:
1798 costly_str = "true_store_to_load_dep_costly";
1801 case store_to_load_dep_costly:
1802 costly_str = "store_to_load_dep_costly";
1806 costly_str = costly_num;
1807 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1811 switch (rs6000_sched_insert_nops)
1813 case sched_finish_regroup_exact:
1814 nop_str = "sched_finish_regroup_exact";
1817 case sched_finish_pad_groups:
1818 nop_str = "sched_finish_pad_groups";
1821 case sched_finish_none:
1822 nop_str = "sched_finish_none";
1827 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1832 "always_hint = %s\n"
1833 "align_branch_targets = %s\n"
1834 "sched_restricted_insns_priority = %d\n"
1835 "sched_costly_dep = %s\n"
1836 "sched_insert_nops = %s\n\n",
1837 rs6000_always_hint ? "true" : "false",
1838 rs6000_align_branch_targets ? "true" : "false",
1839 (int)rs6000_sched_restricted_insns_priority,
1840 costly_str, nop_str);
1843 /* Initialize the various global tables that are based on register size. */
1845 rs6000_init_hard_regno_mode_ok (void)
1851 /* Precalculate REGNO_REG_CLASS. */
1852 rs6000_regno_regclass[0] = GENERAL_REGS;
1853 for (r = 1; r < 32; ++r)
1854 rs6000_regno_regclass[r] = BASE_REGS;
1856 for (r = 32; r < 64; ++r)
1857 rs6000_regno_regclass[r] = FLOAT_REGS;
1859 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1860 rs6000_regno_regclass[r] = NO_REGS;
1862 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
1863 rs6000_regno_regclass[r] = ALTIVEC_REGS;
1865 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
1866 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
1867 rs6000_regno_regclass[r] = CR_REGS;
1869 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
1870 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
1871 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
1872 rs6000_regno_regclass[XER_REGNO] = XER_REGS;
1873 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
1874 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
1875 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
1876 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
1877 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
1878 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
1880 /* Precalculate vector information, this must be set up before the
1881 rs6000_hard_regno_nregs_internal below. */
1882 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1884 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
1885 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
1886 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
1889 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
1890 rs6000_constraints[c] = NO_REGS;
1892 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
1893 believes it can use native alignment or still uses 128-bit alignment. */
1894 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
1905 /* V2DF mode, VSX only. */
1908 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
1909 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
1910 rs6000_vector_align[V2DFmode] = align64;
1913 /* V4SF mode, either VSX or Altivec. */
1916 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
1917 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
1918 rs6000_vector_align[V4SFmode] = align32;
1920 else if (TARGET_ALTIVEC)
1922 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
1923 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
1924 rs6000_vector_align[V4SFmode] = align32;
1927 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
1931 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
1932 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
1933 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
1934 rs6000_vector_align[V4SImode] = align32;
1935 rs6000_vector_align[V8HImode] = align32;
1936 rs6000_vector_align[V16QImode] = align32;
1940 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
1941 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
1942 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
1946 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
1947 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
1948 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
1952 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
1953 Altivec doesn't have 64-bit support. */
1956 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
1957 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
1958 rs6000_vector_align[V2DImode] = align64;
1961 /* DFmode, see if we want to use the VSX unit. */
1962 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
1964 rs6000_vector_unit[DFmode] = VECTOR_VSX;
1965 rs6000_vector_mem[DFmode]
1966 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
1967 rs6000_vector_align[DFmode] = align64;
1970 /* TODO add SPE and paired floating point vector support. */
1972 /* Register class constaints for the constraints that depend on compile
1974 if (TARGET_HARD_FLOAT && TARGET_FPRS)
1975 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
1977 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
1978 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
1982 /* At present, we just use VSX_REGS, but we have different constraints
1983 based on the use, in case we want to fine tune the default register
1984 class used. wa = any VSX register, wf = register class to use for
1985 V4SF, wd = register class to use for V2DF, and ws = register classs to
1986 use for DF scalars. */
1987 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
1988 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
1989 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
1990 if (TARGET_VSX_SCALAR_DOUBLE)
1991 rs6000_constraints[RS6000_CONSTRAINT_ws] = VSX_REGS;
1995 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
1997 /* Set up the reload helper functions. */
1998 if (TARGET_VSX || TARGET_ALTIVEC)
2002 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2003 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2004 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2005 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2006 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2007 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2008 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2009 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2010 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2011 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2012 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2013 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2017 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2018 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2019 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2020 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2021 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2022 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2023 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2024 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2025 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2026 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2027 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2028 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2032 /* Precalculate HARD_REGNO_NREGS. */
2033 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2034 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2035 rs6000_hard_regno_nregs[m][r]
2036 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2038 /* Precalculate HARD_REGNO_MODE_OK. */
2039 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2040 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2041 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2042 rs6000_hard_regno_mode_ok_p[m][r] = true;
2044 /* Precalculate CLASS_MAX_NREGS sizes. */
2045 for (c = 0; c < LIM_REG_CLASSES; ++c)
2049 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2050 reg_size = UNITS_PER_VSX_WORD;
2052 else if (c == ALTIVEC_REGS)
2053 reg_size = UNITS_PER_ALTIVEC_WORD;
2055 else if (c == FLOAT_REGS)
2056 reg_size = UNITS_PER_FP_WORD;
2059 reg_size = UNITS_PER_WORD;
2061 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2062 rs6000_class_max_nregs[m][c]
2063 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2066 if (TARGET_E500_DOUBLE)
2067 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2069 if (TARGET_DEBUG_REG)
2070 rs6000_debug_reg_global ();
2074 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2077 darwin_rs6000_override_options (void)
2079 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2081 rs6000_altivec_abi = 1;
2082 TARGET_ALTIVEC_VRSAVE = 1;
2083 if (DEFAULT_ABI == ABI_DARWIN)
2085 if (MACHO_DYNAMIC_NO_PIC_P)
2088 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2091 else if (flag_pic == 1)
2096 if (TARGET_64BIT && ! TARGET_POWERPC64)
2098 target_flags |= MASK_POWERPC64;
2099 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2103 rs6000_default_long_calls = 1;
2104 target_flags |= MASK_SOFT_FLOAT;
2107 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2109 if (!flag_mkernel && !flag_apple_kext
2111 && ! (target_flags_explicit & MASK_ALTIVEC))
2112 target_flags |= MASK_ALTIVEC;
2114 /* Unless the user (not the configurer) has explicitly overridden
2115 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2116 G4 unless targetting the kernel. */
2119 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2120 && ! (target_flags_explicit & MASK_ALTIVEC)
2121 && ! rs6000_select[1].string)
2123 target_flags |= MASK_ALTIVEC;
2128 /* If not otherwise specified by a target, make 'long double' equivalent to
2131 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2132 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2135 /* Override command line options. Mostly we process the processor
2136 type and sometimes adjust other TARGET_ options. */
2139 rs6000_override_options (const char *default_cpu)
2142 struct rs6000_cpu_select *ptr;
2145 /* Simplifications for entries below. */
2148 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2149 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2152 /* This table occasionally claims that a processor does not support
2153 a particular feature even though it does, but the feature is slower
2154 than the alternative. Thus, it shouldn't be relied on as a
2155 complete description of the processor's support.
2157 Please keep this list in order, and don't forget to update the
2158 documentation in invoke.texi when adding a new processor or
2162 const char *const name; /* Canonical processor name. */
2163 const enum processor_type processor; /* Processor type enum value. */
2164 const int target_enable; /* Target flags to enable. */
2165 } const processor_target_table[]
2166 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2167 {"403", PROCESSOR_PPC403,
2168 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2169 {"405", PROCESSOR_PPC405,
2170 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2171 {"405fp", PROCESSOR_PPC405,
2172 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2173 {"440", PROCESSOR_PPC440,
2174 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2175 {"440fp", PROCESSOR_PPC440,
2176 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2177 {"464", PROCESSOR_PPC440,
2178 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2179 {"464fp", PROCESSOR_PPC440,
2180 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2181 {"476", PROCESSOR_PPC476,
2182 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2183 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2184 {"476fp", PROCESSOR_PPC476,
2185 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2186 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2187 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2188 {"601", PROCESSOR_PPC601,
2189 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2190 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2191 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2192 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2193 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2194 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2195 {"620", PROCESSOR_PPC620,
2196 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2197 {"630", PROCESSOR_PPC630,
2198 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2199 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2200 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2201 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2202 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2203 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2204 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2205 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2206 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2208 /* 8548 has a dummy entry for now. */
2209 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2211 {"a2", PROCESSOR_PPCA2,
2212 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2213 | MASK_CMPB | MASK_NO_UPDATE },
2214 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2215 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2216 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2218 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2219 {"970", PROCESSOR_POWER4,
2220 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2221 {"cell", PROCESSOR_CELL,
2222 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2223 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2224 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2225 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2226 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2227 {"G5", PROCESSOR_POWER4,
2228 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2229 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2230 {"power2", PROCESSOR_POWER,
2231 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2232 {"power3", PROCESSOR_PPC630,
2233 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2234 {"power4", PROCESSOR_POWER4,
2235 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2237 {"power5", PROCESSOR_POWER5,
2238 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2239 | MASK_MFCRF | MASK_POPCNTB},
2240 {"power5+", PROCESSOR_POWER5,
2241 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2242 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2243 {"power6", PROCESSOR_POWER6,
2244 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2245 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP},
2246 {"power6x", PROCESSOR_POWER6,
2247 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2248 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2250 {"power7", PROCESSOR_POWER7,
2251 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2252 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2253 | MASK_VSX}, /* Don't add MASK_ISEL by default */
2254 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2255 {"powerpc64", PROCESSOR_POWERPC64,
2256 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2257 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2258 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2259 {"rios2", PROCESSOR_RIOS2,
2260 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2261 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2262 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2263 {"rs64", PROCESSOR_RS64A,
2264 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2267 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2269 /* Some OSs don't support saving the high part of 64-bit registers on
2270 context switch. Other OSs don't support saving Altivec registers.
2271 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2272 settings; if the user wants either, the user must explicitly specify
2273 them and we won't interfere with the user's specification. */
2276 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2277 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2278 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2279 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2280 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2281 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE)
2284 /* Numerous experiment shows that IRA based loop pressure
2285 calculation works better for RTL loop invariant motion on targets
2286 with enough (>= 32) registers. It is an expensive optimization.
2287 So it is on only for peak performance. */
2289 flag_ira_loop_pressure = 1;
2291 /* Set the pointer size. */
2294 rs6000_pmode = (int)DImode;
2295 rs6000_pointer_size = 64;
2299 rs6000_pmode = (int)SImode;
2300 rs6000_pointer_size = 32;
2303 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2304 #ifdef OS_MISSING_POWERPC64
2305 if (OS_MISSING_POWERPC64)
2306 set_masks &= ~MASK_POWERPC64;
2308 #ifdef OS_MISSING_ALTIVEC
2309 if (OS_MISSING_ALTIVEC)
2310 set_masks &= ~MASK_ALTIVEC;
2313 /* Don't override by the processor default if given explicitly. */
2314 set_masks &= ~target_flags_explicit;
2316 /* Identify the processor type. */
2317 rs6000_select[0].string = default_cpu;
2318 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2320 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2322 ptr = &rs6000_select[i];
2323 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2325 for (j = 0; j < ptt_size; j++)
2326 if (! strcmp (ptr->string, processor_target_table[j].name))
2328 if (ptr->set_tune_p)
2329 rs6000_cpu = processor_target_table[j].processor;
2331 if (ptr->set_arch_p)
2333 target_flags &= ~set_masks;
2334 target_flags |= (processor_target_table[j].target_enable
2341 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2345 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2346 || rs6000_cpu == PROCESSOR_PPCE500MC)
2349 error ("AltiVec not supported in this target");
2351 error ("Spe not supported in this target");
2354 /* Disable Cell microcode if we are optimizing for the Cell
2355 and not optimizing for size. */
2356 if (rs6000_gen_cell_microcode == -1)
2357 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2360 /* If we are optimizing big endian systems for space, use the load/store
2361 multiple and string instructions unless we are not generating
2363 if (BYTES_BIG_ENDIAN && optimize_size && !rs6000_gen_cell_microcode)
2364 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2366 /* Don't allow -mmultiple or -mstring on little endian systems
2367 unless the cpu is a 750, because the hardware doesn't support the
2368 instructions used in little endian mode, and causes an alignment
2369 trap. The 750 does not cause an alignment trap (except when the
2370 target is unaligned). */
2372 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2374 if (TARGET_MULTIPLE)
2376 target_flags &= ~MASK_MULTIPLE;
2377 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2378 warning (0, "-mmultiple is not supported on little endian systems");
2383 target_flags &= ~MASK_STRING;
2384 if ((target_flags_explicit & MASK_STRING) != 0)
2385 warning (0, "-mstring is not supported on little endian systems");
2389 /* Add some warnings for VSX. Enable -maltivec unless the user explicitly
2390 used -mno-altivec */
2393 const char *msg = NULL;
2394 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2395 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2397 if (target_flags_explicit & MASK_VSX)
2398 msg = N_("-mvsx requires hardware floating point");
2400 target_flags &= ~ MASK_VSX;
2402 else if (TARGET_PAIRED_FLOAT)
2403 msg = N_("-mvsx and -mpaired are incompatible");
2404 /* The hardware will allow VSX and little endian, but until we make sure
2405 things like vector select, etc. work don't allow VSX on little endian
2406 systems at this point. */
2407 else if (!BYTES_BIG_ENDIAN)
2408 msg = N_("-mvsx used with little endian code");
2409 else if (TARGET_AVOID_XFORM > 0)
2410 msg = N_("-mvsx needs indexed addressing");
2415 target_flags &= ~ MASK_VSX;
2417 else if (TARGET_VSX && !TARGET_ALTIVEC
2418 && (target_flags_explicit & MASK_ALTIVEC) == 0)
2419 target_flags |= MASK_ALTIVEC;
2422 /* Set debug flags */
2423 if (rs6000_debug_name)
2425 if (! strcmp (rs6000_debug_name, "all"))
2426 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2427 = rs6000_debug_addr = rs6000_debug_cost = 1;
2428 else if (! strcmp (rs6000_debug_name, "stack"))
2429 rs6000_debug_stack = 1;
2430 else if (! strcmp (rs6000_debug_name, "arg"))
2431 rs6000_debug_arg = 1;
2432 else if (! strcmp (rs6000_debug_name, "reg"))
2433 rs6000_debug_reg = 1;
2434 else if (! strcmp (rs6000_debug_name, "addr"))
2435 rs6000_debug_addr = 1;
2436 else if (! strcmp (rs6000_debug_name, "cost"))
2437 rs6000_debug_cost = 1;
2439 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2441 /* If the appropriate debug option is enabled, replace the target hooks
2442 with debug versions that call the real version and then prints
2443 debugging information. */
2444 if (TARGET_DEBUG_COST)
2446 targetm.rtx_costs = rs6000_debug_rtx_costs;
2447 targetm.address_cost = rs6000_debug_address_cost;
2448 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2451 if (TARGET_DEBUG_ADDR)
2453 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2454 targetm.legitimize_address = rs6000_debug_legitimize_address;
2455 rs6000_secondary_reload_class_ptr
2456 = rs6000_debug_secondary_reload_class;
2457 rs6000_secondary_memory_needed_ptr
2458 = rs6000_debug_secondary_memory_needed;
2459 rs6000_cannot_change_mode_class_ptr
2460 = rs6000_debug_cannot_change_mode_class;
2461 rs6000_preferred_reload_class_ptr
2462 = rs6000_debug_preferred_reload_class;
2463 rs6000_legitimize_reload_address_ptr
2464 = rs6000_debug_legitimize_reload_address;
2465 rs6000_mode_dependent_address_ptr
2466 = rs6000_debug_mode_dependent_address;
2470 if (rs6000_traceback_name)
2472 if (! strncmp (rs6000_traceback_name, "full", 4))
2473 rs6000_traceback = traceback_full;
2474 else if (! strncmp (rs6000_traceback_name, "part", 4))
2475 rs6000_traceback = traceback_part;
2476 else if (! strncmp (rs6000_traceback_name, "no", 2))
2477 rs6000_traceback = traceback_none;
2479 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2480 rs6000_traceback_name);
2483 if (!rs6000_explicit_options.long_double)
2484 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2486 #ifndef POWERPC_LINUX
2487 if (!rs6000_explicit_options.ieee)
2488 rs6000_ieeequad = 1;
2491 /* Enable Altivec ABI for AIX -maltivec. */
2492 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2493 rs6000_altivec_abi = 1;
2495 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2496 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2497 be explicitly overridden in either case. */
2500 if (!rs6000_explicit_options.altivec_abi
2501 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2502 rs6000_altivec_abi = 1;
2504 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2505 if (!rs6000_explicit_options.vrsave)
2506 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2509 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2510 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2512 rs6000_darwin64_abi = 1;
2514 darwin_one_byte_bool = 1;
2516 /* Default to natural alignment, for better performance. */
2517 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2520 /* Place FP constants in the constant pool instead of TOC
2521 if section anchors enabled. */
2522 if (flag_section_anchors)
2523 TARGET_NO_FP_IN_TOC = 1;
2525 /* Handle -mtls-size option. */
2526 rs6000_parse_tls_size_option ();
2528 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2529 SUBTARGET_OVERRIDE_OPTIONS;
2531 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2532 SUBSUBTARGET_OVERRIDE_OPTIONS;
2534 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2535 SUB3TARGET_OVERRIDE_OPTIONS;
2538 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC)
2540 /* The e500 and e500mc do not have string instructions, and we set
2541 MASK_STRING above when optimizing for size. */
2542 if ((target_flags & MASK_STRING) != 0)
2543 target_flags = target_flags & ~MASK_STRING;
2545 else if (rs6000_select[1].string != NULL)
2547 /* For the powerpc-eabispe configuration, we set all these by
2548 default, so let's unset them if we manually set another
2549 CPU that is not the E500. */
2550 if (!rs6000_explicit_options.spe_abi)
2552 if (!rs6000_explicit_options.spe)
2554 if (!rs6000_explicit_options.float_gprs)
2555 rs6000_float_gprs = 0;
2556 if (!(target_flags_explicit & MASK_ISEL))
2557 target_flags &= ~MASK_ISEL;
2560 /* Detect invalid option combinations with E500. */
2563 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2564 && rs6000_cpu != PROCESSOR_POWER5
2565 && rs6000_cpu != PROCESSOR_POWER6
2566 && rs6000_cpu != PROCESSOR_POWER7
2567 && rs6000_cpu != PROCESSOR_PPCA2
2568 && rs6000_cpu != PROCESSOR_CELL);
2569 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2570 || rs6000_cpu == PROCESSOR_POWER5
2571 || rs6000_cpu == PROCESSOR_POWER7);
2572 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2573 || rs6000_cpu == PROCESSOR_POWER5
2574 || rs6000_cpu == PROCESSOR_POWER6
2575 || rs6000_cpu == PROCESSOR_POWER7);
2577 /* Allow debug switches to override the above settings. */
2578 if (TARGET_ALWAYS_HINT > 0)
2579 rs6000_always_hint = TARGET_ALWAYS_HINT;
2581 if (TARGET_SCHED_GROUPS > 0)
2582 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2584 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2585 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2587 rs6000_sched_restricted_insns_priority
2588 = (rs6000_sched_groups ? 1 : 0);
2590 /* Handle -msched-costly-dep option. */
2591 rs6000_sched_costly_dep
2592 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2594 if (rs6000_sched_costly_dep_str)
2596 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2597 rs6000_sched_costly_dep = no_dep_costly;
2598 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2599 rs6000_sched_costly_dep = all_deps_costly;
2600 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2601 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2602 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2603 rs6000_sched_costly_dep = store_to_load_dep_costly;
2605 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2606 atoi (rs6000_sched_costly_dep_str));
2609 /* Handle -minsert-sched-nops option. */
2610 rs6000_sched_insert_nops
2611 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2613 if (rs6000_sched_insert_nops_str)
2615 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2616 rs6000_sched_insert_nops = sched_finish_none;
2617 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2618 rs6000_sched_insert_nops = sched_finish_pad_groups;
2619 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2620 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2622 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2623 atoi (rs6000_sched_insert_nops_str));
2626 #ifdef TARGET_REGNAMES
2627 /* If the user desires alternate register names, copy in the
2628 alternate names now. */
2629 if (TARGET_REGNAMES)
2630 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2633 /* Set aix_struct_return last, after the ABI is determined.
2634 If -maix-struct-return or -msvr4-struct-return was explicitly
2635 used, don't override with the ABI default. */
2636 if (!rs6000_explicit_options.aix_struct_ret)
2637 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2639 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2640 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2643 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2645 /* We can only guarantee the availability of DI pseudo-ops when
2646 assembling for 64-bit targets. */
2649 targetm.asm_out.aligned_op.di = NULL;
2650 targetm.asm_out.unaligned_op.di = NULL;
2653 /* Set branch target alignment, if not optimizing for size. */
2656 /* Cell wants to be aligned 8byte for dual issue. */
2657 if (rs6000_cpu == PROCESSOR_CELL)
2659 if (align_functions <= 0)
2660 align_functions = 8;
2661 if (align_jumps <= 0)
2663 if (align_loops <= 0)
2666 if (rs6000_align_branch_targets)
2668 if (align_functions <= 0)
2669 align_functions = 16;
2670 if (align_jumps <= 0)
2672 if (align_loops <= 0)
2675 if (align_jumps_max_skip <= 0)
2676 align_jumps_max_skip = 15;
2677 if (align_loops_max_skip <= 0)
2678 align_loops_max_skip = 15;
2681 /* Arrange to save and restore machine status around nested functions. */
2682 init_machine_status = rs6000_init_machine_status;
2684 /* We should always be splitting complex arguments, but we can't break
2685 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2686 if (DEFAULT_ABI != ABI_AIX)
2687 targetm.calls.split_complex_arg = NULL;
2689 /* Initialize rs6000_cost with the appropriate target costs. */
2691 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2695 case PROCESSOR_RIOS1:
2696 rs6000_cost = &rios1_cost;
2699 case PROCESSOR_RIOS2:
2700 rs6000_cost = &rios2_cost;
2703 case PROCESSOR_RS64A:
2704 rs6000_cost = &rs64a_cost;
2707 case PROCESSOR_MPCCORE:
2708 rs6000_cost = &mpccore_cost;
2711 case PROCESSOR_PPC403:
2712 rs6000_cost = &ppc403_cost;
2715 case PROCESSOR_PPC405:
2716 rs6000_cost = &ppc405_cost;
2719 case PROCESSOR_PPC440:
2720 rs6000_cost = &ppc440_cost;
2723 case PROCESSOR_PPC476:
2724 rs6000_cost = &ppc476_cost;
2727 case PROCESSOR_PPC601:
2728 rs6000_cost = &ppc601_cost;
2731 case PROCESSOR_PPC603:
2732 rs6000_cost = &ppc603_cost;
2735 case PROCESSOR_PPC604:
2736 rs6000_cost = &ppc604_cost;
2739 case PROCESSOR_PPC604e:
2740 rs6000_cost = &ppc604e_cost;
2743 case PROCESSOR_PPC620:
2744 rs6000_cost = &ppc620_cost;
2747 case PROCESSOR_PPC630:
2748 rs6000_cost = &ppc630_cost;
2751 case PROCESSOR_CELL:
2752 rs6000_cost = &ppccell_cost;
2755 case PROCESSOR_PPC750:
2756 case PROCESSOR_PPC7400:
2757 rs6000_cost = &ppc750_cost;
2760 case PROCESSOR_PPC7450:
2761 rs6000_cost = &ppc7450_cost;
2764 case PROCESSOR_PPC8540:
2765 rs6000_cost = &ppc8540_cost;
2768 case PROCESSOR_PPCE300C2:
2769 case PROCESSOR_PPCE300C3:
2770 rs6000_cost = &ppce300c2c3_cost;
2773 case PROCESSOR_PPCE500MC:
2774 rs6000_cost = &ppce500mc_cost;
2777 case PROCESSOR_POWER4:
2778 case PROCESSOR_POWER5:
2779 rs6000_cost = &power4_cost;
2782 case PROCESSOR_POWER6:
2783 rs6000_cost = &power6_cost;
2786 case PROCESSOR_POWER7:
2787 rs6000_cost = &power7_cost;
2790 case PROCESSOR_PPCA2:
2791 rs6000_cost = &ppca2_cost;
2798 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
2799 set_param_value ("simultaneous-prefetches",
2800 rs6000_cost->simultaneous_prefetches);
2801 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
2802 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
2803 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
2804 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
2805 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
2806 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
2808 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
2809 can be optimized to ap = __builtin_next_arg (0). */
2810 if (DEFAULT_ABI != ABI_V4)
2811 targetm.expand_builtin_va_start = NULL;
2813 /* Set up single/double float flags.
2814 If TARGET_HARD_FLOAT is set, but neither single or double is set,
2815 then set both flags. */
2816 if (TARGET_HARD_FLOAT && TARGET_FPRS
2817 && rs6000_single_float == 0 && rs6000_double_float == 0)
2818 rs6000_single_float = rs6000_double_float = 1;
2820 /* Reset single and double FP flags if target is E500. */
2823 rs6000_single_float = rs6000_double_float = 0;
2824 if (TARGET_E500_SINGLE)
2825 rs6000_single_float = 1;
2826 if (TARGET_E500_DOUBLE)
2827 rs6000_single_float = rs6000_double_float = 1;
2830 /* If not explicitly specified via option, decide whether to generate indexed
2831 load/store instructions. */
2832 if (TARGET_AVOID_XFORM == -1)
2833 /* Avoid indexed addressing when targeting Power6 in order to avoid
2834 the DERAT mispredict penalty. */
2835 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
2837 rs6000_init_hard_regno_mode_ok ();
2840 /* Implement targetm.vectorize.builtin_mask_for_load. */
2842 rs6000_builtin_mask_for_load (void)
2844 if (TARGET_ALTIVEC || TARGET_VSX)
2845 return altivec_builtin_mask_for_load;
2850 /* Implement targetm.vectorize.builtin_conversion.
2851 Returns a decl of a function that implements conversion of an integer vector
2852 into a floating-point vector, or vice-versa. TYPE is the type of the integer
2853 side of the conversion.
2854 Return NULL_TREE if it is not available. */
2856 rs6000_builtin_conversion (unsigned int tcode, tree type)
2858 enum tree_code code = (enum tree_code) tcode;
2862 case FIX_TRUNC_EXPR:
2863 switch (TYPE_MODE (type))
2866 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2869 return TYPE_UNSIGNED (type)
2870 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
2871 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
2874 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2877 return TYPE_UNSIGNED (type)
2878 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
2879 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
2886 switch (TYPE_MODE (type))
2889 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2892 return TYPE_UNSIGNED (type)
2893 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
2894 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
2897 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2900 return TYPE_UNSIGNED (type)
2901 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
2902 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
2913 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2915 rs6000_builtin_mul_widen_even (tree type)
2917 if (!TARGET_ALTIVEC)
2920 switch (TYPE_MODE (type))
2923 return TYPE_UNSIGNED (type)
2924 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
2925 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
2928 return TYPE_UNSIGNED (type)
2929 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
2930 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
2936 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2938 rs6000_builtin_mul_widen_odd (tree type)
2940 if (!TARGET_ALTIVEC)
2943 switch (TYPE_MODE (type))
2946 return TYPE_UNSIGNED (type)
2947 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
2948 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
2951 return TYPE_UNSIGNED (type)
2952 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
2953 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
2960 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2961 after applying N number of iterations. This routine does not determine
2962 how may iterations are required to reach desired alignment. */
2965 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
2972 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
2975 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
2985 /* Assuming that all other types are naturally aligned. CHECKME! */
2990 /* Return true if the vector misalignment factor is supported by the
2993 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3000 /* Return if movmisalign pattern is not supported for this mode. */
3001 if (optab_handler (movmisalign_optab, mode)->insn_code ==
3005 if (misalignment == -1)
3007 /* misalignment factor is unknown at compile time but we know
3008 it's word aligned. */
3009 if (rs6000_vector_alignment_reachable (type, is_packed))
3013 /* VSX supports word-aligned vector. */
3014 if (misalignment % 4 == 0)
3020 /* Implement targetm.vectorize.builtin_vec_perm. */
3022 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3024 tree inner_type = TREE_TYPE (type);
3025 bool uns_p = TYPE_UNSIGNED (inner_type);
3028 *mask_element_type = unsigned_char_type_node;
3030 switch (TYPE_MODE (type))
3034 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3035 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3040 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3041 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3046 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3047 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3051 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3055 if (!TARGET_ALLOW_DF_PERMUTE)
3058 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3062 if (!TARGET_ALLOW_DF_PERMUTE)
3066 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3067 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3078 /* Handle generic options of the form -mfoo=yes/no.
3079 NAME is the option name.
3080 VALUE is the option value.
3081 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3082 whether the option value is 'yes' or 'no' respectively. */
3084 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3088 else if (!strcmp (value, "yes"))
3090 else if (!strcmp (value, "no"))
3093 error ("unknown -m%s= option specified: '%s'", name, value);
3096 /* Validate and record the size specified with the -mtls-size option. */
3099 rs6000_parse_tls_size_option (void)
3101 if (rs6000_tls_size_string == 0)
3103 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3104 rs6000_tls_size = 16;
3105 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3106 rs6000_tls_size = 32;
3107 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3108 rs6000_tls_size = 64;
3110 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3114 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3116 if (DEFAULT_ABI == ABI_DARWIN)
3117 /* The Darwin libraries never set errno, so we might as well
3118 avoid calling them when that's the only reason we would. */
3119 flag_errno_math = 0;
3121 /* Double growth factor to counter reduced min jump length. */
3122 set_param_value ("max-grow-copy-bb-insns", 16);
3124 /* Enable section anchors by default.
3125 Skip section anchors for Objective C and Objective C++
3126 until front-ends fixed. */
3127 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3128 flag_section_anchors = 2;
3131 static enum fpu_type_t
3132 rs6000_parse_fpu_option (const char *option)
3134 if (!strcmp("none", option)) return FPU_NONE;
3135 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3136 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3137 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3138 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3139 error("unknown value %s for -mfpu", option);
3143 /* Returns a function decl for a vectorized version of the builtin function
3144 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3145 if it is not available. */
3148 rs6000_builtin_vectorized_function (unsigned int fn, tree type_out,
3151 enum machine_mode in_mode, out_mode;
3154 if (TREE_CODE (type_out) != VECTOR_TYPE
3155 || TREE_CODE (type_in) != VECTOR_TYPE
3156 || !TARGET_VECTORIZE_BUILTINS)
3159 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3160 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3161 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3162 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3166 case BUILT_IN_COPYSIGN:
3167 if (VECTOR_UNIT_VSX_P (V2DFmode)
3168 && out_mode == DFmode && out_n == 2
3169 && in_mode == DFmode && in_n == 2)
3170 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3172 case BUILT_IN_COPYSIGNF:
3173 if (out_mode != SFmode || out_n != 4
3174 || in_mode != SFmode || in_n != 4)
3176 if (VECTOR_UNIT_VSX_P (V4SFmode))
3177 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3178 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3179 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3182 if (VECTOR_UNIT_VSX_P (V2DFmode)
3183 && out_mode == DFmode && out_n == 2
3184 && in_mode == DFmode && in_n == 2)
3185 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3187 case BUILT_IN_SQRTF:
3188 if (VECTOR_UNIT_VSX_P (V4SFmode)
3189 && out_mode == SFmode && out_n == 4
3190 && in_mode == SFmode && in_n == 4)
3191 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3194 if (VECTOR_UNIT_VSX_P (V2DFmode)
3195 && out_mode == DFmode && out_n == 2
3196 && in_mode == DFmode && in_n == 2)
3197 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3199 case BUILT_IN_CEILF:
3200 if (out_mode != SFmode || out_n != 4
3201 || in_mode != SFmode || in_n != 4)
3203 if (VECTOR_UNIT_VSX_P (V4SFmode))
3204 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3205 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3206 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3208 case BUILT_IN_FLOOR:
3209 if (VECTOR_UNIT_VSX_P (V2DFmode)
3210 && out_mode == DFmode && out_n == 2
3211 && in_mode == DFmode && in_n == 2)
3212 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3214 case BUILT_IN_FLOORF:
3215 if (out_mode != SFmode || out_n != 4
3216 || in_mode != SFmode || in_n != 4)
3218 if (VECTOR_UNIT_VSX_P (V4SFmode))
3219 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3220 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3221 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3223 case BUILT_IN_TRUNC:
3224 if (VECTOR_UNIT_VSX_P (V2DFmode)
3225 && out_mode == DFmode && out_n == 2
3226 && in_mode == DFmode && in_n == 2)
3227 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3229 case BUILT_IN_TRUNCF:
3230 if (out_mode != SFmode || out_n != 4
3231 || in_mode != SFmode || in_n != 4)
3233 if (VECTOR_UNIT_VSX_P (V4SFmode))
3234 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3235 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3236 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3238 case BUILT_IN_NEARBYINT:
3239 if (VECTOR_UNIT_VSX_P (V2DFmode)
3240 && flag_unsafe_math_optimizations
3241 && out_mode == DFmode && out_n == 2
3242 && in_mode == DFmode && in_n == 2)
3243 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3245 case BUILT_IN_NEARBYINTF:
3246 if (VECTOR_UNIT_VSX_P (V4SFmode)
3247 && flag_unsafe_math_optimizations
3248 && out_mode == SFmode && out_n == 4
3249 && in_mode == SFmode && in_n == 4)
3250 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3253 if (VECTOR_UNIT_VSX_P (V2DFmode)
3254 && !flag_trapping_math
3255 && out_mode == DFmode && out_n == 2
3256 && in_mode == DFmode && in_n == 2)
3257 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3259 case BUILT_IN_RINTF:
3260 if (VECTOR_UNIT_VSX_P (V4SFmode)
3261 && !flag_trapping_math
3262 && out_mode == SFmode && out_n == 4
3263 && in_mode == SFmode && in_n == 4)
3264 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3273 /* Implement TARGET_HANDLE_OPTION. */
3276 rs6000_handle_option (size_t code, const char *arg, int value)
3278 enum fpu_type_t fpu_type = FPU_NONE;
3284 target_flags &= ~(MASK_POWER | MASK_POWER2
3285 | MASK_MULTIPLE | MASK_STRING);
3286 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3287 | MASK_MULTIPLE | MASK_STRING);
3289 case OPT_mno_powerpc:
3290 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3291 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3292 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3293 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3296 target_flags &= ~MASK_MINIMAL_TOC;
3297 TARGET_NO_FP_IN_TOC = 0;
3298 TARGET_NO_SUM_IN_TOC = 0;
3299 target_flags_explicit |= MASK_MINIMAL_TOC;
3300 #ifdef TARGET_USES_SYSV4_OPT
3301 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3302 just the same as -mminimal-toc. */
3303 target_flags |= MASK_MINIMAL_TOC;
3304 target_flags_explicit |= MASK_MINIMAL_TOC;
3308 #ifdef TARGET_USES_SYSV4_OPT
3310 /* Make -mtoc behave like -mminimal-toc. */
3311 target_flags |= MASK_MINIMAL_TOC;
3312 target_flags_explicit |= MASK_MINIMAL_TOC;
3316 #ifdef TARGET_USES_AIX64_OPT
3321 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3322 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3323 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3326 #ifdef TARGET_USES_AIX64_OPT
3331 target_flags &= ~MASK_POWERPC64;
3332 target_flags_explicit |= MASK_POWERPC64;
3335 case OPT_minsert_sched_nops_:
3336 rs6000_sched_insert_nops_str = arg;
3339 case OPT_mminimal_toc:
3342 TARGET_NO_FP_IN_TOC = 0;
3343 TARGET_NO_SUM_IN_TOC = 0;
3350 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3351 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3358 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3359 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3363 case OPT_mpowerpc_gpopt:
3364 case OPT_mpowerpc_gfxopt:
3367 target_flags |= MASK_POWERPC;
3368 target_flags_explicit |= MASK_POWERPC;
3372 case OPT_maix_struct_return:
3373 case OPT_msvr4_struct_return:
3374 rs6000_explicit_options.aix_struct_ret = true;
3378 rs6000_explicit_options.vrsave = true;
3379 TARGET_ALTIVEC_VRSAVE = value;
3383 rs6000_explicit_options.vrsave = true;
3384 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3388 target_flags_explicit |= MASK_ISEL;
3390 rs6000_parse_yes_no_option ("isel", arg, &isel);
3392 target_flags |= MASK_ISEL;
3394 target_flags &= ~MASK_ISEL;
3398 rs6000_explicit_options.spe = true;
3403 rs6000_explicit_options.spe = true;
3404 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3408 rs6000_debug_name = arg;
3411 #ifdef TARGET_USES_SYSV4_OPT
3413 rs6000_abi_name = arg;
3417 rs6000_sdata_name = arg;
3420 case OPT_mtls_size_:
3421 rs6000_tls_size_string = arg;
3424 case OPT_mrelocatable:
3427 target_flags |= MASK_MINIMAL_TOC;
3428 target_flags_explicit |= MASK_MINIMAL_TOC;
3429 TARGET_NO_FP_IN_TOC = 1;
3433 case OPT_mrelocatable_lib:
3436 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3437 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3438 TARGET_NO_FP_IN_TOC = 1;
3442 target_flags &= ~MASK_RELOCATABLE;
3443 target_flags_explicit |= MASK_RELOCATABLE;
3449 if (!strcmp (arg, "altivec"))
3451 rs6000_explicit_options.altivec_abi = true;
3452 rs6000_altivec_abi = 1;
3454 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3457 else if (! strcmp (arg, "no-altivec"))
3459 rs6000_explicit_options.altivec_abi = true;
3460 rs6000_altivec_abi = 0;
3462 else if (! strcmp (arg, "spe"))
3464 rs6000_explicit_options.spe_abi = true;
3466 rs6000_altivec_abi = 0;
3467 if (!TARGET_SPE_ABI)
3468 error ("not configured for ABI: '%s'", arg);
3470 else if (! strcmp (arg, "no-spe"))
3472 rs6000_explicit_options.spe_abi = true;
3476 /* These are here for testing during development only, do not
3477 document in the manual please. */
3478 else if (! strcmp (arg, "d64"))
3480 rs6000_darwin64_abi = 1;
3481 warning (0, "Using darwin64 ABI");
3483 else if (! strcmp (arg, "d32"))
3485 rs6000_darwin64_abi = 0;
3486 warning (0, "Using old darwin ABI");
3489 else if (! strcmp (arg, "ibmlongdouble"))
3491 rs6000_explicit_options.ieee = true;
3492 rs6000_ieeequad = 0;
3493 warning (0, "Using IBM extended precision long double");
3495 else if (! strcmp (arg, "ieeelongdouble"))
3497 rs6000_explicit_options.ieee = true;
3498 rs6000_ieeequad = 1;
3499 warning (0, "Using IEEE extended precision long double");
3504 error ("unknown ABI specified: '%s'", arg);
3510 rs6000_select[1].string = arg;
3514 rs6000_select[2].string = arg;
3517 case OPT_mtraceback_:
3518 rs6000_traceback_name = arg;
3521 case OPT_mfloat_gprs_:
3522 rs6000_explicit_options.float_gprs = true;
3523 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3524 rs6000_float_gprs = 1;
3525 else if (! strcmp (arg, "double"))
3526 rs6000_float_gprs = 2;
3527 else if (! strcmp (arg, "no"))
3528 rs6000_float_gprs = 0;
3531 error ("invalid option for -mfloat-gprs: '%s'", arg);
3536 case OPT_mlong_double_:
3537 rs6000_explicit_options.long_double = true;
3538 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3539 if (value != 64 && value != 128)
3541 error ("Unknown switch -mlong-double-%s", arg);
3542 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3546 rs6000_long_double_type_size = value;
3549 case OPT_msched_costly_dep_:
3550 rs6000_sched_costly_dep_str = arg;
3554 rs6000_explicit_options.alignment = true;
3555 if (! strcmp (arg, "power"))
3557 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3558 some C library functions, so warn about it. The flag may be
3559 useful for performance studies from time to time though, so
3560 don't disable it entirely. */
3561 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3562 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3563 " it is incompatible with the installed C and C++ libraries");
3564 rs6000_alignment_flags = MASK_ALIGN_POWER;
3566 else if (! strcmp (arg, "natural"))
3567 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3570 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3575 case OPT_msingle_float:
3576 if (!TARGET_SINGLE_FPU)
3577 warning (0, "-msingle-float option equivalent to -mhard-float");
3578 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3579 rs6000_double_float = 0;
3580 target_flags &= ~MASK_SOFT_FLOAT;
3581 target_flags_explicit |= MASK_SOFT_FLOAT;
3584 case OPT_mdouble_float:
3585 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3586 rs6000_single_float = 1;
3587 target_flags &= ~MASK_SOFT_FLOAT;
3588 target_flags_explicit |= MASK_SOFT_FLOAT;
3591 case OPT_msimple_fpu:
3592 if (!TARGET_SINGLE_FPU)
3593 warning (0, "-msimple-fpu option ignored");
3596 case OPT_mhard_float:
3597 /* -mhard_float implies -msingle-float and -mdouble-float. */
3598 rs6000_single_float = rs6000_double_float = 1;
3601 case OPT_msoft_float:
3602 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3603 rs6000_single_float = rs6000_double_float = 0;
3607 fpu_type = rs6000_parse_fpu_option(arg);
3608 if (fpu_type != FPU_NONE)
3609 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3611 target_flags &= ~MASK_SOFT_FLOAT;
3612 target_flags_explicit |= MASK_SOFT_FLOAT;
3613 rs6000_xilinx_fpu = 1;
3614 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3615 rs6000_single_float = 1;
3616 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3617 rs6000_single_float = rs6000_double_float = 1;
3618 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3619 rs6000_simple_fpu = 1;
3623 /* -mfpu=none is equivalent to -msoft-float */
3624 target_flags |= MASK_SOFT_FLOAT;
3625 target_flags_explicit |= MASK_SOFT_FLOAT;
3626 rs6000_single_float = rs6000_double_float = 0;
3633 /* Do anything needed at the start of the asm file. */
3636 rs6000_file_start (void)
3640 const char *start = buffer;
3641 struct rs6000_cpu_select *ptr;
3642 const char *default_cpu = TARGET_CPU_DEFAULT;
3643 FILE *file = asm_out_file;
3645 default_file_start ();
3647 #ifdef TARGET_BI_ARCH
3648 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3652 if (flag_verbose_asm)
3654 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3655 rs6000_select[0].string = default_cpu;
3657 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3659 ptr = &rs6000_select[i];
3660 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
3662 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
3667 if (PPC405_ERRATUM77)
3669 fprintf (file, "%s PPC405CR_ERRATUM77", start);
3673 #ifdef USING_ELFOS_H
3674 switch (rs6000_sdata)
3676 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
3677 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
3678 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
3679 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
3682 if (rs6000_sdata && g_switch_value)
3684 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
3694 #ifdef HAVE_AS_GNU_ATTRIBUTE
3695 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
3697 fprintf (file, "\t.gnu_attribute 4, %d\n",
3698 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
3699 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
3701 fprintf (file, "\t.gnu_attribute 8, %d\n",
3702 (TARGET_ALTIVEC_ABI ? 2
3703 : TARGET_SPE_ABI ? 3
3705 fprintf (file, "\t.gnu_attribute 12, %d\n",
3706 aix_struct_return ? 2 : 1);
3711 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
3713 switch_to_section (toc_section);
3714 switch_to_section (text_section);
3719 /* Return nonzero if this function is known to have a null epilogue. */
3722 direct_return (void)
3724 if (reload_completed)
3726 rs6000_stack_t *info = rs6000_stack_info ();
3728 if (info->first_gp_reg_save == 32
3729 && info->first_fp_reg_save == 64
3730 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
3731 && ! info->lr_save_p
3732 && ! info->cr_save_p
3733 && info->vrsave_mask == 0
3741 /* Return the number of instructions it takes to form a constant in an
3742 integer register. */
3745 num_insns_constant_wide (HOST_WIDE_INT value)
3747 /* signed constant loadable with {cal|addi} */
3748 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
3751 /* constant loadable with {cau|addis} */
3752 else if ((value & 0xffff) == 0
3753 && (value >> 31 == -1 || value >> 31 == 0))
3756 #if HOST_BITS_PER_WIDE_INT == 64
3757 else if (TARGET_POWERPC64)
3759 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
3760 HOST_WIDE_INT high = value >> 31;
3762 if (high == 0 || high == -1)
3768 return num_insns_constant_wide (high) + 1;
3770 return (num_insns_constant_wide (high)
3771 + num_insns_constant_wide (low) + 1);
3780 num_insns_constant (rtx op, enum machine_mode mode)
3782 HOST_WIDE_INT low, high;
3784 switch (GET_CODE (op))
3787 #if HOST_BITS_PER_WIDE_INT == 64
3788 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
3789 && mask64_operand (op, mode))
3793 return num_insns_constant_wide (INTVAL (op));
3796 if (mode == SFmode || mode == SDmode)
3801 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3802 if (DECIMAL_FLOAT_MODE_P (mode))
3803 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
3805 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
3806 return num_insns_constant_wide ((HOST_WIDE_INT) l);
3809 if (mode == VOIDmode || mode == DImode)
3811 high = CONST_DOUBLE_HIGH (op);
3812 low = CONST_DOUBLE_LOW (op);
3819 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3820 if (DECIMAL_FLOAT_MODE_P (mode))
3821 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
3823 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
3824 high = l[WORDS_BIG_ENDIAN == 0];
3825 low = l[WORDS_BIG_ENDIAN != 0];
3829 return (num_insns_constant_wide (low)
3830 + num_insns_constant_wide (high));
3833 if ((high == 0 && low >= 0)
3834 || (high == -1 && low < 0))
3835 return num_insns_constant_wide (low);
3837 else if (mask64_operand (op, mode))
3841 return num_insns_constant_wide (high) + 1;
3844 return (num_insns_constant_wide (high)
3845 + num_insns_constant_wide (low) + 1);
3853 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
3854 If the mode of OP is MODE_VECTOR_INT, this simply returns the
3855 corresponding element of the vector, but for V4SFmode and V2SFmode,
3856 the corresponding "float" is interpreted as an SImode integer. */
3859 const_vector_elt_as_int (rtx op, unsigned int elt)
3861 rtx tmp = CONST_VECTOR_ELT (op, elt);
3862 if (GET_MODE (op) == V4SFmode
3863 || GET_MODE (op) == V2SFmode)
3864 tmp = gen_lowpart (SImode, tmp);
3865 return INTVAL (tmp);
3868 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
3869 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
3870 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
3871 all items are set to the same value and contain COPIES replicas of the
3872 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
3873 operand and the others are set to the value of the operand's msb. */
3876 vspltis_constant (rtx op, unsigned step, unsigned copies)
3878 enum machine_mode mode = GET_MODE (op);
3879 enum machine_mode inner = GET_MODE_INNER (mode);
3882 unsigned nunits = GET_MODE_NUNITS (mode);
3883 unsigned bitsize = GET_MODE_BITSIZE (inner);
3884 unsigned mask = GET_MODE_MASK (inner);
3886 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
3887 HOST_WIDE_INT splat_val = val;
3888 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
3890 /* Construct the value to be splatted, if possible. If not, return 0. */
3891 for (i = 2; i <= copies; i *= 2)
3893 HOST_WIDE_INT small_val;
3895 small_val = splat_val >> bitsize;
3897 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
3899 splat_val = small_val;
3902 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
3903 if (EASY_VECTOR_15 (splat_val))
3906 /* Also check if we can splat, and then add the result to itself. Do so if
3907 the value is positive, of if the splat instruction is using OP's mode;
3908 for splat_val < 0, the splat and the add should use the same mode. */
3909 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
3910 && (splat_val >= 0 || (step == 1 && copies == 1)))
3913 /* Also check if are loading up the most significant bit which can be done by
3914 loading up -1 and shifting the value left by -1. */
3915 else if (EASY_VECTOR_MSB (splat_val, inner))
3921 /* Check if VAL is present in every STEP-th element, and the
3922 other elements are filled with its most significant bit. */
3923 for (i = 0; i < nunits - 1; ++i)
3925 HOST_WIDE_INT desired_val;
3926 if (((i + 1) & (step - 1)) == 0)
3929 desired_val = msb_val;
3931 if (desired_val != const_vector_elt_as_int (op, i))
3939 /* Return true if OP is of the given MODE and can be synthesized
3940 with a vspltisb, vspltish or vspltisw. */
3943 easy_altivec_constant (rtx op, enum machine_mode mode)
3945 unsigned step, copies;
3947 if (mode == VOIDmode)
3948 mode = GET_MODE (op);
3949 else if (mode != GET_MODE (op))
3952 /* Start with a vspltisw. */
3953 step = GET_MODE_NUNITS (mode) / 4;
3956 if (vspltis_constant (op, step, copies))
3959 /* Then try with a vspltish. */
3965 if (vspltis_constant (op, step, copies))
3968 /* And finally a vspltisb. */
3974 if (vspltis_constant (op, step, copies))
3980 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
3981 result is OP. Abort if it is not possible. */
3984 gen_easy_altivec_constant (rtx op)
3986 enum machine_mode mode = GET_MODE (op);
3987 int nunits = GET_MODE_NUNITS (mode);
3988 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
3989 unsigned step = nunits / 4;
3990 unsigned copies = 1;
3992 /* Start with a vspltisw. */
3993 if (vspltis_constant (op, step, copies))
3994 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
3996 /* Then try with a vspltish. */
4002 if (vspltis_constant (op, step, copies))
4003 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4005 /* And finally a vspltisb. */
4011 if (vspltis_constant (op, step, copies))
4012 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4018 output_vec_const_move (rtx *operands)
4021 enum machine_mode mode;
4026 mode = GET_MODE (dest);
4028 if (TARGET_VSX && zero_constant (vec, mode))
4029 return "xxlxor %x0,%x0,%x0";
4034 if (zero_constant (vec, mode))
4035 return "vxor %0,%0,%0";
4037 splat_vec = gen_easy_altivec_constant (vec);
4038 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4039 operands[1] = XEXP (splat_vec, 0);
4040 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4043 switch (GET_MODE (splat_vec))
4046 return "vspltisw %0,%1";
4049 return "vspltish %0,%1";
4052 return "vspltisb %0,%1";
4059 gcc_assert (TARGET_SPE);
4061 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4062 pattern of V1DI, V4HI, and V2SF.
4064 FIXME: We should probably return # and add post reload
4065 splitters for these, but this way is so easy ;-). */
4066 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4067 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4068 operands[1] = CONST_VECTOR_ELT (vec, 0);
4069 operands[2] = CONST_VECTOR_ELT (vec, 1);
4071 return "li %0,%1\n\tevmergelo %0,%0,%0";
4073 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4076 /* Initialize TARGET of vector PAIRED to VALS. */
4079 paired_expand_vector_init (rtx target, rtx vals)
4081 enum machine_mode mode = GET_MODE (target);
4082 int n_elts = GET_MODE_NUNITS (mode);
4084 rtx x, new_rtx, tmp, constant_op, op1, op2;
4087 for (i = 0; i < n_elts; ++i)
4089 x = XVECEXP (vals, 0, i);
4090 if (!CONSTANT_P (x))
4095 /* Load from constant pool. */
4096 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4102 /* The vector is initialized only with non-constants. */
4103 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4104 XVECEXP (vals, 0, 1));
4106 emit_move_insn (target, new_rtx);
4110 /* One field is non-constant and the other one is a constant. Load the
4111 constant from the constant pool and use ps_merge instruction to
4112 construct the whole vector. */
4113 op1 = XVECEXP (vals, 0, 0);
4114 op2 = XVECEXP (vals, 0, 1);
4116 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4118 tmp = gen_reg_rtx (GET_MODE (constant_op));
4119 emit_move_insn (tmp, constant_op);
4121 if (CONSTANT_P (op1))
4122 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4124 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4126 emit_move_insn (target, new_rtx);
4130 paired_expand_vector_move (rtx operands[])
4132 rtx op0 = operands[0], op1 = operands[1];
4134 emit_move_insn (op0, op1);
4137 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4138 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4139 operands for the relation operation COND. This is a recursive
4143 paired_emit_vector_compare (enum rtx_code rcode,
4144 rtx dest, rtx op0, rtx op1,
4145 rtx cc_op0, rtx cc_op1)
4147 rtx tmp = gen_reg_rtx (V2SFmode);
4148 rtx tmp1, max, min, equal_zero;
4150 gcc_assert (TARGET_PAIRED_FLOAT);
4151 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4157 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4161 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4162 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4166 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4169 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4172 tmp1 = gen_reg_rtx (V2SFmode);
4173 max = gen_reg_rtx (V2SFmode);
4174 min = gen_reg_rtx (V2SFmode);
4175 equal_zero = gen_reg_rtx (V2SFmode);
4177 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4178 emit_insn (gen_selv2sf4
4179 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4180 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4181 emit_insn (gen_selv2sf4
4182 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4183 emit_insn (gen_subv2sf3 (tmp1, min, max));
4184 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4187 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4190 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4193 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4196 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4199 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4208 /* Emit vector conditional expression.
4209 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4210 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4213 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4214 rtx cond, rtx cc_op0, rtx cc_op1)
4216 enum rtx_code rcode = GET_CODE (cond);
4218 if (!TARGET_PAIRED_FLOAT)
4221 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4226 /* Initialize vector TARGET to VALS. */
4229 rs6000_expand_vector_init (rtx target, rtx vals)
4231 enum machine_mode mode = GET_MODE (target);
4232 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4233 int n_elts = GET_MODE_NUNITS (mode);
4234 int n_var = 0, one_var = -1;
4235 bool all_same = true, all_const_zero = true;
4239 for (i = 0; i < n_elts; ++i)
4241 x = XVECEXP (vals, 0, i);
4242 if (!CONSTANT_P (x))
4243 ++n_var, one_var = i;
4244 else if (x != CONST0_RTX (inner_mode))
4245 all_const_zero = false;
4247 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4253 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4254 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4255 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4257 /* Zero register. */
4258 emit_insn (gen_rtx_SET (VOIDmode, target,
4259 gen_rtx_XOR (mode, target, target)));
4262 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4264 /* Splat immediate. */
4265 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4270 /* Load from constant pool. */
4271 emit_move_insn (target, const_vec);
4276 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4277 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4281 rtx element = XVECEXP (vals, 0, 0);
4282 if (mode == V2DFmode)
4283 emit_insn (gen_vsx_splat_v2df (target, element));
4285 emit_insn (gen_vsx_splat_v2di (target, element));
4289 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4290 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4291 if (mode == V2DFmode)
4292 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4294 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4299 /* With single precision floating point on VSX, know that internally single
4300 precision is actually represented as a double, and either make 2 V2DF
4301 vectors, and convert these vectors to single precision, or do one
4302 conversion, and splat the result to the other elements. */
4303 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4307 rtx freg = gen_reg_rtx (V4SFmode);
4308 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4310 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4311 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4315 rtx dbl_even = gen_reg_rtx (V2DFmode);
4316 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4317 rtx flt_even = gen_reg_rtx (V4SFmode);
4318 rtx flt_odd = gen_reg_rtx (V4SFmode);
4320 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4321 copy_to_reg (XVECEXP (vals, 0, 0)),
4322 copy_to_reg (XVECEXP (vals, 0, 1))));
4323 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4324 copy_to_reg (XVECEXP (vals, 0, 2)),
4325 copy_to_reg (XVECEXP (vals, 0, 3))));
4326 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4327 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4328 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4333 /* Store value to stack temp. Load vector element. Splat. However, splat
4334 of 64-bit items is not supported on Altivec. */
4335 if (all_same && GET_MODE_SIZE (mode) <= 4)
4337 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4338 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4339 XVECEXP (vals, 0, 0));
4340 x = gen_rtx_UNSPEC (VOIDmode,
4341 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4342 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4344 gen_rtx_SET (VOIDmode,
4347 x = gen_rtx_VEC_SELECT (inner_mode, target,
4348 gen_rtx_PARALLEL (VOIDmode,
4349 gen_rtvec (1, const0_rtx)));
4350 emit_insn (gen_rtx_SET (VOIDmode, target,
4351 gen_rtx_VEC_DUPLICATE (mode, x)));
4355 /* One field is non-constant. Load constant then overwrite
4359 rtx copy = copy_rtx (vals);
4361 /* Load constant part of vector, substitute neighboring value for
4363 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4364 rs6000_expand_vector_init (target, copy);
4366 /* Insert variable. */
4367 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4371 /* Construct the vector in memory one field at a time
4372 and load the whole vector. */
4373 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4374 for (i = 0; i < n_elts; i++)
4375 emit_move_insn (adjust_address_nv (mem, inner_mode,
4376 i * GET_MODE_SIZE (inner_mode)),
4377 XVECEXP (vals, 0, i));
4378 emit_move_insn (target, mem);
4381 /* Set field ELT of TARGET to VAL. */
4384 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4386 enum machine_mode mode = GET_MODE (target);
4387 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4388 rtx reg = gen_reg_rtx (mode);
4390 int width = GET_MODE_SIZE (inner_mode);
4393 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4395 rtx (*set_func) (rtx, rtx, rtx, rtx)
4396 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4397 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4401 /* Load single variable value. */
4402 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4403 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4404 x = gen_rtx_UNSPEC (VOIDmode,
4405 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4406 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4408 gen_rtx_SET (VOIDmode,
4412 /* Linear sequence. */
4413 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4414 for (i = 0; i < 16; ++i)
4415 XVECEXP (mask, 0, i) = GEN_INT (i);
4417 /* Set permute mask to insert element into target. */
4418 for (i = 0; i < width; ++i)
4419 XVECEXP (mask, 0, elt*width + i)
4420 = GEN_INT (i + 0x10);
4421 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4422 x = gen_rtx_UNSPEC (mode,
4423 gen_rtvec (3, target, reg,
4424 force_reg (V16QImode, x)),
4426 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4429 /* Extract field ELT from VEC into TARGET. */
4432 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4434 enum machine_mode mode = GET_MODE (vec);
4435 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4438 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4440 rtx (*extract_func) (rtx, rtx, rtx)
4441 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4442 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4446 /* Allocate mode-sized buffer. */
4447 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4449 /* Add offset to field within buffer matching vector element. */
4450 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4452 /* Store single field into mode-sized buffer. */
4453 x = gen_rtx_UNSPEC (VOIDmode,
4454 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4455 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4457 gen_rtx_SET (VOIDmode,
4460 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4463 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4464 implement ANDing by the mask IN. */
4466 build_mask64_2_operands (rtx in, rtx *out)
4468 #if HOST_BITS_PER_WIDE_INT >= 64
4469 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4472 gcc_assert (GET_CODE (in) == CONST_INT);
4477 /* Assume c initially something like 0x00fff000000fffff. The idea
4478 is to rotate the word so that the middle ^^^^^^ group of zeros
4479 is at the MS end and can be cleared with an rldicl mask. We then
4480 rotate back and clear off the MS ^^ group of zeros with a
4482 c = ~c; /* c == 0xff000ffffff00000 */
4483 lsb = c & -c; /* lsb == 0x0000000000100000 */
4484 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4485 c = ~c; /* c == 0x00fff000000fffff */
4486 c &= -lsb; /* c == 0x00fff00000000000 */
4487 lsb = c & -c; /* lsb == 0x0000100000000000 */
4488 c = ~c; /* c == 0xff000fffffffffff */
4489 c &= -lsb; /* c == 0xff00000000000000 */
4491 while ((lsb >>= 1) != 0)
4492 shift++; /* shift == 44 on exit from loop */
4493 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4494 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4495 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4499 /* Assume c initially something like 0xff000f0000000000. The idea
4500 is to rotate the word so that the ^^^ middle group of zeros
4501 is at the LS end and can be cleared with an rldicr mask. We then
4502 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4504 lsb = c & -c; /* lsb == 0x0000010000000000 */
4505 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4506 c = ~c; /* c == 0x00fff0ffffffffff */
4507 c &= -lsb; /* c == 0x00fff00000000000 */
4508 lsb = c & -c; /* lsb == 0x0000100000000000 */
4509 c = ~c; /* c == 0xff000fffffffffff */
4510 c &= -lsb; /* c == 0xff00000000000000 */
4512 while ((lsb >>= 1) != 0)
4513 shift++; /* shift == 44 on exit from loop */
4514 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4515 m1 >>= shift; /* m1 == 0x0000000000000fff */
4516 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4519 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4520 masks will be all 1's. We are guaranteed more than one transition. */
4521 out[0] = GEN_INT (64 - shift);
4522 out[1] = GEN_INT (m1);
4523 out[2] = GEN_INT (shift);
4524 out[3] = GEN_INT (m2);
4532 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4535 invalid_e500_subreg (rtx op, enum machine_mode mode)
4537 if (TARGET_E500_DOUBLE)
4539 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4540 subreg:TI and reg:TF. Decimal float modes are like integer
4541 modes (only low part of each register used) for this
4543 if (GET_CODE (op) == SUBREG
4544 && (mode == SImode || mode == DImode || mode == TImode
4545 || mode == DDmode || mode == TDmode)
4546 && REG_P (SUBREG_REG (op))
4547 && (GET_MODE (SUBREG_REG (op)) == DFmode
4548 || GET_MODE (SUBREG_REG (op)) == TFmode))
4551 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4553 if (GET_CODE (op) == SUBREG
4554 && (mode == DFmode || mode == TFmode)
4555 && REG_P (SUBREG_REG (op))
4556 && (GET_MODE (SUBREG_REG (op)) == DImode
4557 || GET_MODE (SUBREG_REG (op)) == TImode
4558 || GET_MODE (SUBREG_REG (op)) == DDmode
4559 || GET_MODE (SUBREG_REG (op)) == TDmode))
4564 && GET_CODE (op) == SUBREG
4566 && REG_P (SUBREG_REG (op))
4567 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4573 /* AIX increases natural record alignment to doubleword if the first
4574 field is an FP double while the FP fields remain word aligned. */
4577 rs6000_special_round_type_align (tree type, unsigned int computed,
4578 unsigned int specified)
4580 unsigned int align = MAX (computed, specified);
4581 tree field = TYPE_FIELDS (type);
4583 /* Skip all non field decls */
4584 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4585 field = TREE_CHAIN (field);
4587 if (field != NULL && field != type)
4589 type = TREE_TYPE (field);
4590 while (TREE_CODE (type) == ARRAY_TYPE)
4591 type = TREE_TYPE (type);
4593 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4594 align = MAX (align, 64);
4600 /* Darwin increases record alignment to the natural alignment of
4604 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4605 unsigned int specified)
4607 unsigned int align = MAX (computed, specified);
4609 if (TYPE_PACKED (type))
4612 /* Find the first field, looking down into aggregates. */
4614 tree field = TYPE_FIELDS (type);
4615 /* Skip all non field decls */
4616 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4617 field = TREE_CHAIN (field);
4620 type = TREE_TYPE (field);
4621 while (TREE_CODE (type) == ARRAY_TYPE)
4622 type = TREE_TYPE (type);
4623 } while (AGGREGATE_TYPE_P (type));
4625 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
4626 align = MAX (align, TYPE_ALIGN (type));
4631 /* Return 1 for an operand in small memory on V.4/eabi. */
4634 small_data_operand (rtx op ATTRIBUTE_UNUSED,
4635 enum machine_mode mode ATTRIBUTE_UNUSED)
4640 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
4643 if (DEFAULT_ABI != ABI_V4)
4646 /* Vector and float memory instructions have a limited offset on the
4647 SPE, so using a vector or float variable directly as an operand is
4650 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
4653 if (GET_CODE (op) == SYMBOL_REF)
4656 else if (GET_CODE (op) != CONST
4657 || GET_CODE (XEXP (op, 0)) != PLUS
4658 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
4659 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
4664 rtx sum = XEXP (op, 0);
4665 HOST_WIDE_INT summand;
4667 /* We have to be careful here, because it is the referenced address
4668 that must be 32k from _SDA_BASE_, not just the symbol. */
4669 summand = INTVAL (XEXP (sum, 1));
4670 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
4673 sym_ref = XEXP (sum, 0);
4676 return SYMBOL_REF_SMALL_P (sym_ref);
4682 /* Return true if either operand is a general purpose register. */
4685 gpr_or_gpr_p (rtx op0, rtx op1)
4687 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
4688 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
4692 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
4695 reg_offset_addressing_ok_p (enum machine_mode mode)
4705 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
4706 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
4714 /* Paired vector modes. Only reg+reg addressing is valid. */
4715 if (TARGET_PAIRED_FLOAT)
4727 virtual_stack_registers_memory_p (rtx op)
4731 if (GET_CODE (op) == REG)
4732 regnum = REGNO (op);
4734 else if (GET_CODE (op) == PLUS
4735 && GET_CODE (XEXP (op, 0)) == REG
4736 && GET_CODE (XEXP (op, 1)) == CONST_INT)
4737 regnum = REGNO (XEXP (op, 0));
4742 return (regnum >= FIRST_VIRTUAL_REGISTER
4743 && regnum <= LAST_VIRTUAL_REGISTER);
4747 constant_pool_expr_p (rtx op)
4751 split_const (op, &base, &offset);
4752 return (GET_CODE (base) == SYMBOL_REF
4753 && CONSTANT_POOL_ADDRESS_P (base)
4754 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
4758 toc_relative_expr_p (rtx op)
4762 if (GET_CODE (op) != CONST)
4765 split_const (op, &base, &offset);
4766 return (GET_CODE (base) == UNSPEC
4767 && XINT (base, 1) == UNSPEC_TOCREL);
4771 legitimate_constant_pool_address_p (rtx x)
4774 && GET_CODE (x) == PLUS
4775 && GET_CODE (XEXP (x, 0)) == REG
4776 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
4777 && toc_relative_expr_p (XEXP (x, 1)));
4781 legitimate_small_data_p (enum machine_mode mode, rtx x)
4783 return (DEFAULT_ABI == ABI_V4
4784 && !flag_pic && !TARGET_TOC
4785 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
4786 && small_data_operand (x, mode));
4789 /* SPE offset addressing is limited to 5-bits worth of double words. */
4790 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
4793 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
4795 unsigned HOST_WIDE_INT offset, extra;
4797 if (GET_CODE (x) != PLUS)
4799 if (GET_CODE (XEXP (x, 0)) != REG)
4801 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4803 if (!reg_offset_addressing_ok_p (mode))
4804 return virtual_stack_registers_memory_p (x);
4805 if (legitimate_constant_pool_address_p (x))
4807 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4810 offset = INTVAL (XEXP (x, 1));
4818 /* SPE vector modes. */
4819 return SPE_CONST_OFFSET_OK (offset);
4822 if (TARGET_E500_DOUBLE)
4823 return SPE_CONST_OFFSET_OK (offset);
4825 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
4827 if (VECTOR_MEM_VSX_P (DFmode))
4832 /* On e500v2, we may have:
4834 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
4836 Which gets addressed with evldd instructions. */
4837 if (TARGET_E500_DOUBLE)
4838 return SPE_CONST_OFFSET_OK (offset);
4840 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
4842 else if (offset & 3)
4847 if (TARGET_E500_DOUBLE)
4848 return (SPE_CONST_OFFSET_OK (offset)
4849 && SPE_CONST_OFFSET_OK (offset + 8));
4853 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
4855 else if (offset & 3)
4866 return (offset < 0x10000) && (offset + extra < 0x10000);
4870 legitimate_indexed_address_p (rtx x, int strict)
4874 if (GET_CODE (x) != PLUS)
4880 /* Recognize the rtl generated by reload which we know will later be
4881 replaced with proper base and index regs. */
4883 && reload_in_progress
4884 && (REG_P (op0) || GET_CODE (op0) == PLUS)
4888 return (REG_P (op0) && REG_P (op1)
4889 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
4890 && INT_REG_OK_FOR_INDEX_P (op1, strict))
4891 || (INT_REG_OK_FOR_BASE_P (op1, strict)
4892 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
4896 avoiding_indexed_address_p (enum machine_mode mode)
4898 /* Avoid indexed addressing for modes that have non-indexed
4899 load/store instruction forms. */
4900 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
4904 legitimate_indirect_address_p (rtx x, int strict)
4906 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
4910 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
4912 if (!TARGET_MACHO || !flag_pic
4913 || mode != SImode || GET_CODE (x) != MEM)
4917 if (GET_CODE (x) != LO_SUM)
4919 if (GET_CODE (XEXP (x, 0)) != REG)
4921 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
4925 return CONSTANT_P (x);
4929 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
4931 if (GET_CODE (x) != LO_SUM)
4933 if (GET_CODE (XEXP (x, 0)) != REG)
4935 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4937 /* Restrict addressing for DI because of our SUBREG hackery. */
4938 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4939 || mode == DDmode || mode == TDmode
4944 if (TARGET_ELF || TARGET_MACHO)
4946 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
4950 if (GET_MODE_NUNITS (mode) != 1)
4952 if (GET_MODE_BITSIZE (mode) > 64
4953 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
4954 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4955 && (mode == DFmode || mode == DDmode))))
4958 return CONSTANT_P (x);
4965 /* Try machine-dependent ways of modifying an illegitimate address
4966 to be legitimate. If we find one, return the new, valid address.
4967 This is used from only one place: `memory_address' in explow.c.
4969 OLDX is the address as it was before break_out_memory_refs was
4970 called. In some cases it is useful to look at this to decide what
4973 It is always safe for this function to do nothing. It exists to
4974 recognize opportunities to optimize the output.
4976 On RS/6000, first check for the sum of a register with a constant
4977 integer that is out of range. If so, generate code to add the
4978 constant with the low-order 16 bits masked to the register and force
4979 this result into another register (this can be done with `cau').
4980 Then generate an address of REG+(CONST&0xffff), allowing for the
4981 possibility of bit 16 being a one.
4983 Then check for the sum of a register and something not constant, try to
4984 load the other things into a register and return the sum. */
4987 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
4988 enum machine_mode mode)
4990 unsigned int extra = 0;
4992 if (!reg_offset_addressing_ok_p (mode))
4994 if (virtual_stack_registers_memory_p (x))
4997 /* In theory we should not be seeing addresses of the form reg+0,
4998 but just in case it is generated, optimize it away. */
4999 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5000 return force_reg (Pmode, XEXP (x, 0));
5002 /* Make sure both operands are registers. */
5003 else if (GET_CODE (x) == PLUS)
5004 return gen_rtx_PLUS (Pmode,
5005 force_reg (Pmode, XEXP (x, 0)),
5006 force_reg (Pmode, XEXP (x, 1)));
5008 return force_reg (Pmode, x);
5010 if (GET_CODE (x) == SYMBOL_REF)
5012 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5014 return rs6000_legitimize_tls_address (x, model);
5024 if (!TARGET_POWERPC64)
5032 extra = TARGET_POWERPC64 ? 8 : 12;
5038 if (GET_CODE (x) == PLUS
5039 && GET_CODE (XEXP (x, 0)) == REG
5040 && GET_CODE (XEXP (x, 1)) == CONST_INT
5041 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5043 && !((TARGET_POWERPC64
5044 && (mode == DImode || mode == TImode)
5045 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5046 || SPE_VECTOR_MODE (mode)
5047 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5048 || mode == DImode || mode == DDmode
5049 || mode == TDmode))))
5051 HOST_WIDE_INT high_int, low_int;
5053 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5054 if (low_int >= 0x8000 - extra)
5056 high_int = INTVAL (XEXP (x, 1)) - low_int;
5057 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5058 GEN_INT (high_int)), 0);
5059 return plus_constant (sum, low_int);
5061 else if (GET_CODE (x) == PLUS
5062 && GET_CODE (XEXP (x, 0)) == REG
5063 && GET_CODE (XEXP (x, 1)) != CONST_INT
5064 && GET_MODE_NUNITS (mode) == 1
5065 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5067 || ((mode != DImode && mode != DFmode && mode != DDmode)
5068 || (TARGET_E500_DOUBLE && mode != DDmode)))
5069 && (TARGET_POWERPC64 || mode != DImode)
5070 && !avoiding_indexed_address_p (mode)
5075 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5076 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5078 else if (SPE_VECTOR_MODE (mode)
5079 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5080 || mode == DDmode || mode == TDmode
5081 || mode == DImode)))
5085 /* We accept [reg + reg] and [reg + OFFSET]. */
5087 if (GET_CODE (x) == PLUS)
5089 rtx op1 = XEXP (x, 0);
5090 rtx op2 = XEXP (x, 1);
5093 op1 = force_reg (Pmode, op1);
5095 if (GET_CODE (op2) != REG
5096 && (GET_CODE (op2) != CONST_INT
5097 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5098 || (GET_MODE_SIZE (mode) > 8
5099 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5100 op2 = force_reg (Pmode, op2);
5102 /* We can't always do [reg + reg] for these, because [reg +
5103 reg + offset] is not a legitimate addressing mode. */
5104 y = gen_rtx_PLUS (Pmode, op1, op2);
5106 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5107 return force_reg (Pmode, y);
5112 return force_reg (Pmode, x);
5118 && GET_CODE (x) != CONST_INT
5119 && GET_CODE (x) != CONST_DOUBLE
5121 && GET_MODE_NUNITS (mode) == 1
5122 && (GET_MODE_BITSIZE (mode) <= 32
5123 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5124 && (mode == DFmode || mode == DDmode))))
5126 rtx reg = gen_reg_rtx (Pmode);
5127 emit_insn (gen_elf_high (reg, x));
5128 return gen_rtx_LO_SUM (Pmode, reg, x);
5130 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5133 && ! MACHO_DYNAMIC_NO_PIC_P
5135 && GET_CODE (x) != CONST_INT
5136 && GET_CODE (x) != CONST_DOUBLE
5138 && GET_MODE_NUNITS (mode) == 1
5139 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5140 || (mode != DFmode && mode != DDmode))
5144 rtx reg = gen_reg_rtx (Pmode);
5145 emit_insn (gen_macho_high (reg, x));
5146 return gen_rtx_LO_SUM (Pmode, reg, x);
5149 && GET_CODE (x) == SYMBOL_REF
5150 && constant_pool_expr_p (x)
5151 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5153 return create_TOC_reference (x);
5159 /* Debug version of rs6000_legitimize_address. */
5161 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5167 ret = rs6000_legitimize_address (x, oldx, mode);
5168 insns = get_insns ();
5174 "\nrs6000_legitimize_address: mode %s, old code %s, "
5175 "new code %s, modified\n",
5176 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5177 GET_RTX_NAME (GET_CODE (ret)));
5179 fprintf (stderr, "Original address:\n");
5182 fprintf (stderr, "oldx:\n");
5185 fprintf (stderr, "New address:\n");
5190 fprintf (stderr, "Insns added:\n");
5191 debug_rtx_list (insns, 20);
5197 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5198 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5209 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5210 We need to emit DTP-relative relocations. */
5213 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5218 fputs ("\t.long\t", file);
5221 fputs (DOUBLE_INT_ASM_OP, file);
5226 output_addr_const (file, x);
5227 fputs ("@dtprel+0x8000", file);
5230 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5232 static GTY(()) rtx rs6000_tls_symbol;
5234 rs6000_tls_get_addr (void)
5236 if (!rs6000_tls_symbol)
5237 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5239 return rs6000_tls_symbol;
5242 /* Construct the SYMBOL_REF for TLS GOT references. */
5244 static GTY(()) rtx rs6000_got_symbol;
5246 rs6000_got_sym (void)
5248 if (!rs6000_got_symbol)
5250 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5251 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5252 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5255 return rs6000_got_symbol;
5258 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5259 this (thread-local) address. */
5262 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5266 dest = gen_reg_rtx (Pmode);
5267 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5273 tlsreg = gen_rtx_REG (Pmode, 13);
5274 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5278 tlsreg = gen_rtx_REG (Pmode, 2);
5279 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5283 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5287 tmp = gen_reg_rtx (Pmode);
5290 tlsreg = gen_rtx_REG (Pmode, 13);
5291 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5295 tlsreg = gen_rtx_REG (Pmode, 2);
5296 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5300 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5302 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5307 rtx r3, got, tga, tmp1, tmp2, eqv;
5309 /* We currently use relocations like @got@tlsgd for tls, which
5310 means the linker will handle allocation of tls entries, placing
5311 them in the .got section. So use a pointer to the .got section,
5312 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5313 or to secondary GOT sections used by 32-bit -fPIC. */
5315 got = gen_rtx_REG (Pmode, 2);
5319 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5322 rtx gsym = rs6000_got_sym ();
5323 got = gen_reg_rtx (Pmode);
5325 rs6000_emit_move (got, gsym, Pmode);
5331 tmp1 = gen_reg_rtx (Pmode);
5332 tmp2 = gen_reg_rtx (Pmode);
5333 tmp3 = gen_reg_rtx (Pmode);
5334 mem = gen_const_mem (Pmode, tmp1);
5336 first = emit_insn (gen_load_toc_v4_PIC_1b (gsym));
5337 emit_move_insn (tmp1,
5338 gen_rtx_REG (Pmode, LR_REGNO));
5339 emit_move_insn (tmp2, mem);
5340 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
5341 last = emit_move_insn (got, tmp3);
5342 set_unique_reg_note (last, REG_EQUAL, gsym);
5347 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5349 r3 = gen_rtx_REG (Pmode, 3);
5350 tga = rs6000_tls_get_addr ();
5352 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5353 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5354 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5355 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5356 else if (DEFAULT_ABI == ABI_V4)
5357 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5362 insn = emit_call_insn (insn);
5363 RTL_CONST_CALL_P (insn) = 1;
5364 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5365 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5366 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5367 insn = get_insns ();
5369 emit_libcall_block (insn, dest, r3, addr);
5371 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5373 r3 = gen_rtx_REG (Pmode, 3);
5374 tga = rs6000_tls_get_addr ();
5376 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5377 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5378 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5379 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5380 else if (DEFAULT_ABI == ABI_V4)
5381 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5386 insn = emit_call_insn (insn);
5387 RTL_CONST_CALL_P (insn) = 1;
5388 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5389 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5390 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5391 insn = get_insns ();
5393 tmp1 = gen_reg_rtx (Pmode);
5394 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
5396 emit_libcall_block (insn, tmp1, r3, eqv);
5397 if (rs6000_tls_size == 16)
5400 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5402 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5404 else if (rs6000_tls_size == 32)
5406 tmp2 = gen_reg_rtx (Pmode);
5408 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5410 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5413 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5415 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5419 tmp2 = gen_reg_rtx (Pmode);
5421 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5423 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5425 insn = gen_rtx_SET (Pmode, dest,
5426 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5432 /* IE, or 64-bit offset LE. */
5433 tmp2 = gen_reg_rtx (Pmode);
5435 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5437 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5440 insn = gen_tls_tls_64 (dest, tmp2, addr);
5442 insn = gen_tls_tls_32 (dest, tmp2, addr);
5450 /* Return 1 if X contains a thread-local symbol. */
5453 rs6000_tls_referenced_p (rtx x)
5455 if (! TARGET_HAVE_TLS)
5458 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5461 /* Return 1 if *X is a thread-local symbol. This is the same as
5462 rs6000_tls_symbol_ref except for the type of the unused argument. */
5465 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5467 return RS6000_SYMBOL_REF_TLS_P (*x);
5470 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5471 replace the input X, or the original X if no replacement is called for.
5472 The output parameter *WIN is 1 if the calling macro should goto WIN,
5475 For RS/6000, we wish to handle large displacements off a base
5476 register by splitting the addend across an addiu/addis and the mem insn.
5477 This cuts number of extra insns needed from 3 to 1.
5479 On Darwin, we use this to generate code for floating point constants.
5480 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5481 The Darwin code is inside #if TARGET_MACHO because only then are the
5482 machopic_* functions defined. */
5484 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5485 int opnum, int type,
5486 int ind_levels ATTRIBUTE_UNUSED, int *win)
5488 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5490 /* We must recognize output that we have already generated ourselves. */
5491 if (GET_CODE (x) == PLUS
5492 && GET_CODE (XEXP (x, 0)) == PLUS
5493 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5494 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5495 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5497 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5498 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5499 opnum, (enum reload_type)type);
5505 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5506 && GET_CODE (x) == LO_SUM
5507 && GET_CODE (XEXP (x, 0)) == PLUS
5508 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5509 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5510 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5511 && machopic_operand_p (XEXP (x, 1)))
5513 /* Result of previous invocation of this function on Darwin
5514 floating point constant. */
5515 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5516 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5517 opnum, (enum reload_type)type);
5523 /* Force ld/std non-word aligned offset into base register by wrapping
5525 if (GET_CODE (x) == PLUS
5526 && GET_CODE (XEXP (x, 0)) == REG
5527 && REGNO (XEXP (x, 0)) < 32
5528 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5529 && GET_CODE (XEXP (x, 1)) == CONST_INT
5531 && (INTVAL (XEXP (x, 1)) & 3) != 0
5532 && VECTOR_MEM_NONE_P (mode)
5533 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5534 && TARGET_POWERPC64)
5536 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5537 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5538 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5539 opnum, (enum reload_type) type);
5544 if (GET_CODE (x) == PLUS
5545 && GET_CODE (XEXP (x, 0)) == REG
5546 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5547 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5548 && GET_CODE (XEXP (x, 1)) == CONST_INT
5550 && !SPE_VECTOR_MODE (mode)
5551 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5552 || mode == DDmode || mode == TDmode
5554 && VECTOR_MEM_NONE_P (mode))
5556 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5557 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5559 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5561 /* Check for 32-bit overflow. */
5562 if (high + low != val)
5568 /* Reload the high part into a base reg; leave the low part
5569 in the mem directly. */
5571 x = gen_rtx_PLUS (GET_MODE (x),
5572 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5576 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5577 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5578 opnum, (enum reload_type)type);
5583 if (GET_CODE (x) == SYMBOL_REF
5585 && VECTOR_MEM_NONE_P (mode)
5586 && !SPE_VECTOR_MODE (mode)
5588 && DEFAULT_ABI == ABI_DARWIN
5589 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
5591 && DEFAULT_ABI == ABI_V4
5594 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
5595 The same goes for DImode without 64-bit gprs and DFmode and DDmode
5599 && (mode != DImode || TARGET_POWERPC64)
5600 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
5601 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
5606 rtx offset = machopic_gen_offset (x);
5607 x = gen_rtx_LO_SUM (GET_MODE (x),
5608 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
5609 gen_rtx_HIGH (Pmode, offset)), offset);
5613 x = gen_rtx_LO_SUM (GET_MODE (x),
5614 gen_rtx_HIGH (Pmode, x), x);
5616 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5617 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5618 opnum, (enum reload_type)type);
5623 /* Reload an offset address wrapped by an AND that represents the
5624 masking of the lower bits. Strip the outer AND and let reload
5625 convert the offset address into an indirect address. For VSX,
5626 force reload to create the address with an AND in a separate
5627 register, because we can't guarantee an altivec register will
5629 if (VECTOR_MEM_ALTIVEC_P (mode)
5630 && GET_CODE (x) == AND
5631 && GET_CODE (XEXP (x, 0)) == PLUS
5632 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5633 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5634 && GET_CODE (XEXP (x, 1)) == CONST_INT
5635 && INTVAL (XEXP (x, 1)) == -16)
5644 && GET_CODE (x) == SYMBOL_REF
5645 && constant_pool_expr_p (x)
5646 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
5648 x = create_TOC_reference (x);
5656 /* Debug version of rs6000_legitimize_reload_address. */
5658 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
5659 int opnum, int type,
5660 int ind_levels, int *win)
5662 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
5665 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
5666 "type = %d, ind_levels = %d, win = %d, original addr:\n",
5667 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
5671 fprintf (stderr, "Same address returned\n");
5673 fprintf (stderr, "NULL returned\n");
5676 fprintf (stderr, "New address:\n");
5683 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
5684 that is a valid memory address for an instruction.
5685 The MODE argument is the machine mode for the MEM expression
5686 that wants to use this address.
5688 On the RS/6000, there are four valid address: a SYMBOL_REF that
5689 refers to a constant pool entry of an address (or the sum of it
5690 plus a constant), a short (16-bit signed) constant plus a register,
5691 the sum of two registers, or a register indirect, possibly with an
5692 auto-increment. For DFmode, DDmode and DImode with a constant plus
5693 register, we must ensure that both words are addressable or PowerPC64
5694 with offset word aligned.
5696 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
5697 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
5698 because adjacent memory cells are accessed by adding word-sized offsets
5699 during assembly output. */
5701 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
5703 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5705 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
5706 if (VECTOR_MEM_ALTIVEC_P (mode)
5707 && GET_CODE (x) == AND
5708 && GET_CODE (XEXP (x, 1)) == CONST_INT
5709 && INTVAL (XEXP (x, 1)) == -16)
5712 if (RS6000_SYMBOL_REF_TLS_P (x))
5714 if (legitimate_indirect_address_p (x, reg_ok_strict))
5716 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
5717 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5718 && !SPE_VECTOR_MODE (mode)
5721 /* Restrict addressing for DI because of our SUBREG hackery. */
5722 && !(TARGET_E500_DOUBLE
5723 && (mode == DFmode || mode == DDmode || mode == DImode))
5725 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
5727 if (virtual_stack_registers_memory_p (x))
5729 if (reg_offset_p && legitimate_small_data_p (mode, x))
5731 if (reg_offset_p && legitimate_constant_pool_address_p (x))
5733 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
5736 && GET_CODE (x) == PLUS
5737 && GET_CODE (XEXP (x, 0)) == REG
5738 && (XEXP (x, 0) == virtual_stack_vars_rtx
5739 || XEXP (x, 0) == arg_pointer_rtx)
5740 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5742 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
5747 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5749 || (mode != DFmode && mode != DDmode)
5750 || (TARGET_E500_DOUBLE && mode != DDmode))
5751 && (TARGET_POWERPC64 || mode != DImode)
5752 && !avoiding_indexed_address_p (mode)
5753 && legitimate_indexed_address_p (x, reg_ok_strict))
5755 if (GET_CODE (x) == PRE_MODIFY
5759 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5761 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
5762 && (TARGET_POWERPC64 || mode != DImode)
5763 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5764 && !SPE_VECTOR_MODE (mode)
5765 /* Restrict addressing for DI because of our SUBREG hackery. */
5766 && !(TARGET_E500_DOUBLE
5767 && (mode == DFmode || mode == DDmode || mode == DImode))
5769 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
5770 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
5771 || (!avoiding_indexed_address_p (mode)
5772 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
5773 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5775 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
5780 /* Debug version of rs6000_legitimate_address_p. */
5782 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
5785 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
5787 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
5788 "strict = %d, code = %s\n",
5789 ret ? "true" : "false",
5790 GET_MODE_NAME (mode),
5792 GET_RTX_NAME (GET_CODE (x)));
5798 /* Go to LABEL if ADDR (a legitimate address expression)
5799 has an effect that depends on the machine mode it is used for.
5801 On the RS/6000 this is true of all integral offsets (since AltiVec
5802 and VSX modes don't allow them) or is a pre-increment or decrement.
5804 ??? Except that due to conceptual problems in offsettable_address_p
5805 we can't really report the problems of integral offsets. So leave
5806 this assuming that the adjustable offset must be valid for the
5807 sub-words of a TFmode operand, which is what we had before. */
5810 rs6000_mode_dependent_address (rtx addr)
5812 switch (GET_CODE (addr))
5815 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
5816 is considered a legitimate address before reload, so there
5817 are no offset restrictions in that case. Note that this
5818 condition is safe in strict mode because any address involving
5819 virtual_stack_vars_rtx or arg_pointer_rtx would already have
5820 been rejected as illegitimate. */
5821 if (XEXP (addr, 0) != virtual_stack_vars_rtx
5822 && XEXP (addr, 0) != arg_pointer_rtx
5823 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5825 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
5826 return val + 12 + 0x8000 >= 0x10000;
5833 /* Auto-increment cases are now treated generically in recog.c. */
5835 return TARGET_UPDATE;
5837 /* AND is only allowed in Altivec loads. */
5848 /* Debug version of rs6000_mode_dependent_address. */
5850 rs6000_debug_mode_dependent_address (rtx addr)
5852 bool ret = rs6000_mode_dependent_address (addr);
5854 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
5855 ret ? "true" : "false");
5861 /* Implement FIND_BASE_TERM. */
5864 rs6000_find_base_term (rtx op)
5868 split_const (op, &base, &offset);
5869 if (GET_CODE (base) == UNSPEC)
5870 switch (XINT (base, 1))
5873 case UNSPEC_MACHOPIC_OFFSET:
5874 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
5875 for aliasing purposes. */
5876 return XVECEXP (base, 0, 0);
5882 /* More elaborate version of recog's offsettable_memref_p predicate
5883 that works around the ??? note of rs6000_mode_dependent_address.
5884 In particular it accepts
5886 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
5888 in 32-bit mode, that the recog predicate rejects. */
5891 rs6000_offsettable_memref_p (rtx op)
5896 /* First mimic offsettable_memref_p. */
5897 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
5900 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
5901 the latter predicate knows nothing about the mode of the memory
5902 reference and, therefore, assumes that it is the largest supported
5903 mode (TFmode). As a consequence, legitimate offsettable memory
5904 references are rejected. rs6000_legitimate_offset_address_p contains
5905 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
5906 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
5909 /* Change register usage conditional on target flags. */
5911 rs6000_conditional_register_usage (void)
5915 /* Set MQ register fixed (already call_used) if not POWER
5916 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
5921 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
5923 fixed_regs[13] = call_used_regs[13]
5924 = call_really_used_regs[13] = 1;
5926 /* Conditionally disable FPRs. */
5927 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
5928 for (i = 32; i < 64; i++)
5929 fixed_regs[i] = call_used_regs[i]
5930 = call_really_used_regs[i] = 1;
5932 /* The TOC register is not killed across calls in a way that is
5933 visible to the compiler. */
5934 if (DEFAULT_ABI == ABI_AIX)
5935 call_really_used_regs[2] = 0;
5937 if (DEFAULT_ABI == ABI_V4
5938 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
5940 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5942 if (DEFAULT_ABI == ABI_V4
5943 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
5945 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5946 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5947 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5949 if (DEFAULT_ABI == ABI_DARWIN
5950 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
5951 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5952 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5953 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5955 if (TARGET_TOC && TARGET_MINIMAL_TOC)
5956 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5957 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5961 global_regs[SPEFSCR_REGNO] = 1;
5962 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
5963 registers in prologues and epilogues. We no longer use r14
5964 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
5965 pool for link-compatibility with older versions of GCC. Once
5966 "old" code has died out, we can return r14 to the allocation
5969 = call_used_regs[14]
5970 = call_really_used_regs[14] = 1;
5973 if (!TARGET_ALTIVEC && !TARGET_VSX)
5975 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
5976 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
5977 call_really_used_regs[VRSAVE_REGNO] = 1;
5980 if (TARGET_ALTIVEC || TARGET_VSX)
5981 global_regs[VSCR_REGNO] = 1;
5983 if (TARGET_ALTIVEC_ABI)
5985 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
5986 call_used_regs[i] = call_really_used_regs[i] = 1;
5988 /* AIX reserves VR20:31 in non-extended ABI mode. */
5990 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
5991 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
5995 /* Try to output insns to set TARGET equal to the constant C if it can
5996 be done in less than N insns. Do all computations in MODE.
5997 Returns the place where the output has been placed if it can be
5998 done and the insns have been emitted. If it would take more than N
5999 insns, zero is returned and no insns and emitted. */
6002 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6003 rtx source, int n ATTRIBUTE_UNUSED)
6005 rtx result, insn, set;
6006 HOST_WIDE_INT c0, c1;
6013 dest = gen_reg_rtx (mode);
6014 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6018 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6020 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6021 GEN_INT (INTVAL (source)
6022 & (~ (HOST_WIDE_INT) 0xffff))));
6023 emit_insn (gen_rtx_SET (VOIDmode, dest,
6024 gen_rtx_IOR (SImode, copy_rtx (result),
6025 GEN_INT (INTVAL (source) & 0xffff))));
6030 switch (GET_CODE (source))
6033 c0 = INTVAL (source);
6038 #if HOST_BITS_PER_WIDE_INT >= 64
6039 c0 = CONST_DOUBLE_LOW (source);
6042 c0 = CONST_DOUBLE_LOW (source);
6043 c1 = CONST_DOUBLE_HIGH (source);
6051 result = rs6000_emit_set_long_const (dest, c0, c1);
6058 insn = get_last_insn ();
6059 set = single_set (insn);
6060 if (! CONSTANT_P (SET_SRC (set)))
6061 set_unique_reg_note (insn, REG_EQUAL, source);
6066 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6067 fall back to a straight forward decomposition. We do this to avoid
6068 exponential run times encountered when looking for longer sequences
6069 with rs6000_emit_set_const. */
6071 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6073 if (!TARGET_POWERPC64)
6075 rtx operand1, operand2;
6077 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6079 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6081 emit_move_insn (operand1, GEN_INT (c1));
6082 emit_move_insn (operand2, GEN_INT (c2));
6086 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6089 ud2 = (c1 & 0xffff0000) >> 16;
6090 #if HOST_BITS_PER_WIDE_INT >= 64
6094 ud4 = (c2 & 0xffff0000) >> 16;
6096 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6097 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6100 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6102 emit_move_insn (dest, GEN_INT (ud1));
6105 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6106 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6109 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6112 emit_move_insn (dest, GEN_INT (ud2 << 16));
6114 emit_move_insn (copy_rtx (dest),
6115 gen_rtx_IOR (DImode, copy_rtx (dest),
6118 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6119 || (ud4 == 0 && ! (ud3 & 0x8000)))
6122 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6125 emit_move_insn (dest, GEN_INT (ud3 << 16));
6128 emit_move_insn (copy_rtx (dest),
6129 gen_rtx_IOR (DImode, copy_rtx (dest),
6131 emit_move_insn (copy_rtx (dest),
6132 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6135 emit_move_insn (copy_rtx (dest),
6136 gen_rtx_IOR (DImode, copy_rtx (dest),
6142 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6145 emit_move_insn (dest, GEN_INT (ud4 << 16));
6148 emit_move_insn (copy_rtx (dest),
6149 gen_rtx_IOR (DImode, copy_rtx (dest),
6152 emit_move_insn (copy_rtx (dest),
6153 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6156 emit_move_insn (copy_rtx (dest),
6157 gen_rtx_IOR (DImode, copy_rtx (dest),
6158 GEN_INT (ud2 << 16)));
6160 emit_move_insn (copy_rtx (dest),
6161 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6167 /* Helper for the following. Get rid of [r+r] memory refs
6168 in cases where it won't work (TImode, TFmode, TDmode). */
6171 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6173 if (GET_CODE (operands[0]) == MEM
6174 && GET_CODE (XEXP (operands[0], 0)) != REG
6175 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
6176 && ! reload_in_progress)
6178 = replace_equiv_address (operands[0],
6179 copy_addr_to_reg (XEXP (operands[0], 0)));
6181 if (GET_CODE (operands[1]) == MEM
6182 && GET_CODE (XEXP (operands[1], 0)) != REG
6183 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
6184 && ! reload_in_progress)
6186 = replace_equiv_address (operands[1],
6187 copy_addr_to_reg (XEXP (operands[1], 0)));
6190 /* Emit a move from SOURCE to DEST in mode MODE. */
6192 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6196 operands[1] = source;
6198 if (TARGET_DEBUG_ADDR)
6201 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6202 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6203 GET_MODE_NAME (mode),
6206 can_create_pseudo_p ());
6208 fprintf (stderr, "source:\n");
6212 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6213 if (GET_CODE (operands[1]) == CONST_DOUBLE
6214 && ! FLOAT_MODE_P (mode)
6215 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6217 /* FIXME. This should never happen. */
6218 /* Since it seems that it does, do the safe thing and convert
6220 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6222 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6223 || FLOAT_MODE_P (mode)
6224 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6225 || CONST_DOUBLE_LOW (operands[1]) < 0)
6226 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6227 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6229 /* Check if GCC is setting up a block move that will end up using FP
6230 registers as temporaries. We must make sure this is acceptable. */
6231 if (GET_CODE (operands[0]) == MEM
6232 && GET_CODE (operands[1]) == MEM
6234 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6235 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6236 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6237 ? 32 : MEM_ALIGN (operands[0])))
6238 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6240 : MEM_ALIGN (operands[1]))))
6241 && ! MEM_VOLATILE_P (operands [0])
6242 && ! MEM_VOLATILE_P (operands [1]))
6244 emit_move_insn (adjust_address (operands[0], SImode, 0),
6245 adjust_address (operands[1], SImode, 0));
6246 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6247 adjust_address (copy_rtx (operands[1]), SImode, 4));
6251 /* Fix up invalid (const (plus (symbol_ref) (reg))) that seems to be created
6252 in the secondary_reload phase, which evidently overwrites the CONST_INT
6254 if (GET_CODE (source) == CONST && GET_CODE (XEXP (source, 0)) == PLUS
6257 rtx add_op0 = XEXP (XEXP (source, 0), 0);
6258 rtx add_op1 = XEXP (XEXP (source, 0), 1);
6260 if (GET_CODE (add_op0) == SYMBOL_REF && GET_CODE (add_op1) == REG)
6262 rtx tmp = (can_create_pseudo_p ()) ? gen_reg_rtx (Pmode) : dest;
6264 if (TARGET_DEBUG_ADDR)
6266 fprintf (stderr, "\nrs6000_emit_move: bad source\n");
6270 rs6000_emit_move (tmp, add_op0, Pmode);
6271 emit_insn (gen_rtx_SET (VOIDmode, dest,
6272 gen_rtx_PLUS (Pmode, tmp, add_op1)));
6277 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6278 && !gpc_reg_operand (operands[1], mode))
6279 operands[1] = force_reg (mode, operands[1]);
6281 if (mode == SFmode && ! TARGET_POWERPC
6282 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6283 && GET_CODE (operands[0]) == MEM)
6287 if (reload_in_progress || reload_completed)
6288 regnum = true_regnum (operands[1]);
6289 else if (GET_CODE (operands[1]) == REG)
6290 regnum = REGNO (operands[1]);
6294 /* If operands[1] is a register, on POWER it may have
6295 double-precision data in it, so truncate it to single
6297 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6300 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6301 : gen_reg_rtx (mode));
6302 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6303 operands[1] = newreg;
6307 /* Recognize the case where operand[1] is a reference to thread-local
6308 data and load its address to a register. */
6309 if (rs6000_tls_referenced_p (operands[1]))
6311 enum tls_model model;
6312 rtx tmp = operands[1];
6315 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6317 addend = XEXP (XEXP (tmp, 0), 1);
6318 tmp = XEXP (XEXP (tmp, 0), 0);
6321 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6322 model = SYMBOL_REF_TLS_MODEL (tmp);
6323 gcc_assert (model != 0);
6325 tmp = rs6000_legitimize_tls_address (tmp, model);
6328 tmp = gen_rtx_PLUS (mode, tmp, addend);
6329 tmp = force_operand (tmp, operands[0]);
6334 /* Handle the case where reload calls us with an invalid address. */
6335 if (reload_in_progress && mode == Pmode
6336 && (! general_operand (operands[1], mode)
6337 || ! nonimmediate_operand (operands[0], mode)))
6340 /* 128-bit constant floating-point values on Darwin should really be
6341 loaded as two parts. */
6342 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6343 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6345 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6346 know how to get a DFmode SUBREG of a TFmode. */
6347 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6348 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6349 simplify_gen_subreg (imode, operands[1], mode, 0),
6351 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6352 GET_MODE_SIZE (imode)),
6353 simplify_gen_subreg (imode, operands[1], mode,
6354 GET_MODE_SIZE (imode)),
6359 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6360 cfun->machine->sdmode_stack_slot =
6361 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6363 if (reload_in_progress
6365 && MEM_P (operands[0])
6366 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6367 && REG_P (operands[1]))
6369 if (FP_REGNO_P (REGNO (operands[1])))
6371 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6372 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6373 emit_insn (gen_movsd_store (mem, operands[1]));
6375 else if (INT_REGNO_P (REGNO (operands[1])))
6377 rtx mem = adjust_address_nv (operands[0], mode, 4);
6378 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6379 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6385 if (reload_in_progress
6387 && REG_P (operands[0])
6388 && MEM_P (operands[1])
6389 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6391 if (FP_REGNO_P (REGNO (operands[0])))
6393 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6394 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6395 emit_insn (gen_movsd_load (operands[0], mem));
6397 else if (INT_REGNO_P (REGNO (operands[0])))
6399 rtx mem = adjust_address_nv (operands[1], mode, 4);
6400 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6401 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6408 /* FIXME: In the long term, this switch statement should go away
6409 and be replaced by a sequence of tests based on things like
6415 if (CONSTANT_P (operands[1])
6416 && GET_CODE (operands[1]) != CONST_INT)
6417 operands[1] = force_const_mem (mode, operands[1]);
6422 rs6000_eliminate_indexed_memrefs (operands);
6429 if (CONSTANT_P (operands[1])
6430 && ! easy_fp_constant (operands[1], mode))
6431 operands[1] = force_const_mem (mode, operands[1]);
6444 if (CONSTANT_P (operands[1])
6445 && !easy_vector_constant (operands[1], mode))
6446 operands[1] = force_const_mem (mode, operands[1]);
6451 /* Use default pattern for address of ELF small data */
6454 && DEFAULT_ABI == ABI_V4
6455 && (GET_CODE (operands[1]) == SYMBOL_REF
6456 || GET_CODE (operands[1]) == CONST)
6457 && small_data_operand (operands[1], mode))
6459 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6463 if (DEFAULT_ABI == ABI_V4
6464 && mode == Pmode && mode == SImode
6465 && flag_pic == 1 && got_operand (operands[1], mode))
6467 emit_insn (gen_movsi_got (operands[0], operands[1]));
6471 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6475 && CONSTANT_P (operands[1])
6476 && GET_CODE (operands[1]) != HIGH
6477 && GET_CODE (operands[1]) != CONST_INT)
6479 rtx target = (!can_create_pseudo_p ()
6481 : gen_reg_rtx (mode));
6483 /* If this is a function address on -mcall-aixdesc,
6484 convert it to the address of the descriptor. */
6485 if (DEFAULT_ABI == ABI_AIX
6486 && GET_CODE (operands[1]) == SYMBOL_REF
6487 && XSTR (operands[1], 0)[0] == '.')
6489 const char *name = XSTR (operands[1], 0);
6491 while (*name == '.')
6493 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6494 CONSTANT_POOL_ADDRESS_P (new_ref)
6495 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6496 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6497 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6498 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6499 operands[1] = new_ref;
6502 if (DEFAULT_ABI == ABI_DARWIN)
6505 if (MACHO_DYNAMIC_NO_PIC_P)
6507 /* Take care of any required data indirection. */
6508 operands[1] = rs6000_machopic_legitimize_pic_address (
6509 operands[1], mode, operands[0]);
6510 if (operands[0] != operands[1])
6511 emit_insn (gen_rtx_SET (VOIDmode,
6512 operands[0], operands[1]));
6516 emit_insn (gen_macho_high (target, operands[1]));
6517 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6521 emit_insn (gen_elf_high (target, operands[1]));
6522 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6526 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6527 and we have put it in the TOC, we just need to make a TOC-relative
6530 && GET_CODE (operands[1]) == SYMBOL_REF
6531 && constant_pool_expr_p (operands[1])
6532 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6533 get_pool_mode (operands[1])))
6535 operands[1] = create_TOC_reference (operands[1]);
6537 else if (mode == Pmode
6538 && CONSTANT_P (operands[1])
6539 && ((GET_CODE (operands[1]) != CONST_INT
6540 && ! easy_fp_constant (operands[1], mode))
6541 || (GET_CODE (operands[1]) == CONST_INT
6542 && num_insns_constant (operands[1], mode) > 2)
6543 || (GET_CODE (operands[0]) == REG
6544 && FP_REGNO_P (REGNO (operands[0]))))
6545 && GET_CODE (operands[1]) != HIGH
6546 && ! legitimate_constant_pool_address_p (operands[1])
6547 && ! toc_relative_expr_p (operands[1]))
6551 /* Darwin uses a special PIC legitimizer. */
6552 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
6555 rs6000_machopic_legitimize_pic_address (operands[1], mode,
6557 if (operands[0] != operands[1])
6558 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6563 /* If we are to limit the number of things we put in the TOC and
6564 this is a symbol plus a constant we can add in one insn,
6565 just put the symbol in the TOC and add the constant. Don't do
6566 this if reload is in progress. */
6567 if (GET_CODE (operands[1]) == CONST
6568 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
6569 && GET_CODE (XEXP (operands[1], 0)) == PLUS
6570 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
6571 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
6572 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
6573 && ! side_effects_p (operands[0]))
6576 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
6577 rtx other = XEXP (XEXP (operands[1], 0), 1);
6579 sym = force_reg (mode, sym);
6580 emit_insn (gen_add3_insn (operands[0], sym, other));
6584 operands[1] = force_const_mem (mode, operands[1]);
6587 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6588 && constant_pool_expr_p (XEXP (operands[1], 0))
6589 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
6590 get_pool_constant (XEXP (operands[1], 0)),
6591 get_pool_mode (XEXP (operands[1], 0))))
6594 = gen_const_mem (mode,
6595 create_TOC_reference (XEXP (operands[1], 0)));
6596 set_mem_alias_set (operands[1], get_TOC_alias_set ());
6602 rs6000_eliminate_indexed_memrefs (operands);
6606 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6608 gen_rtx_SET (VOIDmode,
6609 operands[0], operands[1]),
6610 gen_rtx_CLOBBER (VOIDmode,
6611 gen_rtx_SCRATCH (SImode)))));
6617 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
6620 /* Above, we may have called force_const_mem which may have returned
6621 an invalid address. If we can, fix this up; otherwise, reload will
6622 have to deal with it. */
6623 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
6624 operands[1] = validize_mem (operands[1]);
6627 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6630 /* Nonzero if we can use a floating-point register to pass this arg. */
6631 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
6632 (SCALAR_FLOAT_MODE_P (MODE) \
6633 && (CUM)->fregno <= FP_ARG_MAX_REG \
6634 && TARGET_HARD_FLOAT && TARGET_FPRS)
6636 /* Nonzero if we can use an AltiVec register to pass this arg. */
6637 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
6638 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
6639 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
6640 && TARGET_ALTIVEC_ABI \
6643 /* Return a nonzero value to say to return the function value in
6644 memory, just as large structures are always returned. TYPE will be
6645 the data type of the value, and FNTYPE will be the type of the
6646 function doing the returning, or @code{NULL} for libcalls.
6648 The AIX ABI for the RS/6000 specifies that all structures are
6649 returned in memory. The Darwin ABI does the same. The SVR4 ABI
6650 specifies that structures <= 8 bytes are returned in r3/r4, but a
6651 draft put them in memory, and GCC used to implement the draft
6652 instead of the final standard. Therefore, aix_struct_return
6653 controls this instead of DEFAULT_ABI; V.4 targets needing backward
6654 compatibility can change DRAFT_V4_STRUCT_RET to override the
6655 default, and -m switches get the final word. See
6656 rs6000_override_options for more details.
6658 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
6659 long double support is enabled. These values are returned in memory.
6661 int_size_in_bytes returns -1 for variable size objects, which go in
6662 memory always. The cast to unsigned makes -1 > 8. */
6665 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6667 /* In the darwin64 abi, try to use registers for larger structs
6669 if (rs6000_darwin64_abi
6670 && TREE_CODE (type) == RECORD_TYPE
6671 && int_size_in_bytes (type) > 0)
6673 CUMULATIVE_ARGS valcum;
6677 valcum.fregno = FP_ARG_MIN_REG;
6678 valcum.vregno = ALTIVEC_ARG_MIN_REG;
6679 /* Do a trial code generation as if this were going to be passed
6680 as an argument; if any part goes in memory, we return NULL. */
6681 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
6684 /* Otherwise fall through to more conventional ABI rules. */
6687 if (AGGREGATE_TYPE_P (type)
6688 && (aix_struct_return
6689 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
6692 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6693 modes only exist for GCC vector types if -maltivec. */
6694 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
6695 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6698 /* Return synthetic vectors in memory. */
6699 if (TREE_CODE (type) == VECTOR_TYPE
6700 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
6702 static bool warned_for_return_big_vectors = false;
6703 if (!warned_for_return_big_vectors)
6705 warning (0, "GCC vector returned by reference: "
6706 "non-standard ABI extension with no compatibility guarantee");
6707 warned_for_return_big_vectors = true;
6712 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
6718 /* Initialize a variable CUM of type CUMULATIVE_ARGS
6719 for a call to a function whose data type is FNTYPE.
6720 For a library call, FNTYPE is 0.
6722 For incoming args we set the number of arguments in the prototype large
6723 so we never return a PARALLEL. */
6726 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
6727 rtx libname ATTRIBUTE_UNUSED, int incoming,
6728 int libcall, int n_named_args)
6730 static CUMULATIVE_ARGS zero_cumulative;
6732 *cum = zero_cumulative;
6734 cum->fregno = FP_ARG_MIN_REG;
6735 cum->vregno = ALTIVEC_ARG_MIN_REG;
6736 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
6737 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
6738 ? CALL_LIBCALL : CALL_NORMAL);
6739 cum->sysv_gregno = GP_ARG_MIN_REG;
6740 cum->stdarg = fntype
6741 && (TYPE_ARG_TYPES (fntype) != 0
6742 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
6743 != void_type_node));
6745 cum->nargs_prototype = 0;
6746 if (incoming || cum->prototype)
6747 cum->nargs_prototype = n_named_args;
6749 /* Check for a longcall attribute. */
6750 if ((!fntype && rs6000_default_long_calls)
6752 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
6753 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
6754 cum->call_cookie |= CALL_LONG;
6756 if (TARGET_DEBUG_ARG)
6758 fprintf (stderr, "\ninit_cumulative_args:");
6761 tree ret_type = TREE_TYPE (fntype);
6762 fprintf (stderr, " ret code = %s,",
6763 tree_code_name[ (int)TREE_CODE (ret_type) ]);
6766 if (cum->call_cookie & CALL_LONG)
6767 fprintf (stderr, " longcall,");
6769 fprintf (stderr, " proto = %d, nargs = %d\n",
6770 cum->prototype, cum->nargs_prototype);
6775 && TARGET_ALTIVEC_ABI
6776 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
6778 error ("cannot return value in vector register because"
6779 " altivec instructions are disabled, use -maltivec"
6784 /* Return true if TYPE must be passed on the stack and not in registers. */
6787 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
6789 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
6790 return must_pass_in_stack_var_size (mode, type);
6792 return must_pass_in_stack_var_size_or_pad (mode, type);
6795 /* If defined, a C expression which determines whether, and in which
6796 direction, to pad out an argument with extra space. The value
6797 should be of type `enum direction': either `upward' to pad above
6798 the argument, `downward' to pad below, or `none' to inhibit
6801 For the AIX ABI structs are always stored left shifted in their
6805 function_arg_padding (enum machine_mode mode, const_tree type)
6807 #ifndef AGGREGATE_PADDING_FIXED
6808 #define AGGREGATE_PADDING_FIXED 0
6810 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
6811 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
6814 if (!AGGREGATE_PADDING_FIXED)
6816 /* GCC used to pass structures of the same size as integer types as
6817 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
6818 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6819 passed padded downward, except that -mstrict-align further
6820 muddied the water in that multi-component structures of 2 and 4
6821 bytes in size were passed padded upward.
6823 The following arranges for best compatibility with previous
6824 versions of gcc, but removes the -mstrict-align dependency. */
6825 if (BYTES_BIG_ENDIAN)
6827 HOST_WIDE_INT size = 0;
6829 if (mode == BLKmode)
6831 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
6832 size = int_size_in_bytes (type);
6835 size = GET_MODE_SIZE (mode);
6837 if (size == 1 || size == 2 || size == 4)
6843 if (AGGREGATES_PAD_UPWARD_ALWAYS)
6845 if (type != 0 && AGGREGATE_TYPE_P (type))
6849 /* Fall back to the default. */
6850 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
6853 /* If defined, a C expression that gives the alignment boundary, in bits,
6854 of an argument with the specified mode and type. If it is not defined,
6855 PARM_BOUNDARY is used for all arguments.
6857 V.4 wants long longs and doubles to be double word aligned. Just
6858 testing the mode size is a boneheaded way to do this as it means
6859 that other types such as complex int are also double word aligned.
6860 However, we're stuck with this because changing the ABI might break
6861 existing library interfaces.
6863 Doubleword align SPE vectors.
6864 Quadword align Altivec vectors.
6865 Quadword align large synthetic vector types. */
6868 function_arg_boundary (enum machine_mode mode, tree type)
6870 if (DEFAULT_ABI == ABI_V4
6871 && (GET_MODE_SIZE (mode) == 8
6872 || (TARGET_HARD_FLOAT
6874 && (mode == TFmode || mode == TDmode))))
6876 else if (SPE_VECTOR_MODE (mode)
6877 || (type && TREE_CODE (type) == VECTOR_TYPE
6878 && int_size_in_bytes (type) >= 8
6879 && int_size_in_bytes (type) < 16))
6881 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
6882 || (type && TREE_CODE (type) == VECTOR_TYPE
6883 && int_size_in_bytes (type) >= 16))
6885 else if (rs6000_darwin64_abi && mode == BLKmode
6886 && type && TYPE_ALIGN (type) > 64)
6889 return PARM_BOUNDARY;
6892 /* For a function parm of MODE and TYPE, return the starting word in
6893 the parameter area. NWORDS of the parameter area are already used. */
6896 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
6899 unsigned int parm_offset;
6901 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
6902 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
6903 return nwords + (-(parm_offset + nwords) & align);
6906 /* Compute the size (in words) of a function argument. */
6908 static unsigned long
6909 rs6000_arg_size (enum machine_mode mode, tree type)
6913 if (mode != BLKmode)
6914 size = GET_MODE_SIZE (mode);
6916 size = int_size_in_bytes (type);
6919 return (size + 3) >> 2;
6921 return (size + 7) >> 3;
6924 /* Use this to flush pending int fields. */
6927 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
6928 HOST_WIDE_INT bitpos)
6930 unsigned int startbit, endbit;
6931 int intregs, intoffset;
6932 enum machine_mode mode;
6934 if (cum->intoffset == -1)
6937 intoffset = cum->intoffset;
6938 cum->intoffset = -1;
6940 if (intoffset % BITS_PER_WORD != 0)
6942 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
6944 if (mode == BLKmode)
6946 /* We couldn't find an appropriate mode, which happens,
6947 e.g., in packed structs when there are 3 bytes to load.
6948 Back intoffset back to the beginning of the word in this
6950 intoffset = intoffset & -BITS_PER_WORD;
6954 startbit = intoffset & -BITS_PER_WORD;
6955 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
6956 intregs = (endbit - startbit) / BITS_PER_WORD;
6957 cum->words += intregs;
6960 /* The darwin64 ABI calls for us to recurse down through structs,
6961 looking for elements passed in registers. Unfortunately, we have
6962 to track int register count here also because of misalignments
6963 in powerpc alignment mode. */
6966 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
6968 HOST_WIDE_INT startbitpos)
6972 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
6973 if (TREE_CODE (f) == FIELD_DECL)
6975 HOST_WIDE_INT bitpos = startbitpos;
6976 tree ftype = TREE_TYPE (f);
6977 enum machine_mode mode;
6978 if (ftype == error_mark_node)
6980 mode = TYPE_MODE (ftype);
6982 if (DECL_SIZE (f) != 0
6983 && host_integerp (bit_position (f), 1))
6984 bitpos += int_bit_position (f);
6986 /* ??? FIXME: else assume zero offset. */
6988 if (TREE_CODE (ftype) == RECORD_TYPE)
6989 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
6990 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
6992 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
6993 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
6994 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
6996 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
6998 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7002 else if (cum->intoffset == -1)
7003 cum->intoffset = bitpos;
7007 /* Update the data in CUM to advance over an argument
7008 of mode MODE and data type TYPE.
7009 (TYPE is null for libcalls where that information may not be available.)
7011 Note that for args passed by reference, function_arg will be called
7012 with MODE and TYPE set to that of the pointer to the arg, not the arg
7016 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7017 tree type, int named, int depth)
7021 /* Only tick off an argument if we're not recursing. */
7023 cum->nargs_prototype--;
7025 if (TARGET_ALTIVEC_ABI
7026 && (ALTIVEC_VECTOR_MODE (mode)
7027 || VSX_VECTOR_MODE (mode)
7028 || (type && TREE_CODE (type) == VECTOR_TYPE
7029 && int_size_in_bytes (type) == 16)))
7033 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7036 if (!TARGET_ALTIVEC)
7037 error ("cannot pass argument in vector register because"
7038 " altivec instructions are disabled, use -maltivec"
7041 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7042 even if it is going to be passed in a vector register.
7043 Darwin does the same for variable-argument functions. */
7044 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7045 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7055 /* Vector parameters must be 16-byte aligned. This places
7056 them at 2 mod 4 in terms of words in 32-bit mode, since
7057 the parameter save area starts at offset 24 from the
7058 stack. In 64-bit mode, they just have to start on an
7059 even word, since the parameter save area is 16-byte
7060 aligned. Space for GPRs is reserved even if the argument
7061 will be passed in memory. */
7063 align = (2 - cum->words) & 3;
7065 align = cum->words & 1;
7066 cum->words += align + rs6000_arg_size (mode, type);
7068 if (TARGET_DEBUG_ARG)
7070 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7072 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7073 cum->nargs_prototype, cum->prototype,
7074 GET_MODE_NAME (mode));
7078 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7080 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7083 else if (rs6000_darwin64_abi
7085 && TREE_CODE (type) == RECORD_TYPE
7086 && (size = int_size_in_bytes (type)) > 0)
7088 /* Variable sized types have size == -1 and are
7089 treated as if consisting entirely of ints.
7090 Pad to 16 byte boundary if needed. */
7091 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7092 && (cum->words % 2) != 0)
7094 /* For varargs, we can just go up by the size of the struct. */
7096 cum->words += (size + 7) / 8;
7099 /* It is tempting to say int register count just goes up by
7100 sizeof(type)/8, but this is wrong in a case such as
7101 { int; double; int; } [powerpc alignment]. We have to
7102 grovel through the fields for these too. */
7104 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7105 rs6000_darwin64_record_arg_advance_flush (cum,
7106 size * BITS_PER_UNIT);
7109 else if (DEFAULT_ABI == ABI_V4)
7111 if (TARGET_HARD_FLOAT && TARGET_FPRS
7112 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7113 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7114 || (mode == TFmode && !TARGET_IEEEQUAD)
7115 || mode == SDmode || mode == DDmode || mode == TDmode))
7117 /* _Decimal128 must use an even/odd register pair. This assumes
7118 that the register number is odd when fregno is odd. */
7119 if (mode == TDmode && (cum->fregno % 2) == 1)
7122 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7123 <= FP_ARG_V4_MAX_REG)
7124 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7127 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7128 if (mode == DFmode || mode == TFmode
7129 || mode == DDmode || mode == TDmode)
7130 cum->words += cum->words & 1;
7131 cum->words += rs6000_arg_size (mode, type);
7136 int n_words = rs6000_arg_size (mode, type);
7137 int gregno = cum->sysv_gregno;
7139 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7140 (r7,r8) or (r9,r10). As does any other 2 word item such
7141 as complex int due to a historical mistake. */
7143 gregno += (1 - gregno) & 1;
7145 /* Multi-reg args are not split between registers and stack. */
7146 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7148 /* Long long and SPE vectors are aligned on the stack.
7149 So are other 2 word items such as complex int due to
7150 a historical mistake. */
7152 cum->words += cum->words & 1;
7153 cum->words += n_words;
7156 /* Note: continuing to accumulate gregno past when we've started
7157 spilling to the stack indicates the fact that we've started
7158 spilling to the stack to expand_builtin_saveregs. */
7159 cum->sysv_gregno = gregno + n_words;
7162 if (TARGET_DEBUG_ARG)
7164 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7165 cum->words, cum->fregno);
7166 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7167 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7168 fprintf (stderr, "mode = %4s, named = %d\n",
7169 GET_MODE_NAME (mode), named);
7174 int n_words = rs6000_arg_size (mode, type);
7175 int start_words = cum->words;
7176 int align_words = rs6000_parm_start (mode, type, start_words);
7178 cum->words = align_words + n_words;
7180 if (SCALAR_FLOAT_MODE_P (mode)
7181 && TARGET_HARD_FLOAT && TARGET_FPRS)
7183 /* _Decimal128 must be passed in an even/odd float register pair.
7184 This assumes that the register number is odd when fregno is
7186 if (mode == TDmode && (cum->fregno % 2) == 1)
7188 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7191 if (TARGET_DEBUG_ARG)
7193 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7194 cum->words, cum->fregno);
7195 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7196 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7197 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7198 named, align_words - start_words, depth);
7204 spe_build_register_parallel (enum machine_mode mode, int gregno)
7211 r1 = gen_rtx_REG (DImode, gregno);
7212 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7213 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7217 r1 = gen_rtx_REG (DImode, gregno);
7218 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7219 r3 = gen_rtx_REG (DImode, gregno + 2);
7220 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7221 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7224 r1 = gen_rtx_REG (DImode, gregno);
7225 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7226 r3 = gen_rtx_REG (DImode, gregno + 2);
7227 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7228 r5 = gen_rtx_REG (DImode, gregno + 4);
7229 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7230 r7 = gen_rtx_REG (DImode, gregno + 6);
7231 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7232 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7239 /* Determine where to put a SIMD argument on the SPE. */
7241 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7244 int gregno = cum->sysv_gregno;
7246 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7247 are passed and returned in a pair of GPRs for ABI compatibility. */
7248 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7249 || mode == DCmode || mode == TCmode))
7251 int n_words = rs6000_arg_size (mode, type);
7253 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7255 gregno += (1 - gregno) & 1;
7257 /* Multi-reg args are not split between registers and stack. */
7258 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7261 return spe_build_register_parallel (mode, gregno);
7265 int n_words = rs6000_arg_size (mode, type);
7267 /* SPE vectors are put in odd registers. */
7268 if (n_words == 2 && (gregno & 1) == 0)
7271 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7274 enum machine_mode m = SImode;
7276 r1 = gen_rtx_REG (m, gregno);
7277 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7278 r2 = gen_rtx_REG (m, gregno + 1);
7279 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7280 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7287 if (gregno <= GP_ARG_MAX_REG)
7288 return gen_rtx_REG (mode, gregno);
7294 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7295 structure between cum->intoffset and bitpos to integer registers. */
7298 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7299 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7301 enum machine_mode mode;
7303 unsigned int startbit, endbit;
7304 int this_regno, intregs, intoffset;
7307 if (cum->intoffset == -1)
7310 intoffset = cum->intoffset;
7311 cum->intoffset = -1;
7313 /* If this is the trailing part of a word, try to only load that
7314 much into the register. Otherwise load the whole register. Note
7315 that in the latter case we may pick up unwanted bits. It's not a
7316 problem at the moment but may wish to revisit. */
7318 if (intoffset % BITS_PER_WORD != 0)
7320 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7322 if (mode == BLKmode)
7324 /* We couldn't find an appropriate mode, which happens,
7325 e.g., in packed structs when there are 3 bytes to load.
7326 Back intoffset back to the beginning of the word in this
7328 intoffset = intoffset & -BITS_PER_WORD;
7335 startbit = intoffset & -BITS_PER_WORD;
7336 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7337 intregs = (endbit - startbit) / BITS_PER_WORD;
7338 this_regno = cum->words + intoffset / BITS_PER_WORD;
7340 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7343 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7347 intoffset /= BITS_PER_UNIT;
7350 regno = GP_ARG_MIN_REG + this_regno;
7351 reg = gen_rtx_REG (mode, regno);
7353 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7356 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7360 while (intregs > 0);
7363 /* Recursive workhorse for the following. */
7366 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7367 HOST_WIDE_INT startbitpos, rtx rvec[],
7372 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7373 if (TREE_CODE (f) == FIELD_DECL)
7375 HOST_WIDE_INT bitpos = startbitpos;
7376 tree ftype = TREE_TYPE (f);
7377 enum machine_mode mode;
7378 if (ftype == error_mark_node)
7380 mode = TYPE_MODE (ftype);
7382 if (DECL_SIZE (f) != 0
7383 && host_integerp (bit_position (f), 1))
7384 bitpos += int_bit_position (f);
7386 /* ??? FIXME: else assume zero offset. */
7388 if (TREE_CODE (ftype) == RECORD_TYPE)
7389 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7390 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7395 case SCmode: mode = SFmode; break;
7396 case DCmode: mode = DFmode; break;
7397 case TCmode: mode = TFmode; break;
7401 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7403 = gen_rtx_EXPR_LIST (VOIDmode,
7404 gen_rtx_REG (mode, cum->fregno++),
7405 GEN_INT (bitpos / BITS_PER_UNIT));
7406 if (mode == TFmode || mode == TDmode)
7409 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7411 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7413 = gen_rtx_EXPR_LIST (VOIDmode,
7414 gen_rtx_REG (mode, cum->vregno++),
7415 GEN_INT (bitpos / BITS_PER_UNIT));
7417 else if (cum->intoffset == -1)
7418 cum->intoffset = bitpos;
7422 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7423 the register(s) to be used for each field and subfield of a struct
7424 being passed by value, along with the offset of where the
7425 register's value may be found in the block. FP fields go in FP
7426 register, vector fields go in vector registers, and everything
7427 else goes in int registers, packed as in memory.
7429 This code is also used for function return values. RETVAL indicates
7430 whether this is the case.
7432 Much of this is taken from the SPARC V9 port, which has a similar
7433 calling convention. */
7436 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7437 int named, bool retval)
7439 rtx rvec[FIRST_PSEUDO_REGISTER];
7440 int k = 1, kbase = 1;
7441 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7442 /* This is a copy; modifications are not visible to our caller. */
7443 CUMULATIVE_ARGS copy_cum = *orig_cum;
7444 CUMULATIVE_ARGS *cum = ©_cum;
7446 /* Pad to 16 byte boundary if needed. */
7447 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7448 && (cum->words % 2) != 0)
7455 /* Put entries into rvec[] for individual FP and vector fields, and
7456 for the chunks of memory that go in int regs. Note we start at
7457 element 1; 0 is reserved for an indication of using memory, and
7458 may or may not be filled in below. */
7459 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7460 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7462 /* If any part of the struct went on the stack put all of it there.
7463 This hack is because the generic code for
7464 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7465 parts of the struct are not at the beginning. */
7469 return NULL_RTX; /* doesn't go in registers at all */
7471 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7473 if (k > 1 || cum->use_stack)
7474 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7479 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7482 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7486 rtx rvec[GP_ARG_NUM_REG + 1];
7488 if (align_words >= GP_ARG_NUM_REG)
7491 n_units = rs6000_arg_size (mode, type);
7493 /* Optimize the simple case where the arg fits in one gpr, except in
7494 the case of BLKmode due to assign_parms assuming that registers are
7495 BITS_PER_WORD wide. */
7497 || (n_units == 1 && mode != BLKmode))
7498 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7501 if (align_words + n_units > GP_ARG_NUM_REG)
7502 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7503 using a magic NULL_RTX component.
7504 This is not strictly correct. Only some of the arg belongs in
7505 memory, not all of it. However, the normal scheme using
7506 function_arg_partial_nregs can result in unusual subregs, eg.
7507 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7508 store the whole arg to memory is often more efficient than code
7509 to store pieces, and we know that space is available in the right
7510 place for the whole arg. */
7511 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7516 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7517 rtx off = GEN_INT (i++ * 4);
7518 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7520 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7522 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7525 /* Determine where to put an argument to a function.
7526 Value is zero to push the argument on the stack,
7527 or a hard register in which to store the argument.
7529 MODE is the argument's machine mode.
7530 TYPE is the data type of the argument (as a tree).
7531 This is null for libcalls where that information may
7533 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7534 the preceding args and about the function being called. It is
7535 not modified in this routine.
7536 NAMED is nonzero if this argument is a named parameter
7537 (otherwise it is an extra parameter matching an ellipsis).
7539 On RS/6000 the first eight words of non-FP are normally in registers
7540 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7541 Under V.4, the first 8 FP args are in registers.
7543 If this is floating-point and no prototype is specified, we use
7544 both an FP and integer register (or possibly FP reg and stack). Library
7545 functions (when CALL_LIBCALL is set) always have the proper types for args,
7546 so we can pass the FP value just in one register. emit_library_function
7547 doesn't support PARALLEL anyway.
7549 Note that for args passed by reference, function_arg will be called
7550 with MODE and TYPE set to that of the pointer to the arg, not the arg
7554 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7555 tree type, int named)
7557 enum rs6000_abi abi = DEFAULT_ABI;
7559 /* Return a marker to indicate whether CR1 needs to set or clear the
7560 bit that V.4 uses to say fp args were passed in registers.
7561 Assume that we don't need the marker for software floating point,
7562 or compiler generated library calls. */
7563 if (mode == VOIDmode)
7566 && (cum->call_cookie & CALL_LIBCALL) == 0
7568 || (cum->nargs_prototype < 0
7569 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7571 /* For the SPE, we need to crxor CR6 always. */
7573 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
7574 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
7575 return GEN_INT (cum->call_cookie
7576 | ((cum->fregno == FP_ARG_MIN_REG)
7577 ? CALL_V4_SET_FP_ARGS
7578 : CALL_V4_CLEAR_FP_ARGS));
7581 return GEN_INT (cum->call_cookie);
7584 if (rs6000_darwin64_abi && mode == BLKmode
7585 && TREE_CODE (type) == RECORD_TYPE)
7587 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
7588 if (rslt != NULL_RTX)
7590 /* Else fall through to usual handling. */
7593 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7594 if (TARGET_64BIT && ! cum->prototype)
7596 /* Vector parameters get passed in vector register
7597 and also in GPRs or memory, in absence of prototype. */
7600 align_words = (cum->words + 1) & ~1;
7602 if (align_words >= GP_ARG_NUM_REG)
7608 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7610 return gen_rtx_PARALLEL (mode,
7612 gen_rtx_EXPR_LIST (VOIDmode,
7614 gen_rtx_EXPR_LIST (VOIDmode,
7615 gen_rtx_REG (mode, cum->vregno),
7619 return gen_rtx_REG (mode, cum->vregno);
7620 else if (TARGET_ALTIVEC_ABI
7621 && (ALTIVEC_VECTOR_MODE (mode)
7622 || VSX_VECTOR_MODE (mode)
7623 || (type && TREE_CODE (type) == VECTOR_TYPE
7624 && int_size_in_bytes (type) == 16)))
7626 if (named || abi == ABI_V4)
7630 /* Vector parameters to varargs functions under AIX or Darwin
7631 get passed in memory and possibly also in GPRs. */
7632 int align, align_words, n_words;
7633 enum machine_mode part_mode;
7635 /* Vector parameters must be 16-byte aligned. This places them at
7636 2 mod 4 in terms of words in 32-bit mode, since the parameter
7637 save area starts at offset 24 from the stack. In 64-bit mode,
7638 they just have to start on an even word, since the parameter
7639 save area is 16-byte aligned. */
7641 align = (2 - cum->words) & 3;
7643 align = cum->words & 1;
7644 align_words = cum->words + align;
7646 /* Out of registers? Memory, then. */
7647 if (align_words >= GP_ARG_NUM_REG)
7650 if (TARGET_32BIT && TARGET_POWERPC64)
7651 return rs6000_mixed_function_arg (mode, type, align_words);
7653 /* The vector value goes in GPRs. Only the part of the
7654 value in GPRs is reported here. */
7656 n_words = rs6000_arg_size (mode, type);
7657 if (align_words + n_words > GP_ARG_NUM_REG)
7658 /* Fortunately, there are only two possibilities, the value
7659 is either wholly in GPRs or half in GPRs and half not. */
7662 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
7665 else if (TARGET_SPE_ABI && TARGET_SPE
7666 && (SPE_VECTOR_MODE (mode)
7667 || (TARGET_E500_DOUBLE && (mode == DFmode
7670 || mode == TCmode))))
7671 return rs6000_spe_function_arg (cum, mode, type);
7673 else if (abi == ABI_V4)
7675 if (TARGET_HARD_FLOAT && TARGET_FPRS
7676 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7677 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7678 || (mode == TFmode && !TARGET_IEEEQUAD)
7679 || mode == SDmode || mode == DDmode || mode == TDmode))
7681 /* _Decimal128 must use an even/odd register pair. This assumes
7682 that the register number is odd when fregno is odd. */
7683 if (mode == TDmode && (cum->fregno % 2) == 1)
7686 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7687 <= FP_ARG_V4_MAX_REG)
7688 return gen_rtx_REG (mode, cum->fregno);
7694 int n_words = rs6000_arg_size (mode, type);
7695 int gregno = cum->sysv_gregno;
7697 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7698 (r7,r8) or (r9,r10). As does any other 2 word item such
7699 as complex int due to a historical mistake. */
7701 gregno += (1 - gregno) & 1;
7703 /* Multi-reg args are not split between registers and stack. */
7704 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7707 if (TARGET_32BIT && TARGET_POWERPC64)
7708 return rs6000_mixed_function_arg (mode, type,
7709 gregno - GP_ARG_MIN_REG);
7710 return gen_rtx_REG (mode, gregno);
7715 int align_words = rs6000_parm_start (mode, type, cum->words);
7717 /* _Decimal128 must be passed in an even/odd float register pair.
7718 This assumes that the register number is odd when fregno is odd. */
7719 if (mode == TDmode && (cum->fregno % 2) == 1)
7722 if (USE_FP_FOR_ARG_P (cum, mode, type))
7724 rtx rvec[GP_ARG_NUM_REG + 1];
7728 enum machine_mode fmode = mode;
7729 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
7731 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
7733 /* Currently, we only ever need one reg here because complex
7734 doubles are split. */
7735 gcc_assert (cum->fregno == FP_ARG_MAX_REG
7736 && (fmode == TFmode || fmode == TDmode));
7738 /* Long double or _Decimal128 split over regs and memory. */
7739 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
7742 /* Do we also need to pass this arg in the parameter save
7745 && (cum->nargs_prototype <= 0
7746 || (DEFAULT_ABI == ABI_AIX
7748 && align_words >= GP_ARG_NUM_REG)));
7750 if (!needs_psave && mode == fmode)
7751 return gen_rtx_REG (fmode, cum->fregno);
7756 /* Describe the part that goes in gprs or the stack.
7757 This piece must come first, before the fprs. */
7758 if (align_words < GP_ARG_NUM_REG)
7760 unsigned long n_words = rs6000_arg_size (mode, type);
7762 if (align_words + n_words > GP_ARG_NUM_REG
7763 || (TARGET_32BIT && TARGET_POWERPC64))
7765 /* If this is partially on the stack, then we only
7766 include the portion actually in registers here. */
7767 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
7770 if (align_words + n_words > GP_ARG_NUM_REG)
7771 /* Not all of the arg fits in gprs. Say that it
7772 goes in memory too, using a magic NULL_RTX
7773 component. Also see comment in
7774 rs6000_mixed_function_arg for why the normal
7775 function_arg_partial_nregs scheme doesn't work
7777 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
7781 r = gen_rtx_REG (rmode,
7782 GP_ARG_MIN_REG + align_words);
7783 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
7784 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7786 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
7790 /* The whole arg fits in gprs. */
7791 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7792 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7796 /* It's entirely in memory. */
7797 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7800 /* Describe where this piece goes in the fprs. */
7801 r = gen_rtx_REG (fmode, cum->fregno);
7802 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7804 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7806 else if (align_words < GP_ARG_NUM_REG)
7808 if (TARGET_32BIT && TARGET_POWERPC64)
7809 return rs6000_mixed_function_arg (mode, type, align_words);
7811 if (mode == BLKmode)
7814 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7821 /* For an arg passed partly in registers and partly in memory, this is
7822 the number of bytes passed in registers. For args passed entirely in
7823 registers or entirely in memory, zero. When an arg is described by a
7824 PARALLEL, perhaps using more than one register type, this function
7825 returns the number of bytes used by the first element of the PARALLEL. */
7828 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7829 tree type, bool named)
7834 if (DEFAULT_ABI == ABI_V4)
7837 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
7838 && cum->nargs_prototype >= 0)
7841 /* In this complicated case we just disable the partial_nregs code. */
7842 if (rs6000_darwin64_abi && mode == BLKmode
7843 && TREE_CODE (type) == RECORD_TYPE
7844 && int_size_in_bytes (type) > 0)
7847 align_words = rs6000_parm_start (mode, type, cum->words);
7849 if (USE_FP_FOR_ARG_P (cum, mode, type))
7851 /* If we are passing this arg in the fixed parameter save area
7852 (gprs or memory) as well as fprs, then this function should
7853 return the number of partial bytes passed in the parameter
7854 save area rather than partial bytes passed in fprs. */
7856 && (cum->nargs_prototype <= 0
7857 || (DEFAULT_ABI == ABI_AIX
7859 && align_words >= GP_ARG_NUM_REG)))
7861 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
7862 > FP_ARG_MAX_REG + 1)
7863 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
7864 else if (cum->nargs_prototype >= 0)
7868 if (align_words < GP_ARG_NUM_REG
7869 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
7870 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
7872 if (ret != 0 && TARGET_DEBUG_ARG)
7873 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
7878 /* A C expression that indicates when an argument must be passed by
7879 reference. If nonzero for an argument, a copy of that argument is
7880 made in memory and a pointer to the argument is passed instead of
7881 the argument itself. The pointer is passed in whatever way is
7882 appropriate for passing a pointer to that type.
7884 Under V.4, aggregates and long double are passed by reference.
7886 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
7887 reference unless the AltiVec vector extension ABI is in force.
7889 As an extension to all ABIs, variable sized types are passed by
7893 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
7894 enum machine_mode mode, const_tree type,
7895 bool named ATTRIBUTE_UNUSED)
7897 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
7899 if (TARGET_DEBUG_ARG)
7900 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
7907 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
7909 if (TARGET_DEBUG_ARG)
7910 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
7914 if (int_size_in_bytes (type) < 0)
7916 if (TARGET_DEBUG_ARG)
7917 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
7921 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7922 modes only exist for GCC vector types if -maltivec. */
7923 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
7925 if (TARGET_DEBUG_ARG)
7926 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
7930 /* Pass synthetic vectors in memory. */
7931 if (TREE_CODE (type) == VECTOR_TYPE
7932 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7934 static bool warned_for_pass_big_vectors = false;
7935 if (TARGET_DEBUG_ARG)
7936 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
7937 if (!warned_for_pass_big_vectors)
7939 warning (0, "GCC vector passed by reference: "
7940 "non-standard ABI extension with no compatibility guarantee");
7941 warned_for_pass_big_vectors = true;
7950 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
7953 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
7958 for (i = 0; i < nregs; i++)
7960 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
7961 if (reload_completed)
7963 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
7966 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
7967 i * GET_MODE_SIZE (reg_mode));
7970 tem = replace_equiv_address (tem, XEXP (tem, 0));
7974 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
7978 /* Perform any needed actions needed for a function that is receiving a
7979 variable number of arguments.
7983 MODE and TYPE are the mode and type of the current parameter.
7985 PRETEND_SIZE is a variable that should be set to the amount of stack
7986 that must be pushed by the prolog to pretend that our caller pushed
7989 Normally, this macro will push all remaining incoming registers on the
7990 stack and set PRETEND_SIZE to the length of the registers pushed. */
7993 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7994 tree type, int *pretend_size ATTRIBUTE_UNUSED,
7997 CUMULATIVE_ARGS next_cum;
7998 int reg_size = TARGET_32BIT ? 4 : 8;
7999 rtx save_area = NULL_RTX, mem;
8000 int first_reg_offset;
8003 /* Skip the last named argument. */
8005 function_arg_advance (&next_cum, mode, type, 1, 0);
8007 if (DEFAULT_ABI == ABI_V4)
8009 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8013 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8014 HOST_WIDE_INT offset = 0;
8016 /* Try to optimize the size of the varargs save area.
8017 The ABI requires that ap.reg_save_area is doubleword
8018 aligned, but we don't need to allocate space for all
8019 the bytes, only those to which we actually will save
8021 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8022 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8023 if (TARGET_HARD_FLOAT && TARGET_FPRS
8024 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8025 && cfun->va_list_fpr_size)
8028 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8029 * UNITS_PER_FP_WORD;
8030 if (cfun->va_list_fpr_size
8031 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8032 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8034 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8035 * UNITS_PER_FP_WORD;
8039 offset = -((first_reg_offset * reg_size) & ~7);
8040 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8042 gpr_reg_num = cfun->va_list_gpr_size;
8043 if (reg_size == 4 && (first_reg_offset & 1))
8046 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8049 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8051 - (int) (GP_ARG_NUM_REG * reg_size);
8053 if (gpr_size + fpr_size)
8056 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8057 gcc_assert (GET_CODE (reg_save_area) == MEM);
8058 reg_save_area = XEXP (reg_save_area, 0);
8059 if (GET_CODE (reg_save_area) == PLUS)
8061 gcc_assert (XEXP (reg_save_area, 0)
8062 == virtual_stack_vars_rtx);
8063 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8064 offset += INTVAL (XEXP (reg_save_area, 1));
8067 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8070 cfun->machine->varargs_save_offset = offset;
8071 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8076 first_reg_offset = next_cum.words;
8077 save_area = virtual_incoming_args_rtx;
8079 if (targetm.calls.must_pass_in_stack (mode, type))
8080 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8083 set = get_varargs_alias_set ();
8084 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8085 && cfun->va_list_gpr_size)
8087 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8089 if (va_list_gpr_counter_field)
8091 /* V4 va_list_gpr_size counts number of registers needed. */
8092 if (nregs > cfun->va_list_gpr_size)
8093 nregs = cfun->va_list_gpr_size;
8097 /* char * va_list instead counts number of bytes needed. */
8098 if (nregs > cfun->va_list_gpr_size / reg_size)
8099 nregs = cfun->va_list_gpr_size / reg_size;
8102 mem = gen_rtx_MEM (BLKmode,
8103 plus_constant (save_area,
8104 first_reg_offset * reg_size));
8105 MEM_NOTRAP_P (mem) = 1;
8106 set_mem_alias_set (mem, set);
8107 set_mem_align (mem, BITS_PER_WORD);
8109 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8113 /* Save FP registers if needed. */
8114 if (DEFAULT_ABI == ABI_V4
8115 && TARGET_HARD_FLOAT && TARGET_FPRS
8117 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8118 && cfun->va_list_fpr_size)
8120 int fregno = next_cum.fregno, nregs;
8121 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8122 rtx lab = gen_label_rtx ();
8123 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8124 * UNITS_PER_FP_WORD);
8127 (gen_rtx_SET (VOIDmode,
8129 gen_rtx_IF_THEN_ELSE (VOIDmode,
8130 gen_rtx_NE (VOIDmode, cr1,
8132 gen_rtx_LABEL_REF (VOIDmode, lab),
8136 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8137 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8139 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8141 plus_constant (save_area, off));
8142 MEM_NOTRAP_P (mem) = 1;
8143 set_mem_alias_set (mem, set);
8144 set_mem_align (mem, GET_MODE_ALIGNMENT (
8145 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8146 ? DFmode : SFmode));
8147 emit_move_insn (mem, gen_rtx_REG (
8148 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8149 ? DFmode : SFmode, fregno));
8156 /* Create the va_list data type. */
8159 rs6000_build_builtin_va_list (void)
8161 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8163 /* For AIX, prefer 'char *' because that's what the system
8164 header files like. */
8165 if (DEFAULT_ABI != ABI_V4)
8166 return build_pointer_type (char_type_node);
8168 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8169 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8170 get_identifier ("__va_list_tag"), record);
8172 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8173 unsigned_char_type_node);
8174 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8175 unsigned_char_type_node);
8176 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8178 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8179 get_identifier ("reserved"), short_unsigned_type_node);
8180 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8181 get_identifier ("overflow_arg_area"),
8183 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8184 get_identifier ("reg_save_area"),
8187 va_list_gpr_counter_field = f_gpr;
8188 va_list_fpr_counter_field = f_fpr;
8190 DECL_FIELD_CONTEXT (f_gpr) = record;
8191 DECL_FIELD_CONTEXT (f_fpr) = record;
8192 DECL_FIELD_CONTEXT (f_res) = record;
8193 DECL_FIELD_CONTEXT (f_ovf) = record;
8194 DECL_FIELD_CONTEXT (f_sav) = record;
8196 TREE_CHAIN (record) = type_decl;
8197 TYPE_NAME (record) = type_decl;
8198 TYPE_FIELDS (record) = f_gpr;
8199 TREE_CHAIN (f_gpr) = f_fpr;
8200 TREE_CHAIN (f_fpr) = f_res;
8201 TREE_CHAIN (f_res) = f_ovf;
8202 TREE_CHAIN (f_ovf) = f_sav;
8204 layout_type (record);
8206 /* The correct type is an array type of one element. */
8207 return build_array_type (record, build_index_type (size_zero_node));
8210 /* Implement va_start. */
8213 rs6000_va_start (tree valist, rtx nextarg)
8215 HOST_WIDE_INT words, n_gpr, n_fpr;
8216 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8217 tree gpr, fpr, ovf, sav, t;
8219 /* Only SVR4 needs something special. */
8220 if (DEFAULT_ABI != ABI_V4)
8222 std_expand_builtin_va_start (valist, nextarg);
8226 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8227 f_fpr = TREE_CHAIN (f_gpr);
8228 f_res = TREE_CHAIN (f_fpr);
8229 f_ovf = TREE_CHAIN (f_res);
8230 f_sav = TREE_CHAIN (f_ovf);
8232 valist = build_va_arg_indirect_ref (valist);
8233 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8234 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8236 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8238 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8241 /* Count number of gp and fp argument registers used. */
8242 words = crtl->args.info.words;
8243 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8245 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8248 if (TARGET_DEBUG_ARG)
8249 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8250 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8251 words, n_gpr, n_fpr);
8253 if (cfun->va_list_gpr_size)
8255 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8256 build_int_cst (NULL_TREE, n_gpr));
8257 TREE_SIDE_EFFECTS (t) = 1;
8258 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8261 if (cfun->va_list_fpr_size)
8263 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8264 build_int_cst (NULL_TREE, n_fpr));
8265 TREE_SIDE_EFFECTS (t) = 1;
8266 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8269 /* Find the overflow area. */
8270 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8272 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8273 size_int (words * UNITS_PER_WORD));
8274 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8275 TREE_SIDE_EFFECTS (t) = 1;
8276 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8278 /* If there were no va_arg invocations, don't set up the register
8280 if (!cfun->va_list_gpr_size
8281 && !cfun->va_list_fpr_size
8282 && n_gpr < GP_ARG_NUM_REG
8283 && n_fpr < FP_ARG_V4_MAX_REG)
8286 /* Find the register save area. */
8287 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8288 if (cfun->machine->varargs_save_offset)
8289 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8290 size_int (cfun->machine->varargs_save_offset));
8291 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8292 TREE_SIDE_EFFECTS (t) = 1;
8293 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8296 /* Implement va_arg. */
8299 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8302 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8303 tree gpr, fpr, ovf, sav, reg, t, u;
8304 int size, rsize, n_reg, sav_ofs, sav_scale;
8305 tree lab_false, lab_over, addr;
8307 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8311 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8313 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8314 return build_va_arg_indirect_ref (t);
8317 if (DEFAULT_ABI != ABI_V4)
8319 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8321 tree elem_type = TREE_TYPE (type);
8322 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8323 int elem_size = GET_MODE_SIZE (elem_mode);
8325 if (elem_size < UNITS_PER_WORD)
8327 tree real_part, imag_part;
8328 gimple_seq post = NULL;
8330 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8332 /* Copy the value into a temporary, lest the formal temporary
8333 be reused out from under us. */
8334 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8335 gimple_seq_add_seq (pre_p, post);
8337 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8340 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8344 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8347 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8348 f_fpr = TREE_CHAIN (f_gpr);
8349 f_res = TREE_CHAIN (f_fpr);
8350 f_ovf = TREE_CHAIN (f_res);
8351 f_sav = TREE_CHAIN (f_ovf);
8353 valist = build_va_arg_indirect_ref (valist);
8354 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8355 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8357 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8359 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8362 size = int_size_in_bytes (type);
8363 rsize = (size + 3) / 4;
8366 if (TARGET_HARD_FLOAT && TARGET_FPRS
8367 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8368 || (TARGET_DOUBLE_FLOAT
8369 && (TYPE_MODE (type) == DFmode
8370 || TYPE_MODE (type) == TFmode
8371 || TYPE_MODE (type) == SDmode
8372 || TYPE_MODE (type) == DDmode
8373 || TYPE_MODE (type) == TDmode))))
8375 /* FP args go in FP registers, if present. */
8377 n_reg = (size + 7) / 8;
8378 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8379 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8380 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8385 /* Otherwise into GP registers. */
8394 /* Pull the value out of the saved registers.... */
8397 addr = create_tmp_var (ptr_type_node, "addr");
8399 /* AltiVec vectors never go in registers when -mabi=altivec. */
8400 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8404 lab_false = create_artificial_label (input_location);
8405 lab_over = create_artificial_label (input_location);
8407 /* Long long and SPE vectors are aligned in the registers.
8408 As are any other 2 gpr item such as complex int due to a
8409 historical mistake. */
8411 if (n_reg == 2 && reg == gpr)
8414 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8415 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8416 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8417 unshare_expr (reg), u);
8419 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8420 reg number is 0 for f1, so we want to make it odd. */
8421 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8423 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8424 build_int_cst (TREE_TYPE (reg), 1));
8425 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8428 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8429 t = build2 (GE_EXPR, boolean_type_node, u, t);
8430 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8431 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8432 gimplify_and_add (t, pre_p);
8436 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8438 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8439 build_int_cst (TREE_TYPE (reg), n_reg));
8440 u = fold_convert (sizetype, u);
8441 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8442 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8444 /* _Decimal32 varargs are located in the second word of the 64-bit
8445 FP register for 32-bit binaries. */
8446 if (!TARGET_POWERPC64
8447 && TARGET_HARD_FLOAT && TARGET_FPRS
8448 && TYPE_MODE (type) == SDmode)
8449 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8451 gimplify_assign (addr, t, pre_p);
8453 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8455 stmt = gimple_build_label (lab_false);
8456 gimple_seq_add_stmt (pre_p, stmt);
8458 if ((n_reg == 2 && !regalign) || n_reg > 2)
8460 /* Ensure that we don't find any more args in regs.
8461 Alignment has taken care of for special cases. */
8462 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8466 /* ... otherwise out of the overflow area. */
8468 /* Care for on-stack alignment if needed. */
8472 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8473 t = fold_convert (sizetype, t);
8474 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8476 t = fold_convert (TREE_TYPE (ovf), t);
8478 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8480 gimplify_assign (unshare_expr (addr), t, pre_p);
8482 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8483 gimplify_assign (unshare_expr (ovf), t, pre_p);
8487 stmt = gimple_build_label (lab_over);
8488 gimple_seq_add_stmt (pre_p, stmt);
8491 if (STRICT_ALIGNMENT
8492 && (TYPE_ALIGN (type)
8493 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8495 /* The value (of type complex double, for example) may not be
8496 aligned in memory in the saved registers, so copy via a
8497 temporary. (This is the same code as used for SPARC.) */
8498 tree tmp = create_tmp_var (type, "va_arg_tmp");
8499 tree dest_addr = build_fold_addr_expr (tmp);
8501 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8502 3, dest_addr, addr, size_int (rsize * 4));
8504 gimplify_and_add (copy, pre_p);
8508 addr = fold_convert (ptrtype, addr);
8509 return build_va_arg_indirect_ref (addr);
8515 def_builtin (int mask, const char *name, tree type, int code)
8517 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8520 if (rs6000_builtin_decls[code])
8521 fatal_error ("internal error: builtin function to %s already processed.",
8524 rs6000_builtin_decls[code] = t =
8525 add_builtin_function (name, type, code, BUILT_IN_MD,
8528 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
8529 switch (builtin_classify[code])
8534 /* assume builtin can do anything. */
8535 case RS6000_BTC_MISC:
8538 /* const function, function only depends on the inputs. */
8539 case RS6000_BTC_CONST:
8540 TREE_READONLY (t) = 1;
8541 TREE_NOTHROW (t) = 1;
8544 /* pure function, function can read global memory. */
8545 case RS6000_BTC_PURE:
8546 DECL_PURE_P (t) = 1;
8547 TREE_NOTHROW (t) = 1;
8550 /* Function is a math function. If rounding mode is on, then treat
8551 the function as not reading global memory, but it can have
8552 arbitrary side effects. If it is off, then assume the function is
8553 a const function. This mimics the ATTR_MATHFN_FPROUNDING
8554 attribute in builtin-attribute.def that is used for the math
8556 case RS6000_BTC_FP_PURE:
8557 TREE_NOTHROW (t) = 1;
8558 if (flag_rounding_math)
8560 DECL_PURE_P (t) = 1;
8561 DECL_IS_NOVOPS (t) = 1;
8564 TREE_READONLY (t) = 1;
8570 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
8572 static const struct builtin_description bdesc_3arg[] =
8574 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
8575 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
8576 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
8577 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
8578 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
8579 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
8580 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
8581 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
8582 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
8583 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
8584 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
8585 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
8586 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
8587 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
8588 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
8589 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
8590 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
8591 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
8592 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
8593 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
8594 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
8595 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
8596 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
8597 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
8598 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
8599 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
8600 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
8601 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
8602 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
8603 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
8604 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
8605 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
8606 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
8607 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
8608 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
8610 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
8611 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
8612 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
8613 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
8614 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
8615 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
8616 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
8617 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
8618 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
8619 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
8620 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
8621 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
8622 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
8623 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
8624 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
8626 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
8627 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
8628 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
8629 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
8631 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
8632 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
8633 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
8634 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
8636 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
8637 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
8639 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
8640 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
8641 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
8642 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
8643 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
8644 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
8645 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
8646 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
8647 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
8648 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
8650 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
8651 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
8652 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
8653 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
8654 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
8655 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
8656 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
8657 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
8658 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
8659 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
8661 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
8662 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
8663 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
8664 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
8665 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
8666 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
8667 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
8668 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
8669 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
8671 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
8672 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
8673 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
8674 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
8675 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
8676 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
8677 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
8679 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
8680 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
8681 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
8682 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
8683 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
8684 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
8685 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
8686 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
8687 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
8690 /* DST operations: void foo (void *, const int, const char). */
8692 static const struct builtin_description bdesc_dst[] =
8694 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
8695 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
8696 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
8697 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
8699 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
8700 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
8701 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
8702 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
8705 /* Simple binary operations: VECc = foo (VECa, VECb). */
8707 static struct builtin_description bdesc_2arg[] =
8709 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
8710 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
8711 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
8712 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
8713 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
8714 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
8715 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
8716 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
8717 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
8718 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
8719 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
8720 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
8721 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
8722 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
8723 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
8724 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
8725 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
8726 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
8727 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
8728 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
8729 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
8730 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
8731 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
8732 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
8733 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
8734 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
8735 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
8736 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
8737 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
8738 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
8739 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
8740 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
8741 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
8742 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
8743 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
8744 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
8745 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
8746 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
8747 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
8748 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
8749 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
8750 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
8751 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
8752 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
8753 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
8754 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
8755 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
8756 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
8757 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
8758 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
8759 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
8760 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
8761 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
8762 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
8763 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
8764 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
8765 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
8766 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
8767 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
8768 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
8769 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
8770 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
8771 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
8772 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
8773 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
8774 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
8775 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
8776 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
8777 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
8778 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
8779 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
8780 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
8781 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
8782 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
8783 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
8784 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
8785 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
8786 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
8787 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
8788 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
8789 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
8790 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
8791 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
8792 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
8793 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
8794 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
8795 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
8796 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
8797 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
8798 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
8799 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
8800 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
8801 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
8802 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
8803 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
8804 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
8805 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
8806 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
8807 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
8808 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
8809 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
8810 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
8811 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
8812 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
8813 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
8814 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
8815 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
8816 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
8817 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
8818 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
8819 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
8820 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
8821 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
8822 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
8823 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
8824 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
8826 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
8827 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
8828 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
8829 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
8830 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
8831 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
8832 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
8833 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
8834 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
8835 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
8836 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
8838 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
8839 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
8840 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
8841 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
8842 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
8843 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
8844 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
8845 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
8846 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
8847 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
8848 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
8850 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
8851 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
8852 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
8853 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
8854 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
8855 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
8857 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
8858 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
8859 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
8860 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
8861 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
8862 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
8863 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
8864 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
8866 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
8867 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
8868 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
8869 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
8870 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
8871 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
8872 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
8873 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
8874 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
8875 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
8876 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
8877 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
8878 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
8879 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
8880 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
8881 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
8882 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
8883 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
8884 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
8885 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
8886 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
8887 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
8888 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
8889 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
8890 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
8891 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
8892 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
8893 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
8894 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
8895 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
8896 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
8897 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
8898 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
8899 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
8900 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
8901 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
8902 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
8903 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
8904 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
8905 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
8906 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
8907 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
8908 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
8909 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
8910 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
8911 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
8912 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
8913 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
8914 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
8915 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
8916 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
8917 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
8918 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
8919 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
8920 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
8921 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
8922 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
8923 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
8924 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
8925 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
8926 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
8927 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
8928 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
8929 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
8930 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
8931 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
8932 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
8933 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
8934 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
8935 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
8936 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
8937 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
8938 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
8939 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
8940 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
8941 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
8942 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
8943 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
8944 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
8945 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
8946 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
8947 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
8948 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
8949 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
8950 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
8951 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
8952 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
8953 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
8954 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
8955 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
8956 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
8957 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
8958 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
8959 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
8960 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
8961 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
8962 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
8963 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
8964 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
8965 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
8966 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
8967 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
8968 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
8969 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
8970 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
8971 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
8972 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
8973 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
8974 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
8975 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
8976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
8977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
8978 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
8979 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
8980 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
8981 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
8982 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
8983 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
8984 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
8985 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
8986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
8987 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
8988 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
8989 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
8990 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
8991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
8992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
8993 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
8995 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
8996 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
8998 { 0, CODE_FOR_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
8999 { 0, CODE_FOR_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9000 { 0, CODE_FOR_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9001 { 0, CODE_FOR_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9002 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9003 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9004 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9005 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9006 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9007 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9009 /* Place holder, leave as first spe builtin. */
9010 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9011 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9012 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9013 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9014 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9015 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9016 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9017 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9018 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9019 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9020 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9021 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9022 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9023 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9024 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9025 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9026 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9027 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9028 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9029 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9030 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9031 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9032 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9033 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9034 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9035 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9036 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9037 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9038 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9039 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9040 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9041 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9042 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9043 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9044 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9045 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9046 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9047 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9048 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9049 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9050 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9051 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9052 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9053 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9054 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9055 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9056 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9057 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9058 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9059 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9060 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9061 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9062 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9063 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9064 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9065 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9066 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9067 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9068 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9069 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9070 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9071 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9072 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9073 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9074 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9075 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9076 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9077 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9078 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9079 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9080 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9081 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9082 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9083 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9084 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9085 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9086 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9087 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9088 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9089 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9090 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9091 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9092 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9093 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9094 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9095 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9096 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9097 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9098 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9099 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9100 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9101 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9102 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9103 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9104 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9105 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9106 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9107 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9108 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9109 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9110 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9111 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9112 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9113 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9114 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9115 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9116 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9117 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9118 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9120 /* SPE binary operations expecting a 5-bit unsigned literal. */
9121 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9123 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9124 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9125 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9126 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9127 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9128 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9129 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9130 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9131 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9132 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9133 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9134 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9135 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9136 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9137 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9138 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9139 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9140 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9141 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9142 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9143 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9144 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9145 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9146 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9147 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9148 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9150 /* Place-holder. Leave as last binary SPE builtin. */
9151 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9154 /* AltiVec predicates. */
9156 struct builtin_description_predicates
9158 const unsigned int mask;
9159 const enum insn_code icode;
9160 const char *const name;
9161 const enum rs6000_builtins code;
9164 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9166 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9167 ALTIVEC_BUILTIN_VCMPBFP_P },
9168 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9169 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9170 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9171 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9172 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9173 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9174 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9175 ALTIVEC_BUILTIN_VCMPEQUW_P },
9176 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9177 ALTIVEC_BUILTIN_VCMPGTSW_P },
9178 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9179 ALTIVEC_BUILTIN_VCMPGTUW_P },
9180 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9181 ALTIVEC_BUILTIN_VCMPEQUH_P },
9182 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9183 ALTIVEC_BUILTIN_VCMPGTSH_P },
9184 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9185 ALTIVEC_BUILTIN_VCMPGTUH_P },
9186 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9187 ALTIVEC_BUILTIN_VCMPEQUB_P },
9188 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9189 ALTIVEC_BUILTIN_VCMPGTSB_P },
9190 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9191 ALTIVEC_BUILTIN_VCMPGTUB_P },
9193 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9194 VSX_BUILTIN_XVCMPEQSP_P },
9195 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9196 VSX_BUILTIN_XVCMPGESP_P },
9197 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9198 VSX_BUILTIN_XVCMPGTSP_P },
9199 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9200 VSX_BUILTIN_XVCMPEQDP_P },
9201 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9202 VSX_BUILTIN_XVCMPGEDP_P },
9203 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9204 VSX_BUILTIN_XVCMPGTDP_P },
9206 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9207 ALTIVEC_BUILTIN_VCMPEQ_P },
9208 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9209 ALTIVEC_BUILTIN_VCMPGT_P },
9210 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9211 ALTIVEC_BUILTIN_VCMPGE_P }
9214 /* SPE predicates. */
9215 static struct builtin_description bdesc_spe_predicates[] =
9217 /* Place-holder. Leave as first. */
9218 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9219 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9220 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9221 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9222 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9223 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9224 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9225 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9226 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9227 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9228 /* Place-holder. Leave as last. */
9229 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9232 /* SPE evsel predicates. */
9233 static struct builtin_description bdesc_spe_evsel[] =
9235 /* Place-holder. Leave as first. */
9236 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9237 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9238 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9239 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9240 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9241 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9242 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9243 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9244 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9245 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9246 /* Place-holder. Leave as last. */
9247 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9250 /* PAIRED predicates. */
9251 static const struct builtin_description bdesc_paired_preds[] =
9253 /* Place-holder. Leave as first. */
9254 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9255 /* Place-holder. Leave as last. */
9256 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9259 /* ABS* operations. */
9261 static const struct builtin_description bdesc_abs[] =
9263 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9264 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9265 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9266 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9267 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9268 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9269 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9270 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9271 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9272 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9273 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9276 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9279 static struct builtin_description bdesc_1arg[] =
9281 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9282 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9283 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9284 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9285 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9286 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9287 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9288 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9289 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9290 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9291 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9292 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9293 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9294 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9295 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9296 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9297 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9299 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9300 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9301 { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9302 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9303 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9304 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9306 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9307 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9308 { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9309 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9310 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9311 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9313 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9314 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9315 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9316 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9317 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9318 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9320 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9321 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9322 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9323 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9324 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9325 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9327 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9328 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9329 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9330 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9332 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9333 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9334 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9335 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9336 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9337 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9338 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9339 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9340 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9342 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9343 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9344 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9345 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9346 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9347 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9348 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9349 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9350 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9352 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9353 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9354 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9355 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9356 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9358 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9359 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9360 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9361 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9362 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9363 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9364 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9365 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9366 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9367 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9368 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9369 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9370 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9371 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9372 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9373 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9374 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9375 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9376 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9378 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9379 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9380 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9382 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9383 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9384 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9385 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9387 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9388 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9389 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9390 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9391 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9392 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9393 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9394 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9395 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9396 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9397 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9398 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9399 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9400 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9401 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9402 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9403 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9404 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9405 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9406 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9407 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9408 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9409 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9410 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9411 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9412 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9413 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9414 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9415 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9416 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9418 /* Place-holder. Leave as last unary SPE builtin. */
9419 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9421 { 0, CODE_FOR_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9422 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9423 { 0, CODE_FOR_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9424 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9425 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9429 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9432 tree arg0 = CALL_EXPR_ARG (exp, 0);
9433 rtx op0 = expand_normal (arg0);
9434 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9435 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9437 if (icode == CODE_FOR_nothing)
9438 /* Builtin not supported on this processor. */
9441 /* If we got invalid arguments bail out before generating bad rtl. */
9442 if (arg0 == error_mark_node)
9445 if (icode == CODE_FOR_altivec_vspltisb
9446 || icode == CODE_FOR_altivec_vspltish
9447 || icode == CODE_FOR_altivec_vspltisw
9448 || icode == CODE_FOR_spe_evsplatfi
9449 || icode == CODE_FOR_spe_evsplati)
9451 /* Only allow 5-bit *signed* literals. */
9452 if (GET_CODE (op0) != CONST_INT
9453 || INTVAL (op0) > 15
9454 || INTVAL (op0) < -16)
9456 error ("argument 1 must be a 5-bit signed literal");
9462 || GET_MODE (target) != tmode
9463 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9464 target = gen_reg_rtx (tmode);
9466 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9467 op0 = copy_to_mode_reg (mode0, op0);
9469 pat = GEN_FCN (icode) (target, op0);
9478 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9480 rtx pat, scratch1, scratch2;
9481 tree arg0 = CALL_EXPR_ARG (exp, 0);
9482 rtx op0 = expand_normal (arg0);
9483 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9484 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9486 /* If we have invalid arguments, bail out before generating bad rtl. */
9487 if (arg0 == error_mark_node)
9491 || GET_MODE (target) != tmode
9492 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9493 target = gen_reg_rtx (tmode);
9495 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9496 op0 = copy_to_mode_reg (mode0, op0);
9498 scratch1 = gen_reg_rtx (mode0);
9499 scratch2 = gen_reg_rtx (mode0);
9501 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9510 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
9513 tree arg0 = CALL_EXPR_ARG (exp, 0);
9514 tree arg1 = CALL_EXPR_ARG (exp, 1);
9515 rtx op0 = expand_normal (arg0);
9516 rtx op1 = expand_normal (arg1);
9517 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9518 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9519 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9521 if (icode == CODE_FOR_nothing)
9522 /* Builtin not supported on this processor. */
9525 /* If we got invalid arguments bail out before generating bad rtl. */
9526 if (arg0 == error_mark_node || arg1 == error_mark_node)
9529 if (icode == CODE_FOR_altivec_vcfux
9530 || icode == CODE_FOR_altivec_vcfsx
9531 || icode == CODE_FOR_altivec_vctsxs
9532 || icode == CODE_FOR_altivec_vctuxs
9533 || icode == CODE_FOR_altivec_vspltb
9534 || icode == CODE_FOR_altivec_vsplth
9535 || icode == CODE_FOR_altivec_vspltw
9536 || icode == CODE_FOR_spe_evaddiw
9537 || icode == CODE_FOR_spe_evldd
9538 || icode == CODE_FOR_spe_evldh
9539 || icode == CODE_FOR_spe_evldw
9540 || icode == CODE_FOR_spe_evlhhesplat
9541 || icode == CODE_FOR_spe_evlhhossplat
9542 || icode == CODE_FOR_spe_evlhhousplat
9543 || icode == CODE_FOR_spe_evlwhe
9544 || icode == CODE_FOR_spe_evlwhos
9545 || icode == CODE_FOR_spe_evlwhou
9546 || icode == CODE_FOR_spe_evlwhsplat
9547 || icode == CODE_FOR_spe_evlwwsplat
9548 || icode == CODE_FOR_spe_evrlwi
9549 || icode == CODE_FOR_spe_evslwi
9550 || icode == CODE_FOR_spe_evsrwis
9551 || icode == CODE_FOR_spe_evsubifw
9552 || icode == CODE_FOR_spe_evsrwiu)
9554 /* Only allow 5-bit unsigned literals. */
9556 if (TREE_CODE (arg1) != INTEGER_CST
9557 || TREE_INT_CST_LOW (arg1) & ~0x1f)
9559 error ("argument 2 must be a 5-bit unsigned literal");
9565 || GET_MODE (target) != tmode
9566 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9567 target = gen_reg_rtx (tmode);
9569 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9570 op0 = copy_to_mode_reg (mode0, op0);
9571 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9572 op1 = copy_to_mode_reg (mode1, op1);
9574 pat = GEN_FCN (icode) (target, op0, op1);
9583 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
9586 tree cr6_form = CALL_EXPR_ARG (exp, 0);
9587 tree arg0 = CALL_EXPR_ARG (exp, 1);
9588 tree arg1 = CALL_EXPR_ARG (exp, 2);
9589 rtx op0 = expand_normal (arg0);
9590 rtx op1 = expand_normal (arg1);
9591 enum machine_mode tmode = SImode;
9592 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9593 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9596 if (TREE_CODE (cr6_form) != INTEGER_CST)
9598 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9602 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
9604 gcc_assert (mode0 == mode1);
9606 /* If we have invalid arguments, bail out before generating bad rtl. */
9607 if (arg0 == error_mark_node || arg1 == error_mark_node)
9611 || GET_MODE (target) != tmode
9612 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9613 target = gen_reg_rtx (tmode);
9615 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9616 op0 = copy_to_mode_reg (mode0, op0);
9617 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9618 op1 = copy_to_mode_reg (mode1, op1);
9620 scratch = gen_reg_rtx (mode0);
9622 pat = GEN_FCN (icode) (scratch, op0, op1);
9627 /* The vec_any* and vec_all* predicates use the same opcodes for two
9628 different operations, but the bits in CR6 will be different
9629 depending on what information we want. So we have to play tricks
9630 with CR6 to get the right bits out.
9632 If you think this is disgusting, look at the specs for the
9633 AltiVec predicates. */
9635 switch (cr6_form_int)
9638 emit_insn (gen_cr6_test_for_zero (target));
9641 emit_insn (gen_cr6_test_for_zero_reverse (target));
9644 emit_insn (gen_cr6_test_for_lt (target));
9647 emit_insn (gen_cr6_test_for_lt_reverse (target));
9650 error ("argument 1 of __builtin_altivec_predicate is out of range");
9658 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
9661 tree arg0 = CALL_EXPR_ARG (exp, 0);
9662 tree arg1 = CALL_EXPR_ARG (exp, 1);
9663 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9664 enum machine_mode mode0 = Pmode;
9665 enum machine_mode mode1 = Pmode;
9666 rtx op0 = expand_normal (arg0);
9667 rtx op1 = expand_normal (arg1);
9669 if (icode == CODE_FOR_nothing)
9670 /* Builtin not supported on this processor. */
9673 /* If we got invalid arguments bail out before generating bad rtl. */
9674 if (arg0 == error_mark_node || arg1 == error_mark_node)
9678 || GET_MODE (target) != tmode
9679 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9680 target = gen_reg_rtx (tmode);
9682 op1 = copy_to_mode_reg (mode1, op1);
9684 if (op0 == const0_rtx)
9686 addr = gen_rtx_MEM (tmode, op1);
9690 op0 = copy_to_mode_reg (mode0, op0);
9691 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
9694 pat = GEN_FCN (icode) (target, addr);
9704 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
9707 tree arg0 = CALL_EXPR_ARG (exp, 0);
9708 tree arg1 = CALL_EXPR_ARG (exp, 1);
9709 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9710 enum machine_mode mode0 = Pmode;
9711 enum machine_mode mode1 = Pmode;
9712 rtx op0 = expand_normal (arg0);
9713 rtx op1 = expand_normal (arg1);
9715 if (icode == CODE_FOR_nothing)
9716 /* Builtin not supported on this processor. */
9719 /* If we got invalid arguments bail out before generating bad rtl. */
9720 if (arg0 == error_mark_node || arg1 == error_mark_node)
9724 || GET_MODE (target) != tmode
9725 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9726 target = gen_reg_rtx (tmode);
9728 op1 = copy_to_mode_reg (mode1, op1);
9730 if (op0 == const0_rtx)
9732 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
9736 op0 = copy_to_mode_reg (mode0, op0);
9737 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
9740 pat = GEN_FCN (icode) (target, addr);
9750 spe_expand_stv_builtin (enum insn_code icode, tree exp)
9752 tree arg0 = CALL_EXPR_ARG (exp, 0);
9753 tree arg1 = CALL_EXPR_ARG (exp, 1);
9754 tree arg2 = CALL_EXPR_ARG (exp, 2);
9755 rtx op0 = expand_normal (arg0);
9756 rtx op1 = expand_normal (arg1);
9757 rtx op2 = expand_normal (arg2);
9759 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
9760 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
9761 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
9763 /* Invalid arguments. Bail before doing anything stoopid! */
9764 if (arg0 == error_mark_node
9765 || arg1 == error_mark_node
9766 || arg2 == error_mark_node)
9769 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
9770 op0 = copy_to_mode_reg (mode2, op0);
9771 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
9772 op1 = copy_to_mode_reg (mode0, op1);
9773 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
9774 op2 = copy_to_mode_reg (mode1, op2);
9776 pat = GEN_FCN (icode) (op1, op2, op0);
9783 paired_expand_stv_builtin (enum insn_code icode, tree exp)
9785 tree arg0 = CALL_EXPR_ARG (exp, 0);
9786 tree arg1 = CALL_EXPR_ARG (exp, 1);
9787 tree arg2 = CALL_EXPR_ARG (exp, 2);
9788 rtx op0 = expand_normal (arg0);
9789 rtx op1 = expand_normal (arg1);
9790 rtx op2 = expand_normal (arg2);
9792 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9793 enum machine_mode mode1 = Pmode;
9794 enum machine_mode mode2 = Pmode;
9796 /* Invalid arguments. Bail before doing anything stoopid! */
9797 if (arg0 == error_mark_node
9798 || arg1 == error_mark_node
9799 || arg2 == error_mark_node)
9802 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9803 op0 = copy_to_mode_reg (tmode, op0);
9805 op2 = copy_to_mode_reg (mode2, op2);
9807 if (op1 == const0_rtx)
9809 addr = gen_rtx_MEM (tmode, op2);
9813 op1 = copy_to_mode_reg (mode1, op1);
9814 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9817 pat = GEN_FCN (icode) (addr, op0);
9824 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
9826 tree arg0 = CALL_EXPR_ARG (exp, 0);
9827 tree arg1 = CALL_EXPR_ARG (exp, 1);
9828 tree arg2 = CALL_EXPR_ARG (exp, 2);
9829 rtx op0 = expand_normal (arg0);
9830 rtx op1 = expand_normal (arg1);
9831 rtx op2 = expand_normal (arg2);
9833 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9834 enum machine_mode mode1 = Pmode;
9835 enum machine_mode mode2 = Pmode;
9837 /* Invalid arguments. Bail before doing anything stoopid! */
9838 if (arg0 == error_mark_node
9839 || arg1 == error_mark_node
9840 || arg2 == error_mark_node)
9843 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9844 op0 = copy_to_mode_reg (tmode, op0);
9846 op2 = copy_to_mode_reg (mode2, op2);
9848 if (op1 == const0_rtx)
9850 addr = gen_rtx_MEM (tmode, op2);
9854 op1 = copy_to_mode_reg (mode1, op1);
9855 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9858 pat = GEN_FCN (icode) (addr, op0);
9865 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
9868 tree arg0 = CALL_EXPR_ARG (exp, 0);
9869 tree arg1 = CALL_EXPR_ARG (exp, 1);
9870 tree arg2 = CALL_EXPR_ARG (exp, 2);
9871 rtx op0 = expand_normal (arg0);
9872 rtx op1 = expand_normal (arg1);
9873 rtx op2 = expand_normal (arg2);
9874 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9875 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9876 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9877 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
9879 if (icode == CODE_FOR_nothing)
9880 /* Builtin not supported on this processor. */
9883 /* If we got invalid arguments bail out before generating bad rtl. */
9884 if (arg0 == error_mark_node
9885 || arg1 == error_mark_node
9886 || arg2 == error_mark_node)
9891 case CODE_FOR_altivec_vsldoi_v4sf:
9892 case CODE_FOR_altivec_vsldoi_v4si:
9893 case CODE_FOR_altivec_vsldoi_v8hi:
9894 case CODE_FOR_altivec_vsldoi_v16qi:
9895 /* Only allow 4-bit unsigned literals. */
9897 if (TREE_CODE (arg2) != INTEGER_CST
9898 || TREE_INT_CST_LOW (arg2) & ~0xf)
9900 error ("argument 3 must be a 4-bit unsigned literal");
9905 case CODE_FOR_vsx_xxpermdi_v2df:
9906 case CODE_FOR_vsx_xxpermdi_v2di:
9907 case CODE_FOR_vsx_xxsldwi_v16qi:
9908 case CODE_FOR_vsx_xxsldwi_v8hi:
9909 case CODE_FOR_vsx_xxsldwi_v4si:
9910 case CODE_FOR_vsx_xxsldwi_v4sf:
9911 case CODE_FOR_vsx_xxsldwi_v2di:
9912 case CODE_FOR_vsx_xxsldwi_v2df:
9913 /* Only allow 2-bit unsigned literals. */
9915 if (TREE_CODE (arg2) != INTEGER_CST
9916 || TREE_INT_CST_LOW (arg2) & ~0x3)
9918 error ("argument 3 must be a 2-bit unsigned literal");
9923 case CODE_FOR_vsx_set_v2df:
9924 case CODE_FOR_vsx_set_v2di:
9925 /* Only allow 1-bit unsigned literals. */
9927 if (TREE_CODE (arg2) != INTEGER_CST
9928 || TREE_INT_CST_LOW (arg2) & ~0x1)
9930 error ("argument 3 must be a 1-bit unsigned literal");
9940 || GET_MODE (target) != tmode
9941 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9942 target = gen_reg_rtx (tmode);
9944 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9945 op0 = copy_to_mode_reg (mode0, op0);
9946 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9947 op1 = copy_to_mode_reg (mode1, op1);
9948 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
9949 op2 = copy_to_mode_reg (mode2, op2);
9951 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
9952 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
9954 pat = GEN_FCN (icode) (target, op0, op1, op2);
9962 /* Expand the lvx builtins. */
9964 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
9966 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9967 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9969 enum machine_mode tmode, mode0;
9971 enum insn_code icode;
9975 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
9976 icode = CODE_FOR_vector_load_v16qi;
9978 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
9979 icode = CODE_FOR_vector_load_v8hi;
9981 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
9982 icode = CODE_FOR_vector_load_v4si;
9984 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
9985 icode = CODE_FOR_vector_load_v4sf;
9994 arg0 = CALL_EXPR_ARG (exp, 0);
9995 op0 = expand_normal (arg0);
9996 tmode = insn_data[icode].operand[0].mode;
9997 mode0 = insn_data[icode].operand[1].mode;
10000 || GET_MODE (target) != tmode
10001 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10002 target = gen_reg_rtx (tmode);
10004 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10005 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10007 pat = GEN_FCN (icode) (target, op0);
10014 /* Expand the stvx builtins. */
10016 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10019 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10020 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10022 enum machine_mode mode0, mode1;
10024 enum insn_code icode;
10028 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10029 icode = CODE_FOR_vector_store_v16qi;
10031 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10032 icode = CODE_FOR_vector_store_v8hi;
10034 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10035 icode = CODE_FOR_vector_store_v4si;
10037 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10038 icode = CODE_FOR_vector_store_v4sf;
10041 *expandedp = false;
10045 arg0 = CALL_EXPR_ARG (exp, 0);
10046 arg1 = CALL_EXPR_ARG (exp, 1);
10047 op0 = expand_normal (arg0);
10048 op1 = expand_normal (arg1);
10049 mode0 = insn_data[icode].operand[0].mode;
10050 mode1 = insn_data[icode].operand[1].mode;
10052 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10053 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10054 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10055 op1 = copy_to_mode_reg (mode1, op1);
10057 pat = GEN_FCN (icode) (op0, op1);
10065 /* Expand the dst builtins. */
10067 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10070 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10071 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10072 tree arg0, arg1, arg2;
10073 enum machine_mode mode0, mode1, mode2;
10074 rtx pat, op0, op1, op2;
10075 const struct builtin_description *d;
10078 *expandedp = false;
10080 /* Handle DST variants. */
10082 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10083 if (d->code == fcode)
10085 arg0 = CALL_EXPR_ARG (exp, 0);
10086 arg1 = CALL_EXPR_ARG (exp, 1);
10087 arg2 = CALL_EXPR_ARG (exp, 2);
10088 op0 = expand_normal (arg0);
10089 op1 = expand_normal (arg1);
10090 op2 = expand_normal (arg2);
10091 mode0 = insn_data[d->icode].operand[0].mode;
10092 mode1 = insn_data[d->icode].operand[1].mode;
10093 mode2 = insn_data[d->icode].operand[2].mode;
10095 /* Invalid arguments, bail out before generating bad rtl. */
10096 if (arg0 == error_mark_node
10097 || arg1 == error_mark_node
10098 || arg2 == error_mark_node)
10103 if (TREE_CODE (arg2) != INTEGER_CST
10104 || TREE_INT_CST_LOW (arg2) & ~0x3)
10106 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10110 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10111 op0 = copy_to_mode_reg (Pmode, op0);
10112 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10113 op1 = copy_to_mode_reg (mode1, op1);
10115 pat = GEN_FCN (d->icode) (op0, op1, op2);
10125 /* Expand vec_init builtin. */
10127 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10129 enum machine_mode tmode = TYPE_MODE (type);
10130 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10131 int i, n_elt = GET_MODE_NUNITS (tmode);
10132 rtvec v = rtvec_alloc (n_elt);
10134 gcc_assert (VECTOR_MODE_P (tmode));
10135 gcc_assert (n_elt == call_expr_nargs (exp));
10137 for (i = 0; i < n_elt; ++i)
10139 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10140 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10143 if (!target || !register_operand (target, tmode))
10144 target = gen_reg_rtx (tmode);
10146 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10150 /* Return the integer constant in ARG. Constrain it to be in the range
10151 of the subparts of VEC_TYPE; issue an error if not. */
10154 get_element_number (tree vec_type, tree arg)
10156 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10158 if (!host_integerp (arg, 1)
10159 || (elt = tree_low_cst (arg, 1), elt > max))
10161 error ("selector must be an integer constant in the range 0..%wi", max);
10168 /* Expand vec_set builtin. */
10170 altivec_expand_vec_set_builtin (tree exp)
10172 enum machine_mode tmode, mode1;
10173 tree arg0, arg1, arg2;
10177 arg0 = CALL_EXPR_ARG (exp, 0);
10178 arg1 = CALL_EXPR_ARG (exp, 1);
10179 arg2 = CALL_EXPR_ARG (exp, 2);
10181 tmode = TYPE_MODE (TREE_TYPE (arg0));
10182 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10183 gcc_assert (VECTOR_MODE_P (tmode));
10185 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10186 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10187 elt = get_element_number (TREE_TYPE (arg0), arg2);
10189 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10190 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10192 op0 = force_reg (tmode, op0);
10193 op1 = force_reg (mode1, op1);
10195 rs6000_expand_vector_set (op0, op1, elt);
10200 /* Expand vec_ext builtin. */
10202 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10204 enum machine_mode tmode, mode0;
10209 arg0 = CALL_EXPR_ARG (exp, 0);
10210 arg1 = CALL_EXPR_ARG (exp, 1);
10212 op0 = expand_normal (arg0);
10213 elt = get_element_number (TREE_TYPE (arg0), arg1);
10215 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10216 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10217 gcc_assert (VECTOR_MODE_P (mode0));
10219 op0 = force_reg (mode0, op0);
10221 if (optimize || !target || !register_operand (target, tmode))
10222 target = gen_reg_rtx (tmode);
10224 rs6000_expand_vector_extract (target, op0, elt);
10229 /* Expand the builtin in EXP and store the result in TARGET. Store
10230 true in *EXPANDEDP if we found a builtin to expand. */
10232 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10234 const struct builtin_description *d;
10235 const struct builtin_description_predicates *dp;
10237 enum insn_code icode;
10238 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10241 enum machine_mode tmode, mode0;
10242 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10244 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10245 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10246 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10247 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10250 error ("unresolved overload for Altivec builtin %qF", fndecl);
10254 target = altivec_expand_ld_builtin (exp, target, expandedp);
10258 target = altivec_expand_st_builtin (exp, target, expandedp);
10262 target = altivec_expand_dst_builtin (exp, target, expandedp);
10270 case ALTIVEC_BUILTIN_STVX:
10271 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10272 case ALTIVEC_BUILTIN_STVEBX:
10273 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10274 case ALTIVEC_BUILTIN_STVEHX:
10275 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10276 case ALTIVEC_BUILTIN_STVEWX:
10277 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10278 case ALTIVEC_BUILTIN_STVXL:
10279 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10281 case ALTIVEC_BUILTIN_STVLX:
10282 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10283 case ALTIVEC_BUILTIN_STVLXL:
10284 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10285 case ALTIVEC_BUILTIN_STVRX:
10286 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10287 case ALTIVEC_BUILTIN_STVRXL:
10288 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10290 case ALTIVEC_BUILTIN_MFVSCR:
10291 icode = CODE_FOR_altivec_mfvscr;
10292 tmode = insn_data[icode].operand[0].mode;
10295 || GET_MODE (target) != tmode
10296 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10297 target = gen_reg_rtx (tmode);
10299 pat = GEN_FCN (icode) (target);
10305 case ALTIVEC_BUILTIN_MTVSCR:
10306 icode = CODE_FOR_altivec_mtvscr;
10307 arg0 = CALL_EXPR_ARG (exp, 0);
10308 op0 = expand_normal (arg0);
10309 mode0 = insn_data[icode].operand[0].mode;
10311 /* If we got invalid arguments bail out before generating bad rtl. */
10312 if (arg0 == error_mark_node)
10315 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10316 op0 = copy_to_mode_reg (mode0, op0);
10318 pat = GEN_FCN (icode) (op0);
10323 case ALTIVEC_BUILTIN_DSSALL:
10324 emit_insn (gen_altivec_dssall ());
10327 case ALTIVEC_BUILTIN_DSS:
10328 icode = CODE_FOR_altivec_dss;
10329 arg0 = CALL_EXPR_ARG (exp, 0);
10331 op0 = expand_normal (arg0);
10332 mode0 = insn_data[icode].operand[0].mode;
10334 /* If we got invalid arguments bail out before generating bad rtl. */
10335 if (arg0 == error_mark_node)
10338 if (TREE_CODE (arg0) != INTEGER_CST
10339 || TREE_INT_CST_LOW (arg0) & ~0x3)
10341 error ("argument to dss must be a 2-bit unsigned literal");
10345 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10346 op0 = copy_to_mode_reg (mode0, op0);
10348 emit_insn (gen_altivec_dss (op0));
10351 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10352 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10353 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10354 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10355 case VSX_BUILTIN_VEC_INIT_V2DF:
10356 case VSX_BUILTIN_VEC_INIT_V2DI:
10357 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10359 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10360 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10361 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10362 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10363 case VSX_BUILTIN_VEC_SET_V2DF:
10364 case VSX_BUILTIN_VEC_SET_V2DI:
10365 return altivec_expand_vec_set_builtin (exp);
10367 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10368 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10369 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10370 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10371 case VSX_BUILTIN_VEC_EXT_V2DF:
10372 case VSX_BUILTIN_VEC_EXT_V2DI:
10373 return altivec_expand_vec_ext_builtin (exp, target);
10377 /* Fall through. */
10380 /* Expand abs* operations. */
10382 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10383 if (d->code == fcode)
10384 return altivec_expand_abs_builtin (d->icode, exp, target);
10386 /* Expand the AltiVec predicates. */
10387 dp = bdesc_altivec_preds;
10388 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10389 if (dp->code == fcode)
10390 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10392 /* LV* are funky. We initialized them differently. */
10395 case ALTIVEC_BUILTIN_LVSL:
10396 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10397 exp, target, false);
10398 case ALTIVEC_BUILTIN_LVSR:
10399 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10400 exp, target, false);
10401 case ALTIVEC_BUILTIN_LVEBX:
10402 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10403 exp, target, false);
10404 case ALTIVEC_BUILTIN_LVEHX:
10405 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10406 exp, target, false);
10407 case ALTIVEC_BUILTIN_LVEWX:
10408 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10409 exp, target, false);
10410 case ALTIVEC_BUILTIN_LVXL:
10411 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10412 exp, target, false);
10413 case ALTIVEC_BUILTIN_LVX:
10414 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10415 exp, target, false);
10416 case ALTIVEC_BUILTIN_LVLX:
10417 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10418 exp, target, true);
10419 case ALTIVEC_BUILTIN_LVLXL:
10420 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10421 exp, target, true);
10422 case ALTIVEC_BUILTIN_LVRX:
10423 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10424 exp, target, true);
10425 case ALTIVEC_BUILTIN_LVRXL:
10426 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10427 exp, target, true);
10430 /* Fall through. */
10433 *expandedp = false;
10437 /* Expand the builtin in EXP and store the result in TARGET. Store
10438 true in *EXPANDEDP if we found a builtin to expand. */
10440 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10442 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10443 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10444 const struct builtin_description *d;
10451 case PAIRED_BUILTIN_STX:
10452 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10453 case PAIRED_BUILTIN_LX:
10454 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10457 /* Fall through. */
10460 /* Expand the paired predicates. */
10461 d = bdesc_paired_preds;
10462 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10463 if (d->code == fcode)
10464 return paired_expand_predicate_builtin (d->icode, exp, target);
10466 *expandedp = false;
10470 /* Binops that need to be initialized manually, but can be expanded
10471 automagically by rs6000_expand_binop_builtin. */
10472 static struct builtin_description bdesc_2arg_spe[] =
10474 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10475 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10476 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10477 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10478 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10479 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10480 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10481 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10482 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10483 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10484 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10485 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10486 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10487 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10488 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10489 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10490 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10491 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10492 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10493 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10494 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10495 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10498 /* Expand the builtin in EXP and store the result in TARGET. Store
10499 true in *EXPANDEDP if we found a builtin to expand.
10501 This expands the SPE builtins that are not simple unary and binary
10504 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10506 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10508 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10509 enum insn_code icode;
10510 enum machine_mode tmode, mode0;
10512 struct builtin_description *d;
10517 /* Syntax check for a 5-bit unsigned immediate. */
10520 case SPE_BUILTIN_EVSTDD:
10521 case SPE_BUILTIN_EVSTDH:
10522 case SPE_BUILTIN_EVSTDW:
10523 case SPE_BUILTIN_EVSTWHE:
10524 case SPE_BUILTIN_EVSTWHO:
10525 case SPE_BUILTIN_EVSTWWE:
10526 case SPE_BUILTIN_EVSTWWO:
10527 arg1 = CALL_EXPR_ARG (exp, 2);
10528 if (TREE_CODE (arg1) != INTEGER_CST
10529 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10531 error ("argument 2 must be a 5-bit unsigned literal");
10539 /* The evsplat*i instructions are not quite generic. */
10542 case SPE_BUILTIN_EVSPLATFI:
10543 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
10545 case SPE_BUILTIN_EVSPLATI:
10546 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
10552 d = (struct builtin_description *) bdesc_2arg_spe;
10553 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
10554 if (d->code == fcode)
10555 return rs6000_expand_binop_builtin (d->icode, exp, target);
10557 d = (struct builtin_description *) bdesc_spe_predicates;
10558 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
10559 if (d->code == fcode)
10560 return spe_expand_predicate_builtin (d->icode, exp, target);
10562 d = (struct builtin_description *) bdesc_spe_evsel;
10563 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
10564 if (d->code == fcode)
10565 return spe_expand_evsel_builtin (d->icode, exp, target);
10569 case SPE_BUILTIN_EVSTDDX:
10570 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
10571 case SPE_BUILTIN_EVSTDHX:
10572 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
10573 case SPE_BUILTIN_EVSTDWX:
10574 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
10575 case SPE_BUILTIN_EVSTWHEX:
10576 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
10577 case SPE_BUILTIN_EVSTWHOX:
10578 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
10579 case SPE_BUILTIN_EVSTWWEX:
10580 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
10581 case SPE_BUILTIN_EVSTWWOX:
10582 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
10583 case SPE_BUILTIN_EVSTDD:
10584 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
10585 case SPE_BUILTIN_EVSTDH:
10586 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
10587 case SPE_BUILTIN_EVSTDW:
10588 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
10589 case SPE_BUILTIN_EVSTWHE:
10590 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
10591 case SPE_BUILTIN_EVSTWHO:
10592 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
10593 case SPE_BUILTIN_EVSTWWE:
10594 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
10595 case SPE_BUILTIN_EVSTWWO:
10596 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
10597 case SPE_BUILTIN_MFSPEFSCR:
10598 icode = CODE_FOR_spe_mfspefscr;
10599 tmode = insn_data[icode].operand[0].mode;
10602 || GET_MODE (target) != tmode
10603 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10604 target = gen_reg_rtx (tmode);
10606 pat = GEN_FCN (icode) (target);
10611 case SPE_BUILTIN_MTSPEFSCR:
10612 icode = CODE_FOR_spe_mtspefscr;
10613 arg0 = CALL_EXPR_ARG (exp, 0);
10614 op0 = expand_normal (arg0);
10615 mode0 = insn_data[icode].operand[0].mode;
10617 if (arg0 == error_mark_node)
10620 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10621 op0 = copy_to_mode_reg (mode0, op0);
10623 pat = GEN_FCN (icode) (op0);
10631 *expandedp = false;
10636 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10638 rtx pat, scratch, tmp;
10639 tree form = CALL_EXPR_ARG (exp, 0);
10640 tree arg0 = CALL_EXPR_ARG (exp, 1);
10641 tree arg1 = CALL_EXPR_ARG (exp, 2);
10642 rtx op0 = expand_normal (arg0);
10643 rtx op1 = expand_normal (arg1);
10644 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10645 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10647 enum rtx_code code;
10649 if (TREE_CODE (form) != INTEGER_CST)
10651 error ("argument 1 of __builtin_paired_predicate must be a constant");
10655 form_int = TREE_INT_CST_LOW (form);
10657 gcc_assert (mode0 == mode1);
10659 if (arg0 == error_mark_node || arg1 == error_mark_node)
10663 || GET_MODE (target) != SImode
10664 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
10665 target = gen_reg_rtx (SImode);
10666 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10667 op0 = copy_to_mode_reg (mode0, op0);
10668 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10669 op1 = copy_to_mode_reg (mode1, op1);
10671 scratch = gen_reg_rtx (CCFPmode);
10673 pat = GEN_FCN (icode) (scratch, op0, op1);
10695 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10698 error ("argument 1 of __builtin_paired_predicate is out of range");
10702 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10703 emit_move_insn (target, tmp);
10708 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10710 rtx pat, scratch, tmp;
10711 tree form = CALL_EXPR_ARG (exp, 0);
10712 tree arg0 = CALL_EXPR_ARG (exp, 1);
10713 tree arg1 = CALL_EXPR_ARG (exp, 2);
10714 rtx op0 = expand_normal (arg0);
10715 rtx op1 = expand_normal (arg1);
10716 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10717 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10719 enum rtx_code code;
10721 if (TREE_CODE (form) != INTEGER_CST)
10723 error ("argument 1 of __builtin_spe_predicate must be a constant");
10727 form_int = TREE_INT_CST_LOW (form);
10729 gcc_assert (mode0 == mode1);
10731 if (arg0 == error_mark_node || arg1 == error_mark_node)
10735 || GET_MODE (target) != SImode
10736 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
10737 target = gen_reg_rtx (SImode);
10739 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10740 op0 = copy_to_mode_reg (mode0, op0);
10741 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10742 op1 = copy_to_mode_reg (mode1, op1);
10744 scratch = gen_reg_rtx (CCmode);
10746 pat = GEN_FCN (icode) (scratch, op0, op1);
10751 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
10752 _lower_. We use one compare, but look in different bits of the
10753 CR for each variant.
10755 There are 2 elements in each SPE simd type (upper/lower). The CR
10756 bits are set as follows:
10758 BIT0 | BIT 1 | BIT 2 | BIT 3
10759 U | L | (U | L) | (U & L)
10761 So, for an "all" relationship, BIT 3 would be set.
10762 For an "any" relationship, BIT 2 would be set. Etc.
10764 Following traditional nomenclature, these bits map to:
10766 BIT0 | BIT 1 | BIT 2 | BIT 3
10769 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
10774 /* All variant. OV bit. */
10776 /* We need to get to the OV bit, which is the ORDERED bit. We
10777 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
10778 that's ugly and will make validate_condition_mode die.
10779 So let's just use another pattern. */
10780 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10782 /* Any variant. EQ bit. */
10786 /* Upper variant. LT bit. */
10790 /* Lower variant. GT bit. */
10795 error ("argument 1 of __builtin_spe_predicate is out of range");
10799 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10800 emit_move_insn (target, tmp);
10805 /* The evsel builtins look like this:
10807 e = __builtin_spe_evsel_OP (a, b, c, d);
10809 and work like this:
10811 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
10812 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
10816 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
10819 tree arg0 = CALL_EXPR_ARG (exp, 0);
10820 tree arg1 = CALL_EXPR_ARG (exp, 1);
10821 tree arg2 = CALL_EXPR_ARG (exp, 2);
10822 tree arg3 = CALL_EXPR_ARG (exp, 3);
10823 rtx op0 = expand_normal (arg0);
10824 rtx op1 = expand_normal (arg1);
10825 rtx op2 = expand_normal (arg2);
10826 rtx op3 = expand_normal (arg3);
10827 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10828 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10830 gcc_assert (mode0 == mode1);
10832 if (arg0 == error_mark_node || arg1 == error_mark_node
10833 || arg2 == error_mark_node || arg3 == error_mark_node)
10837 || GET_MODE (target) != mode0
10838 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
10839 target = gen_reg_rtx (mode0);
10841 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10842 op0 = copy_to_mode_reg (mode0, op0);
10843 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10844 op1 = copy_to_mode_reg (mode0, op1);
10845 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10846 op2 = copy_to_mode_reg (mode0, op2);
10847 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
10848 op3 = copy_to_mode_reg (mode0, op3);
10850 /* Generate the compare. */
10851 scratch = gen_reg_rtx (CCmode);
10852 pat = GEN_FCN (icode) (scratch, op0, op1);
10857 if (mode0 == V2SImode)
10858 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
10860 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
10865 /* Expand an expression EXP that calls a built-in function,
10866 with result going to TARGET if that's convenient
10867 (and in mode MODE if that's convenient).
10868 SUBTARGET may be used as the target for computing one of EXP's operands.
10869 IGNORE is nonzero if the value is to be ignored. */
10872 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10873 enum machine_mode mode ATTRIBUTE_UNUSED,
10874 int ignore ATTRIBUTE_UNUSED)
10876 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10877 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10878 const struct builtin_description *d;
10883 if (fcode == RS6000_BUILTIN_RECIP)
10884 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
10886 if (fcode == RS6000_BUILTIN_RECIPF)
10887 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
10889 if (fcode == RS6000_BUILTIN_RSQRTF)
10890 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
10892 if (fcode == RS6000_BUILTIN_BSWAP_HI)
10893 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
10895 if (fcode == POWER7_BUILTIN_BPERMD)
10896 return rs6000_expand_binop_builtin (((TARGET_64BIT)
10897 ? CODE_FOR_bpermd_di
10898 : CODE_FOR_bpermd_si), exp, target);
10900 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
10901 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10903 int icode = (int) CODE_FOR_altivec_lvsr;
10904 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10905 enum machine_mode mode = insn_data[icode].operand[1].mode;
10909 gcc_assert (TARGET_ALTIVEC);
10911 arg = CALL_EXPR_ARG (exp, 0);
10912 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
10913 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
10914 addr = memory_address (mode, op);
10915 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10919 /* For the load case need to negate the address. */
10920 op = gen_reg_rtx (GET_MODE (addr));
10921 emit_insn (gen_rtx_SET (VOIDmode, op,
10922 gen_rtx_NEG (GET_MODE (addr), addr)));
10924 op = gen_rtx_MEM (mode, op);
10927 || GET_MODE (target) != tmode
10928 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10929 target = gen_reg_rtx (tmode);
10931 /*pat = gen_altivec_lvsr (target, op);*/
10932 pat = GEN_FCN (icode) (target, op);
10940 /* FIXME: There's got to be a nicer way to handle this case than
10941 constructing a new CALL_EXPR. */
10942 if (fcode == ALTIVEC_BUILTIN_VCFUX
10943 || fcode == ALTIVEC_BUILTIN_VCFSX
10944 || fcode == ALTIVEC_BUILTIN_VCTUXS
10945 || fcode == ALTIVEC_BUILTIN_VCTSXS)
10947 if (call_expr_nargs (exp) == 1)
10948 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
10949 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
10952 if (TARGET_ALTIVEC)
10954 ret = altivec_expand_builtin (exp, target, &success);
10961 ret = spe_expand_builtin (exp, target, &success);
10966 if (TARGET_PAIRED_FLOAT)
10968 ret = paired_expand_builtin (exp, target, &success);
10974 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
10976 /* Handle simple unary operations. */
10977 d = (struct builtin_description *) bdesc_1arg;
10978 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
10979 if (d->code == fcode)
10980 return rs6000_expand_unop_builtin (d->icode, exp, target);
10982 /* Handle simple binary operations. */
10983 d = (struct builtin_description *) bdesc_2arg;
10984 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
10985 if (d->code == fcode)
10986 return rs6000_expand_binop_builtin (d->icode, exp, target);
10988 /* Handle simple ternary operations. */
10990 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
10991 if (d->code == fcode)
10992 return rs6000_expand_ternop_builtin (d->icode, exp, target);
10994 gcc_unreachable ();
10998 rs6000_init_builtins (void)
11002 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11003 V2SF_type_node = build_vector_type (float_type_node, 2);
11004 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11005 V2DF_type_node = build_vector_type (double_type_node, 2);
11006 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11007 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11008 V4SF_type_node = build_vector_type (float_type_node, 4);
11009 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11010 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11012 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11013 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11014 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11015 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11017 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11018 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11019 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11020 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11022 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11023 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11024 'vector unsigned short'. */
11026 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11027 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11028 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11029 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11030 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11032 long_integer_type_internal_node = long_integer_type_node;
11033 long_unsigned_type_internal_node = long_unsigned_type_node;
11034 intQI_type_internal_node = intQI_type_node;
11035 uintQI_type_internal_node = unsigned_intQI_type_node;
11036 intHI_type_internal_node = intHI_type_node;
11037 uintHI_type_internal_node = unsigned_intHI_type_node;
11038 intSI_type_internal_node = intSI_type_node;
11039 uintSI_type_internal_node = unsigned_intSI_type_node;
11040 intDI_type_internal_node = intDI_type_node;
11041 uintDI_type_internal_node = unsigned_intDI_type_node;
11042 float_type_internal_node = float_type_node;
11043 double_type_internal_node = float_type_node;
11044 void_type_internal_node = void_type_node;
11046 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11048 builtin_mode_to_type[QImode][0] = integer_type_node;
11049 builtin_mode_to_type[HImode][0] = integer_type_node;
11050 builtin_mode_to_type[SImode][0] = intSI_type_node;
11051 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
11052 builtin_mode_to_type[DImode][0] = intDI_type_node;
11053 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
11054 builtin_mode_to_type[SFmode][0] = float_type_node;
11055 builtin_mode_to_type[DFmode][0] = double_type_node;
11056 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
11057 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
11058 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
11059 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
11060 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
11061 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
11062 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11063 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11064 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11065 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11066 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11067 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11068 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11070 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11071 get_identifier ("__bool char"),
11072 bool_char_type_node);
11073 TYPE_NAME (bool_char_type_node) = tdecl;
11074 (*lang_hooks.decls.pushdecl) (tdecl);
11075 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11076 get_identifier ("__bool short"),
11077 bool_short_type_node);
11078 TYPE_NAME (bool_short_type_node) = tdecl;
11079 (*lang_hooks.decls.pushdecl) (tdecl);
11080 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11081 get_identifier ("__bool int"),
11082 bool_int_type_node);
11083 TYPE_NAME (bool_int_type_node) = tdecl;
11084 (*lang_hooks.decls.pushdecl) (tdecl);
11085 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
11087 TYPE_NAME (pixel_type_node) = tdecl;
11088 (*lang_hooks.decls.pushdecl) (tdecl);
11090 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
11091 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11092 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11093 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11094 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11096 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11097 get_identifier ("__vector unsigned char"),
11098 unsigned_V16QI_type_node);
11099 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11100 (*lang_hooks.decls.pushdecl) (tdecl);
11101 tdecl = build_decl (BUILTINS_LOCATION,
11102 TYPE_DECL, get_identifier ("__vector signed char"),
11104 TYPE_NAME (V16QI_type_node) = tdecl;
11105 (*lang_hooks.decls.pushdecl) (tdecl);
11106 tdecl = build_decl (BUILTINS_LOCATION,
11107 TYPE_DECL, get_identifier ("__vector __bool char"),
11108 bool_V16QI_type_node);
11109 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11110 (*lang_hooks.decls.pushdecl) (tdecl);
11112 tdecl = build_decl (BUILTINS_LOCATION,
11113 TYPE_DECL, get_identifier ("__vector unsigned short"),
11114 unsigned_V8HI_type_node);
11115 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11116 (*lang_hooks.decls.pushdecl) (tdecl);
11117 tdecl = build_decl (BUILTINS_LOCATION,
11118 TYPE_DECL, get_identifier ("__vector signed short"),
11120 TYPE_NAME (V8HI_type_node) = tdecl;
11121 (*lang_hooks.decls.pushdecl) (tdecl);
11122 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11123 get_identifier ("__vector __bool short"),
11124 bool_V8HI_type_node);
11125 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11126 (*lang_hooks.decls.pushdecl) (tdecl);
11128 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11129 get_identifier ("__vector unsigned int"),
11130 unsigned_V4SI_type_node);
11131 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11132 (*lang_hooks.decls.pushdecl) (tdecl);
11133 tdecl = build_decl (BUILTINS_LOCATION,
11134 TYPE_DECL, get_identifier ("__vector signed int"),
11136 TYPE_NAME (V4SI_type_node) = tdecl;
11137 (*lang_hooks.decls.pushdecl) (tdecl);
11138 tdecl = build_decl (BUILTINS_LOCATION,
11139 TYPE_DECL, get_identifier ("__vector __bool int"),
11140 bool_V4SI_type_node);
11141 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11142 (*lang_hooks.decls.pushdecl) (tdecl);
11144 tdecl = build_decl (BUILTINS_LOCATION,
11145 TYPE_DECL, get_identifier ("__vector float"),
11147 TYPE_NAME (V4SF_type_node) = tdecl;
11148 (*lang_hooks.decls.pushdecl) (tdecl);
11149 tdecl = build_decl (BUILTINS_LOCATION,
11150 TYPE_DECL, get_identifier ("__vector __pixel"),
11151 pixel_V8HI_type_node);
11152 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11153 (*lang_hooks.decls.pushdecl) (tdecl);
11157 tdecl = build_decl (BUILTINS_LOCATION,
11158 TYPE_DECL, get_identifier ("__vector double"),
11160 TYPE_NAME (V2DF_type_node) = tdecl;
11161 (*lang_hooks.decls.pushdecl) (tdecl);
11163 tdecl = build_decl (BUILTINS_LOCATION,
11164 TYPE_DECL, get_identifier ("__vector long"),
11166 TYPE_NAME (V2DI_type_node) = tdecl;
11167 (*lang_hooks.decls.pushdecl) (tdecl);
11169 tdecl = build_decl (BUILTINS_LOCATION,
11170 TYPE_DECL, get_identifier ("__vector unsigned long"),
11171 unsigned_V2DI_type_node);
11172 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11173 (*lang_hooks.decls.pushdecl) (tdecl);
11175 tdecl = build_decl (BUILTINS_LOCATION,
11176 TYPE_DECL, get_identifier ("__vector __bool long"),
11177 bool_V2DI_type_node);
11178 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11179 (*lang_hooks.decls.pushdecl) (tdecl);
11182 if (TARGET_PAIRED_FLOAT)
11183 paired_init_builtins ();
11185 spe_init_builtins ();
11186 if (TARGET_ALTIVEC)
11187 altivec_init_builtins ();
11188 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11189 rs6000_common_init_builtins ();
11190 if (TARGET_PPC_GFXOPT)
11192 tree ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11193 RS6000_BUILTIN_RECIPF,
11194 "__builtin_recipdivf");
11195 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11196 RS6000_BUILTIN_RECIPF);
11198 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11199 RS6000_BUILTIN_RSQRTF,
11200 "__builtin_rsqrtf");
11201 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11202 RS6000_BUILTIN_RSQRTF);
11204 if (TARGET_POPCNTB)
11206 tree ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11207 RS6000_BUILTIN_RECIP,
11208 "__builtin_recipdiv");
11209 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11210 RS6000_BUILTIN_RECIP);
11213 if (TARGET_POPCNTD)
11215 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11216 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11217 POWER7_BUILTIN_BPERMD,
11218 "__builtin_bpermd");
11219 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11220 POWER7_BUILTIN_BPERMD);
11222 if (TARGET_POWERPC)
11224 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11225 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11226 unsigned_intHI_type_node,
11228 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11229 RS6000_BUILTIN_BSWAP_HI);
11233 /* AIX libm provides clog as __clog. */
11234 if (built_in_decls [BUILT_IN_CLOG])
11235 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11238 #ifdef SUBTARGET_INIT_BUILTINS
11239 SUBTARGET_INIT_BUILTINS;
11243 /* Returns the rs6000 builtin decl for CODE. */
11246 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
11248 if (code >= RS6000_BUILTIN_COUNT)
11249 return error_mark_node;
11251 return rs6000_builtin_decls[code];
11254 /* Search through a set of builtins and enable the mask bits.
11255 DESC is an array of builtins.
11256 SIZE is the total number of builtins.
11257 START is the builtin enum at which to start.
11258 END is the builtin enum at which to end. */
11260 enable_mask_for_builtins (struct builtin_description *desc, int size,
11261 enum rs6000_builtins start,
11262 enum rs6000_builtins end)
11266 for (i = 0; i < size; ++i)
11267 if (desc[i].code == start)
11273 for (; i < size; ++i)
11275 /* Flip all the bits on. */
11276 desc[i].mask = target_flags;
11277 if (desc[i].code == end)
11283 spe_init_builtins (void)
11285 tree endlink = void_list_node;
11286 tree puint_type_node = build_pointer_type (unsigned_type_node);
11287 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11288 struct builtin_description *d;
11291 tree v2si_ftype_4_v2si
11292 = build_function_type
11293 (opaque_V2SI_type_node,
11294 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11295 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11296 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11297 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11300 tree v2sf_ftype_4_v2sf
11301 = build_function_type
11302 (opaque_V2SF_type_node,
11303 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11304 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11305 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11306 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11309 tree int_ftype_int_v2si_v2si
11310 = build_function_type
11311 (integer_type_node,
11312 tree_cons (NULL_TREE, integer_type_node,
11313 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11314 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11317 tree int_ftype_int_v2sf_v2sf
11318 = build_function_type
11319 (integer_type_node,
11320 tree_cons (NULL_TREE, integer_type_node,
11321 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11322 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11325 tree void_ftype_v2si_puint_int
11326 = build_function_type (void_type_node,
11327 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11328 tree_cons (NULL_TREE, puint_type_node,
11329 tree_cons (NULL_TREE,
11333 tree void_ftype_v2si_puint_char
11334 = build_function_type (void_type_node,
11335 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11336 tree_cons (NULL_TREE, puint_type_node,
11337 tree_cons (NULL_TREE,
11341 tree void_ftype_v2si_pv2si_int
11342 = build_function_type (void_type_node,
11343 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11344 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11345 tree_cons (NULL_TREE,
11349 tree void_ftype_v2si_pv2si_char
11350 = build_function_type (void_type_node,
11351 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11352 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11353 tree_cons (NULL_TREE,
11357 tree void_ftype_int
11358 = build_function_type (void_type_node,
11359 tree_cons (NULL_TREE, integer_type_node, endlink));
11361 tree int_ftype_void
11362 = build_function_type (integer_type_node, endlink);
11364 tree v2si_ftype_pv2si_int
11365 = build_function_type (opaque_V2SI_type_node,
11366 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11367 tree_cons (NULL_TREE, integer_type_node,
11370 tree v2si_ftype_puint_int
11371 = build_function_type (opaque_V2SI_type_node,
11372 tree_cons (NULL_TREE, puint_type_node,
11373 tree_cons (NULL_TREE, integer_type_node,
11376 tree v2si_ftype_pushort_int
11377 = build_function_type (opaque_V2SI_type_node,
11378 tree_cons (NULL_TREE, pushort_type_node,
11379 tree_cons (NULL_TREE, integer_type_node,
11382 tree v2si_ftype_signed_char
11383 = build_function_type (opaque_V2SI_type_node,
11384 tree_cons (NULL_TREE, signed_char_type_node,
11387 /* The initialization of the simple binary and unary builtins is
11388 done in rs6000_common_init_builtins, but we have to enable the
11389 mask bits here manually because we have run out of `target_flags'
11390 bits. We really need to redesign this mask business. */
11392 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11393 ARRAY_SIZE (bdesc_2arg),
11394 SPE_BUILTIN_EVADDW,
11395 SPE_BUILTIN_EVXOR);
11396 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11397 ARRAY_SIZE (bdesc_1arg),
11399 SPE_BUILTIN_EVSUBFUSIAAW);
11400 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11401 ARRAY_SIZE (bdesc_spe_predicates),
11402 SPE_BUILTIN_EVCMPEQ,
11403 SPE_BUILTIN_EVFSTSTLT);
11404 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11405 ARRAY_SIZE (bdesc_spe_evsel),
11406 SPE_BUILTIN_EVSEL_CMPGTS,
11407 SPE_BUILTIN_EVSEL_FSTSTEQ);
11409 (*lang_hooks.decls.pushdecl)
11410 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11411 get_identifier ("__ev64_opaque__"),
11412 opaque_V2SI_type_node));
11414 /* Initialize irregular SPE builtins. */
11416 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11417 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11418 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11419 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11420 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11421 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11422 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11423 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11424 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11425 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11426 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11427 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11428 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11429 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11430 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11431 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11432 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11433 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11436 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11437 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11438 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11439 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11440 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11441 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11442 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11443 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11444 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11445 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11446 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11447 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11448 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11449 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11450 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11451 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11452 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11453 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11454 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11455 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11456 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11457 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11460 d = (struct builtin_description *) bdesc_spe_predicates;
11461 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11465 switch (insn_data[d->icode].operand[1].mode)
11468 type = int_ftype_int_v2si_v2si;
11471 type = int_ftype_int_v2sf_v2sf;
11474 gcc_unreachable ();
11477 def_builtin (d->mask, d->name, type, d->code);
11480 /* Evsel predicates. */
11481 d = (struct builtin_description *) bdesc_spe_evsel;
11482 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11486 switch (insn_data[d->icode].operand[1].mode)
11489 type = v2si_ftype_4_v2si;
11492 type = v2sf_ftype_4_v2sf;
11495 gcc_unreachable ();
11498 def_builtin (d->mask, d->name, type, d->code);
11503 paired_init_builtins (void)
11505 const struct builtin_description *d;
11507 tree endlink = void_list_node;
11509 tree int_ftype_int_v2sf_v2sf
11510 = build_function_type
11511 (integer_type_node,
11512 tree_cons (NULL_TREE, integer_type_node,
11513 tree_cons (NULL_TREE, V2SF_type_node,
11514 tree_cons (NULL_TREE, V2SF_type_node,
11516 tree pcfloat_type_node =
11517 build_pointer_type (build_qualified_type
11518 (float_type_node, TYPE_QUAL_CONST));
11520 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
11521 long_integer_type_node,
11524 tree void_ftype_v2sf_long_pcfloat =
11525 build_function_type_list (void_type_node,
11527 long_integer_type_node,
11532 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
11533 PAIRED_BUILTIN_LX);
11536 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
11537 PAIRED_BUILTIN_STX);
11540 d = bdesc_paired_preds;
11541 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
11545 switch (insn_data[d->icode].operand[1].mode)
11548 type = int_ftype_int_v2sf_v2sf;
11551 gcc_unreachable ();
11554 def_builtin (d->mask, d->name, type, d->code);
11559 altivec_init_builtins (void)
11561 const struct builtin_description *d;
11562 const struct builtin_description_predicates *dp;
11566 tree pfloat_type_node = build_pointer_type (float_type_node);
11567 tree pint_type_node = build_pointer_type (integer_type_node);
11568 tree pshort_type_node = build_pointer_type (short_integer_type_node);
11569 tree pchar_type_node = build_pointer_type (char_type_node);
11571 tree pvoid_type_node = build_pointer_type (void_type_node);
11573 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
11574 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
11575 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
11576 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
11578 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
11580 tree int_ftype_opaque
11581 = build_function_type_list (integer_type_node,
11582 opaque_V4SI_type_node, NULL_TREE);
11583 tree opaque_ftype_opaque
11584 = build_function_type (integer_type_node,
11586 tree opaque_ftype_opaque_int
11587 = build_function_type_list (opaque_V4SI_type_node,
11588 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
11589 tree opaque_ftype_opaque_opaque_int
11590 = build_function_type_list (opaque_V4SI_type_node,
11591 opaque_V4SI_type_node, opaque_V4SI_type_node,
11592 integer_type_node, NULL_TREE);
11593 tree int_ftype_int_opaque_opaque
11594 = build_function_type_list (integer_type_node,
11595 integer_type_node, opaque_V4SI_type_node,
11596 opaque_V4SI_type_node, NULL_TREE);
11597 tree int_ftype_int_v4si_v4si
11598 = build_function_type_list (integer_type_node,
11599 integer_type_node, V4SI_type_node,
11600 V4SI_type_node, NULL_TREE);
11601 tree v4sf_ftype_pcfloat
11602 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
11603 tree void_ftype_pfloat_v4sf
11604 = build_function_type_list (void_type_node,
11605 pfloat_type_node, V4SF_type_node, NULL_TREE);
11606 tree v4si_ftype_pcint
11607 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
11608 tree void_ftype_pint_v4si
11609 = build_function_type_list (void_type_node,
11610 pint_type_node, V4SI_type_node, NULL_TREE);
11611 tree v8hi_ftype_pcshort
11612 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
11613 tree void_ftype_pshort_v8hi
11614 = build_function_type_list (void_type_node,
11615 pshort_type_node, V8HI_type_node, NULL_TREE);
11616 tree v16qi_ftype_pcchar
11617 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
11618 tree void_ftype_pchar_v16qi
11619 = build_function_type_list (void_type_node,
11620 pchar_type_node, V16QI_type_node, NULL_TREE);
11621 tree void_ftype_v4si
11622 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
11623 tree v8hi_ftype_void
11624 = build_function_type (V8HI_type_node, void_list_node);
11625 tree void_ftype_void
11626 = build_function_type (void_type_node, void_list_node);
11627 tree void_ftype_int
11628 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
11630 tree opaque_ftype_long_pcvoid
11631 = build_function_type_list (opaque_V4SI_type_node,
11632 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11633 tree v16qi_ftype_long_pcvoid
11634 = build_function_type_list (V16QI_type_node,
11635 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11636 tree v8hi_ftype_long_pcvoid
11637 = build_function_type_list (V8HI_type_node,
11638 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11639 tree v4si_ftype_long_pcvoid
11640 = build_function_type_list (V4SI_type_node,
11641 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11643 tree void_ftype_opaque_long_pvoid
11644 = build_function_type_list (void_type_node,
11645 opaque_V4SI_type_node, long_integer_type_node,
11646 pvoid_type_node, NULL_TREE);
11647 tree void_ftype_v4si_long_pvoid
11648 = build_function_type_list (void_type_node,
11649 V4SI_type_node, long_integer_type_node,
11650 pvoid_type_node, NULL_TREE);
11651 tree void_ftype_v16qi_long_pvoid
11652 = build_function_type_list (void_type_node,
11653 V16QI_type_node, long_integer_type_node,
11654 pvoid_type_node, NULL_TREE);
11655 tree void_ftype_v8hi_long_pvoid
11656 = build_function_type_list (void_type_node,
11657 V8HI_type_node, long_integer_type_node,
11658 pvoid_type_node, NULL_TREE);
11659 tree int_ftype_int_v8hi_v8hi
11660 = build_function_type_list (integer_type_node,
11661 integer_type_node, V8HI_type_node,
11662 V8HI_type_node, NULL_TREE);
11663 tree int_ftype_int_v16qi_v16qi
11664 = build_function_type_list (integer_type_node,
11665 integer_type_node, V16QI_type_node,
11666 V16QI_type_node, NULL_TREE);
11667 tree int_ftype_int_v4sf_v4sf
11668 = build_function_type_list (integer_type_node,
11669 integer_type_node, V4SF_type_node,
11670 V4SF_type_node, NULL_TREE);
11671 tree int_ftype_int_v2df_v2df
11672 = build_function_type_list (integer_type_node,
11673 integer_type_node, V2DF_type_node,
11674 V2DF_type_node, NULL_TREE);
11675 tree v4si_ftype_v4si
11676 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
11677 tree v8hi_ftype_v8hi
11678 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
11679 tree v16qi_ftype_v16qi
11680 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
11681 tree v4sf_ftype_v4sf
11682 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
11683 tree v2df_ftype_v2df
11684 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
11685 tree void_ftype_pcvoid_int_int
11686 = build_function_type_list (void_type_node,
11687 pcvoid_type_node, integer_type_node,
11688 integer_type_node, NULL_TREE);
11690 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
11691 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
11692 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
11693 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
11694 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
11695 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
11696 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
11697 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
11698 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
11699 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
11700 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
11701 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
11702 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
11703 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
11704 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
11705 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
11706 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
11707 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
11708 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
11709 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
11710 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
11711 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
11712 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
11713 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
11714 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
11715 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
11716 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
11717 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
11718 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
11719 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
11720 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
11721 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
11722 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
11723 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
11724 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
11725 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
11726 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
11727 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
11728 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
11729 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
11730 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
11731 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
11732 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
11733 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
11734 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
11735 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
11737 if (rs6000_cpu == PROCESSOR_CELL)
11739 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
11740 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
11741 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
11742 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
11744 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
11745 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
11746 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
11747 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
11749 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
11750 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
11751 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
11752 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
11754 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
11755 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
11756 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
11757 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
11759 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
11760 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
11761 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
11763 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
11764 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
11765 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
11766 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
11767 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
11768 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
11769 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
11770 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
11771 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
11772 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
11773 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
11774 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
11776 /* Add the DST variants. */
11778 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11779 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
11781 /* Initialize the predicates. */
11782 dp = bdesc_altivec_preds;
11783 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11785 enum machine_mode mode1;
11787 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11788 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11789 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
11790 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
11795 mode1 = insn_data[dp->icode].operand[1].mode;
11800 type = int_ftype_int_opaque_opaque;
11803 type = int_ftype_int_v4si_v4si;
11806 type = int_ftype_int_v8hi_v8hi;
11809 type = int_ftype_int_v16qi_v16qi;
11812 type = int_ftype_int_v4sf_v4sf;
11815 type = int_ftype_int_v2df_v2df;
11818 gcc_unreachable ();
11821 def_builtin (dp->mask, dp->name, type, dp->code);
11824 /* Initialize the abs* operators. */
11826 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11828 enum machine_mode mode0;
11831 mode0 = insn_data[d->icode].operand[0].mode;
11836 type = v4si_ftype_v4si;
11839 type = v8hi_ftype_v8hi;
11842 type = v16qi_ftype_v16qi;
11845 type = v4sf_ftype_v4sf;
11848 type = v2df_ftype_v2df;
11851 gcc_unreachable ();
11854 def_builtin (d->mask, d->name, type, d->code);
11857 if (TARGET_ALTIVEC)
11861 /* Initialize target builtin that implements
11862 targetm.vectorize.builtin_mask_for_load. */
11864 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
11865 v16qi_ftype_long_pcvoid,
11866 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
11867 BUILT_IN_MD, NULL, NULL_TREE);
11868 TREE_READONLY (decl) = 1;
11869 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
11870 altivec_builtin_mask_for_load = decl;
11873 /* Access to the vec_init patterns. */
11874 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
11875 integer_type_node, integer_type_node,
11876 integer_type_node, NULL_TREE);
11877 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
11878 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
11880 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
11881 short_integer_type_node,
11882 short_integer_type_node,
11883 short_integer_type_node,
11884 short_integer_type_node,
11885 short_integer_type_node,
11886 short_integer_type_node,
11887 short_integer_type_node, NULL_TREE);
11888 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
11889 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
11891 ftype = build_function_type_list (V16QI_type_node, char_type_node,
11892 char_type_node, char_type_node,
11893 char_type_node, char_type_node,
11894 char_type_node, char_type_node,
11895 char_type_node, char_type_node,
11896 char_type_node, char_type_node,
11897 char_type_node, char_type_node,
11898 char_type_node, char_type_node,
11899 char_type_node, NULL_TREE);
11900 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
11901 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
11903 ftype = build_function_type_list (V4SF_type_node, float_type_node,
11904 float_type_node, float_type_node,
11905 float_type_node, NULL_TREE);
11906 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
11907 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
11911 ftype = build_function_type_list (V2DF_type_node, double_type_node,
11912 double_type_node, NULL_TREE);
11913 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
11914 VSX_BUILTIN_VEC_INIT_V2DF);
11916 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
11917 intDI_type_node, NULL_TREE);
11918 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
11919 VSX_BUILTIN_VEC_INIT_V2DI);
11922 /* Access to the vec_set patterns. */
11923 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
11925 integer_type_node, NULL_TREE);
11926 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
11927 ALTIVEC_BUILTIN_VEC_SET_V4SI);
11929 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
11931 integer_type_node, NULL_TREE);
11932 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
11933 ALTIVEC_BUILTIN_VEC_SET_V8HI);
11935 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
11937 integer_type_node, NULL_TREE);
11938 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
11939 ALTIVEC_BUILTIN_VEC_SET_V16QI);
11941 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
11943 integer_type_node, NULL_TREE);
11944 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
11945 ALTIVEC_BUILTIN_VEC_SET_V4SF);
11949 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
11951 integer_type_node, NULL_TREE);
11952 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
11953 VSX_BUILTIN_VEC_SET_V2DF);
11955 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
11957 integer_type_node, NULL_TREE);
11958 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
11959 VSX_BUILTIN_VEC_SET_V2DI);
11962 /* Access to the vec_extract patterns. */
11963 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
11964 integer_type_node, NULL_TREE);
11965 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
11966 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
11968 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
11969 integer_type_node, NULL_TREE);
11970 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
11971 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
11973 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
11974 integer_type_node, NULL_TREE);
11975 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
11976 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
11978 ftype = build_function_type_list (float_type_node, V4SF_type_node,
11979 integer_type_node, NULL_TREE);
11980 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
11981 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
11985 ftype = build_function_type_list (double_type_node, V2DF_type_node,
11986 integer_type_node, NULL_TREE);
11987 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
11988 VSX_BUILTIN_VEC_EXT_V2DF);
11990 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
11991 integer_type_node, NULL_TREE);
11992 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
11993 VSX_BUILTIN_VEC_EXT_V2DI);
11997 /* Hash function for builtin functions with up to 3 arguments and a return
12000 builtin_hash_function (const void *hash_entry)
12004 const struct builtin_hash_struct *bh =
12005 (const struct builtin_hash_struct *) hash_entry;
12007 for (i = 0; i < 4; i++)
12009 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12010 ret = (ret * 2) + bh->uns_p[i];
12016 /* Compare builtin hash entries H1 and H2 for equivalence. */
12018 builtin_hash_eq (const void *h1, const void *h2)
12020 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12021 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
12023 return ((p1->mode[0] == p2->mode[0])
12024 && (p1->mode[1] == p2->mode[1])
12025 && (p1->mode[2] == p2->mode[2])
12026 && (p1->mode[3] == p2->mode[3])
12027 && (p1->uns_p[0] == p2->uns_p[0])
12028 && (p1->uns_p[1] == p2->uns_p[1])
12029 && (p1->uns_p[2] == p2->uns_p[2])
12030 && (p1->uns_p[3] == p2->uns_p[3]));
12033 /* Map types for builtin functions with an explicit return type and up to 3
12034 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12035 of the argument. */
12037 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
12038 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
12039 enum rs6000_builtins builtin, const char *name)
12041 struct builtin_hash_struct h;
12042 struct builtin_hash_struct *h2;
12046 tree ret_type = NULL_TREE;
12047 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
12050 /* Create builtin_hash_table. */
12051 if (builtin_hash_table == NULL)
12052 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
12053 builtin_hash_eq, NULL);
12055 h.type = NULL_TREE;
12056 h.mode[0] = mode_ret;
12057 h.mode[1] = mode_arg0;
12058 h.mode[2] = mode_arg1;
12059 h.mode[3] = mode_arg2;
12065 /* If the builtin is a type that produces unsigned results or takes unsigned
12066 arguments, and it is returned as a decl for the vectorizer (such as
12067 widening multiplies, permute), make sure the arguments and return value
12068 are type correct. */
12071 /* unsigned 2 argument functions. */
12072 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12073 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12074 case ALTIVEC_BUILTIN_VMULOUB_UNS:
12075 case ALTIVEC_BUILTIN_VMULOUH_UNS:
12081 /* unsigned 3 argument functions. */
12082 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
12083 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
12084 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
12085 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
12086 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
12087 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
12088 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
12089 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
12090 case VSX_BUILTIN_VPERM_16QI_UNS:
12091 case VSX_BUILTIN_VPERM_8HI_UNS:
12092 case VSX_BUILTIN_VPERM_4SI_UNS:
12093 case VSX_BUILTIN_VPERM_2DI_UNS:
12094 case VSX_BUILTIN_XXSEL_16QI_UNS:
12095 case VSX_BUILTIN_XXSEL_8HI_UNS:
12096 case VSX_BUILTIN_XXSEL_4SI_UNS:
12097 case VSX_BUILTIN_XXSEL_2DI_UNS:
12104 /* signed permute functions with unsigned char mask. */
12105 case ALTIVEC_BUILTIN_VPERM_16QI:
12106 case ALTIVEC_BUILTIN_VPERM_8HI:
12107 case ALTIVEC_BUILTIN_VPERM_4SI:
12108 case ALTIVEC_BUILTIN_VPERM_4SF:
12109 case ALTIVEC_BUILTIN_VPERM_2DI:
12110 case ALTIVEC_BUILTIN_VPERM_2DF:
12111 case VSX_BUILTIN_VPERM_16QI:
12112 case VSX_BUILTIN_VPERM_8HI:
12113 case VSX_BUILTIN_VPERM_4SI:
12114 case VSX_BUILTIN_VPERM_4SF:
12115 case VSX_BUILTIN_VPERM_2DI:
12116 case VSX_BUILTIN_VPERM_2DF:
12120 /* unsigned args, signed return. */
12121 case VSX_BUILTIN_XVCVUXDDP_UNS:
12122 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12126 /* signed args, unsigned return. */
12127 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12128 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12136 /* Figure out how many args are present. */
12137 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12141 fatal_error ("internal error: builtin function %s had no type", name);
12143 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12144 if (!ret_type && h.uns_p[0])
12145 ret_type = builtin_mode_to_type[h.mode[0]][0];
12148 fatal_error ("internal error: builtin function %s had an unexpected "
12149 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12151 for (i = 0; i < num_args; i++)
12153 int m = (int) h.mode[i+1];
12154 int uns_p = h.uns_p[i+1];
12156 arg_type[i] = builtin_mode_to_type[m][uns_p];
12157 if (!arg_type[i] && uns_p)
12158 arg_type[i] = builtin_mode_to_type[m][0];
12161 fatal_error ("internal error: builtin function %s, argument %d "
12162 "had unexpected argument type %s", name, i,
12163 GET_MODE_NAME (m));
12166 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12167 if (*found == NULL)
12169 h2 = GGC_NEW (struct builtin_hash_struct);
12171 *found = (void *)h2;
12172 args = void_list_node;
12174 for (i = num_args - 1; i >= 0; i--)
12175 args = tree_cons (NULL_TREE, arg_type[i], args);
12177 h2->type = build_function_type (ret_type, args);
12180 return ((struct builtin_hash_struct *)(*found))->type;
12184 rs6000_common_init_builtins (void)
12186 const struct builtin_description *d;
12189 tree opaque_ftype_opaque = NULL_TREE;
12190 tree opaque_ftype_opaque_opaque = NULL_TREE;
12191 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12192 tree v2si_ftype_qi = NULL_TREE;
12193 tree v2si_ftype_v2si_qi = NULL_TREE;
12194 tree v2si_ftype_int_qi = NULL_TREE;
12196 if (!TARGET_PAIRED_FLOAT)
12198 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12199 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12202 /* Add the ternary operators. */
12204 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12207 int mask = d->mask;
12209 if ((mask != 0 && (mask & target_flags) == 0)
12210 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12213 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12214 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12215 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12216 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12218 if (! (type = opaque_ftype_opaque_opaque_opaque))
12219 type = opaque_ftype_opaque_opaque_opaque
12220 = build_function_type_list (opaque_V4SI_type_node,
12221 opaque_V4SI_type_node,
12222 opaque_V4SI_type_node,
12223 opaque_V4SI_type_node,
12228 enum insn_code icode = d->icode;
12229 if (d->name == 0 || icode == CODE_FOR_nothing)
12232 type = builtin_function_type (insn_data[icode].operand[0].mode,
12233 insn_data[icode].operand[1].mode,
12234 insn_data[icode].operand[2].mode,
12235 insn_data[icode].operand[3].mode,
12239 def_builtin (d->mask, d->name, type, d->code);
12242 /* Add the binary operators. */
12244 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12246 enum machine_mode mode0, mode1, mode2;
12248 int mask = d->mask;
12250 if ((mask != 0 && (mask & target_flags) == 0)
12251 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12254 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12255 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12256 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12257 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12259 if (! (type = opaque_ftype_opaque_opaque))
12260 type = opaque_ftype_opaque_opaque
12261 = build_function_type_list (opaque_V4SI_type_node,
12262 opaque_V4SI_type_node,
12263 opaque_V4SI_type_node,
12268 enum insn_code icode = d->icode;
12269 if (d->name == 0 || icode == CODE_FOR_nothing)
12272 mode0 = insn_data[icode].operand[0].mode;
12273 mode1 = insn_data[icode].operand[1].mode;
12274 mode2 = insn_data[icode].operand[2].mode;
12276 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12278 if (! (type = v2si_ftype_v2si_qi))
12279 type = v2si_ftype_v2si_qi
12280 = build_function_type_list (opaque_V2SI_type_node,
12281 opaque_V2SI_type_node,
12286 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12287 && mode2 == QImode)
12289 if (! (type = v2si_ftype_int_qi))
12290 type = v2si_ftype_int_qi
12291 = build_function_type_list (opaque_V2SI_type_node,
12298 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12302 def_builtin (d->mask, d->name, type, d->code);
12305 /* Add the simple unary operators. */
12306 d = (struct builtin_description *) bdesc_1arg;
12307 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12309 enum machine_mode mode0, mode1;
12311 int mask = d->mask;
12313 if ((mask != 0 && (mask & target_flags) == 0)
12314 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12317 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12318 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12319 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12320 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12322 if (! (type = opaque_ftype_opaque))
12323 type = opaque_ftype_opaque
12324 = build_function_type_list (opaque_V4SI_type_node,
12325 opaque_V4SI_type_node,
12330 enum insn_code icode = d->icode;
12331 if (d->name == 0 || icode == CODE_FOR_nothing)
12334 mode0 = insn_data[icode].operand[0].mode;
12335 mode1 = insn_data[icode].operand[1].mode;
12337 if (mode0 == V2SImode && mode1 == QImode)
12339 if (! (type = v2si_ftype_qi))
12340 type = v2si_ftype_qi
12341 = build_function_type_list (opaque_V2SI_type_node,
12347 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12351 def_builtin (d->mask, d->name, type, d->code);
12356 rs6000_init_libfuncs (void)
12358 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12359 && !TARGET_POWER2 && !TARGET_POWERPC)
12361 /* AIX library routines for float->int conversion. */
12362 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12363 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12364 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12365 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12368 if (!TARGET_IEEEQUAD)
12369 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12370 if (!TARGET_XL_COMPAT)
12372 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12373 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12374 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12375 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12377 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12379 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12380 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12381 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12382 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12383 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12384 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12385 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12387 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12388 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12389 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12390 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12391 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12392 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12393 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12394 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12397 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12398 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12402 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12403 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12404 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12405 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12409 /* 32-bit SVR4 quad floating point routines. */
12411 set_optab_libfunc (add_optab, TFmode, "_q_add");
12412 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12413 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12414 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12415 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12416 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12417 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12419 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12420 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12421 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12422 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12423 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12424 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12426 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12427 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12428 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12429 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12430 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12431 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12432 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12433 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12438 /* Expand a block clear operation, and return 1 if successful. Return 0
12439 if we should let the compiler generate normal code.
12441 operands[0] is the destination
12442 operands[1] is the length
12443 operands[3] is the alignment */
12446 expand_block_clear (rtx operands[])
12448 rtx orig_dest = operands[0];
12449 rtx bytes_rtx = operands[1];
12450 rtx align_rtx = operands[3];
12451 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12452 HOST_WIDE_INT align;
12453 HOST_WIDE_INT bytes;
12458 /* If this is not a fixed size move, just call memcpy */
12462 /* This must be a fixed size alignment */
12463 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12464 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12466 /* Anything to clear? */
12467 bytes = INTVAL (bytes_rtx);
12471 /* Use the builtin memset after a point, to avoid huge code bloat.
12472 When optimize_size, avoid any significant code bloat; calling
12473 memset is about 4 instructions, so allow for one instruction to
12474 load zero and three to do clearing. */
12475 if (TARGET_ALTIVEC && align >= 128)
12477 else if (TARGET_POWERPC64 && align >= 32)
12479 else if (TARGET_SPE && align >= 64)
12484 if (optimize_size && bytes > 3 * clear_step)
12486 if (! optimize_size && bytes > 8 * clear_step)
12489 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12491 enum machine_mode mode = BLKmode;
12494 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
12499 else if (bytes >= 8 && TARGET_SPE && align >= 64)
12504 else if (bytes >= 8 && TARGET_POWERPC64
12505 /* 64-bit loads and stores require word-aligned
12507 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12512 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12513 { /* move 4 bytes */
12517 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12518 { /* move 2 bytes */
12522 else /* move 1 byte at a time */
12528 dest = adjust_address (orig_dest, mode, offset);
12530 emit_move_insn (dest, CONST0_RTX (mode));
12537 /* Expand a block move operation, and return 1 if successful. Return 0
12538 if we should let the compiler generate normal code.
12540 operands[0] is the destination
12541 operands[1] is the source
12542 operands[2] is the length
12543 operands[3] is the alignment */
12545 #define MAX_MOVE_REG 4
12548 expand_block_move (rtx operands[])
12550 rtx orig_dest = operands[0];
12551 rtx orig_src = operands[1];
12552 rtx bytes_rtx = operands[2];
12553 rtx align_rtx = operands[3];
12554 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
12559 rtx stores[MAX_MOVE_REG];
12562 /* If this is not a fixed size move, just call memcpy */
12566 /* This must be a fixed size alignment */
12567 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12568 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12570 /* Anything to move? */
12571 bytes = INTVAL (bytes_rtx);
12575 /* store_one_arg depends on expand_block_move to handle at least the size of
12576 reg_parm_stack_space. */
12577 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
12580 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
12583 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
12584 rtx (*mov) (rtx, rtx);
12586 enum machine_mode mode = BLKmode;
12589 /* Altivec first, since it will be faster than a string move
12590 when it applies, and usually not significantly larger. */
12591 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
12595 gen_func.mov = gen_movv4si;
12597 else if (TARGET_SPE && bytes >= 8 && align >= 64)
12601 gen_func.mov = gen_movv2si;
12603 else if (TARGET_STRING
12604 && bytes > 24 /* move up to 32 bytes at a time */
12610 && ! fixed_regs[10]
12611 && ! fixed_regs[11]
12612 && ! fixed_regs[12])
12614 move_bytes = (bytes > 32) ? 32 : bytes;
12615 gen_func.movmemsi = gen_movmemsi_8reg;
12617 else if (TARGET_STRING
12618 && bytes > 16 /* move up to 24 bytes at a time */
12624 && ! fixed_regs[10])
12626 move_bytes = (bytes > 24) ? 24 : bytes;
12627 gen_func.movmemsi = gen_movmemsi_6reg;
12629 else if (TARGET_STRING
12630 && bytes > 8 /* move up to 16 bytes at a time */
12634 && ! fixed_regs[8])
12636 move_bytes = (bytes > 16) ? 16 : bytes;
12637 gen_func.movmemsi = gen_movmemsi_4reg;
12639 else if (bytes >= 8 && TARGET_POWERPC64
12640 /* 64-bit loads and stores require word-aligned
12642 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12646 gen_func.mov = gen_movdi;
12648 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
12649 { /* move up to 8 bytes at a time */
12650 move_bytes = (bytes > 8) ? 8 : bytes;
12651 gen_func.movmemsi = gen_movmemsi_2reg;
12653 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12654 { /* move 4 bytes */
12657 gen_func.mov = gen_movsi;
12659 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12660 { /* move 2 bytes */
12663 gen_func.mov = gen_movhi;
12665 else if (TARGET_STRING && bytes > 1)
12666 { /* move up to 4 bytes at a time */
12667 move_bytes = (bytes > 4) ? 4 : bytes;
12668 gen_func.movmemsi = gen_movmemsi_1reg;
12670 else /* move 1 byte at a time */
12674 gen_func.mov = gen_movqi;
12677 src = adjust_address (orig_src, mode, offset);
12678 dest = adjust_address (orig_dest, mode, offset);
12680 if (mode != BLKmode)
12682 rtx tmp_reg = gen_reg_rtx (mode);
12684 emit_insn ((*gen_func.mov) (tmp_reg, src));
12685 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
12688 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
12691 for (i = 0; i < num_reg; i++)
12692 emit_insn (stores[i]);
12696 if (mode == BLKmode)
12698 /* Move the address into scratch registers. The movmemsi
12699 patterns require zero offset. */
12700 if (!REG_P (XEXP (src, 0)))
12702 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
12703 src = replace_equiv_address (src, src_reg);
12705 set_mem_size (src, GEN_INT (move_bytes));
12707 if (!REG_P (XEXP (dest, 0)))
12709 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
12710 dest = replace_equiv_address (dest, dest_reg);
12712 set_mem_size (dest, GEN_INT (move_bytes));
12714 emit_insn ((*gen_func.movmemsi) (dest, src,
12715 GEN_INT (move_bytes & 31),
12724 /* Return a string to perform a load_multiple operation.
12725 operands[0] is the vector.
12726 operands[1] is the source address.
12727 operands[2] is the first destination register. */
12730 rs6000_output_load_multiple (rtx operands[3])
12732 /* We have to handle the case where the pseudo used to contain the address
12733 is assigned to one of the output registers. */
12735 int words = XVECLEN (operands[0], 0);
12738 if (XVECLEN (operands[0], 0) == 1)
12739 return "{l|lwz} %2,0(%1)";
12741 for (i = 0; i < words; i++)
12742 if (refers_to_regno_p (REGNO (operands[2]) + i,
12743 REGNO (operands[2]) + i + 1, operands[1], 0))
12747 xop[0] = GEN_INT (4 * (words-1));
12748 xop[1] = operands[1];
12749 xop[2] = operands[2];
12750 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
12755 xop[0] = GEN_INT (4 * (words-1));
12756 xop[1] = operands[1];
12757 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
12758 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);
12763 for (j = 0; j < words; j++)
12766 xop[0] = GEN_INT (j * 4);
12767 xop[1] = operands[1];
12768 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
12769 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
12771 xop[0] = GEN_INT (i * 4);
12772 xop[1] = operands[1];
12773 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
12778 return "{lsi|lswi} %2,%1,%N0";
12782 /* A validation routine: say whether CODE, a condition code, and MODE
12783 match. The other alternatives either don't make sense or should
12784 never be generated. */
12787 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
12789 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
12790 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
12791 && GET_MODE_CLASS (mode) == MODE_CC);
12793 /* These don't make sense. */
12794 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
12795 || mode != CCUNSmode);
12797 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
12798 || mode == CCUNSmode);
12800 gcc_assert (mode == CCFPmode
12801 || (code != ORDERED && code != UNORDERED
12802 && code != UNEQ && code != LTGT
12803 && code != UNGT && code != UNLT
12804 && code != UNGE && code != UNLE));
12806 /* These should never be generated except for
12807 flag_finite_math_only. */
12808 gcc_assert (mode != CCFPmode
12809 || flag_finite_math_only
12810 || (code != LE && code != GE
12811 && code != UNEQ && code != LTGT
12812 && code != UNGT && code != UNLT));
12814 /* These are invalid; the information is not there. */
12815 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
12819 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
12820 mask required to convert the result of a rotate insn into a shift
12821 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
12824 includes_lshift_p (rtx shiftop, rtx andop)
12826 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12828 shift_mask <<= INTVAL (shiftop);
12830 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12833 /* Similar, but for right shift. */
12836 includes_rshift_p (rtx shiftop, rtx andop)
12838 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12840 shift_mask >>= INTVAL (shiftop);
12842 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12845 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
12846 to perform a left shift. It must have exactly SHIFTOP least
12847 significant 0's, then one or more 1's, then zero or more 0's. */
12850 includes_rldic_lshift_p (rtx shiftop, rtx andop)
12852 if (GET_CODE (andop) == CONST_INT)
12854 HOST_WIDE_INT c, lsb, shift_mask;
12856 c = INTVAL (andop);
12857 if (c == 0 || c == ~0)
12861 shift_mask <<= INTVAL (shiftop);
12863 /* Find the least significant one bit. */
12866 /* It must coincide with the LSB of the shift mask. */
12867 if (-lsb != shift_mask)
12870 /* Invert to look for the next transition (if any). */
12873 /* Remove the low group of ones (originally low group of zeros). */
12876 /* Again find the lsb, and check we have all 1's above. */
12880 else if (GET_CODE (andop) == CONST_DOUBLE
12881 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12883 HOST_WIDE_INT low, high, lsb;
12884 HOST_WIDE_INT shift_mask_low, shift_mask_high;
12886 low = CONST_DOUBLE_LOW (andop);
12887 if (HOST_BITS_PER_WIDE_INT < 64)
12888 high = CONST_DOUBLE_HIGH (andop);
12890 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
12891 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
12894 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12896 shift_mask_high = ~0;
12897 if (INTVAL (shiftop) > 32)
12898 shift_mask_high <<= INTVAL (shiftop) - 32;
12900 lsb = high & -high;
12902 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
12908 lsb = high & -high;
12909 return high == -lsb;
12912 shift_mask_low = ~0;
12913 shift_mask_low <<= INTVAL (shiftop);
12917 if (-lsb != shift_mask_low)
12920 if (HOST_BITS_PER_WIDE_INT < 64)
12925 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12927 lsb = high & -high;
12928 return high == -lsb;
12932 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
12938 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
12939 to perform a left shift. It must have SHIFTOP or more least
12940 significant 0's, with the remainder of the word 1's. */
12943 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
12945 if (GET_CODE (andop) == CONST_INT)
12947 HOST_WIDE_INT c, lsb, shift_mask;
12950 shift_mask <<= INTVAL (shiftop);
12951 c = INTVAL (andop);
12953 /* Find the least significant one bit. */
12956 /* It must be covered by the shift mask.
12957 This test also rejects c == 0. */
12958 if ((lsb & shift_mask) == 0)
12961 /* Check we have all 1's above the transition, and reject all 1's. */
12962 return c == -lsb && lsb != 1;
12964 else if (GET_CODE (andop) == CONST_DOUBLE
12965 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12967 HOST_WIDE_INT low, lsb, shift_mask_low;
12969 low = CONST_DOUBLE_LOW (andop);
12971 if (HOST_BITS_PER_WIDE_INT < 64)
12973 HOST_WIDE_INT high, shift_mask_high;
12975 high = CONST_DOUBLE_HIGH (andop);
12979 shift_mask_high = ~0;
12980 if (INTVAL (shiftop) > 32)
12981 shift_mask_high <<= INTVAL (shiftop) - 32;
12983 lsb = high & -high;
12985 if ((lsb & shift_mask_high) == 0)
12988 return high == -lsb;
12994 shift_mask_low = ~0;
12995 shift_mask_low <<= INTVAL (shiftop);
12999 if ((lsb & shift_mask_low) == 0)
13002 return low == -lsb && lsb != 1;
13008 /* Return 1 if operands will generate a valid arguments to rlwimi
13009 instruction for insert with right shift in 64-bit mode. The mask may
13010 not start on the first bit or stop on the last bit because wrap-around
13011 effects of instruction do not correspond to semantics of RTL insn. */
13014 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13016 if (INTVAL (startop) > 32
13017 && INTVAL (startop) < 64
13018 && INTVAL (sizeop) > 1
13019 && INTVAL (sizeop) + INTVAL (startop) < 64
13020 && INTVAL (shiftop) > 0
13021 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13022 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
13028 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13029 for lfq and stfq insns iff the registers are hard registers. */
13032 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
13034 /* We might have been passed a SUBREG. */
13035 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
13038 /* We might have been passed non floating point registers. */
13039 if (!FP_REGNO_P (REGNO (reg1))
13040 || !FP_REGNO_P (REGNO (reg2)))
13043 return (REGNO (reg1) == REGNO (reg2) - 1);
13046 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13047 addr1 and addr2 must be in consecutive memory locations
13048 (addr2 == addr1 + 8). */
13051 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
13054 unsigned int reg1, reg2;
13055 int offset1, offset2;
13057 /* The mems cannot be volatile. */
13058 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
13061 addr1 = XEXP (mem1, 0);
13062 addr2 = XEXP (mem2, 0);
13064 /* Extract an offset (if used) from the first addr. */
13065 if (GET_CODE (addr1) == PLUS)
13067 /* If not a REG, return zero. */
13068 if (GET_CODE (XEXP (addr1, 0)) != REG)
13072 reg1 = REGNO (XEXP (addr1, 0));
13073 /* The offset must be constant! */
13074 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13076 offset1 = INTVAL (XEXP (addr1, 1));
13079 else if (GET_CODE (addr1) != REG)
13083 reg1 = REGNO (addr1);
13084 /* This was a simple (mem (reg)) expression. Offset is 0. */
13088 /* And now for the second addr. */
13089 if (GET_CODE (addr2) == PLUS)
13091 /* If not a REG, return zero. */
13092 if (GET_CODE (XEXP (addr2, 0)) != REG)
13096 reg2 = REGNO (XEXP (addr2, 0));
13097 /* The offset must be constant. */
13098 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
13100 offset2 = INTVAL (XEXP (addr2, 1));
13103 else if (GET_CODE (addr2) != REG)
13107 reg2 = REGNO (addr2);
13108 /* This was a simple (mem (reg)) expression. Offset is 0. */
13112 /* Both of these must have the same base register. */
13116 /* The offset for the second addr must be 8 more than the first addr. */
13117 if (offset2 != offset1 + 8)
13120 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13127 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13129 static bool eliminated = false;
13132 if (mode != SDmode)
13133 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13136 rtx mem = cfun->machine->sdmode_stack_slot;
13137 gcc_assert (mem != NULL_RTX);
13141 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13142 cfun->machine->sdmode_stack_slot = mem;
13148 if (TARGET_DEBUG_ADDR)
13150 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13151 GET_MODE_NAME (mode));
13153 fprintf (stderr, "\tNULL_RTX\n");
13162 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13164 /* Don't walk into types. */
13165 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13167 *walk_subtrees = 0;
13171 switch (TREE_CODE (*tp))
13180 case ALIGN_INDIRECT_REF:
13181 case MISALIGNED_INDIRECT_REF:
13182 case VIEW_CONVERT_EXPR:
13183 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13193 enum reload_reg_type {
13195 VECTOR_REGISTER_TYPE,
13196 OTHER_REGISTER_TYPE
13199 static enum reload_reg_type
13200 rs6000_reload_register_type (enum reg_class rclass)
13206 return GPR_REGISTER_TYPE;
13211 return VECTOR_REGISTER_TYPE;
13214 return OTHER_REGISTER_TYPE;
13218 /* Inform reload about cases where moving X with a mode MODE to a register in
13219 RCLASS requires an extra scratch or immediate register. Return the class
13220 needed for the immediate register.
13222 For VSX and Altivec, we may need a register to convert sp+offset into
13225 static enum reg_class
13226 rs6000_secondary_reload (bool in_p,
13228 enum reg_class rclass,
13229 enum machine_mode mode,
13230 secondary_reload_info *sri)
13232 enum reg_class ret = ALL_REGS;
13233 enum insn_code icode;
13234 bool default_p = false;
13236 sri->icode = CODE_FOR_nothing;
13238 /* Convert vector loads and stores into gprs to use an additional base
13240 icode = rs6000_vector_reload[mode][in_p != false];
13241 if (icode != CODE_FOR_nothing)
13244 sri->icode = CODE_FOR_nothing;
13245 sri->extra_cost = 0;
13247 if (GET_CODE (x) == MEM)
13249 rtx addr = XEXP (x, 0);
13251 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13252 an extra register in that case, but it would need an extra
13253 register if the addressing is reg+reg or (reg+reg)&(-16). */
13254 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13256 if (!legitimate_indirect_address_p (addr, false)
13257 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13259 sri->icode = icode;
13260 /* account for splitting the loads, and converting the
13261 address from reg+reg to reg. */
13262 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13263 + ((GET_CODE (addr) == AND) ? 1 : 0));
13266 /* Loads to and stores from vector registers can only do reg+reg
13267 addressing. Altivec registers can also do (reg+reg)&(-16). */
13268 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13269 || rclass == FLOAT_REGS || rclass == NO_REGS)
13271 if (!VECTOR_MEM_ALTIVEC_P (mode)
13272 && GET_CODE (addr) == AND
13273 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13274 && INTVAL (XEXP (addr, 1)) == -16
13275 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13276 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13278 sri->icode = icode;
13279 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13282 else if (!legitimate_indirect_address_p (addr, false)
13283 && (rclass == NO_REGS
13284 || !legitimate_indexed_address_p (addr, false)))
13286 sri->icode = icode;
13287 sri->extra_cost = 1;
13290 icode = CODE_FOR_nothing;
13292 /* Any other loads, including to pseudo registers which haven't been
13293 assigned to a register yet, default to require a scratch
13297 sri->icode = icode;
13298 sri->extra_cost = 2;
13301 else if (REG_P (x))
13303 int regno = true_regnum (x);
13305 icode = CODE_FOR_nothing;
13306 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13310 enum reg_class xclass = REGNO_REG_CLASS (regno);
13311 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13312 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13314 /* If memory is needed, use default_secondary_reload to create the
13316 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13329 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13331 gcc_assert (ret != ALL_REGS);
13333 if (TARGET_DEBUG_ADDR)
13336 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13338 reg_class_names[ret],
13339 in_p ? "true" : "false",
13340 reg_class_names[rclass],
13341 GET_MODE_NAME (mode));
13344 fprintf (stderr, ", default secondary reload");
13346 if (sri->icode != CODE_FOR_nothing)
13347 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13348 insn_data[sri->icode].name, sri->extra_cost);
13350 fprintf (stderr, "\n");
13358 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13359 to SP+reg addressing. */
13362 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13364 int regno = true_regnum (reg);
13365 enum machine_mode mode = GET_MODE (reg);
13366 enum reg_class rclass;
13368 rtx and_op2 = NULL_RTX;
13371 rtx scratch_or_premodify = scratch;
13375 if (TARGET_DEBUG_ADDR)
13377 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13378 store_p ? "store" : "load");
13379 fprintf (stderr, "reg:\n");
13381 fprintf (stderr, "mem:\n");
13383 fprintf (stderr, "scratch:\n");
13384 debug_rtx (scratch);
13387 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13388 gcc_assert (GET_CODE (mem) == MEM);
13389 rclass = REGNO_REG_CLASS (regno);
13390 addr = XEXP (mem, 0);
13394 /* GPRs can handle reg + small constant, all other addresses need to use
13395 the scratch register. */
13398 if (GET_CODE (addr) == AND)
13400 and_op2 = XEXP (addr, 1);
13401 addr = XEXP (addr, 0);
13404 if (GET_CODE (addr) == PRE_MODIFY)
13406 scratch_or_premodify = XEXP (addr, 0);
13407 gcc_assert (REG_P (scratch_or_premodify));
13408 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13409 addr = XEXP (addr, 1);
13412 if (GET_CODE (addr) == PLUS
13413 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13414 || and_op2 != NULL_RTX))
13416 addr_op1 = XEXP (addr, 0);
13417 addr_op2 = XEXP (addr, 1);
13418 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13420 if (!REG_P (addr_op2)
13421 && (GET_CODE (addr_op2) != CONST_INT
13422 || !satisfies_constraint_I (addr_op2)))
13424 if (TARGET_DEBUG_ADDR)
13427 "\nMove plus addr to register %s, mode = %s: ",
13428 rs6000_reg_names[REGNO (scratch)],
13429 GET_MODE_NAME (mode));
13430 debug_rtx (addr_op2);
13432 rs6000_emit_move (scratch, addr_op2, Pmode);
13433 addr_op2 = scratch;
13436 emit_insn (gen_rtx_SET (VOIDmode,
13437 scratch_or_premodify,
13438 gen_rtx_PLUS (Pmode,
13442 addr = scratch_or_premodify;
13443 scratch_or_premodify = scratch;
13445 else if (!legitimate_indirect_address_p (addr, false)
13446 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13448 if (TARGET_DEBUG_ADDR)
13450 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13451 rs6000_reg_names[REGNO (scratch_or_premodify)],
13452 GET_MODE_NAME (mode));
13455 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13456 addr = scratch_or_premodify;
13457 scratch_or_premodify = scratch;
13461 /* Float/Altivec registers can only handle reg+reg addressing. Move
13462 other addresses into a scratch register. */
13467 /* With float regs, we need to handle the AND ourselves, since we can't
13468 use the Altivec instruction with an implicit AND -16. Allow scalar
13469 loads to float registers to use reg+offset even if VSX. */
13470 if (GET_CODE (addr) == AND
13471 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13472 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13473 || INTVAL (XEXP (addr, 1)) != -16
13474 || !VECTOR_MEM_ALTIVEC_P (mode)))
13476 and_op2 = XEXP (addr, 1);
13477 addr = XEXP (addr, 0);
13480 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13481 as the address later. */
13482 if (GET_CODE (addr) == PRE_MODIFY
13483 && (!VECTOR_MEM_VSX_P (mode)
13484 || and_op2 != NULL_RTX
13485 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13487 scratch_or_premodify = XEXP (addr, 0);
13488 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13490 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13491 addr = XEXP (addr, 1);
13494 if (legitimate_indirect_address_p (addr, false) /* reg */
13495 || legitimate_indexed_address_p (addr, false) /* reg+reg */
13496 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
13497 || (GET_CODE (addr) == AND /* Altivec memory */
13498 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13499 && INTVAL (XEXP (addr, 1)) == -16
13500 && VECTOR_MEM_ALTIVEC_P (mode))
13501 || (rclass == FLOAT_REGS /* legacy float mem */
13502 && GET_MODE_SIZE (mode) == 8
13503 && and_op2 == NULL_RTX
13504 && scratch_or_premodify == scratch
13505 && rs6000_legitimate_offset_address_p (mode, addr, false)))
13508 else if (GET_CODE (addr) == PLUS)
13510 addr_op1 = XEXP (addr, 0);
13511 addr_op2 = XEXP (addr, 1);
13512 gcc_assert (REG_P (addr_op1));
13514 if (TARGET_DEBUG_ADDR)
13516 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
13517 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13518 debug_rtx (addr_op2);
13520 rs6000_emit_move (scratch, addr_op2, Pmode);
13521 emit_insn (gen_rtx_SET (VOIDmode,
13522 scratch_or_premodify,
13523 gen_rtx_PLUS (Pmode,
13526 addr = scratch_or_premodify;
13527 scratch_or_premodify = scratch;
13530 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
13531 || GET_CODE (addr) == CONST_INT || REG_P (addr))
13533 if (TARGET_DEBUG_ADDR)
13535 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13536 rs6000_reg_names[REGNO (scratch_or_premodify)],
13537 GET_MODE_NAME (mode));
13541 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13542 addr = scratch_or_premodify;
13543 scratch_or_premodify = scratch;
13547 gcc_unreachable ();
13552 gcc_unreachable ();
13555 /* If the original address involved a pre-modify that we couldn't use the VSX
13556 memory instruction with update, and we haven't taken care of already,
13557 store the address in the pre-modify register and use that as the
13559 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
13561 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
13562 addr = scratch_or_premodify;
13565 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
13566 memory instruction, recreate the AND now, including the clobber which is
13567 generated by the general ANDSI3/ANDDI3 patterns for the
13568 andi. instruction. */
13569 if (and_op2 != NULL_RTX)
13571 if (! legitimate_indirect_address_p (addr, false))
13573 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
13577 if (TARGET_DEBUG_ADDR)
13579 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
13580 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13581 debug_rtx (and_op2);
13584 and_rtx = gen_rtx_SET (VOIDmode,
13586 gen_rtx_AND (Pmode,
13590 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
13591 emit_insn (gen_rtx_PARALLEL (VOIDmode,
13592 gen_rtvec (2, and_rtx, cc_clobber)));
13596 /* Adjust the address if it changed. */
13597 if (addr != XEXP (mem, 0))
13599 mem = change_address (mem, mode, addr);
13600 if (TARGET_DEBUG_ADDR)
13601 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
13604 /* Now create the move. */
13606 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
13608 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
13613 /* Target hook to return the cover classes for Integrated Register Allocator.
13614 Cover classes is a set of non-intersected register classes covering all hard
13615 registers used for register allocation purpose. Any move between two
13616 registers of a cover class should be cheaper than load or store of the
13617 registers. The value is array of register classes with LIM_REG_CLASSES used
13620 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
13621 account for the Altivec and Floating registers being subsets of the VSX
13622 register set under VSX, but distinct register sets on pre-VSX machines. */
13624 static const enum reg_class *
13625 rs6000_ira_cover_classes (void)
13627 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
13628 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
13630 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
13633 /* Allocate a 64-bit stack slot to be used for copying SDmode
13634 values through if this function has any SDmode references. */
13637 rs6000_alloc_sdmode_stack_slot (void)
13641 gimple_stmt_iterator gsi;
13643 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
13646 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
13648 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
13651 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13652 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13658 /* Check for any SDmode parameters of the function. */
13659 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
13661 if (TREE_TYPE (t) == error_mark_node)
13664 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
13665 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
13667 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13668 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13676 rs6000_instantiate_decls (void)
13678 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
13679 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
13682 /* Given an rtx X being reloaded into a reg required to be
13683 in class CLASS, return the class of reg to actually use.
13684 In general this is just CLASS; but on some machines
13685 in some cases it is preferable to use a more restrictive class.
13687 On the RS/6000, we have to return NO_REGS when we want to reload a
13688 floating-point CONST_DOUBLE to force it to be copied to memory.
13690 We also don't want to reload integer values into floating-point
13691 registers if we can at all help it. In fact, this can
13692 cause reload to die, if it tries to generate a reload of CTR
13693 into a FP register and discovers it doesn't have the memory location
13696 ??? Would it be a good idea to have reload do the converse, that is
13697 try to reload floating modes into FP registers if possible?
13700 static enum reg_class
13701 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
13703 enum machine_mode mode = GET_MODE (x);
13705 if (VECTOR_UNIT_VSX_P (mode)
13706 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
13709 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
13710 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
13711 && easy_vector_constant (x, mode))
13712 return ALTIVEC_REGS;
13714 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
13717 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
13718 return GENERAL_REGS;
13720 /* For VSX, prefer the traditional registers for DF if the address is of the
13721 form reg+offset because we can use the non-VSX loads. Prefer the Altivec
13722 registers if Altivec is handling the vector operations (i.e. V16QI, V8HI,
13724 if (rclass == VSX_REGS && VECTOR_MEM_VSX_P (mode))
13726 if (mode == DFmode && GET_CODE (x) == MEM)
13728 rtx addr = XEXP (x, 0);
13730 if (legitimate_indirect_address_p (addr, false)) /* reg */
13733 if (legitimate_indexed_address_p (addr, false)) /* reg+reg */
13736 if (GET_CODE (addr) == PRE_MODIFY
13737 && legitimate_indexed_address_p (XEXP (addr, 0), false))
13743 if (VECTOR_UNIT_ALTIVEC_P (mode))
13744 return ALTIVEC_REGS;
13752 /* Debug version of rs6000_preferred_reload_class. */
13753 static enum reg_class
13754 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
13756 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
13759 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
13761 reg_class_names[ret], reg_class_names[rclass],
13762 GET_MODE_NAME (GET_MODE (x)));
13768 /* If we are copying between FP or AltiVec registers and anything else, we need
13769 a memory location. The exception is when we are targeting ppc64 and the
13770 move to/from fpr to gpr instructions are available. Also, under VSX, you
13771 can copy vector registers from the FP register set to the Altivec register
13772 set and vice versa. */
13775 rs6000_secondary_memory_needed (enum reg_class class1,
13776 enum reg_class class2,
13777 enum machine_mode mode)
13779 if (class1 == class2)
13782 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
13783 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
13784 between these classes. But we need memory for other things that can go in
13785 FLOAT_REGS like SFmode. */
13787 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
13788 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
13789 || class1 == FLOAT_REGS))
13790 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
13791 && class2 != FLOAT_REGS);
13793 if (class1 == VSX_REGS || class2 == VSX_REGS)
13796 if (class1 == FLOAT_REGS
13797 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13798 || ((mode != DFmode)
13799 && (mode != DDmode)
13800 && (mode != DImode))))
13803 if (class2 == FLOAT_REGS
13804 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13805 || ((mode != DFmode)
13806 && (mode != DDmode)
13807 && (mode != DImode))))
13810 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
13816 /* Debug version of rs6000_secondary_memory_needed. */
13818 rs6000_debug_secondary_memory_needed (enum reg_class class1,
13819 enum reg_class class2,
13820 enum machine_mode mode)
13822 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
13825 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
13826 "class2 = %s, mode = %s\n",
13827 ret ? "true" : "false", reg_class_names[class1],
13828 reg_class_names[class2], GET_MODE_NAME (mode));
13833 /* Return the register class of a scratch register needed to copy IN into
13834 or out of a register in RCLASS in MODE. If it can be done directly,
13835 NO_REGS is returned. */
13837 static enum reg_class
13838 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
13843 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
13845 && MACHOPIC_INDIRECT
13849 /* We cannot copy a symbolic operand directly into anything
13850 other than BASE_REGS for TARGET_ELF. So indicate that a
13851 register from BASE_REGS is needed as an intermediate
13854 On Darwin, pic addresses require a load from memory, which
13855 needs a base register. */
13856 if (rclass != BASE_REGS
13857 && (GET_CODE (in) == SYMBOL_REF
13858 || GET_CODE (in) == HIGH
13859 || GET_CODE (in) == LABEL_REF
13860 || GET_CODE (in) == CONST))
13864 if (GET_CODE (in) == REG)
13866 regno = REGNO (in);
13867 if (regno >= FIRST_PSEUDO_REGISTER)
13869 regno = true_regnum (in);
13870 if (regno >= FIRST_PSEUDO_REGISTER)
13874 else if (GET_CODE (in) == SUBREG)
13876 regno = true_regnum (in);
13877 if (regno >= FIRST_PSEUDO_REGISTER)
13883 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
13885 if (rclass == GENERAL_REGS || rclass == BASE_REGS
13886 || (regno >= 0 && INT_REGNO_P (regno)))
13889 /* Constants, memory, and FP registers can go into FP registers. */
13890 if ((regno == -1 || FP_REGNO_P (regno))
13891 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
13892 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
13894 /* Memory, and FP/altivec registers can go into fp/altivec registers under
13897 && (regno == -1 || VSX_REGNO_P (regno))
13898 && VSX_REG_CLASS_P (rclass))
13901 /* Memory, and AltiVec registers can go into AltiVec registers. */
13902 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
13903 && rclass == ALTIVEC_REGS)
13906 /* We can copy among the CR registers. */
13907 if ((rclass == CR_REGS || rclass == CR0_REGS)
13908 && regno >= 0 && CR_REGNO_P (regno))
13911 /* Otherwise, we need GENERAL_REGS. */
13912 return GENERAL_REGS;
13915 /* Debug version of rs6000_secondary_reload_class. */
13916 static enum reg_class
13917 rs6000_debug_secondary_reload_class (enum reg_class rclass,
13918 enum machine_mode mode, rtx in)
13920 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
13922 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
13923 "mode = %s, input rtx:\n",
13924 reg_class_names[ret], reg_class_names[rclass],
13925 GET_MODE_NAME (mode));
13931 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
13934 rs6000_cannot_change_mode_class (enum machine_mode from,
13935 enum machine_mode to,
13936 enum reg_class rclass)
13938 unsigned from_size = GET_MODE_SIZE (from);
13939 unsigned to_size = GET_MODE_SIZE (to);
13941 if (from_size != to_size)
13943 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
13944 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
13945 && reg_classes_intersect_p (xclass, rclass));
13948 if (TARGET_E500_DOUBLE
13949 && ((((to) == DFmode) + ((from) == DFmode)) == 1
13950 || (((to) == TFmode) + ((from) == TFmode)) == 1
13951 || (((to) == DDmode) + ((from) == DDmode)) == 1
13952 || (((to) == TDmode) + ((from) == TDmode)) == 1
13953 || (((to) == DImode) + ((from) == DImode)) == 1))
13956 /* Since the VSX register set includes traditional floating point registers
13957 and altivec registers, just check for the size being different instead of
13958 trying to check whether the modes are vector modes. Otherwise it won't
13959 allow say DF and DI to change classes. */
13960 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
13961 return (from_size != 8 && from_size != 16);
13963 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
13964 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
13967 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
13968 && reg_classes_intersect_p (GENERAL_REGS, rclass))
13974 /* Debug version of rs6000_cannot_change_mode_class. */
13976 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
13977 enum machine_mode to,
13978 enum reg_class rclass)
13980 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
13983 "rs6000_cannot_change_mode_class, return %s, from = %s, "
13984 "to = %s, rclass = %s\n",
13985 ret ? "true" : "false",
13986 GET_MODE_NAME (from), GET_MODE_NAME (to),
13987 reg_class_names[rclass]);
13992 /* Given a comparison operation, return the bit number in CCR to test. We
13993 know this is a valid comparison.
13995 SCC_P is 1 if this is for an scc. That means that %D will have been
13996 used instead of %C, so the bits will be in different places.
13998 Return -1 if OP isn't a valid comparison for some reason. */
14001 ccr_bit (rtx op, int scc_p)
14003 enum rtx_code code = GET_CODE (op);
14004 enum machine_mode cc_mode;
14009 if (!COMPARISON_P (op))
14012 reg = XEXP (op, 0);
14014 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14016 cc_mode = GET_MODE (reg);
14017 cc_regnum = REGNO (reg);
14018 base_bit = 4 * (cc_regnum - CR0_REGNO);
14020 validate_condition_mode (code, cc_mode);
14022 /* When generating a sCOND operation, only positive conditions are
14025 || code == EQ || code == GT || code == LT || code == UNORDERED
14026 || code == GTU || code == LTU);
14031 return scc_p ? base_bit + 3 : base_bit + 2;
14033 return base_bit + 2;
14034 case GT: case GTU: case UNLE:
14035 return base_bit + 1;
14036 case LT: case LTU: case UNGE:
14038 case ORDERED: case UNORDERED:
14039 return base_bit + 3;
14042 /* If scc, we will have done a cror to put the bit in the
14043 unordered position. So test that bit. For integer, this is ! LT
14044 unless this is an scc insn. */
14045 return scc_p ? base_bit + 3 : base_bit;
14048 return scc_p ? base_bit + 3 : base_bit + 1;
14051 gcc_unreachable ();
14055 /* Return the GOT register. */
14058 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
14060 /* The second flow pass currently (June 1999) can't update
14061 regs_ever_live without disturbing other parts of the compiler, so
14062 update it here to make the prolog/epilogue code happy. */
14063 if (!can_create_pseudo_p ()
14064 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
14065 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
14067 crtl->uses_pic_offset_table = 1;
14069 return pic_offset_table_rtx;
14072 /* Function to init struct machine_function.
14073 This will be called, via a pointer variable,
14074 from push_function_context. */
14076 static struct machine_function *
14077 rs6000_init_machine_status (void)
14079 return GGC_CNEW (machine_function);
14082 /* These macros test for integers and extract the low-order bits. */
14084 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
14085 && GET_MODE (X) == VOIDmode)
14087 #define INT_LOWPART(X) \
14088 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
14091 extract_MB (rtx op)
14094 unsigned long val = INT_LOWPART (op);
14096 /* If the high bit is zero, the value is the first 1 bit we find
14098 if ((val & 0x80000000) == 0)
14100 gcc_assert (val & 0xffffffff);
14103 while (((val <<= 1) & 0x80000000) == 0)
14108 /* If the high bit is set and the low bit is not, or the mask is all
14109 1's, the value is zero. */
14110 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14113 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14116 while (((val >>= 1) & 1) != 0)
14123 extract_ME (rtx op)
14126 unsigned long val = INT_LOWPART (op);
14128 /* If the low bit is zero, the value is the first 1 bit we find from
14130 if ((val & 1) == 0)
14132 gcc_assert (val & 0xffffffff);
14135 while (((val >>= 1) & 1) == 0)
14141 /* If the low bit is set and the high bit is not, or the mask is all
14142 1's, the value is 31. */
14143 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14146 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14149 while (((val <<= 1) & 0x80000000) != 0)
14155 /* Locate some local-dynamic symbol still in use by this function
14156 so that we can print its name in some tls_ld pattern. */
14158 static const char *
14159 rs6000_get_some_local_dynamic_name (void)
14163 if (cfun->machine->some_ld_name)
14164 return cfun->machine->some_ld_name;
14166 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14168 && for_each_rtx (&PATTERN (insn),
14169 rs6000_get_some_local_dynamic_name_1, 0))
14170 return cfun->machine->some_ld_name;
14172 gcc_unreachable ();
14175 /* Helper function for rs6000_get_some_local_dynamic_name. */
14178 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14182 if (GET_CODE (x) == SYMBOL_REF)
14184 const char *str = XSTR (x, 0);
14185 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14187 cfun->machine->some_ld_name = str;
14195 /* Write out a function code label. */
14198 rs6000_output_function_entry (FILE *file, const char *fname)
14200 if (fname[0] != '.')
14202 switch (DEFAULT_ABI)
14205 gcc_unreachable ();
14211 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14220 RS6000_OUTPUT_BASENAME (file, fname);
14222 assemble_name (file, fname);
14225 /* Print an operand. Recognize special options, documented below. */
14228 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14229 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14231 #define SMALL_DATA_RELOC "sda21"
14232 #define SMALL_DATA_REG 0
14236 print_operand (FILE *file, rtx x, int code)
14240 unsigned HOST_WIDE_INT uval;
14245 /* Write out an instruction after the call which may be replaced
14246 with glue code by the loader. This depends on the AIX version. */
14247 asm_fprintf (file, RS6000_CALL_GLUE);
14250 /* %a is output_address. */
14253 /* If X is a constant integer whose low-order 5 bits are zero,
14254 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14255 in the AIX assembler where "sri" with a zero shift count
14256 writes a trash instruction. */
14257 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14264 /* If constant, low-order 16 bits of constant, unsigned.
14265 Otherwise, write normally. */
14267 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14269 print_operand (file, x, 0);
14273 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14274 for 64-bit mask direction. */
14275 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14278 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14282 /* X is a CR register. Print the number of the GT bit of the CR. */
14283 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14284 output_operand_lossage ("invalid %%c value");
14286 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14290 /* Like 'J' but get to the GT bit only. */
14291 gcc_assert (GET_CODE (x) == REG);
14293 /* Bit 1 is GT bit. */
14294 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14296 /* Add one for shift count in rlinm for scc. */
14297 fprintf (file, "%d", i + 1);
14301 /* X is a CR register. Print the number of the EQ bit of the CR */
14302 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14303 output_operand_lossage ("invalid %%E value");
14305 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14309 /* X is a CR register. Print the shift count needed to move it
14310 to the high-order four bits. */
14311 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14312 output_operand_lossage ("invalid %%f value");
14314 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14318 /* Similar, but print the count for the rotate in the opposite
14320 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14321 output_operand_lossage ("invalid %%F value");
14323 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14327 /* X is a constant integer. If it is negative, print "m",
14328 otherwise print "z". This is to make an aze or ame insn. */
14329 if (GET_CODE (x) != CONST_INT)
14330 output_operand_lossage ("invalid %%G value");
14331 else if (INTVAL (x) >= 0)
14338 /* If constant, output low-order five bits. Otherwise, write
14341 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14343 print_operand (file, x, 0);
14347 /* If constant, output low-order six bits. Otherwise, write
14350 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14352 print_operand (file, x, 0);
14356 /* Print `i' if this is a constant, else nothing. */
14362 /* Write the bit number in CCR for jump. */
14363 i = ccr_bit (x, 0);
14365 output_operand_lossage ("invalid %%j code");
14367 fprintf (file, "%d", i);
14371 /* Similar, but add one for shift count in rlinm for scc and pass
14372 scc flag to `ccr_bit'. */
14373 i = ccr_bit (x, 1);
14375 output_operand_lossage ("invalid %%J code");
14377 /* If we want bit 31, write a shift count of zero, not 32. */
14378 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14382 /* X must be a constant. Write the 1's complement of the
14385 output_operand_lossage ("invalid %%k value");
14387 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14391 /* X must be a symbolic constant on ELF. Write an
14392 expression suitable for an 'addi' that adds in the low 16
14393 bits of the MEM. */
14394 if (GET_CODE (x) != CONST)
14396 print_operand_address (file, x);
14397 fputs ("@l", file);
14401 if (GET_CODE (XEXP (x, 0)) != PLUS
14402 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14403 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14404 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14405 output_operand_lossage ("invalid %%K value");
14406 print_operand_address (file, XEXP (XEXP (x, 0), 0));
14407 fputs ("@l", file);
14408 /* For GNU as, there must be a non-alphanumeric character
14409 between 'l' and the number. The '-' is added by
14410 print_operand() already. */
14411 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
14413 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
14417 /* %l is output_asm_label. */
14420 /* Write second word of DImode or DFmode reference. Works on register
14421 or non-indexed memory only. */
14422 if (GET_CODE (x) == REG)
14423 fputs (reg_names[REGNO (x) + 1], file);
14424 else if (GET_CODE (x) == MEM)
14426 /* Handle possible auto-increment. Since it is pre-increment and
14427 we have already done it, we can just use an offset of word. */
14428 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14429 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14430 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14432 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14433 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14436 output_address (XEXP (adjust_address_nv (x, SImode,
14440 if (small_data_operand (x, GET_MODE (x)))
14441 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14442 reg_names[SMALL_DATA_REG]);
14447 /* MB value for a mask operand. */
14448 if (! mask_operand (x, SImode))
14449 output_operand_lossage ("invalid %%m value");
14451 fprintf (file, "%d", extract_MB (x));
14455 /* ME value for a mask operand. */
14456 if (! mask_operand (x, SImode))
14457 output_operand_lossage ("invalid %%M value");
14459 fprintf (file, "%d", extract_ME (x));
14462 /* %n outputs the negative of its operand. */
14465 /* Write the number of elements in the vector times 4. */
14466 if (GET_CODE (x) != PARALLEL)
14467 output_operand_lossage ("invalid %%N value");
14469 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14473 /* Similar, but subtract 1 first. */
14474 if (GET_CODE (x) != PARALLEL)
14475 output_operand_lossage ("invalid %%O value");
14477 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14481 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14483 || INT_LOWPART (x) < 0
14484 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14485 output_operand_lossage ("invalid %%p value");
14487 fprintf (file, "%d", i);
14491 /* The operand must be an indirect memory reference. The result
14492 is the register name. */
14493 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14494 || REGNO (XEXP (x, 0)) >= 32)
14495 output_operand_lossage ("invalid %%P value");
14497 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14501 /* This outputs the logical code corresponding to a boolean
14502 expression. The expression may have one or both operands
14503 negated (if one, only the first one). For condition register
14504 logical operations, it will also treat the negated
14505 CR codes as NOTs, but not handle NOTs of them. */
14507 const char *const *t = 0;
14509 enum rtx_code code = GET_CODE (x);
14510 static const char * const tbl[3][3] = {
14511 { "and", "andc", "nor" },
14512 { "or", "orc", "nand" },
14513 { "xor", "eqv", "xor" } };
14517 else if (code == IOR)
14519 else if (code == XOR)
14522 output_operand_lossage ("invalid %%q value");
14524 if (GET_CODE (XEXP (x, 0)) != NOT)
14528 if (GET_CODE (XEXP (x, 1)) == NOT)
14546 /* X is a CR register. Print the mask for `mtcrf'. */
14547 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14548 output_operand_lossage ("invalid %%R value");
14550 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
14554 /* Low 5 bits of 32 - value */
14556 output_operand_lossage ("invalid %%s value");
14558 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
14562 /* PowerPC64 mask position. All 0's is excluded.
14563 CONST_INT 32-bit mask is considered sign-extended so any
14564 transition must occur within the CONST_INT, not on the boundary. */
14565 if (! mask64_operand (x, DImode))
14566 output_operand_lossage ("invalid %%S value");
14568 uval = INT_LOWPART (x);
14570 if (uval & 1) /* Clear Left */
14572 #if HOST_BITS_PER_WIDE_INT > 64
14573 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14577 else /* Clear Right */
14580 #if HOST_BITS_PER_WIDE_INT > 64
14581 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14587 gcc_assert (i >= 0);
14588 fprintf (file, "%d", i);
14592 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
14593 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
14595 /* Bit 3 is OV bit. */
14596 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
14598 /* If we want bit 31, write a shift count of zero, not 32. */
14599 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14603 /* Print the symbolic name of a branch target register. */
14604 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
14605 && REGNO (x) != CTR_REGNO))
14606 output_operand_lossage ("invalid %%T value");
14607 else if (REGNO (x) == LR_REGNO)
14608 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
14610 fputs ("ctr", file);
14614 /* High-order 16 bits of constant for use in unsigned operand. */
14616 output_operand_lossage ("invalid %%u value");
14618 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14619 (INT_LOWPART (x) >> 16) & 0xffff);
14623 /* High-order 16 bits of constant for use in signed operand. */
14625 output_operand_lossage ("invalid %%v value");
14627 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14628 (INT_LOWPART (x) >> 16) & 0xffff);
14632 /* Print `u' if this has an auto-increment or auto-decrement. */
14633 if (GET_CODE (x) == MEM
14634 && (GET_CODE (XEXP (x, 0)) == PRE_INC
14635 || GET_CODE (XEXP (x, 0)) == PRE_DEC
14636 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
14641 /* Print the trap code for this operand. */
14642 switch (GET_CODE (x))
14645 fputs ("eq", file); /* 4 */
14648 fputs ("ne", file); /* 24 */
14651 fputs ("lt", file); /* 16 */
14654 fputs ("le", file); /* 20 */
14657 fputs ("gt", file); /* 8 */
14660 fputs ("ge", file); /* 12 */
14663 fputs ("llt", file); /* 2 */
14666 fputs ("lle", file); /* 6 */
14669 fputs ("lgt", file); /* 1 */
14672 fputs ("lge", file); /* 5 */
14675 gcc_unreachable ();
14680 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
14683 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
14684 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
14686 print_operand (file, x, 0);
14690 /* MB value for a PowerPC64 rldic operand. */
14691 val = (GET_CODE (x) == CONST_INT
14692 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
14697 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
14698 if ((val <<= 1) < 0)
14701 #if HOST_BITS_PER_WIDE_INT == 32
14702 if (GET_CODE (x) == CONST_INT && i >= 0)
14703 i += 32; /* zero-extend high-part was all 0's */
14704 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
14706 val = CONST_DOUBLE_LOW (x);
14712 for ( ; i < 64; i++)
14713 if ((val <<= 1) < 0)
14718 fprintf (file, "%d", i + 1);
14722 /* X is a FPR or Altivec register used in a VSX context. */
14723 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
14724 output_operand_lossage ("invalid %%x value");
14727 int reg = REGNO (x);
14728 int vsx_reg = (FP_REGNO_P (reg)
14730 : reg - FIRST_ALTIVEC_REGNO + 32);
14732 #ifdef TARGET_REGNAMES
14733 if (TARGET_REGNAMES)
14734 fprintf (file, "%%vs%d", vsx_reg);
14737 fprintf (file, "%d", vsx_reg);
14742 if (GET_CODE (x) == MEM
14743 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
14744 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
14745 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
14750 /* Like 'L', for third word of TImode */
14751 if (GET_CODE (x) == REG)
14752 fputs (reg_names[REGNO (x) + 2], file);
14753 else if (GET_CODE (x) == MEM)
14755 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14756 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14757 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14758 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14759 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14761 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
14762 if (small_data_operand (x, GET_MODE (x)))
14763 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14764 reg_names[SMALL_DATA_REG]);
14769 /* X is a SYMBOL_REF. Write out the name preceded by a
14770 period and without any trailing data in brackets. Used for function
14771 names. If we are configured for System V (or the embedded ABI) on
14772 the PowerPC, do not emit the period, since those systems do not use
14773 TOCs and the like. */
14774 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14776 /* Mark the decl as referenced so that cgraph will output the
14778 if (SYMBOL_REF_DECL (x))
14779 mark_decl_referenced (SYMBOL_REF_DECL (x));
14781 /* For macho, check to see if we need a stub. */
14784 const char *name = XSTR (x, 0);
14786 if (MACHOPIC_INDIRECT
14787 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
14788 name = machopic_indirection_name (x, /*stub_p=*/true);
14790 assemble_name (file, name);
14792 else if (!DOT_SYMBOLS)
14793 assemble_name (file, XSTR (x, 0));
14795 rs6000_output_function_entry (file, XSTR (x, 0));
14799 /* Like 'L', for last word of TImode. */
14800 if (GET_CODE (x) == REG)
14801 fputs (reg_names[REGNO (x) + 3], file);
14802 else if (GET_CODE (x) == MEM)
14804 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14805 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14806 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14807 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14808 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14810 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
14811 if (small_data_operand (x, GET_MODE (x)))
14812 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14813 reg_names[SMALL_DATA_REG]);
14817 /* Print AltiVec or SPE memory operand. */
14822 gcc_assert (GET_CODE (x) == MEM);
14826 /* Ugly hack because %y is overloaded. */
14827 if ((TARGET_SPE || TARGET_E500_DOUBLE)
14828 && (GET_MODE_SIZE (GET_MODE (x)) == 8
14829 || GET_MODE (x) == TFmode
14830 || GET_MODE (x) == TImode))
14832 /* Handle [reg]. */
14833 if (GET_CODE (tmp) == REG)
14835 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
14838 /* Handle [reg+UIMM]. */
14839 else if (GET_CODE (tmp) == PLUS &&
14840 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
14844 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
14846 x = INTVAL (XEXP (tmp, 1));
14847 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
14851 /* Fall through. Must be [reg+reg]. */
14853 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
14854 && GET_CODE (tmp) == AND
14855 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
14856 && INTVAL (XEXP (tmp, 1)) == -16)
14857 tmp = XEXP (tmp, 0);
14858 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
14859 && GET_CODE (tmp) == PRE_MODIFY)
14860 tmp = XEXP (tmp, 1);
14861 if (GET_CODE (tmp) == REG)
14862 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
14865 if (!GET_CODE (tmp) == PLUS
14866 || !REG_P (XEXP (tmp, 0))
14867 || !REG_P (XEXP (tmp, 1)))
14869 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
14873 if (REGNO (XEXP (tmp, 0)) == 0)
14874 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
14875 reg_names[ REGNO (XEXP (tmp, 0)) ]);
14877 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
14878 reg_names[ REGNO (XEXP (tmp, 1)) ]);
14884 if (GET_CODE (x) == REG)
14885 fprintf (file, "%s", reg_names[REGNO (x)]);
14886 else if (GET_CODE (x) == MEM)
14888 /* We need to handle PRE_INC and PRE_DEC here, since we need to
14889 know the width from the mode. */
14890 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
14891 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
14892 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14893 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
14894 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
14895 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14896 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14897 output_address (XEXP (XEXP (x, 0), 1));
14899 output_address (XEXP (x, 0));
14902 output_addr_const (file, x);
14906 assemble_name (file, rs6000_get_some_local_dynamic_name ());
14910 output_operand_lossage ("invalid %%xn code");
14914 /* Print the address of an operand. */
14917 print_operand_address (FILE *file, rtx x)
14919 if (GET_CODE (x) == REG)
14920 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
14921 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
14922 || GET_CODE (x) == LABEL_REF)
14924 output_addr_const (file, x);
14925 if (small_data_operand (x, GET_MODE (x)))
14926 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14927 reg_names[SMALL_DATA_REG]);
14929 gcc_assert (!TARGET_TOC);
14931 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
14933 gcc_assert (REG_P (XEXP (x, 0)));
14934 if (REGNO (XEXP (x, 0)) == 0)
14935 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
14936 reg_names[ REGNO (XEXP (x, 0)) ]);
14938 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
14939 reg_names[ REGNO (XEXP (x, 1)) ]);
14941 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
14942 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
14943 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
14945 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
14946 && CONSTANT_P (XEXP (x, 1)))
14948 output_addr_const (file, XEXP (x, 1));
14949 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
14953 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
14954 && CONSTANT_P (XEXP (x, 1)))
14956 fprintf (file, "lo16(");
14957 output_addr_const (file, XEXP (x, 1));
14958 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
14961 else if (legitimate_constant_pool_address_p (x))
14963 output_addr_const (file, XEXP (x, 1));
14964 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
14967 gcc_unreachable ();
14970 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
14973 rs6000_output_addr_const_extra (FILE *file, rtx x)
14975 if (GET_CODE (x) == UNSPEC)
14976 switch (XINT (x, 1))
14978 case UNSPEC_TOCREL:
14979 x = XVECEXP (x, 0, 0);
14980 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14981 output_addr_const (file, x);
14982 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
14985 assemble_name (file, toc_label_name);
14987 else if (TARGET_ELF)
14988 fputs ("@toc", file);
14992 case UNSPEC_MACHOPIC_OFFSET:
14993 output_addr_const (file, XVECEXP (x, 0, 0));
14995 machopic_output_function_base_name (file);
15002 /* Target hook for assembling integer objects. The PowerPC version has
15003 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15004 is defined. It also needs to handle DI-mode objects on 64-bit
15008 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15010 #ifdef RELOCATABLE_NEEDS_FIXUP
15011 /* Special handling for SI values. */
15012 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
15014 static int recurse = 0;
15016 /* For -mrelocatable, we mark all addresses that need to be fixed up
15017 in the .fixup section. */
15018 if (TARGET_RELOCATABLE
15019 && in_section != toc_section
15020 && in_section != text_section
15021 && !unlikely_text_section_p (in_section)
15023 && GET_CODE (x) != CONST_INT
15024 && GET_CODE (x) != CONST_DOUBLE
15030 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
15032 ASM_OUTPUT_LABEL (asm_out_file, buf);
15033 fprintf (asm_out_file, "\t.long\t(");
15034 output_addr_const (asm_out_file, x);
15035 fprintf (asm_out_file, ")@fixup\n");
15036 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
15037 ASM_OUTPUT_ALIGN (asm_out_file, 2);
15038 fprintf (asm_out_file, "\t.long\t");
15039 assemble_name (asm_out_file, buf);
15040 fprintf (asm_out_file, "\n\t.previous\n");
15044 /* Remove initial .'s to turn a -mcall-aixdesc function
15045 address into the address of the descriptor, not the function
15047 else if (GET_CODE (x) == SYMBOL_REF
15048 && XSTR (x, 0)[0] == '.'
15049 && DEFAULT_ABI == ABI_AIX)
15051 const char *name = XSTR (x, 0);
15052 while (*name == '.')
15055 fprintf (asm_out_file, "\t.long\t%s\n", name);
15059 #endif /* RELOCATABLE_NEEDS_FIXUP */
15060 return default_assemble_integer (x, size, aligned_p);
15063 #ifdef HAVE_GAS_HIDDEN
15064 /* Emit an assembler directive to set symbol visibility for DECL to
15065 VISIBILITY_TYPE. */
15068 rs6000_assemble_visibility (tree decl, int vis)
15070 /* Functions need to have their entry point symbol visibility set as
15071 well as their descriptor symbol visibility. */
15072 if (DEFAULT_ABI == ABI_AIX
15074 && TREE_CODE (decl) == FUNCTION_DECL)
15076 static const char * const visibility_types[] = {
15077 NULL, "internal", "hidden", "protected"
15080 const char *name, *type;
15082 name = ((* targetm.strip_name_encoding)
15083 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
15084 type = visibility_types[vis];
15086 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
15087 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
15090 default_assemble_visibility (decl, vis);
15095 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15097 /* Reversal of FP compares takes care -- an ordered compare
15098 becomes an unordered compare and vice versa. */
15099 if (mode == CCFPmode
15100 && (!flag_finite_math_only
15101 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15102 || code == UNEQ || code == LTGT))
15103 return reverse_condition_maybe_unordered (code);
15105 return reverse_condition (code);
15108 /* Generate a compare for CODE. Return a brand-new rtx that
15109 represents the result of the compare. */
15112 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15114 enum machine_mode comp_mode;
15115 rtx compare_result;
15116 enum rtx_code code = GET_CODE (cmp);
15117 rtx op0 = XEXP (cmp, 0);
15118 rtx op1 = XEXP (cmp, 1);
15120 if (FLOAT_MODE_P (mode))
15121 comp_mode = CCFPmode;
15122 else if (code == GTU || code == LTU
15123 || code == GEU || code == LEU)
15124 comp_mode = CCUNSmode;
15125 else if ((code == EQ || code == NE)
15126 && GET_CODE (op0) == SUBREG
15127 && GET_CODE (op1) == SUBREG
15128 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15129 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15130 /* These are unsigned values, perhaps there will be a later
15131 ordering compare that can be shared with this one.
15132 Unfortunately we cannot detect the signedness of the operands
15133 for non-subregs. */
15134 comp_mode = CCUNSmode;
15136 comp_mode = CCmode;
15138 /* First, the compare. */
15139 compare_result = gen_reg_rtx (comp_mode);
15141 /* E500 FP compare instructions on the GPRs. Yuck! */
15142 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15143 && FLOAT_MODE_P (mode))
15145 rtx cmp, or_result, compare_result2;
15146 enum machine_mode op_mode = GET_MODE (op0);
15148 if (op_mode == VOIDmode)
15149 op_mode = GET_MODE (op1);
15151 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15152 This explains the following mess. */
15156 case EQ: case UNEQ: case NE: case LTGT:
15160 cmp = (flag_finite_math_only && !flag_trapping_math)
15161 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15162 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15166 cmp = (flag_finite_math_only && !flag_trapping_math)
15167 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15168 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15172 cmp = (flag_finite_math_only && !flag_trapping_math)
15173 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15174 : gen_cmptfeq_gpr (compare_result, op0, op1);
15178 gcc_unreachable ();
15182 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15186 cmp = (flag_finite_math_only && !flag_trapping_math)
15187 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15188 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15192 cmp = (flag_finite_math_only && !flag_trapping_math)
15193 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15194 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15198 cmp = (flag_finite_math_only && !flag_trapping_math)
15199 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15200 : gen_cmptfgt_gpr (compare_result, op0, op1);
15204 gcc_unreachable ();
15208 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15212 cmp = (flag_finite_math_only && !flag_trapping_math)
15213 ? gen_tstsflt_gpr (compare_result, op0, op1)
15214 : gen_cmpsflt_gpr (compare_result, op0, op1);
15218 cmp = (flag_finite_math_only && !flag_trapping_math)
15219 ? gen_tstdflt_gpr (compare_result, op0, op1)
15220 : gen_cmpdflt_gpr (compare_result, op0, op1);
15224 cmp = (flag_finite_math_only && !flag_trapping_math)
15225 ? gen_tsttflt_gpr (compare_result, op0, op1)
15226 : gen_cmptflt_gpr (compare_result, op0, op1);
15230 gcc_unreachable ();
15234 gcc_unreachable ();
15237 /* Synthesize LE and GE from LT/GT || EQ. */
15238 if (code == LE || code == GE || code == LEU || code == GEU)
15244 case LE: code = LT; break;
15245 case GE: code = GT; break;
15246 case LEU: code = LT; break;
15247 case GEU: code = GT; break;
15248 default: gcc_unreachable ();
15251 compare_result2 = gen_reg_rtx (CCFPmode);
15257 cmp = (flag_finite_math_only && !flag_trapping_math)
15258 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15259 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15263 cmp = (flag_finite_math_only && !flag_trapping_math)
15264 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15265 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15269 cmp = (flag_finite_math_only && !flag_trapping_math)
15270 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15271 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15275 gcc_unreachable ();
15279 /* OR them together. */
15280 or_result = gen_reg_rtx (CCFPmode);
15281 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15283 compare_result = or_result;
15288 if (code == NE || code == LTGT)
15298 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15299 CLOBBERs to match cmptf_internal2 pattern. */
15300 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15301 && GET_MODE (op0) == TFmode
15302 && !TARGET_IEEEQUAD
15303 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15304 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15306 gen_rtx_SET (VOIDmode,
15308 gen_rtx_COMPARE (comp_mode, op0, op1)),
15309 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15310 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15311 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15312 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15313 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15314 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15315 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15316 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
15317 else if (GET_CODE (op1) == UNSPEC
15318 && XINT (op1, 1) == UNSPEC_SP_TEST)
15320 rtx op1b = XVECEXP (op1, 0, 0);
15321 comp_mode = CCEQmode;
15322 compare_result = gen_reg_rtx (CCEQmode);
15324 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15326 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15329 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15330 gen_rtx_COMPARE (comp_mode, op0, op1)));
15333 /* Some kinds of FP comparisons need an OR operation;
15334 under flag_finite_math_only we don't bother. */
15335 if (FLOAT_MODE_P (mode)
15336 && !flag_finite_math_only
15337 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15338 && (code == LE || code == GE
15339 || code == UNEQ || code == LTGT
15340 || code == UNGT || code == UNLT))
15342 enum rtx_code or1, or2;
15343 rtx or1_rtx, or2_rtx, compare2_rtx;
15344 rtx or_result = gen_reg_rtx (CCEQmode);
15348 case LE: or1 = LT; or2 = EQ; break;
15349 case GE: or1 = GT; or2 = EQ; break;
15350 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15351 case LTGT: or1 = LT; or2 = GT; break;
15352 case UNGT: or1 = UNORDERED; or2 = GT; break;
15353 case UNLT: or1 = UNORDERED; or2 = LT; break;
15354 default: gcc_unreachable ();
15356 validate_condition_mode (or1, comp_mode);
15357 validate_condition_mode (or2, comp_mode);
15358 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15359 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15360 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15361 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15363 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15365 compare_result = or_result;
15369 validate_condition_mode (code, GET_MODE (compare_result));
15371 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15375 /* Emit the RTL for an sCOND pattern. */
15378 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15381 enum machine_mode op_mode;
15382 enum rtx_code cond_code;
15383 rtx result = operands[0];
15385 condition_rtx = rs6000_generate_compare (operands[1], mode);
15386 cond_code = GET_CODE (condition_rtx);
15388 if (FLOAT_MODE_P (mode)
15389 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15393 PUT_MODE (condition_rtx, SImode);
15394 t = XEXP (condition_rtx, 0);
15396 gcc_assert (cond_code == NE || cond_code == EQ);
15398 if (cond_code == NE)
15399 emit_insn (gen_e500_flip_gt_bit (t, t));
15401 emit_insn (gen_move_from_CR_gt_bit (result, t));
15405 if (cond_code == NE
15406 || cond_code == GE || cond_code == LE
15407 || cond_code == GEU || cond_code == LEU
15408 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15410 rtx not_result = gen_reg_rtx (CCEQmode);
15411 rtx not_op, rev_cond_rtx;
15412 enum machine_mode cc_mode;
15414 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15416 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15417 SImode, XEXP (condition_rtx, 0), const0_rtx);
15418 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15419 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15420 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15423 op_mode = GET_MODE (XEXP (operands[1], 0));
15424 if (op_mode == VOIDmode)
15425 op_mode = GET_MODE (XEXP (operands[1], 1));
15427 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15429 PUT_MODE (condition_rtx, DImode);
15430 convert_move (result, condition_rtx, 0);
15434 PUT_MODE (condition_rtx, SImode);
15435 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15439 /* Emit a branch of kind CODE to location LOC. */
15442 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15444 rtx condition_rtx, loc_ref;
15446 condition_rtx = rs6000_generate_compare (operands[0], mode);
15447 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15448 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15449 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15450 loc_ref, pc_rtx)));
15453 /* Return the string to output a conditional branch to LABEL, which is
15454 the operand number of the label, or -1 if the branch is really a
15455 conditional return.
15457 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15458 condition code register and its mode specifies what kind of
15459 comparison we made.
15461 REVERSED is nonzero if we should reverse the sense of the comparison.
15463 INSN is the insn. */
15466 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
15468 static char string[64];
15469 enum rtx_code code = GET_CODE (op);
15470 rtx cc_reg = XEXP (op, 0);
15471 enum machine_mode mode = GET_MODE (cc_reg);
15472 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
15473 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
15474 int really_reversed = reversed ^ need_longbranch;
15480 validate_condition_mode (code, mode);
15482 /* Work out which way this really branches. We could use
15483 reverse_condition_maybe_unordered here always but this
15484 makes the resulting assembler clearer. */
15485 if (really_reversed)
15487 /* Reversal of FP compares takes care -- an ordered compare
15488 becomes an unordered compare and vice versa. */
15489 if (mode == CCFPmode)
15490 code = reverse_condition_maybe_unordered (code);
15492 code = reverse_condition (code);
15495 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
15497 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
15502 /* Opposite of GT. */
15511 gcc_unreachable ();
15517 /* Not all of these are actually distinct opcodes, but
15518 we distinguish them for clarity of the resulting assembler. */
15519 case NE: case LTGT:
15520 ccode = "ne"; break;
15521 case EQ: case UNEQ:
15522 ccode = "eq"; break;
15524 ccode = "ge"; break;
15525 case GT: case GTU: case UNGT:
15526 ccode = "gt"; break;
15528 ccode = "le"; break;
15529 case LT: case LTU: case UNLT:
15530 ccode = "lt"; break;
15531 case UNORDERED: ccode = "un"; break;
15532 case ORDERED: ccode = "nu"; break;
15533 case UNGE: ccode = "nl"; break;
15534 case UNLE: ccode = "ng"; break;
15536 gcc_unreachable ();
15539 /* Maybe we have a guess as to how likely the branch is.
15540 The old mnemonics don't have a way to specify this information. */
15542 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
15543 if (note != NULL_RTX)
15545 /* PROB is the difference from 50%. */
15546 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
15548 /* Only hint for highly probable/improbable branches on newer
15549 cpus as static prediction overrides processor dynamic
15550 prediction. For older cpus we may as well always hint, but
15551 assume not taken for branches that are very close to 50% as a
15552 mispredicted taken branch is more expensive than a
15553 mispredicted not-taken branch. */
15554 if (rs6000_always_hint
15555 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
15556 && br_prob_note_reliable_p (note)))
15558 if (abs (prob) > REG_BR_PROB_BASE / 20
15559 && ((prob > 0) ^ need_longbranch))
15567 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
15569 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
15571 /* We need to escape any '%' characters in the reg_names string.
15572 Assume they'd only be the first character.... */
15573 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
15575 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
15579 /* If the branch distance was too far, we may have to use an
15580 unconditional branch to go the distance. */
15581 if (need_longbranch)
15582 s += sprintf (s, ",$+8\n\tb %s", label);
15584 s += sprintf (s, ",%s", label);
15590 /* Return the string to flip the GT bit on a CR. */
15592 output_e500_flip_gt_bit (rtx dst, rtx src)
15594 static char string[64];
15597 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
15598 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
15601 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
15602 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
15604 sprintf (string, "crnot %d,%d", a, b);
15608 /* Return insn for VSX or Altivec comparisons. */
15611 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
15614 enum machine_mode mode = GET_MODE (op0);
15622 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
15628 mask = gen_reg_rtx (mode);
15629 emit_insn (gen_rtx_SET (VOIDmode,
15631 gen_rtx_fmt_ee (code, mode, op0, op1)));
15638 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
15639 DMODE is expected destination mode. This is a recursive function. */
15642 rs6000_emit_vector_compare (enum rtx_code rcode,
15644 enum machine_mode dmode)
15647 bool swap_operands = false;
15648 bool try_again = false;
15650 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
15651 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
15653 /* See if the comparison works as is. */
15654 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15662 swap_operands = true;
15667 swap_operands = true;
15675 /* Invert condition and try again.
15676 e.g., A != B becomes ~(A==B). */
15678 enum rtx_code rev_code;
15679 enum insn_code nor_code;
15682 rev_code = reverse_condition_maybe_unordered (rcode);
15683 if (rev_code == UNKNOWN)
15686 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
15687 if (nor_code == CODE_FOR_nothing)
15690 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
15694 mask = gen_reg_rtx (dmode);
15695 emit_insn (GEN_FCN (nor_code) (mask, mask2));
15703 /* Try GT/GTU/LT/LTU OR EQ */
15706 enum insn_code ior_code;
15707 enum rtx_code new_code;
15728 gcc_unreachable ();
15731 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
15732 if (ior_code == CODE_FOR_nothing)
15735 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
15739 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
15743 mask = gen_reg_rtx (dmode);
15744 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
15762 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15767 /* You only get two chances. */
15771 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
15772 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
15773 operands for the relation operation COND. */
15776 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
15777 rtx cond, rtx cc_op0, rtx cc_op1)
15779 enum machine_mode dest_mode = GET_MODE (dest);
15780 enum rtx_code rcode = GET_CODE (cond);
15781 enum machine_mode cc_mode = CCmode;
15785 bool invert_move = false;
15787 if (VECTOR_UNIT_NONE_P (dest_mode))
15792 /* Swap operands if we can, and fall back to doing the operation as
15793 specified, and doing a NOR to invert the test. */
15799 /* Invert condition and try again.
15800 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
15801 invert_move = true;
15802 rcode = reverse_condition_maybe_unordered (rcode);
15803 if (rcode == UNKNOWN)
15807 /* Mark unsigned tests with CCUNSmode. */
15812 cc_mode = CCUNSmode;
15819 /* Get the vector mask for the given relational operations. */
15820 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
15828 op_true = op_false;
15832 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
15833 emit_insn (gen_rtx_SET (VOIDmode,
15835 gen_rtx_IF_THEN_ELSE (dest_mode,
15842 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
15843 operands of the last comparison is nonzero/true, FALSE_COND if it
15844 is zero/false. Return 0 if the hardware has no such operation. */
15847 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15849 enum rtx_code code = GET_CODE (op);
15850 rtx op0 = XEXP (op, 0);
15851 rtx op1 = XEXP (op, 1);
15852 REAL_VALUE_TYPE c1;
15853 enum machine_mode compare_mode = GET_MODE (op0);
15854 enum machine_mode result_mode = GET_MODE (dest);
15856 bool is_against_zero;
15858 /* These modes should always match. */
15859 if (GET_MODE (op1) != compare_mode
15860 /* In the isel case however, we can use a compare immediate, so
15861 op1 may be a small constant. */
15862 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
15864 if (GET_MODE (true_cond) != result_mode)
15866 if (GET_MODE (false_cond) != result_mode)
15869 /* First, work out if the hardware can do this at all, or
15870 if it's too slow.... */
15871 if (!FLOAT_MODE_P (compare_mode))
15874 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
15877 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
15878 && SCALAR_FLOAT_MODE_P (compare_mode))
15881 is_against_zero = op1 == CONST0_RTX (compare_mode);
15883 /* A floating-point subtract might overflow, underflow, or produce
15884 an inexact result, thus changing the floating-point flags, so it
15885 can't be generated if we care about that. It's safe if one side
15886 of the construct is zero, since then no subtract will be
15888 if (SCALAR_FLOAT_MODE_P (compare_mode)
15889 && flag_trapping_math && ! is_against_zero)
15892 /* Eliminate half of the comparisons by switching operands, this
15893 makes the remaining code simpler. */
15894 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
15895 || code == LTGT || code == LT || code == UNLE)
15897 code = reverse_condition_maybe_unordered (code);
15899 true_cond = false_cond;
15903 /* UNEQ and LTGT take four instructions for a comparison with zero,
15904 it'll probably be faster to use a branch here too. */
15905 if (code == UNEQ && HONOR_NANS (compare_mode))
15908 if (GET_CODE (op1) == CONST_DOUBLE)
15909 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
15911 /* We're going to try to implement comparisons by performing
15912 a subtract, then comparing against zero. Unfortunately,
15913 Inf - Inf is NaN which is not zero, and so if we don't
15914 know that the operand is finite and the comparison
15915 would treat EQ different to UNORDERED, we can't do it. */
15916 if (HONOR_INFINITIES (compare_mode)
15917 && code != GT && code != UNGE
15918 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
15919 /* Constructs of the form (a OP b ? a : b) are safe. */
15920 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
15921 || (! rtx_equal_p (op0, true_cond)
15922 && ! rtx_equal_p (op1, true_cond))))
15925 /* At this point we know we can use fsel. */
15927 /* Reduce the comparison to a comparison against zero. */
15928 if (! is_against_zero)
15930 temp = gen_reg_rtx (compare_mode);
15931 emit_insn (gen_rtx_SET (VOIDmode, temp,
15932 gen_rtx_MINUS (compare_mode, op0, op1)));
15934 op1 = CONST0_RTX (compare_mode);
15937 /* If we don't care about NaNs we can reduce some of the comparisons
15938 down to faster ones. */
15939 if (! HONOR_NANS (compare_mode))
15945 true_cond = false_cond;
15958 /* Now, reduce everything down to a GE. */
15965 temp = gen_reg_rtx (compare_mode);
15966 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15971 temp = gen_reg_rtx (compare_mode);
15972 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
15977 temp = gen_reg_rtx (compare_mode);
15978 emit_insn (gen_rtx_SET (VOIDmode, temp,
15979 gen_rtx_NEG (compare_mode,
15980 gen_rtx_ABS (compare_mode, op0))));
15985 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
15986 temp = gen_reg_rtx (result_mode);
15987 emit_insn (gen_rtx_SET (VOIDmode, temp,
15988 gen_rtx_IF_THEN_ELSE (result_mode,
15989 gen_rtx_GE (VOIDmode,
15991 true_cond, false_cond)));
15992 false_cond = true_cond;
15995 temp = gen_reg_rtx (compare_mode);
15996 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16001 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
16002 temp = gen_reg_rtx (result_mode);
16003 emit_insn (gen_rtx_SET (VOIDmode, temp,
16004 gen_rtx_IF_THEN_ELSE (result_mode,
16005 gen_rtx_GE (VOIDmode,
16007 true_cond, false_cond)));
16008 true_cond = false_cond;
16011 temp = gen_reg_rtx (compare_mode);
16012 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16017 gcc_unreachable ();
16020 emit_insn (gen_rtx_SET (VOIDmode, dest,
16021 gen_rtx_IF_THEN_ELSE (result_mode,
16022 gen_rtx_GE (VOIDmode,
16024 true_cond, false_cond)));
16028 /* Same as above, but for ints (isel). */
16031 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16033 rtx condition_rtx, cr;
16034 enum machine_mode mode = GET_MODE (XEXP (op, 0));
16036 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
16039 /* We still have to do the compare, because isel doesn't do a
16040 compare, it just looks at the CRx bits set by a previous compare
16042 condition_rtx = rs6000_generate_compare (op, SImode);
16043 cr = XEXP (condition_rtx, 0);
16045 if (mode == SImode)
16047 if (GET_MODE (cr) == CCmode)
16048 emit_insn (gen_isel_signed_si (dest, condition_rtx,
16049 true_cond, false_cond, cr));
16051 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
16052 true_cond, false_cond, cr));
16056 if (GET_MODE (cr) == CCmode)
16057 emit_insn (gen_isel_signed_di (dest, condition_rtx,
16058 true_cond, false_cond, cr));
16060 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
16061 true_cond, false_cond, cr));
16068 output_isel (rtx *operands)
16070 enum rtx_code code;
16072 code = GET_CODE (operands[1]);
16073 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
16075 PUT_CODE (operands[1], reverse_condition (code));
16076 return "isel %0,%3,%2,%j1";
16079 return "isel %0,%2,%3,%j1";
16083 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
16085 enum machine_mode mode = GET_MODE (op0);
16089 /* VSX/altivec have direct min/max insns. */
16090 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
16092 emit_insn (gen_rtx_SET (VOIDmode,
16094 gen_rtx_fmt_ee (code, mode, op0, op1)));
16098 if (code == SMAX || code == SMIN)
16103 if (code == SMAX || code == UMAX)
16104 target = emit_conditional_move (dest, c, op0, op1, mode,
16105 op0, op1, mode, 0);
16107 target = emit_conditional_move (dest, c, op0, op1, mode,
16108 op1, op0, mode, 0);
16109 gcc_assert (target);
16110 if (target != dest)
16111 emit_move_insn (dest, target);
16114 /* Emit instructions to perform a load-reserved/store-conditional operation.
16115 The operation performed is an atomic
16116 (set M (CODE:MODE M OP))
16117 If not NULL, BEFORE is atomically set to M before the operation, and
16118 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16119 If SYNC_P then a memory barrier is emitted before the operation.
16120 Either OP or M may be wrapped in a NOT operation. */
16123 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16124 rtx m, rtx op, rtx before_param, rtx after_param,
16127 enum machine_mode used_mode;
16128 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16131 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16132 rtx shift = NULL_RTX;
16135 emit_insn (gen_lwsync ());
16139 /* If this is smaller than SImode, we'll have to use SImode with
16141 if (mode == QImode || mode == HImode)
16145 if (MEM_ALIGN (used_m) >= 32)
16148 if (BYTES_BIG_ENDIAN)
16149 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16151 shift = GEN_INT (ishift);
16152 used_m = change_address (used_m, SImode, 0);
16156 rtx addrSI, aligned_addr;
16157 int shift_mask = mode == QImode ? 0x18 : 0x10;
16159 addrSI = gen_lowpart_common (SImode,
16160 force_reg (Pmode, XEXP (used_m, 0)));
16161 addrSI = force_reg (SImode, addrSI);
16162 shift = gen_reg_rtx (SImode);
16164 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16165 GEN_INT (shift_mask)));
16166 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16168 aligned_addr = expand_binop (Pmode, and_optab,
16170 GEN_INT (-4), NULL_RTX,
16171 1, OPTAB_LIB_WIDEN);
16172 used_m = change_address (used_m, SImode, aligned_addr);
16173 set_mem_align (used_m, 32);
16175 /* It's safe to keep the old alias set of USED_M, because
16176 the operation is atomic and only affects the original
16180 if (GET_CODE (op) == NOT)
16182 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16183 oldop = gen_rtx_NOT (SImode, oldop);
16186 oldop = lowpart_subreg (SImode, op, mode);
16192 newop = expand_binop (SImode, and_optab,
16193 oldop, GEN_INT (imask), NULL_RTX,
16194 1, OPTAB_LIB_WIDEN);
16195 emit_insn (gen_ashlsi3 (newop, newop, shift));
16198 case NOT: /* NAND */
16199 newop = expand_binop (SImode, ior_optab,
16200 oldop, GEN_INT (~imask), NULL_RTX,
16201 1, OPTAB_LIB_WIDEN);
16202 emit_insn (gen_rotlsi3 (newop, newop, shift));
16206 newop = expand_binop (SImode, ior_optab,
16207 oldop, GEN_INT (~imask), NULL_RTX,
16208 1, OPTAB_LIB_WIDEN);
16209 emit_insn (gen_rotlsi3 (newop, newop, shift));
16217 newop = expand_binop (SImode, and_optab,
16218 oldop, GEN_INT (imask), NULL_RTX,
16219 1, OPTAB_LIB_WIDEN);
16220 emit_insn (gen_ashlsi3 (newop, newop, shift));
16222 mask = gen_reg_rtx (SImode);
16223 emit_move_insn (mask, GEN_INT (imask));
16224 emit_insn (gen_ashlsi3 (mask, mask, shift));
16227 newop = gen_rtx_PLUS (SImode, m, newop);
16229 newop = gen_rtx_MINUS (SImode, m, newop);
16230 newop = gen_rtx_AND (SImode, newop, mask);
16231 newop = gen_rtx_IOR (SImode, newop,
16232 gen_rtx_AND (SImode,
16233 gen_rtx_NOT (SImode, mask),
16239 gcc_unreachable ();
16243 used_mode = SImode;
16244 before = gen_reg_rtx (used_mode);
16245 after = gen_reg_rtx (used_mode);
16250 before = before_param;
16251 after = after_param;
16253 if (before == NULL_RTX)
16254 before = gen_reg_rtx (used_mode);
16255 if (after == NULL_RTX)
16256 after = gen_reg_rtx (used_mode);
16259 if ((code == PLUS || code == MINUS)
16260 && used_mode != mode)
16261 the_op = op; /* Computed above. */
16262 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16263 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16264 else if (code == NOT)
16265 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16266 gen_rtx_NOT (used_mode, m),
16267 gen_rtx_NOT (used_mode, op));
16269 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16271 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16272 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16273 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16274 gen_rtx_UNSPEC (used_mode,
16275 gen_rtvec (1, the_op),
16277 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16279 if ((code == PLUS || code == MINUS) && used_mode != mode)
16280 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16281 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16283 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16284 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16286 /* Shift and mask the return values properly. */
16287 if (used_mode != mode && before_param)
16289 emit_insn (gen_lshrsi3 (before, before, shift));
16290 convert_move (before_param, before, 1);
16293 if (used_mode != mode && after_param)
16295 emit_insn (gen_lshrsi3 (after, after, shift));
16296 convert_move (after_param, after, 1);
16299 /* The previous sequence will end with a branch that's dependent on
16300 the conditional store, so placing an isync will ensure that no
16301 other instructions (especially, no load or store instructions)
16302 can start before the atomic operation completes. */
16304 emit_insn (gen_isync ());
16307 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16308 COND is true. Mark the jump as unlikely to be taken. */
16311 emit_unlikely_jump (rtx cond, rtx label)
16313 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16316 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16317 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16318 add_reg_note (x, REG_BR_PROB, very_unlikely);
16321 /* A subroutine of the atomic operation splitters. Emit a load-locked
16322 instruction in MODE. */
16325 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16327 rtx (*fn) (rtx, rtx) = NULL;
16328 if (mode == SImode)
16329 fn = gen_load_locked_si;
16330 else if (mode == DImode)
16331 fn = gen_load_locked_di;
16332 emit_insn (fn (reg, mem));
16335 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16336 instruction in MODE. */
16339 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16341 rtx (*fn) (rtx, rtx, rtx) = NULL;
16342 if (mode == SImode)
16343 fn = gen_store_conditional_si;
16344 else if (mode == DImode)
16345 fn = gen_store_conditional_di;
16347 /* Emit sync before stwcx. to address PPC405 Erratum. */
16348 if (PPC405_ERRATUM77)
16349 emit_insn (gen_memory_barrier ());
16351 emit_insn (fn (res, mem, val));
16354 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16355 to perform. MEM is the memory on which to operate. VAL is the second
16356 operand of the binary operator. BEFORE and AFTER are optional locations to
16357 return the value of MEM either before of after the operation. SCRATCH is
16358 a scratch register. */
16361 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16362 rtx before, rtx after, rtx scratch)
16364 enum machine_mode mode = GET_MODE (mem);
16365 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16367 emit_insn (gen_lwsync ());
16369 label = gen_label_rtx ();
16370 emit_label (label);
16371 label = gen_rtx_LABEL_REF (VOIDmode, label);
16373 if (before == NULL_RTX)
16375 emit_load_locked (mode, before, mem);
16378 x = gen_rtx_IOR (mode,
16379 gen_rtx_NOT (mode, before),
16380 gen_rtx_NOT (mode, val));
16381 else if (code == AND)
16382 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16384 x = gen_rtx_fmt_ee (code, mode, before, val);
16386 if (after != NULL_RTX)
16387 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16388 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16390 emit_store_conditional (mode, cond, mem, scratch);
16392 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16393 emit_unlikely_jump (x, label);
16395 emit_insn (gen_isync ());
16398 /* Expand an atomic compare and swap operation. MEM is the memory on which
16399 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16400 value to be stored. SCRATCH is a scratch GPR. */
16403 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16406 enum machine_mode mode = GET_MODE (mem);
16407 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16409 emit_insn (gen_lwsync ());
16411 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16412 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16413 emit_label (XEXP (label1, 0));
16415 emit_load_locked (mode, retval, mem);
16417 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16418 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16420 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16421 emit_unlikely_jump (x, label2);
16423 emit_move_insn (scratch, newval);
16424 emit_store_conditional (mode, cond, mem, scratch);
16426 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16427 emit_unlikely_jump (x, label1);
16429 emit_insn (gen_isync ());
16430 emit_label (XEXP (label2, 0));
16433 /* Expand an atomic test and set operation. MEM is the memory on which
16434 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16437 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16439 enum machine_mode mode = GET_MODE (mem);
16440 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16442 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16443 emit_label (XEXP (label, 0));
16445 emit_load_locked (mode, retval, mem);
16446 emit_move_insn (scratch, val);
16447 emit_store_conditional (mode, cond, mem, scratch);
16449 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16450 emit_unlikely_jump (x, label);
16452 emit_insn (gen_isync ());
16456 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
16458 enum machine_mode mode = GET_MODE (mem);
16459 rtx addrSI, align, wdst, shift, mask;
16460 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
16461 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16463 /* Shift amount for subword relative to aligned word. */
16464 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
16465 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
16466 shift = gen_reg_rtx (SImode);
16467 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16468 GEN_INT (shift_mask)));
16469 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16471 /* Shift and mask old value into position within word. */
16472 oldval = convert_modes (SImode, mode, oldval, 1);
16473 oldval = expand_binop (SImode, and_optab,
16474 oldval, GEN_INT (imask), NULL_RTX,
16475 1, OPTAB_LIB_WIDEN);
16476 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
16478 /* Shift and mask new value into position within word. */
16479 newval = convert_modes (SImode, mode, newval, 1);
16480 newval = expand_binop (SImode, and_optab,
16481 newval, GEN_INT (imask), NULL_RTX,
16482 1, OPTAB_LIB_WIDEN);
16483 emit_insn (gen_ashlsi3 (newval, newval, shift));
16485 /* Mask for insertion. */
16486 mask = gen_reg_rtx (SImode);
16487 emit_move_insn (mask, GEN_INT (imask));
16488 emit_insn (gen_ashlsi3 (mask, mask, shift));
16490 /* Address of aligned word containing subword. */
16491 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
16492 NULL_RTX, 1, OPTAB_LIB_WIDEN);
16493 mem = change_address (mem, SImode, align);
16494 set_mem_align (mem, 32);
16495 MEM_VOLATILE_P (mem) = 1;
16497 wdst = gen_reg_rtx (SImode);
16498 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
16499 oldval, newval, mem));
16501 /* Shift the result back. */
16502 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
16504 emit_move_insn (dst, gen_lowpart (mode, wdst));
16508 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
16509 rtx oldval, rtx newval, rtx mem,
16512 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16514 emit_insn (gen_lwsync ());
16515 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16516 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16517 emit_label (XEXP (label1, 0));
16519 emit_load_locked (SImode, scratch, mem);
16521 /* Mask subword within loaded value for comparison with oldval.
16522 Use UNSPEC_AND to avoid clobber.*/
16523 emit_insn (gen_rtx_SET (SImode, dest,
16524 gen_rtx_UNSPEC (SImode,
16525 gen_rtvec (2, scratch, mask),
16528 x = gen_rtx_COMPARE (CCmode, dest, oldval);
16529 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16531 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16532 emit_unlikely_jump (x, label2);
16534 /* Clear subword within loaded value for insertion of new value. */
16535 emit_insn (gen_rtx_SET (SImode, scratch,
16536 gen_rtx_AND (SImode,
16537 gen_rtx_NOT (SImode, mask), scratch)));
16538 emit_insn (gen_iorsi3 (scratch, scratch, newval));
16539 emit_store_conditional (SImode, cond, mem, scratch);
16541 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16542 emit_unlikely_jump (x, label1);
16544 emit_insn (gen_isync ());
16545 emit_label (XEXP (label2, 0));
16549 /* Emit instructions to move SRC to DST. Called by splitters for
16550 multi-register moves. It will emit at most one instruction for
16551 each register that is accessed; that is, it won't emit li/lis pairs
16552 (or equivalent for 64-bit code). One of SRC or DST must be a hard
16556 rs6000_split_multireg_move (rtx dst, rtx src)
16558 /* The register number of the first register being moved. */
16560 /* The mode that is to be moved. */
16561 enum machine_mode mode;
16562 /* The mode that the move is being done in, and its size. */
16563 enum machine_mode reg_mode;
16565 /* The number of registers that will be moved. */
16568 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
16569 mode = GET_MODE (dst);
16570 nregs = hard_regno_nregs[reg][mode];
16571 if (FP_REGNO_P (reg))
16572 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
16573 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
16574 else if (ALTIVEC_REGNO_P (reg))
16575 reg_mode = V16QImode;
16576 else if (TARGET_E500_DOUBLE && mode == TFmode)
16579 reg_mode = word_mode;
16580 reg_mode_size = GET_MODE_SIZE (reg_mode);
16582 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
16584 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
16586 /* Move register range backwards, if we might have destructive
16589 for (i = nregs - 1; i >= 0; i--)
16590 emit_insn (gen_rtx_SET (VOIDmode,
16591 simplify_gen_subreg (reg_mode, dst, mode,
16592 i * reg_mode_size),
16593 simplify_gen_subreg (reg_mode, src, mode,
16594 i * reg_mode_size)));
16600 bool used_update = false;
16602 if (MEM_P (src) && INT_REGNO_P (reg))
16606 if (GET_CODE (XEXP (src, 0)) == PRE_INC
16607 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
16610 breg = XEXP (XEXP (src, 0), 0);
16611 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
16612 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
16613 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
16614 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16615 src = replace_equiv_address (src, breg);
16617 else if (! rs6000_offsettable_memref_p (src))
16620 basereg = gen_rtx_REG (Pmode, reg);
16621 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
16622 src = replace_equiv_address (src, basereg);
16625 breg = XEXP (src, 0);
16626 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
16627 breg = XEXP (breg, 0);
16629 /* If the base register we are using to address memory is
16630 also a destination reg, then change that register last. */
16632 && REGNO (breg) >= REGNO (dst)
16633 && REGNO (breg) < REGNO (dst) + nregs)
16634 j = REGNO (breg) - REGNO (dst);
16637 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
16641 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
16642 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
16645 breg = XEXP (XEXP (dst, 0), 0);
16646 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
16647 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
16648 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
16650 /* We have to update the breg before doing the store.
16651 Use store with update, if available. */
16655 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16656 emit_insn (TARGET_32BIT
16657 ? (TARGET_POWERPC64
16658 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
16659 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
16660 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
16661 used_update = true;
16664 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
16665 dst = replace_equiv_address (dst, breg);
16668 gcc_assert (rs6000_offsettable_memref_p (dst));
16671 for (i = 0; i < nregs; i++)
16673 /* Calculate index to next subword. */
16678 /* If compiler already emitted move of first word by
16679 store with update, no need to do anything. */
16680 if (j == 0 && used_update)
16683 emit_insn (gen_rtx_SET (VOIDmode,
16684 simplify_gen_subreg (reg_mode, dst, mode,
16685 j * reg_mode_size),
16686 simplify_gen_subreg (reg_mode, src, mode,
16687 j * reg_mode_size)));
16693 /* This page contains routines that are used to determine what the
16694 function prologue and epilogue code will do and write them out. */
16696 /* Return the first fixed-point register that is required to be
16697 saved. 32 if none. */
16700 first_reg_to_save (void)
16704 /* Find lowest numbered live register. */
16705 for (first_reg = 13; first_reg <= 31; first_reg++)
16706 if (df_regs_ever_live_p (first_reg)
16707 && (! call_used_regs[first_reg]
16708 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
16709 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
16710 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
16711 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
16716 && crtl->uses_pic_offset_table
16717 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
16718 return RS6000_PIC_OFFSET_TABLE_REGNUM;
16724 /* Similar, for FP regs. */
16727 first_fp_reg_to_save (void)
16731 /* Find lowest numbered live register. */
16732 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
16733 if (df_regs_ever_live_p (first_reg))
16739 /* Similar, for AltiVec regs. */
16742 first_altivec_reg_to_save (void)
16746 /* Stack frame remains as is unless we are in AltiVec ABI. */
16747 if (! TARGET_ALTIVEC_ABI)
16748 return LAST_ALTIVEC_REGNO + 1;
16750 /* On Darwin, the unwind routines are compiled without
16751 TARGET_ALTIVEC, and use save_world to save/restore the
16752 altivec registers when necessary. */
16753 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16754 && ! TARGET_ALTIVEC)
16755 return FIRST_ALTIVEC_REGNO + 20;
16757 /* Find lowest numbered live register. */
16758 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
16759 if (df_regs_ever_live_p (i))
16765 /* Return a 32-bit mask of the AltiVec registers we need to set in
16766 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
16767 the 32-bit word is 0. */
16769 static unsigned int
16770 compute_vrsave_mask (void)
16772 unsigned int i, mask = 0;
16774 /* On Darwin, the unwind routines are compiled without
16775 TARGET_ALTIVEC, and use save_world to save/restore the
16776 call-saved altivec registers when necessary. */
16777 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16778 && ! TARGET_ALTIVEC)
16781 /* First, find out if we use _any_ altivec registers. */
16782 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
16783 if (df_regs_ever_live_p (i))
16784 mask |= ALTIVEC_REG_BIT (i);
16789 /* Next, remove the argument registers from the set. These must
16790 be in the VRSAVE mask set by the caller, so we don't need to add
16791 them in again. More importantly, the mask we compute here is
16792 used to generate CLOBBERs in the set_vrsave insn, and we do not
16793 wish the argument registers to die. */
16794 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
16795 mask &= ~ALTIVEC_REG_BIT (i);
16797 /* Similarly, remove the return value from the set. */
16800 diddle_return_value (is_altivec_return_reg, &yes);
16802 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
16808 /* For a very restricted set of circumstances, we can cut down the
16809 size of prologues/epilogues by calling our own save/restore-the-world
16813 compute_save_world_info (rs6000_stack_t *info_ptr)
16815 info_ptr->world_save_p = 1;
16816 info_ptr->world_save_p
16817 = (WORLD_SAVE_P (info_ptr)
16818 && DEFAULT_ABI == ABI_DARWIN
16819 && ! (cfun->calls_setjmp && flag_exceptions)
16820 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
16821 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
16822 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
16823 && info_ptr->cr_save_p);
16825 /* This will not work in conjunction with sibcalls. Make sure there
16826 are none. (This check is expensive, but seldom executed.) */
16827 if (WORLD_SAVE_P (info_ptr))
16830 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
16831 if ( GET_CODE (insn) == CALL_INSN
16832 && SIBLING_CALL_P (insn))
16834 info_ptr->world_save_p = 0;
16839 if (WORLD_SAVE_P (info_ptr))
16841 /* Even if we're not touching VRsave, make sure there's room on the
16842 stack for it, if it looks like we're calling SAVE_WORLD, which
16843 will attempt to save it. */
16844 info_ptr->vrsave_size = 4;
16846 /* If we are going to save the world, we need to save the link register too. */
16847 info_ptr->lr_save_p = 1;
16849 /* "Save" the VRsave register too if we're saving the world. */
16850 if (info_ptr->vrsave_mask == 0)
16851 info_ptr->vrsave_mask = compute_vrsave_mask ();
16853 /* Because the Darwin register save/restore routines only handle
16854 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
16856 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
16857 && (info_ptr->first_altivec_reg_save
16858 >= FIRST_SAVED_ALTIVEC_REGNO));
16865 is_altivec_return_reg (rtx reg, void *xyes)
16867 bool *yes = (bool *) xyes;
16868 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
16873 /* Calculate the stack information for the current function. This is
16874 complicated by having two separate calling sequences, the AIX calling
16875 sequence and the V.4 calling sequence.
16877 AIX (and Darwin/Mac OS X) stack frames look like:
16879 SP----> +---------------------------------------+
16880 | back chain to caller | 0 0
16881 +---------------------------------------+
16882 | saved CR | 4 8 (8-11)
16883 +---------------------------------------+
16885 +---------------------------------------+
16886 | reserved for compilers | 12 24
16887 +---------------------------------------+
16888 | reserved for binders | 16 32
16889 +---------------------------------------+
16890 | saved TOC pointer | 20 40
16891 +---------------------------------------+
16892 | Parameter save area (P) | 24 48
16893 +---------------------------------------+
16894 | Alloca space (A) | 24+P etc.
16895 +---------------------------------------+
16896 | Local variable space (L) | 24+P+A
16897 +---------------------------------------+
16898 | Float/int conversion temporary (X) | 24+P+A+L
16899 +---------------------------------------+
16900 | Save area for AltiVec registers (W) | 24+P+A+L+X
16901 +---------------------------------------+
16902 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
16903 +---------------------------------------+
16904 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
16905 +---------------------------------------+
16906 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
16907 +---------------------------------------+
16908 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
16909 +---------------------------------------+
16910 old SP->| back chain to caller's caller |
16911 +---------------------------------------+
16913 The required alignment for AIX configurations is two words (i.e., 8
16917 V.4 stack frames look like:
16919 SP----> +---------------------------------------+
16920 | back chain to caller | 0
16921 +---------------------------------------+
16922 | caller's saved LR | 4
16923 +---------------------------------------+
16924 | Parameter save area (P) | 8
16925 +---------------------------------------+
16926 | Alloca space (A) | 8+P
16927 +---------------------------------------+
16928 | Varargs save area (V) | 8+P+A
16929 +---------------------------------------+
16930 | Local variable space (L) | 8+P+A+V
16931 +---------------------------------------+
16932 | Float/int conversion temporary (X) | 8+P+A+V+L
16933 +---------------------------------------+
16934 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
16935 +---------------------------------------+
16936 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
16937 +---------------------------------------+
16938 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
16939 +---------------------------------------+
16940 | SPE: area for 64-bit GP registers |
16941 +---------------------------------------+
16942 | SPE alignment padding |
16943 +---------------------------------------+
16944 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
16945 +---------------------------------------+
16946 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
16947 +---------------------------------------+
16948 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
16949 +---------------------------------------+
16950 old SP->| back chain to caller's caller |
16951 +---------------------------------------+
16953 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
16954 given. (But note below and in sysv4.h that we require only 8 and
16955 may round up the size of our stack frame anyways. The historical
16956 reason is early versions of powerpc-linux which didn't properly
16957 align the stack at program startup. A happy side-effect is that
16958 -mno-eabi libraries can be used with -meabi programs.)
16960 The EABI configuration defaults to the V.4 layout. However,
16961 the stack alignment requirements may differ. If -mno-eabi is not
16962 given, the required stack alignment is 8 bytes; if -mno-eabi is
16963 given, the required alignment is 16 bytes. (But see V.4 comment
16966 #ifndef ABI_STACK_BOUNDARY
16967 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
16970 static rs6000_stack_t *
16971 rs6000_stack_info (void)
16973 static rs6000_stack_t info;
16974 rs6000_stack_t *info_ptr = &info;
16975 int reg_size = TARGET_32BIT ? 4 : 8;
16979 HOST_WIDE_INT non_fixed_size;
16981 memset (&info, 0, sizeof (info));
16985 /* Cache value so we don't rescan instruction chain over and over. */
16986 if (cfun->machine->insn_chain_scanned_p == 0)
16987 cfun->machine->insn_chain_scanned_p
16988 = spe_func_has_64bit_regs_p () + 1;
16989 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
16992 /* Select which calling sequence. */
16993 info_ptr->abi = DEFAULT_ABI;
16995 /* Calculate which registers need to be saved & save area size. */
16996 info_ptr->first_gp_reg_save = first_reg_to_save ();
16997 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
16998 even if it currently looks like we won't. Reload may need it to
16999 get at a constant; if so, it will have already created a constant
17000 pool entry for it. */
17001 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
17002 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
17003 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
17004 && crtl->uses_const_pool
17005 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
17006 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
17008 first_gp = info_ptr->first_gp_reg_save;
17010 info_ptr->gp_size = reg_size * (32 - first_gp);
17012 /* For the SPE, we have an additional upper 32-bits on each GPR.
17013 Ideally we should save the entire 64-bits only when the upper
17014 half is used in SIMD instructions. Since we only record
17015 registers live (not the size they are used in), this proves
17016 difficult because we'd have to traverse the instruction chain at
17017 the right time, taking reload into account. This is a real pain,
17018 so we opt to save the GPRs in 64-bits always if but one register
17019 gets used in 64-bits. Otherwise, all the registers in the frame
17020 get saved in 32-bits.
17022 So... since when we save all GPRs (except the SP) in 64-bits, the
17023 traditional GP save area will be empty. */
17024 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17025 info_ptr->gp_size = 0;
17027 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
17028 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
17030 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
17031 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
17032 - info_ptr->first_altivec_reg_save);
17034 /* Does this function call anything? */
17035 info_ptr->calls_p = (! current_function_is_leaf
17036 || cfun->machine->ra_needs_full_frame);
17038 /* Determine if we need to save the link register. */
17039 if ((DEFAULT_ABI == ABI_AIX
17041 && !TARGET_PROFILE_KERNEL)
17042 #ifdef TARGET_RELOCATABLE
17043 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
17045 || (info_ptr->first_fp_reg_save != 64
17046 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
17047 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
17048 || info_ptr->calls_p
17049 || rs6000_ra_ever_killed ())
17051 info_ptr->lr_save_p = 1;
17052 df_set_regs_ever_live (LR_REGNO, true);
17055 /* Determine if we need to save the condition code registers. */
17056 if (df_regs_ever_live_p (CR2_REGNO)
17057 || df_regs_ever_live_p (CR3_REGNO)
17058 || df_regs_ever_live_p (CR4_REGNO))
17060 info_ptr->cr_save_p = 1;
17061 if (DEFAULT_ABI == ABI_V4)
17062 info_ptr->cr_size = reg_size;
17065 /* If the current function calls __builtin_eh_return, then we need
17066 to allocate stack space for registers that will hold data for
17067 the exception handler. */
17068 if (crtl->calls_eh_return)
17071 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
17074 /* SPE saves EH registers in 64-bits. */
17075 ehrd_size = i * (TARGET_SPE_ABI
17076 && info_ptr->spe_64bit_regs_used != 0
17077 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
17082 /* Determine various sizes. */
17083 info_ptr->reg_size = reg_size;
17084 info_ptr->fixed_size = RS6000_SAVE_AREA;
17085 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
17086 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
17087 TARGET_ALTIVEC ? 16 : 8);
17088 if (FRAME_GROWS_DOWNWARD)
17089 info_ptr->vars_size
17090 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
17091 + info_ptr->parm_size,
17092 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
17093 - (info_ptr->fixed_size + info_ptr->vars_size
17094 + info_ptr->parm_size);
17096 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17097 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17099 info_ptr->spe_gp_size = 0;
17101 if (TARGET_ALTIVEC_ABI)
17102 info_ptr->vrsave_mask = compute_vrsave_mask ();
17104 info_ptr->vrsave_mask = 0;
17106 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17107 info_ptr->vrsave_size = 4;
17109 info_ptr->vrsave_size = 0;
17111 compute_save_world_info (info_ptr);
17113 /* Calculate the offsets. */
17114 switch (DEFAULT_ABI)
17118 gcc_unreachable ();
17122 info_ptr->fp_save_offset = - info_ptr->fp_size;
17123 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17125 if (TARGET_ALTIVEC_ABI)
17127 info_ptr->vrsave_save_offset
17128 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17130 /* Align stack so vector save area is on a quadword boundary.
17131 The padding goes above the vectors. */
17132 if (info_ptr->altivec_size != 0)
17133 info_ptr->altivec_padding_size
17134 = info_ptr->vrsave_save_offset & 0xF;
17136 info_ptr->altivec_padding_size = 0;
17138 info_ptr->altivec_save_offset
17139 = info_ptr->vrsave_save_offset
17140 - info_ptr->altivec_padding_size
17141 - info_ptr->altivec_size;
17142 gcc_assert (info_ptr->altivec_size == 0
17143 || info_ptr->altivec_save_offset % 16 == 0);
17145 /* Adjust for AltiVec case. */
17146 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17149 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17150 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17151 info_ptr->lr_save_offset = 2*reg_size;
17155 info_ptr->fp_save_offset = - info_ptr->fp_size;
17156 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17157 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17159 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17161 /* Align stack so SPE GPR save area is aligned on a
17162 double-word boundary. */
17163 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17164 info_ptr->spe_padding_size
17165 = 8 - (-info_ptr->cr_save_offset % 8);
17167 info_ptr->spe_padding_size = 0;
17169 info_ptr->spe_gp_save_offset
17170 = info_ptr->cr_save_offset
17171 - info_ptr->spe_padding_size
17172 - info_ptr->spe_gp_size;
17174 /* Adjust for SPE case. */
17175 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17177 else if (TARGET_ALTIVEC_ABI)
17179 info_ptr->vrsave_save_offset
17180 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17182 /* Align stack so vector save area is on a quadword boundary. */
17183 if (info_ptr->altivec_size != 0)
17184 info_ptr->altivec_padding_size
17185 = 16 - (-info_ptr->vrsave_save_offset % 16);
17187 info_ptr->altivec_padding_size = 0;
17189 info_ptr->altivec_save_offset
17190 = info_ptr->vrsave_save_offset
17191 - info_ptr->altivec_padding_size
17192 - info_ptr->altivec_size;
17194 /* Adjust for AltiVec case. */
17195 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17198 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17199 info_ptr->ehrd_offset -= ehrd_size;
17200 info_ptr->lr_save_offset = reg_size;
17204 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17205 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17206 + info_ptr->gp_size
17207 + info_ptr->altivec_size
17208 + info_ptr->altivec_padding_size
17209 + info_ptr->spe_gp_size
17210 + info_ptr->spe_padding_size
17212 + info_ptr->cr_size
17213 + info_ptr->vrsave_size,
17216 non_fixed_size = (info_ptr->vars_size
17217 + info_ptr->parm_size
17218 + info_ptr->save_size);
17220 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17221 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17223 /* Determine if we need to allocate any stack frame:
17225 For AIX we need to push the stack if a frame pointer is needed
17226 (because the stack might be dynamically adjusted), if we are
17227 debugging, if we make calls, or if the sum of fp_save, gp_save,
17228 and local variables are more than the space needed to save all
17229 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17230 + 18*8 = 288 (GPR13 reserved).
17232 For V.4 we don't have the stack cushion that AIX uses, but assume
17233 that the debugger can handle stackless frames. */
17235 if (info_ptr->calls_p)
17236 info_ptr->push_p = 1;
17238 else if (DEFAULT_ABI == ABI_V4)
17239 info_ptr->push_p = non_fixed_size != 0;
17241 else if (frame_pointer_needed)
17242 info_ptr->push_p = 1;
17244 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17245 info_ptr->push_p = 1;
17248 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17250 /* Zero offsets if we're not saving those registers. */
17251 if (info_ptr->fp_size == 0)
17252 info_ptr->fp_save_offset = 0;
17254 if (info_ptr->gp_size == 0)
17255 info_ptr->gp_save_offset = 0;
17257 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17258 info_ptr->altivec_save_offset = 0;
17260 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17261 info_ptr->vrsave_save_offset = 0;
17263 if (! TARGET_SPE_ABI
17264 || info_ptr->spe_64bit_regs_used == 0
17265 || info_ptr->spe_gp_size == 0)
17266 info_ptr->spe_gp_save_offset = 0;
17268 if (! info_ptr->lr_save_p)
17269 info_ptr->lr_save_offset = 0;
17271 if (! info_ptr->cr_save_p)
17272 info_ptr->cr_save_offset = 0;
17277 /* Return true if the current function uses any GPRs in 64-bit SIMD
17281 spe_func_has_64bit_regs_p (void)
17285 /* Functions that save and restore all the call-saved registers will
17286 need to save/restore the registers in 64-bits. */
17287 if (crtl->calls_eh_return
17288 || cfun->calls_setjmp
17289 || crtl->has_nonlocal_goto)
17292 insns = get_insns ();
17294 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17300 /* FIXME: This should be implemented with attributes...
17302 (set_attr "spe64" "true")....then,
17303 if (get_spe64(insn)) return true;
17305 It's the only reliable way to do the stuff below. */
17307 i = PATTERN (insn);
17308 if (GET_CODE (i) == SET)
17310 enum machine_mode mode = GET_MODE (SET_SRC (i));
17312 if (SPE_VECTOR_MODE (mode))
17314 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17324 debug_stack_info (rs6000_stack_t *info)
17326 const char *abi_string;
17329 info = rs6000_stack_info ();
17331 fprintf (stderr, "\nStack information for function %s:\n",
17332 ((current_function_decl && DECL_NAME (current_function_decl))
17333 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17338 default: abi_string = "Unknown"; break;
17339 case ABI_NONE: abi_string = "NONE"; break;
17340 case ABI_AIX: abi_string = "AIX"; break;
17341 case ABI_DARWIN: abi_string = "Darwin"; break;
17342 case ABI_V4: abi_string = "V.4"; break;
17345 fprintf (stderr, "\tABI = %5s\n", abi_string);
17347 if (TARGET_ALTIVEC_ABI)
17348 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17350 if (TARGET_SPE_ABI)
17351 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17353 if (info->first_gp_reg_save != 32)
17354 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17356 if (info->first_fp_reg_save != 64)
17357 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17359 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17360 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17361 info->first_altivec_reg_save);
17363 if (info->lr_save_p)
17364 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17366 if (info->cr_save_p)
17367 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17369 if (info->vrsave_mask)
17370 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17373 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17376 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17378 if (info->gp_save_offset)
17379 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17381 if (info->fp_save_offset)
17382 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17384 if (info->altivec_save_offset)
17385 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17386 info->altivec_save_offset);
17388 if (info->spe_gp_save_offset)
17389 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17390 info->spe_gp_save_offset);
17392 if (info->vrsave_save_offset)
17393 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17394 info->vrsave_save_offset);
17396 if (info->lr_save_offset)
17397 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
17399 if (info->cr_save_offset)
17400 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
17402 if (info->varargs_save_offset)
17403 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
17405 if (info->total_size)
17406 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17409 if (info->vars_size)
17410 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17413 if (info->parm_size)
17414 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
17416 if (info->fixed_size)
17417 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
17420 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
17422 if (info->spe_gp_size)
17423 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
17426 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
17428 if (info->altivec_size)
17429 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
17431 if (info->vrsave_size)
17432 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
17434 if (info->altivec_padding_size)
17435 fprintf (stderr, "\taltivec_padding_size= %5d\n",
17436 info->altivec_padding_size);
17438 if (info->spe_padding_size)
17439 fprintf (stderr, "\tspe_padding_size = %5d\n",
17440 info->spe_padding_size);
17443 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
17445 if (info->save_size)
17446 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
17448 if (info->reg_size != 4)
17449 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
17451 fprintf (stderr, "\n");
17455 rs6000_return_addr (int count, rtx frame)
17457 /* Currently we don't optimize very well between prolog and body
17458 code and for PIC code the code can be actually quite bad, so
17459 don't try to be too clever here. */
17460 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
17462 cfun->machine->ra_needs_full_frame = 1;
17469 plus_constant (copy_to_reg
17470 (gen_rtx_MEM (Pmode,
17471 memory_address (Pmode, frame))),
17472 RETURN_ADDRESS_OFFSET)));
17475 cfun->machine->ra_need_lr = 1;
17476 return get_hard_reg_initial_val (Pmode, LR_REGNO);
17479 /* Say whether a function is a candidate for sibcall handling or not.
17480 We do not allow indirect calls to be optimized into sibling calls.
17481 Also, we can't do it if there are any vector parameters; there's
17482 nowhere to put the VRsave code so it works; note that functions with
17483 vector parameters are required to have a prototype, so the argument
17484 type info must be available here. (The tail recursion case can work
17485 with vector parameters, but there's no way to distinguish here.) */
17487 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
17492 if (TARGET_ALTIVEC_VRSAVE)
17494 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
17495 type; type = TREE_CHAIN (type))
17497 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
17501 if (DEFAULT_ABI == ABI_DARWIN
17502 || ((*targetm.binds_local_p) (decl)
17503 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
17505 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
17507 if (!lookup_attribute ("longcall", attr_list)
17508 || lookup_attribute ("shortcall", attr_list))
17515 /* NULL if INSN insn is valid within a low-overhead loop.
17516 Otherwise return why doloop cannot be applied.
17517 PowerPC uses the COUNT register for branch on table instructions. */
17519 static const char *
17520 rs6000_invalid_within_doloop (const_rtx insn)
17523 return "Function call in the loop.";
17526 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
17527 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
17528 return "Computed branch in the loop.";
17534 rs6000_ra_ever_killed (void)
17540 if (cfun->is_thunk)
17543 /* regs_ever_live has LR marked as used if any sibcalls are present,
17544 but this should not force saving and restoring in the
17545 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
17546 clobbers LR, so that is inappropriate. */
17548 /* Also, the prologue can generate a store into LR that
17549 doesn't really count, like this:
17552 bcl to set PIC register
17556 When we're called from the epilogue, we need to avoid counting
17557 this as a store. */
17559 push_topmost_sequence ();
17560 top = get_insns ();
17561 pop_topmost_sequence ();
17562 reg = gen_rtx_REG (Pmode, LR_REGNO);
17564 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
17570 if (!SIBLING_CALL_P (insn))
17573 else if (find_regno_note (insn, REG_INC, LR_REGNO))
17575 else if (set_of (reg, insn) != NULL_RTX
17576 && !prologue_epilogue_contains (insn))
17583 /* Emit instructions needed to load the TOC register.
17584 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
17585 a constant pool; or for SVR4 -fpic. */
17588 rs6000_emit_load_toc_table (int fromprolog)
17591 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
17593 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
17596 rtx lab, tmp1, tmp2, got;
17598 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17599 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17601 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17603 got = rs6000_got_sym ();
17604 tmp1 = tmp2 = dest;
17607 tmp1 = gen_reg_rtx (Pmode);
17608 tmp2 = gen_reg_rtx (Pmode);
17610 emit_insn (gen_load_toc_v4_PIC_1 (lab));
17611 emit_move_insn (tmp1,
17612 gen_rtx_REG (Pmode, LR_REGNO));
17613 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
17614 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
17616 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
17618 emit_insn (gen_load_toc_v4_pic_si ());
17619 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
17621 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
17624 rtx temp0 = (fromprolog
17625 ? gen_rtx_REG (Pmode, 0)
17626 : gen_reg_rtx (Pmode));
17632 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17633 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17635 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
17636 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17638 emit_insn (gen_load_toc_v4_PIC_1 (symF));
17639 emit_move_insn (dest,
17640 gen_rtx_REG (Pmode, LR_REGNO));
17641 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
17647 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17648 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
17649 emit_move_insn (dest,
17650 gen_rtx_REG (Pmode, LR_REGNO));
17651 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
17653 emit_insn (gen_addsi3 (dest, temp0, dest));
17655 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
17657 /* This is for AIX code running in non-PIC ELF32. */
17660 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
17661 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17663 emit_insn (gen_elf_high (dest, realsym));
17664 emit_insn (gen_elf_low (dest, dest, realsym));
17668 gcc_assert (DEFAULT_ABI == ABI_AIX);
17671 emit_insn (gen_load_toc_aix_si (dest));
17673 emit_insn (gen_load_toc_aix_di (dest));
17677 /* Emit instructions to restore the link register after determining where
17678 its value has been stored. */
17681 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
17683 rs6000_stack_t *info = rs6000_stack_info ();
17686 operands[0] = source;
17687 operands[1] = scratch;
17689 if (info->lr_save_p)
17691 rtx frame_rtx = stack_pointer_rtx;
17692 HOST_WIDE_INT sp_offset = 0;
17695 if (frame_pointer_needed
17696 || cfun->calls_alloca
17697 || info->total_size > 32767)
17699 tmp = gen_frame_mem (Pmode, frame_rtx);
17700 emit_move_insn (operands[1], tmp);
17701 frame_rtx = operands[1];
17703 else if (info->push_p)
17704 sp_offset = info->total_size;
17706 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
17707 tmp = gen_frame_mem (Pmode, tmp);
17708 emit_move_insn (tmp, operands[0]);
17711 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
17714 static GTY(()) alias_set_type set = -1;
17717 get_TOC_alias_set (void)
17720 set = new_alias_set ();
17724 /* This returns nonzero if the current function uses the TOC. This is
17725 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
17726 is generated by the ABI_V4 load_toc_* patterns. */
17733 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
17736 rtx pat = PATTERN (insn);
17739 if (GET_CODE (pat) == PARALLEL)
17740 for (i = 0; i < XVECLEN (pat, 0); i++)
17742 rtx sub = XVECEXP (pat, 0, i);
17743 if (GET_CODE (sub) == USE)
17745 sub = XEXP (sub, 0);
17746 if (GET_CODE (sub) == UNSPEC
17747 && XINT (sub, 1) == UNSPEC_TOC)
17757 create_TOC_reference (rtx symbol)
17759 if (TARGET_DEBUG_ADDR)
17761 if (GET_CODE (symbol) == SYMBOL_REF)
17762 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
17766 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
17767 GET_RTX_NAME (GET_CODE (symbol)));
17768 debug_rtx (symbol);
17772 if (!can_create_pseudo_p ())
17773 df_set_regs_ever_live (TOC_REGISTER, true);
17774 return gen_rtx_PLUS (Pmode,
17775 gen_rtx_REG (Pmode, TOC_REGISTER),
17776 gen_rtx_CONST (Pmode,
17777 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL)));
17780 /* Issue assembly directives that create a reference to the given DWARF
17781 FRAME_TABLE_LABEL from the current function section. */
17783 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
17785 fprintf (asm_out_file, "\t.ref %s\n",
17786 TARGET_STRIP_NAME_ENCODING (frame_table_label));
17789 /* If _Unwind_* has been called from within the same module,
17790 toc register is not guaranteed to be saved to 40(1) on function
17791 entry. Save it there in that case. */
17794 rs6000_aix_emit_builtin_unwind_init (void)
17797 rtx stack_top = gen_reg_rtx (Pmode);
17798 rtx opcode_addr = gen_reg_rtx (Pmode);
17799 rtx opcode = gen_reg_rtx (SImode);
17800 rtx tocompare = gen_reg_rtx (SImode);
17801 rtx no_toc_save_needed = gen_label_rtx ();
17803 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
17804 emit_move_insn (stack_top, mem);
17806 mem = gen_frame_mem (Pmode,
17807 gen_rtx_PLUS (Pmode, stack_top,
17808 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
17809 emit_move_insn (opcode_addr, mem);
17810 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
17811 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
17812 : 0xE8410028, SImode));
17814 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
17815 SImode, NULL_RTX, NULL_RTX,
17816 no_toc_save_needed);
17818 mem = gen_frame_mem (Pmode,
17819 gen_rtx_PLUS (Pmode, stack_top,
17820 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
17821 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
17822 emit_label (no_toc_save_needed);
17825 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
17826 and the change to the stack pointer. */
17829 rs6000_emit_stack_tie (void)
17831 rtx mem = gen_frame_mem (BLKmode,
17832 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
17834 emit_insn (gen_stack_tie (mem));
17837 /* Emit the correct code for allocating stack space, as insns.
17838 If COPY_R12, make sure a copy of the old frame is left in r12.
17839 If COPY_R11, make sure a copy of the old frame is left in r11,
17840 in preference to r12 if COPY_R12.
17841 The generated code may use hard register 0 as a temporary. */
17844 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
17847 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
17848 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
17849 rtx todec = gen_int_mode (-size, Pmode);
17852 if (INTVAL (todec) != -size)
17854 warning (0, "stack frame too large");
17855 emit_insn (gen_trap ());
17859 if (crtl->limit_stack)
17861 if (REG_P (stack_limit_rtx)
17862 && REGNO (stack_limit_rtx) > 1
17863 && REGNO (stack_limit_rtx) <= 31)
17865 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
17866 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
17869 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
17871 && DEFAULT_ABI == ABI_V4)
17873 rtx toload = gen_rtx_CONST (VOIDmode,
17874 gen_rtx_PLUS (Pmode,
17878 emit_insn (gen_elf_high (tmp_reg, toload));
17879 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
17880 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
17884 warning (0, "stack limit expression is not supported");
17887 if (copy_r12 || copy_r11)
17888 emit_move_insn (copy_r11
17889 ? gen_rtx_REG (Pmode, 11)
17890 : gen_rtx_REG (Pmode, 12),
17895 /* Need a note here so that try_split doesn't get confused. */
17896 if (get_last_insn () == NULL_RTX)
17897 emit_note (NOTE_INSN_DELETED);
17898 insn = emit_move_insn (tmp_reg, todec);
17899 try_split (PATTERN (insn), insn, 0);
17903 insn = emit_insn (TARGET_32BIT
17904 ? gen_movsi_update_stack (stack_reg, stack_reg,
17906 : gen_movdi_di_update_stack (stack_reg, stack_reg,
17907 todec, stack_reg));
17908 /* Since we didn't use gen_frame_mem to generate the MEM, grab
17909 it now and set the alias set/attributes. The above gen_*_update
17910 calls will generate a PARALLEL with the MEM set being the first
17912 par = PATTERN (insn);
17913 gcc_assert (GET_CODE (par) == PARALLEL);
17914 set = XVECEXP (par, 0, 0);
17915 gcc_assert (GET_CODE (set) == SET);
17916 mem = SET_DEST (set);
17917 gcc_assert (MEM_P (mem));
17918 MEM_NOTRAP_P (mem) = 1;
17919 set_mem_alias_set (mem, get_frame_alias_set ());
17921 RTX_FRAME_RELATED_P (insn) = 1;
17922 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
17923 gen_rtx_SET (VOIDmode, stack_reg,
17924 gen_rtx_PLUS (Pmode, stack_reg,
17925 GEN_INT (-size))));
17928 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
17929 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
17930 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
17931 deduce these equivalences by itself so it wasn't necessary to hold
17932 its hand so much. */
17935 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
17936 rtx reg2, rtx rreg)
17940 /* copy_rtx will not make unique copies of registers, so we need to
17941 ensure we don't have unwanted sharing here. */
17943 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
17946 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
17948 real = copy_rtx (PATTERN (insn));
17950 if (reg2 != NULL_RTX)
17951 real = replace_rtx (real, reg2, rreg);
17953 real = replace_rtx (real, reg,
17954 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
17955 STACK_POINTER_REGNUM),
17958 /* We expect that 'real' is either a SET or a PARALLEL containing
17959 SETs (and possibly other stuff). In a PARALLEL, all the SETs
17960 are important so they all have to be marked RTX_FRAME_RELATED_P. */
17962 if (GET_CODE (real) == SET)
17966 temp = simplify_rtx (SET_SRC (set));
17968 SET_SRC (set) = temp;
17969 temp = simplify_rtx (SET_DEST (set));
17971 SET_DEST (set) = temp;
17972 if (GET_CODE (SET_DEST (set)) == MEM)
17974 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
17976 XEXP (SET_DEST (set), 0) = temp;
17983 gcc_assert (GET_CODE (real) == PARALLEL);
17984 for (i = 0; i < XVECLEN (real, 0); i++)
17985 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
17987 rtx set = XVECEXP (real, 0, i);
17989 temp = simplify_rtx (SET_SRC (set));
17991 SET_SRC (set) = temp;
17992 temp = simplify_rtx (SET_DEST (set));
17994 SET_DEST (set) = temp;
17995 if (GET_CODE (SET_DEST (set)) == MEM)
17997 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
17999 XEXP (SET_DEST (set), 0) = temp;
18001 RTX_FRAME_RELATED_P (set) = 1;
18005 RTX_FRAME_RELATED_P (insn) = 1;
18006 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
18009 /* Returns an insn that has a vrsave set operation with the
18010 appropriate CLOBBERs. */
18013 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
18016 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
18017 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18020 = gen_rtx_SET (VOIDmode,
18022 gen_rtx_UNSPEC_VOLATILE (SImode,
18023 gen_rtvec (2, reg, vrsave),
18024 UNSPECV_SET_VRSAVE));
18028 /* We need to clobber the registers in the mask so the scheduler
18029 does not move sets to VRSAVE before sets of AltiVec registers.
18031 However, if the function receives nonlocal gotos, reload will set
18032 all call saved registers live. We will end up with:
18034 (set (reg 999) (mem))
18035 (parallel [ (set (reg vrsave) (unspec blah))
18036 (clobber (reg 999))])
18038 The clobber will cause the store into reg 999 to be dead, and
18039 flow will attempt to delete an epilogue insn. In this case, we
18040 need an unspec use/set of the register. */
18042 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18043 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18045 if (!epiloguep || call_used_regs [i])
18046 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
18047 gen_rtx_REG (V4SImode, i));
18050 rtx reg = gen_rtx_REG (V4SImode, i);
18053 = gen_rtx_SET (VOIDmode,
18055 gen_rtx_UNSPEC (V4SImode,
18056 gen_rtvec (1, reg), 27));
18060 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
18062 for (i = 0; i < nclobs; ++i)
18063 XVECEXP (insn, 0, i) = clobs[i];
18068 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
18069 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
18072 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
18073 unsigned int regno, int offset, HOST_WIDE_INT total_size)
18075 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
18076 rtx replacea, replaceb;
18078 int_rtx = GEN_INT (offset);
18080 /* Some cases that need register indexed addressing. */
18081 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
18082 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
18083 || (TARGET_E500_DOUBLE && mode == DFmode)
18085 && SPE_VECTOR_MODE (mode)
18086 && !SPE_CONST_OFFSET_OK (offset)))
18088 /* Whomever calls us must make sure r11 is available in the
18089 flow path of instructions in the prologue. */
18090 offset_rtx = gen_rtx_REG (Pmode, 11);
18091 emit_move_insn (offset_rtx, int_rtx);
18093 replacea = offset_rtx;
18094 replaceb = int_rtx;
18098 offset_rtx = int_rtx;
18099 replacea = NULL_RTX;
18100 replaceb = NULL_RTX;
18103 reg = gen_rtx_REG (mode, regno);
18104 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18105 mem = gen_frame_mem (mode, addr);
18107 insn = emit_move_insn (mem, reg);
18109 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18112 /* Emit an offset memory reference suitable for a frame store, while
18113 converting to a valid addressing mode. */
18116 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18118 rtx int_rtx, offset_rtx;
18120 int_rtx = GEN_INT (offset);
18122 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18123 || (TARGET_E500_DOUBLE && mode == DFmode))
18125 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18126 emit_move_insn (offset_rtx, int_rtx);
18129 offset_rtx = int_rtx;
18131 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18134 /* Look for user-defined global regs. We should not save and restore these,
18135 and cannot use stmw/lmw if there are any in its range. */
18138 no_global_regs_above (int first, bool gpr)
18141 int last = gpr ? 32 : 64;
18142 for (i = first; i < last; i++)
18143 if (global_regs[i])
18148 #ifndef TARGET_FIX_AND_CONTINUE
18149 #define TARGET_FIX_AND_CONTINUE 0
18152 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18153 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18154 #define LAST_SAVRES_REGISTER 31
18155 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18157 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18159 /* Temporary holding space for an out-of-line register save/restore
18161 static char savres_routine_name[30];
18163 /* Return the name for an out-of-line register save/restore routine.
18164 We are saving/restoring GPRs if GPR is true. */
18167 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18168 bool savep, bool gpr, bool lr)
18170 const char *prefix = "";
18171 const char *suffix = "";
18173 /* Different targets are supposed to define
18174 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18175 routine name could be defined with:
18177 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18179 This is a nice idea in practice, but in reality, things are
18180 complicated in several ways:
18182 - ELF targets have save/restore routines for GPRs.
18184 - SPE targets use different prefixes for 32/64-bit registers, and
18185 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18187 - PPC64 ELF targets have routines for save/restore of GPRs that
18188 differ in what they do with the link register, so having a set
18189 prefix doesn't work. (We only use one of the save routines at
18190 the moment, though.)
18192 - PPC32 elf targets have "exit" versions of the restore routines
18193 that restore the link register and can save some extra space.
18194 These require an extra suffix. (There are also "tail" versions
18195 of the restore routines and "GOT" versions of the save routines,
18196 but we don't generate those at present. Same problems apply,
18199 We deal with all this by synthesizing our own prefix/suffix and
18200 using that for the simple sprintf call shown above. */
18203 /* No floating point saves on the SPE. */
18207 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
18209 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
18214 else if (DEFAULT_ABI == ABI_V4)
18220 prefix = savep ? "_savegpr_" : "_restgpr_";
18222 prefix = savep ? "_savefpr_" : "_restfpr_";
18227 else if (DEFAULT_ABI == ABI_AIX)
18229 #ifndef POWERPC_LINUX
18230 /* No out-of-line save/restore routines for GPRs on AIX. */
18231 gcc_assert (!TARGET_AIX || !gpr);
18237 ? (lr ? "_savegpr0_" : "_savegpr1_")
18238 : (lr ? "_restgpr0_" : "_restgpr1_"));
18239 #ifdef POWERPC_LINUX
18241 prefix = (savep ? "_savefpr_" : "_restfpr_");
18245 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
18246 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
18249 else if (DEFAULT_ABI == ABI_DARWIN)
18250 sorry ("Out-of-line save/restore routines not supported on Darwin");
18252 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
18254 return savres_routine_name;
18257 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18258 We are saving/restoring GPRs if GPR is true. */
18261 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
18264 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18266 int select = ((savep ? 1 : 0) << 2
18268 /* On the SPE, we never have any FPRs, but we do have
18269 32/64-bit versions of the routines. */
18270 ? (info->spe_64bit_regs_used ? 1 : 0)
18271 : (gpr ? 1 : 0)) << 1)
18274 /* Don't generate bogus routine names. */
18275 gcc_assert (FIRST_SAVRES_REGISTER <= regno
18276 && regno <= LAST_SAVRES_REGISTER);
18278 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18284 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
18286 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18287 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18288 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
18294 /* Emit a sequence of insns, including a stack tie if needed, for
18295 resetting the stack pointer. If SAVRES is true, then don't reset the
18296 stack pointer, but move the base of the frame into r11 for use by
18297 out-of-line register restore routines. */
18300 rs6000_emit_stack_reset (rs6000_stack_t *info,
18301 rtx sp_reg_rtx, rtx frame_reg_rtx,
18302 int sp_offset, bool savres)
18304 /* This blockage is needed so that sched doesn't decide to move
18305 the sp change before the register restores. */
18306 if (frame_reg_rtx != sp_reg_rtx
18308 && info->spe_64bit_regs_used != 0
18309 && info->first_gp_reg_save != 32))
18310 rs6000_emit_stack_tie ();
18312 if (frame_reg_rtx != sp_reg_rtx)
18314 if (sp_offset != 0)
18316 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
18317 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
18318 GEN_INT (sp_offset)));
18321 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18323 else if (sp_offset != 0)
18325 /* If we are restoring registers out-of-line, we will be using the
18326 "exit" variants of the restore routines, which will reset the
18327 stack for us. But we do need to point r11 into the right place
18328 for those routines. */
18329 rtx dest_reg = (savres
18330 ? gen_rtx_REG (Pmode, 11)
18333 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18334 GEN_INT (sp_offset)));
18341 /* Construct a parallel rtx describing the effect of a call to an
18342 out-of-line register save/restore routine. */
18345 rs6000_make_savres_rtx (rs6000_stack_t *info,
18346 rtx frame_reg_rtx, int save_area_offset,
18347 enum machine_mode reg_mode,
18348 bool savep, bool gpr, bool lr)
18351 int offset, start_reg, end_reg, n_regs;
18352 int reg_size = GET_MODE_SIZE (reg_mode);
18358 ? info->first_gp_reg_save
18359 : info->first_fp_reg_save);
18360 end_reg = gpr ? 32 : 64;
18361 n_regs = end_reg - start_reg;
18362 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
18365 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18367 RTVEC_ELT (p, offset++)
18368 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18370 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
18371 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18372 RTVEC_ELT (p, offset++)
18373 = gen_rtx_USE (VOIDmode,
18374 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
18378 for (i = 0; i < end_reg - start_reg; i++)
18380 rtx addr, reg, mem;
18381 reg = gen_rtx_REG (reg_mode, start_reg + i);
18382 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18383 GEN_INT (save_area_offset + reg_size*i));
18384 mem = gen_frame_mem (reg_mode, addr);
18386 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
18388 savep ? reg : mem);
18393 rtx addr, reg, mem;
18394 reg = gen_rtx_REG (Pmode, 0);
18395 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18396 GEN_INT (info->lr_save_offset));
18397 mem = gen_frame_mem (Pmode, addr);
18398 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
18401 return gen_rtx_PARALLEL (VOIDmode, p);
18404 /* Determine whether the gp REG is really used. */
18407 rs6000_reg_live_or_pic_offset_p (int reg)
18409 return ((df_regs_ever_live_p (reg)
18410 && (!call_used_regs[reg]
18411 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18412 && TARGET_TOC && TARGET_MINIMAL_TOC)))
18413 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18414 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18415 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
18419 SAVRES_MULTIPLE = 0x1,
18420 SAVRES_INLINE_FPRS = 0x2,
18421 SAVRES_INLINE_GPRS = 0x4,
18422 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
18423 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
18424 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
18427 /* Determine the strategy for savings/restoring registers. */
18430 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
18431 int using_static_chain_p, int sibcall)
18433 bool using_multiple_p;
18435 bool savres_fprs_inline;
18436 bool savres_gprs_inline;
18437 bool noclobber_global_gprs
18438 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
18441 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
18442 && (!TARGET_SPE_ABI
18443 || info->spe_64bit_regs_used == 0)
18444 && info->first_gp_reg_save < 31
18445 && noclobber_global_gprs);
18446 /* Don't bother to try to save things out-of-line if r11 is occupied
18447 by the static chain. It would require too much fiddling and the
18448 static chain is rarely used anyway. */
18449 common = (using_static_chain_p
18451 || crtl->calls_eh_return
18452 || !info->lr_save_p
18453 || cfun->machine->ra_need_lr
18454 || info->total_size > 32767);
18455 savres_fprs_inline = (common
18456 || info->first_fp_reg_save == 64
18457 || !no_global_regs_above (info->first_fp_reg_save,
18459 /* The out-of-line FP routines use
18460 double-precision stores; we can't use those
18461 routines if we don't have such stores. */
18462 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18463 || FP_SAVE_INLINE (info->first_fp_reg_save));
18464 savres_gprs_inline = (common
18465 /* Saving CR interferes with the exit routines
18466 used on the SPE, so just punt here. */
18469 && info->spe_64bit_regs_used != 0
18470 && info->cr_save_p != 0)
18471 || info->first_gp_reg_save == 32
18472 || !noclobber_global_gprs
18473 || GP_SAVE_INLINE (info->first_gp_reg_save));
18476 /* If we are going to use store multiple, then don't even bother
18477 with the out-of-line routines, since the store-multiple instruction
18478 will always be smaller. */
18479 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18482 /* The situation is more complicated with load multiple. We'd
18483 prefer to use the out-of-line routines for restores, since the
18484 "exit" out-of-line routines can handle the restore of LR and
18485 the frame teardown. But we can only use the out-of-line
18486 routines if we know that we've used store multiple or
18487 out-of-line routines in the prologue, i.e. if we've saved all
18488 the registers from first_gp_reg_save. Otherwise, we risk
18489 loading garbage from the stack. Furthermore, we can only use
18490 the "exit" out-of-line gpr restore if we haven't saved any
18492 bool saved_all = !savres_gprs_inline || using_multiple_p;
18494 if (saved_all && info->first_fp_reg_save != 64)
18495 /* We can't use the exit routine; use load multiple if it's
18497 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18500 strategy = (using_multiple_p
18501 | (savres_fprs_inline << 1)
18502 | (savres_gprs_inline << 2));
18503 #ifdef POWERPC_LINUX
18506 if (!savres_fprs_inline)
18507 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
18508 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
18509 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
18512 if (TARGET_AIX && !savres_fprs_inline)
18513 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18518 /* Emit function prologue as insns. */
18521 rs6000_emit_prologue (void)
18523 rs6000_stack_t *info = rs6000_stack_info ();
18524 enum machine_mode reg_mode = Pmode;
18525 int reg_size = TARGET_32BIT ? 4 : 8;
18526 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18527 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
18528 rtx frame_reg_rtx = sp_reg_rtx;
18529 rtx cr_save_rtx = NULL_RTX;
18532 int saving_FPRs_inline;
18533 int saving_GPRs_inline;
18534 int using_store_multiple;
18535 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18536 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18537 && call_used_regs[STATIC_CHAIN_REGNUM]);
18538 HOST_WIDE_INT sp_offset = 0;
18540 if (TARGET_FIX_AND_CONTINUE)
18542 /* gdb on darwin arranges to forward a function from the old
18543 address by modifying the first 5 instructions of the function
18544 to branch to the overriding function. This is necessary to
18545 permit function pointers that point to the old function to
18546 actually forward to the new function. */
18547 emit_insn (gen_nop ());
18548 emit_insn (gen_nop ());
18549 emit_insn (gen_nop ());
18550 emit_insn (gen_nop ());
18551 emit_insn (gen_nop ());
18554 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
18556 reg_mode = V2SImode;
18560 strategy = rs6000_savres_strategy (info, /*savep=*/true,
18561 /*static_chain_p=*/using_static_chain_p,
18563 using_store_multiple = strategy & SAVRES_MULTIPLE;
18564 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
18565 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
18567 /* For V.4, update stack before we do any saving and set back pointer. */
18568 if (! WORLD_SAVE_P (info)
18570 && (DEFAULT_ABI == ABI_V4
18571 || crtl->calls_eh_return))
18573 bool need_r11 = (TARGET_SPE
18574 ? (!saving_GPRs_inline
18575 && info->spe_64bit_regs_used == 0)
18576 : (!saving_FPRs_inline || !saving_GPRs_inline));
18577 if (info->total_size < 32767)
18578 sp_offset = info->total_size;
18580 frame_reg_rtx = (need_r11
18581 ? gen_rtx_REG (Pmode, 11)
18583 rs6000_emit_allocate_stack (info->total_size,
18584 (frame_reg_rtx != sp_reg_rtx
18585 && (info->cr_save_p
18587 || info->first_fp_reg_save < 64
18588 || info->first_gp_reg_save < 32
18591 if (frame_reg_rtx != sp_reg_rtx)
18592 rs6000_emit_stack_tie ();
18595 /* Handle world saves specially here. */
18596 if (WORLD_SAVE_P (info))
18603 /* save_world expects lr in r0. */
18604 reg0 = gen_rtx_REG (Pmode, 0);
18605 if (info->lr_save_p)
18607 insn = emit_move_insn (reg0,
18608 gen_rtx_REG (Pmode, LR_REGNO));
18609 RTX_FRAME_RELATED_P (insn) = 1;
18612 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
18613 assumptions about the offsets of various bits of the stack
18615 gcc_assert (info->gp_save_offset == -220
18616 && info->fp_save_offset == -144
18617 && info->lr_save_offset == 8
18618 && info->cr_save_offset == 4
18621 && (!crtl->calls_eh_return
18622 || info->ehrd_offset == -432)
18623 && info->vrsave_save_offset == -224
18624 && info->altivec_save_offset == -416);
18626 treg = gen_rtx_REG (SImode, 11);
18627 emit_move_insn (treg, GEN_INT (-info->total_size));
18629 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
18630 in R11. It also clobbers R12, so beware! */
18632 /* Preserve CR2 for save_world prologues */
18634 sz += 32 - info->first_gp_reg_save;
18635 sz += 64 - info->first_fp_reg_save;
18636 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
18637 p = rtvec_alloc (sz);
18639 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
18640 gen_rtx_REG (SImode,
18642 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
18643 gen_rtx_SYMBOL_REF (Pmode,
18645 /* We do floats first so that the instruction pattern matches
18647 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18649 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18650 ? DFmode : SFmode),
18651 info->first_fp_reg_save + i);
18652 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18653 GEN_INT (info->fp_save_offset
18654 + sp_offset + 8 * i));
18655 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18656 ? DFmode : SFmode), addr);
18658 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18660 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
18662 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
18663 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18664 GEN_INT (info->altivec_save_offset
18665 + sp_offset + 16 * i));
18666 rtx mem = gen_frame_mem (V4SImode, addr);
18668 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18670 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18672 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18673 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18674 GEN_INT (info->gp_save_offset
18675 + sp_offset + reg_size * i));
18676 rtx mem = gen_frame_mem (reg_mode, addr);
18678 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18682 /* CR register traditionally saved as CR2. */
18683 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
18684 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18685 GEN_INT (info->cr_save_offset
18687 rtx mem = gen_frame_mem (reg_mode, addr);
18689 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18691 /* Explain about use of R0. */
18692 if (info->lr_save_p)
18694 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18695 GEN_INT (info->lr_save_offset
18697 rtx mem = gen_frame_mem (reg_mode, addr);
18699 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
18701 /* Explain what happens to the stack pointer. */
18703 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
18704 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
18707 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18708 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18709 treg, GEN_INT (-info->total_size));
18710 sp_offset = info->total_size;
18713 /* If we use the link register, get it into r0. */
18714 if (!WORLD_SAVE_P (info) && info->lr_save_p)
18716 rtx addr, reg, mem;
18718 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
18719 gen_rtx_REG (Pmode, LR_REGNO));
18720 RTX_FRAME_RELATED_P (insn) = 1;
18722 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
18723 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
18725 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18726 GEN_INT (info->lr_save_offset + sp_offset));
18727 reg = gen_rtx_REG (Pmode, 0);
18728 mem = gen_rtx_MEM (Pmode, addr);
18729 /* This should not be of rs6000_sr_alias_set, because of
18730 __builtin_return_address. */
18732 insn = emit_move_insn (mem, reg);
18733 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18734 NULL_RTX, NULL_RTX);
18738 /* If we need to save CR, put it into r12 or r11. */
18739 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
18744 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
18746 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18747 RTX_FRAME_RELATED_P (insn) = 1;
18748 /* Now, there's no way that dwarf2out_frame_debug_expr is going
18749 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
18750 But that's OK. All we have to do is specify that _one_ condition
18751 code register is saved in this stack slot. The thrower's epilogue
18752 will then restore all the call-saved registers.
18753 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
18754 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
18755 gen_rtx_REG (SImode, CR2_REGNO));
18756 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18759 /* Do any required saving of fpr's. If only one or two to save, do
18760 it ourselves. Otherwise, call function. */
18761 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
18764 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18765 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
18766 && ! call_used_regs[info->first_fp_reg_save+i]))
18767 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
18768 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18770 info->first_fp_reg_save + i,
18771 info->fp_save_offset + sp_offset + 8 * i,
18774 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
18778 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18779 info->fp_save_offset + sp_offset,
18781 /*savep=*/true, /*gpr=*/false,
18783 & SAVRES_NOINLINE_FPRS_SAVES_LR)
18785 insn = emit_insn (par);
18786 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18787 NULL_RTX, NULL_RTX);
18790 /* Save GPRs. This is done as a PARALLEL if we are using
18791 the store-multiple instructions. */
18792 if (!WORLD_SAVE_P (info)
18794 && info->spe_64bit_regs_used != 0
18795 && info->first_gp_reg_save != 32)
18798 rtx spe_save_area_ptr;
18800 /* Determine whether we can address all of the registers that need
18801 to be saved with an offset from the stack pointer that fits in
18802 the small const field for SPE memory instructions. */
18803 int spe_regs_addressable_via_sp
18804 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
18805 + (32 - info->first_gp_reg_save - 1) * reg_size)
18806 && saving_GPRs_inline);
18809 if (spe_regs_addressable_via_sp)
18811 spe_save_area_ptr = frame_reg_rtx;
18812 spe_offset = info->spe_gp_save_offset + sp_offset;
18816 /* Make r11 point to the start of the SPE save area. We need
18817 to be careful here if r11 is holding the static chain. If
18818 it is, then temporarily save it in r0. We would use r0 as
18819 our base register here, but using r0 as a base register in
18820 loads and stores means something different from what we
18822 int ool_adjust = (saving_GPRs_inline
18824 : (info->first_gp_reg_save
18825 - (FIRST_SAVRES_REGISTER+1))*8);
18826 HOST_WIDE_INT offset = (info->spe_gp_save_offset
18827 + sp_offset - ool_adjust);
18829 if (using_static_chain_p)
18831 rtx r0 = gen_rtx_REG (Pmode, 0);
18832 gcc_assert (info->first_gp_reg_save > 11);
18834 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
18837 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
18838 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
18840 GEN_INT (offset)));
18841 /* We need to make sure the move to r11 gets noted for
18842 properly outputting unwind information. */
18843 if (!saving_GPRs_inline)
18844 rs6000_frame_related (insn, frame_reg_rtx, offset,
18845 NULL_RTX, NULL_RTX);
18849 if (saving_GPRs_inline)
18851 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18852 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
18854 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18855 rtx offset, addr, mem;
18857 /* We're doing all this to ensure that the offset fits into
18858 the immediate offset of 'evstdd'. */
18859 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
18861 offset = GEN_INT (reg_size * i + spe_offset);
18862 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
18863 mem = gen_rtx_MEM (V2SImode, addr);
18865 insn = emit_move_insn (mem, reg);
18867 rs6000_frame_related (insn, spe_save_area_ptr,
18868 info->spe_gp_save_offset
18869 + sp_offset + reg_size * i,
18870 offset, const0_rtx);
18877 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
18879 /*savep=*/true, /*gpr=*/true,
18881 insn = emit_insn (par);
18882 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18883 NULL_RTX, NULL_RTX);
18887 /* Move the static chain pointer back. */
18888 if (using_static_chain_p && !spe_regs_addressable_via_sp)
18889 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
18891 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
18895 /* Need to adjust r11 (r12) if we saved any FPRs. */
18896 if (info->first_fp_reg_save != 64)
18898 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
18900 rtx offset = GEN_INT (sp_offset
18901 + (-8 * (64-info->first_fp_reg_save)));
18902 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
18905 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18906 info->gp_save_offset + sp_offset,
18908 /*savep=*/true, /*gpr=*/true,
18910 & SAVRES_NOINLINE_GPRS_SAVES_LR)
18912 insn = emit_insn (par);
18913 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18914 NULL_RTX, NULL_RTX);
18916 else if (!WORLD_SAVE_P (info) && using_store_multiple)
18920 p = rtvec_alloc (32 - info->first_gp_reg_save);
18921 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18923 rtx addr, reg, mem;
18924 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18925 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18926 GEN_INT (info->gp_save_offset
18929 mem = gen_frame_mem (reg_mode, addr);
18931 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
18933 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18934 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18935 NULL_RTX, NULL_RTX);
18937 else if (!WORLD_SAVE_P (info))
18940 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18941 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
18943 rtx addr, reg, mem;
18944 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18946 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18947 GEN_INT (info->gp_save_offset
18950 mem = gen_frame_mem (reg_mode, addr);
18952 insn = emit_move_insn (mem, reg);
18953 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18954 NULL_RTX, NULL_RTX);
18958 /* ??? There's no need to emit actual instructions here, but it's the
18959 easiest way to get the frame unwind information emitted. */
18960 if (crtl->calls_eh_return)
18962 unsigned int i, regno;
18964 /* In AIX ABI we need to pretend we save r2 here. */
18967 rtx addr, reg, mem;
18969 reg = gen_rtx_REG (reg_mode, 2);
18970 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18971 GEN_INT (sp_offset + 5 * reg_size));
18972 mem = gen_frame_mem (reg_mode, addr);
18974 insn = emit_move_insn (mem, reg);
18975 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18976 NULL_RTX, NULL_RTX);
18977 PATTERN (insn) = gen_blockage ();
18982 regno = EH_RETURN_DATA_REGNO (i);
18983 if (regno == INVALID_REGNUM)
18986 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
18987 info->ehrd_offset + sp_offset
18988 + reg_size * (int) i,
18993 /* Save CR if we use any that must be preserved. */
18994 if (!WORLD_SAVE_P (info) && info->cr_save_p)
18996 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18997 GEN_INT (info->cr_save_offset + sp_offset));
18998 rtx mem = gen_frame_mem (SImode, addr);
18999 /* See the large comment above about why CR2_REGNO is used. */
19000 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
19002 /* If r12 was used to hold the original sp, copy cr into r0 now
19004 if (REGNO (frame_reg_rtx) == 12)
19008 cr_save_rtx = gen_rtx_REG (SImode, 0);
19009 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19010 RTX_FRAME_RELATED_P (insn) = 1;
19011 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
19012 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19014 insn = emit_move_insn (mem, cr_save_rtx);
19016 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19017 NULL_RTX, NULL_RTX);
19020 /* Update stack and set back pointer unless this is V.4,
19021 for which it was done previously. */
19022 if (!WORLD_SAVE_P (info) && info->push_p
19023 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
19025 if (info->total_size < 32767)
19026 sp_offset = info->total_size;
19028 frame_reg_rtx = frame_ptr_rtx;
19029 rs6000_emit_allocate_stack (info->total_size,
19030 (frame_reg_rtx != sp_reg_rtx
19031 && ((info->altivec_size != 0)
19032 || (info->vrsave_mask != 0)
19035 if (frame_reg_rtx != sp_reg_rtx)
19036 rs6000_emit_stack_tie ();
19039 /* Set frame pointer, if needed. */
19040 if (frame_pointer_needed)
19042 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
19044 RTX_FRAME_RELATED_P (insn) = 1;
19047 /* Save AltiVec registers if needed. Save here because the red zone does
19048 not include AltiVec registers. */
19049 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
19053 /* There should be a non inline version of this, for when we
19054 are saving lots of vector registers. */
19055 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19056 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19058 rtx areg, savereg, mem;
19061 offset = info->altivec_save_offset + sp_offset
19062 + 16 * (i - info->first_altivec_reg_save);
19064 savereg = gen_rtx_REG (V4SImode, i);
19066 areg = gen_rtx_REG (Pmode, 0);
19067 emit_move_insn (areg, GEN_INT (offset));
19069 /* AltiVec addressing mode is [reg+reg]. */
19070 mem = gen_frame_mem (V4SImode,
19071 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
19073 insn = emit_move_insn (mem, savereg);
19075 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19076 areg, GEN_INT (offset));
19080 /* VRSAVE is a bit vector representing which AltiVec registers
19081 are used. The OS uses this to determine which vector
19082 registers to save on a context switch. We need to save
19083 VRSAVE on the stack frame, add whatever AltiVec registers we
19084 used in this function, and do the corresponding magic in the
19087 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
19088 && info->vrsave_mask != 0)
19090 rtx reg, mem, vrsave;
19093 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
19094 as frame_reg_rtx and r11 as the static chain pointer for
19095 nested functions. */
19096 reg = gen_rtx_REG (SImode, 0);
19097 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19099 emit_insn (gen_get_vrsave_internal (reg));
19101 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19103 if (!WORLD_SAVE_P (info))
19106 offset = info->vrsave_save_offset + sp_offset;
19107 mem = gen_frame_mem (SImode,
19108 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19109 GEN_INT (offset)));
19110 insn = emit_move_insn (mem, reg);
19113 /* Include the registers in the mask. */
19114 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19116 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19119 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19120 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19121 || (DEFAULT_ABI == ABI_V4
19122 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19123 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19125 /* If emit_load_toc_table will use the link register, we need to save
19126 it. We use R12 for this purpose because emit_load_toc_table
19127 can use register 0. This allows us to use a plain 'blr' to return
19128 from the procedure more often. */
19129 int save_LR_around_toc_setup = (TARGET_ELF
19130 && DEFAULT_ABI != ABI_AIX
19132 && ! info->lr_save_p
19133 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19134 if (save_LR_around_toc_setup)
19136 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19138 insn = emit_move_insn (frame_ptr_rtx, lr);
19139 RTX_FRAME_RELATED_P (insn) = 1;
19141 rs6000_emit_load_toc_table (TRUE);
19143 insn = emit_move_insn (lr, frame_ptr_rtx);
19144 RTX_FRAME_RELATED_P (insn) = 1;
19147 rs6000_emit_load_toc_table (TRUE);
19151 if (DEFAULT_ABI == ABI_DARWIN
19152 && flag_pic && crtl->uses_pic_offset_table)
19154 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19155 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19157 /* Save and restore LR locally around this call (in R0). */
19158 if (!info->lr_save_p)
19159 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19161 emit_insn (gen_load_macho_picbase (src));
19163 emit_move_insn (gen_rtx_REG (Pmode,
19164 RS6000_PIC_OFFSET_TABLE_REGNUM),
19167 if (!info->lr_save_p)
19168 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19173 /* Write function prologue. */
19176 rs6000_output_function_prologue (FILE *file,
19177 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19179 rs6000_stack_t *info = rs6000_stack_info ();
19181 if (TARGET_DEBUG_STACK)
19182 debug_stack_info (info);
19184 /* Write .extern for any function we will call to save and restore
19186 if (info->first_fp_reg_save < 64
19187 && !FP_SAVE_INLINE (info->first_fp_reg_save))
19190 int regno = info->first_fp_reg_save - 32;
19192 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
19193 /*gpr=*/false, /*lr=*/false);
19194 fprintf (file, "\t.extern %s\n", name);
19196 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
19197 /*gpr=*/false, /*lr=*/true);
19198 fprintf (file, "\t.extern %s\n", name);
19201 /* Write .extern for AIX common mode routines, if needed. */
19202 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
19204 fputs ("\t.extern __mulh\n", file);
19205 fputs ("\t.extern __mull\n", file);
19206 fputs ("\t.extern __divss\n", file);
19207 fputs ("\t.extern __divus\n", file);
19208 fputs ("\t.extern __quoss\n", file);
19209 fputs ("\t.extern __quous\n", file);
19210 common_mode_defined = 1;
19213 if (! HAVE_prologue)
19219 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19220 the "toplevel" insn chain. */
19221 emit_note (NOTE_INSN_DELETED);
19222 rs6000_emit_prologue ();
19223 emit_note (NOTE_INSN_DELETED);
19225 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19229 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19231 INSN_ADDRESSES_NEW (insn, addr);
19236 prologue = get_insns ();
19239 if (TARGET_DEBUG_STACK)
19240 debug_rtx_list (prologue, 100);
19242 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
19246 rs6000_pic_labelno++;
19249 /* Non-zero if vmx regs are restored before the frame pop, zero if
19250 we restore after the pop when possible. */
19251 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19253 /* Reload CR from REG. */
19256 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
19261 if (using_mfcr_multiple)
19263 for (i = 0; i < 8; i++)
19264 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19266 gcc_assert (count);
19269 if (using_mfcr_multiple && count > 1)
19274 p = rtvec_alloc (count);
19277 for (i = 0; i < 8; i++)
19278 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19280 rtvec r = rtvec_alloc (2);
19281 RTVEC_ELT (r, 0) = reg;
19282 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19283 RTVEC_ELT (p, ndx) =
19284 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19285 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19288 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19289 gcc_assert (ndx == count);
19292 for (i = 0; i < 8; i++)
19293 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19295 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19301 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19302 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19303 below stack pointer not cloberred by signals. */
19306 offset_below_red_zone_p (HOST_WIDE_INT offset)
19308 return offset < (DEFAULT_ABI == ABI_V4
19310 : TARGET_32BIT ? -220 : -288);
19313 /* Emit function epilogue as insns. */
19316 rs6000_emit_epilogue (int sibcall)
19318 rs6000_stack_t *info;
19319 int restoring_GPRs_inline;
19320 int restoring_FPRs_inline;
19321 int using_load_multiple;
19322 int using_mtcr_multiple;
19323 int use_backchain_to_restore_sp;
19327 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19328 rtx frame_reg_rtx = sp_reg_rtx;
19329 rtx cfa_restores = NULL_RTX;
19331 rtx cr_save_reg = NULL_RTX;
19332 enum machine_mode reg_mode = Pmode;
19333 int reg_size = TARGET_32BIT ? 4 : 8;
19336 info = rs6000_stack_info ();
19338 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19340 reg_mode = V2SImode;
19344 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19345 /*static_chain_p=*/0, sibcall);
19346 using_load_multiple = strategy & SAVRES_MULTIPLE;
19347 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19348 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19349 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19350 || rs6000_cpu == PROCESSOR_PPC603
19351 || rs6000_cpu == PROCESSOR_PPC750
19353 /* Restore via the backchain when we have a large frame, since this
19354 is more efficient than an addis, addi pair. The second condition
19355 here will not trigger at the moment; We don't actually need a
19356 frame pointer for alloca, but the generic parts of the compiler
19357 give us one anyway. */
19358 use_backchain_to_restore_sp = (info->total_size > 32767
19359 || info->total_size
19360 + (info->lr_save_p ? info->lr_save_offset : 0)
19362 || (cfun->calls_alloca
19363 && !frame_pointer_needed));
19364 restore_lr = (info->lr_save_p
19365 && (restoring_FPRs_inline
19366 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
19367 && (restoring_GPRs_inline
19368 || info->first_fp_reg_save < 64));
19370 if (WORLD_SAVE_P (info))
19374 const char *alloc_rname;
19377 /* eh_rest_world_r10 will return to the location saved in the LR
19378 stack slot (which is not likely to be our caller.)
19379 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19380 rest_world is similar, except any R10 parameter is ignored.
19381 The exception-handling stuff that was here in 2.95 is no
19382 longer necessary. */
19386 + 32 - info->first_gp_reg_save
19387 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
19388 + 63 + 1 - info->first_fp_reg_save);
19390 strcpy (rname, ((crtl->calls_eh_return) ?
19391 "*eh_rest_world_r10" : "*rest_world"));
19392 alloc_rname = ggc_strdup (rname);
19395 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
19396 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19397 gen_rtx_REG (Pmode,
19400 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
19401 /* The instruction pattern requires a clobber here;
19402 it is shared with the restVEC helper. */
19404 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
19407 /* CR register traditionally saved as CR2. */
19408 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19409 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19410 GEN_INT (info->cr_save_offset));
19411 rtx mem = gen_frame_mem (reg_mode, addr);
19413 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19416 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19418 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19419 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19420 GEN_INT (info->gp_save_offset
19422 rtx mem = gen_frame_mem (reg_mode, addr);
19424 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19426 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19428 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19429 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19430 GEN_INT (info->altivec_save_offset
19432 rtx mem = gen_frame_mem (V4SImode, addr);
19434 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19436 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
19438 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19439 ? DFmode : SFmode),
19440 info->first_fp_reg_save + i);
19441 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19442 GEN_INT (info->fp_save_offset
19444 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19445 ? DFmode : SFmode), addr);
19447 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19450 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
19452 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
19454 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
19456 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
19458 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
19459 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19464 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
19466 sp_offset = info->total_size;
19468 /* Restore AltiVec registers if we must do so before adjusting the
19470 if (TARGET_ALTIVEC_ABI
19471 && info->altivec_size != 0
19472 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19473 || (DEFAULT_ABI != ABI_V4
19474 && offset_below_red_zone_p (info->altivec_save_offset))))
19478 if (use_backchain_to_restore_sp)
19480 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19481 emit_move_insn (frame_reg_rtx,
19482 gen_rtx_MEM (Pmode, sp_reg_rtx));
19485 else if (frame_pointer_needed)
19486 frame_reg_rtx = hard_frame_pointer_rtx;
19488 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19489 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19491 rtx addr, areg, mem, reg;
19493 areg = gen_rtx_REG (Pmode, 0);
19495 (areg, GEN_INT (info->altivec_save_offset
19497 + 16 * (i - info->first_altivec_reg_save)));
19499 /* AltiVec addressing mode is [reg+reg]. */
19500 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19501 mem = gen_frame_mem (V4SImode, addr);
19503 reg = gen_rtx_REG (V4SImode, i);
19504 emit_move_insn (reg, mem);
19505 if (offset_below_red_zone_p (info->altivec_save_offset
19506 + (i - info->first_altivec_reg_save)
19508 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19513 /* Restore VRSAVE if we must do so before adjusting the stack. */
19515 && TARGET_ALTIVEC_VRSAVE
19516 && info->vrsave_mask != 0
19517 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19518 || (DEFAULT_ABI != ABI_V4
19519 && offset_below_red_zone_p (info->vrsave_save_offset))))
19521 rtx addr, mem, reg;
19523 if (frame_reg_rtx == sp_reg_rtx)
19525 if (use_backchain_to_restore_sp)
19527 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19528 emit_move_insn (frame_reg_rtx,
19529 gen_rtx_MEM (Pmode, sp_reg_rtx));
19532 else if (frame_pointer_needed)
19533 frame_reg_rtx = hard_frame_pointer_rtx;
19536 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19537 GEN_INT (info->vrsave_save_offset + sp_offset));
19538 mem = gen_frame_mem (SImode, addr);
19539 reg = gen_rtx_REG (SImode, 12);
19540 emit_move_insn (reg, mem);
19542 emit_insn (generate_set_vrsave (reg, info, 1));
19546 /* If we have a large stack frame, restore the old stack pointer
19547 using the backchain. */
19548 if (use_backchain_to_restore_sp)
19550 if (frame_reg_rtx == sp_reg_rtx)
19552 /* Under V.4, don't reset the stack pointer until after we're done
19553 loading the saved registers. */
19554 if (DEFAULT_ABI == ABI_V4)
19555 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19557 insn = emit_move_insn (frame_reg_rtx,
19558 gen_rtx_MEM (Pmode, sp_reg_rtx));
19561 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19562 && DEFAULT_ABI == ABI_V4)
19563 /* frame_reg_rtx has been set up by the altivec restore. */
19567 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19568 frame_reg_rtx = sp_reg_rtx;
19571 /* If we have a frame pointer, we can restore the old stack pointer
19573 else if (frame_pointer_needed)
19575 frame_reg_rtx = sp_reg_rtx;
19576 if (DEFAULT_ABI == ABI_V4)
19577 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19579 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
19580 GEN_INT (info->total_size)));
19583 else if (info->push_p
19584 && DEFAULT_ABI != ABI_V4
19585 && !crtl->calls_eh_return)
19587 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
19588 GEN_INT (info->total_size)));
19591 if (insn && frame_reg_rtx == sp_reg_rtx)
19595 REG_NOTES (insn) = cfa_restores;
19596 cfa_restores = NULL_RTX;
19598 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19599 RTX_FRAME_RELATED_P (insn) = 1;
19602 /* Restore AltiVec registers if we have not done so already. */
19603 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19604 && TARGET_ALTIVEC_ABI
19605 && info->altivec_size != 0
19606 && (DEFAULT_ABI == ABI_V4
19607 || !offset_below_red_zone_p (info->altivec_save_offset)))
19611 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19612 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19614 rtx addr, areg, mem, reg;
19616 areg = gen_rtx_REG (Pmode, 0);
19618 (areg, GEN_INT (info->altivec_save_offset
19620 + 16 * (i - info->first_altivec_reg_save)));
19622 /* AltiVec addressing mode is [reg+reg]. */
19623 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19624 mem = gen_frame_mem (V4SImode, addr);
19626 reg = gen_rtx_REG (V4SImode, i);
19627 emit_move_insn (reg, mem);
19628 if (DEFAULT_ABI == ABI_V4)
19629 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19634 /* Restore VRSAVE if we have not done so already. */
19635 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19637 && TARGET_ALTIVEC_VRSAVE
19638 && info->vrsave_mask != 0
19639 && (DEFAULT_ABI == ABI_V4
19640 || !offset_below_red_zone_p (info->vrsave_save_offset)))
19642 rtx addr, mem, reg;
19644 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19645 GEN_INT (info->vrsave_save_offset + sp_offset));
19646 mem = gen_frame_mem (SImode, addr);
19647 reg = gen_rtx_REG (SImode, 12);
19648 emit_move_insn (reg, mem);
19650 emit_insn (generate_set_vrsave (reg, info, 1));
19653 /* Get the old lr if we saved it. If we are restoring registers
19654 out-of-line, then the out-of-line routines can do this for us. */
19655 if (restore_lr && restoring_GPRs_inline)
19657 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19658 info->lr_save_offset + sp_offset);
19660 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19663 /* Get the old cr if we saved it. */
19664 if (info->cr_save_p)
19666 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19667 GEN_INT (info->cr_save_offset + sp_offset));
19668 rtx mem = gen_frame_mem (SImode, addr);
19670 cr_save_reg = gen_rtx_REG (SImode,
19671 DEFAULT_ABI == ABI_AIX
19672 && !restoring_GPRs_inline
19673 && info->first_fp_reg_save < 64
19675 emit_move_insn (cr_save_reg, mem);
19678 /* Set LR here to try to overlap restores below. LR is always saved
19679 above incoming stack, so it never needs REG_CFA_RESTORE. */
19680 if (restore_lr && restoring_GPRs_inline)
19681 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19682 gen_rtx_REG (Pmode, 0));
19684 /* Load exception handler data registers, if needed. */
19685 if (crtl->calls_eh_return)
19687 unsigned int i, regno;
19691 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19692 GEN_INT (sp_offset + 5 * reg_size));
19693 rtx mem = gen_frame_mem (reg_mode, addr);
19695 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
19702 regno = EH_RETURN_DATA_REGNO (i);
19703 if (regno == INVALID_REGNUM)
19706 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
19707 info->ehrd_offset + sp_offset
19708 + reg_size * (int) i);
19710 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
19714 /* Restore GPRs. This is done as a PARALLEL if we are using
19715 the load-multiple instructions. */
19717 && info->spe_64bit_regs_used != 0
19718 && info->first_gp_reg_save != 32)
19720 /* Determine whether we can address all of the registers that need
19721 to be saved with an offset from the stack pointer that fits in
19722 the small const field for SPE memory instructions. */
19723 int spe_regs_addressable_via_sp
19724 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19725 + (32 - info->first_gp_reg_save - 1) * reg_size)
19726 && restoring_GPRs_inline);
19729 if (spe_regs_addressable_via_sp)
19730 spe_offset = info->spe_gp_save_offset + sp_offset;
19733 rtx old_frame_reg_rtx = frame_reg_rtx;
19734 /* Make r11 point to the start of the SPE save area. We worried about
19735 not clobbering it when we were saving registers in the prologue.
19736 There's no need to worry here because the static chain is passed
19737 anew to every function. */
19738 int ool_adjust = (restoring_GPRs_inline
19740 : (info->first_gp_reg_save
19741 - (FIRST_SAVRES_REGISTER+1))*8);
19743 if (frame_reg_rtx == sp_reg_rtx)
19744 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19745 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
19746 GEN_INT (info->spe_gp_save_offset
19749 /* Keep the invariant that frame_reg_rtx + sp_offset points
19750 at the top of the stack frame. */
19751 sp_offset = -info->spe_gp_save_offset;
19756 if (restoring_GPRs_inline)
19758 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19759 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19761 rtx offset, addr, mem, reg;
19763 /* We're doing all this to ensure that the immediate offset
19764 fits into the immediate field of 'evldd'. */
19765 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
19767 offset = GEN_INT (spe_offset + reg_size * i);
19768 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
19769 mem = gen_rtx_MEM (V2SImode, addr);
19770 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19772 insn = emit_move_insn (reg, mem);
19773 if (DEFAULT_ABI == ABI_V4)
19775 if (frame_pointer_needed
19776 && info->first_gp_reg_save + i
19777 == HARD_FRAME_POINTER_REGNUM)
19779 add_reg_note (insn, REG_CFA_DEF_CFA,
19780 plus_constant (frame_reg_rtx,
19782 RTX_FRAME_RELATED_P (insn) = 1;
19785 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19794 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19796 /*savep=*/false, /*gpr=*/true,
19798 emit_jump_insn (par);
19799 /* We don't want anybody else emitting things after we jumped
19804 else if (!restoring_GPRs_inline)
19806 /* We are jumping to an out-of-line function. */
19807 bool can_use_exit = info->first_fp_reg_save == 64;
19810 /* Emit stack reset code if we need it. */
19812 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19813 sp_offset, can_use_exit);
19816 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
19819 GEN_INT (sp_offset - info->fp_size)));
19820 if (REGNO (frame_reg_rtx) == 11)
19821 sp_offset += info->fp_size;
19824 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19825 info->gp_save_offset, reg_mode,
19826 /*savep=*/false, /*gpr=*/true,
19827 /*lr=*/can_use_exit);
19831 if (info->cr_save_p)
19833 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
19834 if (DEFAULT_ABI == ABI_V4)
19836 = alloc_reg_note (REG_CFA_RESTORE,
19837 gen_rtx_REG (SImode, CR2_REGNO),
19841 emit_jump_insn (par);
19843 /* We don't want anybody else emitting things after we jumped
19848 insn = emit_insn (par);
19849 if (DEFAULT_ABI == ABI_V4)
19851 if (frame_pointer_needed)
19853 add_reg_note (insn, REG_CFA_DEF_CFA,
19854 plus_constant (frame_reg_rtx, sp_offset));
19855 RTX_FRAME_RELATED_P (insn) = 1;
19858 for (i = info->first_gp_reg_save; i < 32; i++)
19860 = alloc_reg_note (REG_CFA_RESTORE,
19861 gen_rtx_REG (reg_mode, i), cfa_restores);
19864 else if (using_load_multiple)
19867 p = rtvec_alloc (32 - info->first_gp_reg_save);
19868 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19870 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19871 GEN_INT (info->gp_save_offset
19874 rtx mem = gen_frame_mem (reg_mode, addr);
19875 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19877 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
19878 if (DEFAULT_ABI == ABI_V4)
19879 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19882 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19883 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
19885 add_reg_note (insn, REG_CFA_DEF_CFA,
19886 plus_constant (frame_reg_rtx, sp_offset));
19887 RTX_FRAME_RELATED_P (insn) = 1;
19892 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19893 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19895 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19896 GEN_INT (info->gp_save_offset
19899 rtx mem = gen_frame_mem (reg_mode, addr);
19900 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19902 insn = emit_move_insn (reg, mem);
19903 if (DEFAULT_ABI == ABI_V4)
19905 if (frame_pointer_needed
19906 && info->first_gp_reg_save + i
19907 == HARD_FRAME_POINTER_REGNUM)
19909 add_reg_note (insn, REG_CFA_DEF_CFA,
19910 plus_constant (frame_reg_rtx, sp_offset));
19911 RTX_FRAME_RELATED_P (insn) = 1;
19914 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19920 if (restore_lr && !restoring_GPRs_inline)
19922 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19923 info->lr_save_offset + sp_offset);
19925 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19926 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19927 gen_rtx_REG (Pmode, 0));
19930 /* Restore fpr's if we need to do it without calling a function. */
19931 if (restoring_FPRs_inline)
19932 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19933 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
19934 && ! call_used_regs[info->first_fp_reg_save+i]))
19936 rtx addr, mem, reg;
19937 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19938 GEN_INT (info->fp_save_offset
19941 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19942 ? DFmode : SFmode), addr);
19943 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19944 ? DFmode : SFmode),
19945 info->first_fp_reg_save + i);
19947 emit_move_insn (reg, mem);
19948 if (DEFAULT_ABI == ABI_V4)
19949 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19953 /* If we saved cr, restore it here. Just those that were used. */
19954 if (info->cr_save_p)
19956 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
19957 if (DEFAULT_ABI == ABI_V4)
19959 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
19963 /* If this is V.4, unwind the stack pointer after all of the loads
19965 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19966 sp_offset, !restoring_FPRs_inline);
19971 REG_NOTES (insn) = cfa_restores;
19972 cfa_restores = NULL_RTX;
19974 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19975 RTX_FRAME_RELATED_P (insn) = 1;
19978 if (crtl->calls_eh_return)
19980 rtx sa = EH_RETURN_STACKADJ_RTX;
19981 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
19987 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
19988 if (! restoring_FPRs_inline)
19989 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
19991 p = rtvec_alloc (2);
19993 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
19994 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
19995 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
19996 : gen_rtx_CLOBBER (VOIDmode,
19997 gen_rtx_REG (Pmode, 65)));
19999 /* If we have to restore more than two FP registers, branch to the
20000 restore function. It will return to our caller. */
20001 if (! restoring_FPRs_inline)
20006 sym = rs6000_savres_routine_sym (info,
20010 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
20011 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
20012 gen_rtx_REG (Pmode,
20013 DEFAULT_ABI == ABI_AIX
20015 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20018 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
20019 GEN_INT (info->fp_save_offset + 8*i));
20020 mem = gen_frame_mem (DFmode, addr);
20022 RTVEC_ELT (p, i+4) =
20023 gen_rtx_SET (VOIDmode,
20024 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
20029 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20033 /* Write function epilogue. */
20036 rs6000_output_function_epilogue (FILE *file,
20037 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20039 if (! HAVE_epilogue)
20041 rtx insn = get_last_insn ();
20042 /* If the last insn was a BARRIER, we don't have to write anything except
20043 the trace table. */
20044 if (GET_CODE (insn) == NOTE)
20045 insn = prev_nonnote_insn (insn);
20046 if (insn == 0 || GET_CODE (insn) != BARRIER)
20048 /* This is slightly ugly, but at least we don't have two
20049 copies of the epilogue-emitting code. */
20052 /* A NOTE_INSN_DELETED is supposed to be at the start
20053 and end of the "toplevel" insn chain. */
20054 emit_note (NOTE_INSN_DELETED);
20055 rs6000_emit_epilogue (FALSE);
20056 emit_note (NOTE_INSN_DELETED);
20058 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20062 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20064 INSN_ADDRESSES_NEW (insn, addr);
20069 if (TARGET_DEBUG_STACK)
20070 debug_rtx_list (get_insns (), 100);
20071 final (get_insns (), file, FALSE);
20077 macho_branch_islands ();
20078 /* Mach-O doesn't support labels at the end of objects, so if
20079 it looks like we might want one, insert a NOP. */
20081 rtx insn = get_last_insn ();
20084 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
20085 insn = PREV_INSN (insn);
20089 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
20090 fputs ("\tnop\n", file);
20094 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20097 We don't output a traceback table if -finhibit-size-directive was
20098 used. The documentation for -finhibit-size-directive reads
20099 ``don't output a @code{.size} assembler directive, or anything
20100 else that would cause trouble if the function is split in the
20101 middle, and the two halves are placed at locations far apart in
20102 memory.'' The traceback table has this property, since it
20103 includes the offset from the start of the function to the
20104 traceback table itself.
20106 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20107 different traceback table. */
20108 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20109 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20111 const char *fname = NULL;
20112 const char *language_string = lang_hooks.name;
20113 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20115 int optional_tbtab;
20116 rs6000_stack_t *info = rs6000_stack_info ();
20118 if (rs6000_traceback == traceback_full)
20119 optional_tbtab = 1;
20120 else if (rs6000_traceback == traceback_part)
20121 optional_tbtab = 0;
20123 optional_tbtab = !optimize_size && !TARGET_ELF;
20125 if (optional_tbtab)
20127 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20128 while (*fname == '.') /* V.4 encodes . in the name */
20131 /* Need label immediately before tbtab, so we can compute
20132 its offset from the function start. */
20133 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20134 ASM_OUTPUT_LABEL (file, fname);
20137 /* The .tbtab pseudo-op can only be used for the first eight
20138 expressions, since it can't handle the possibly variable
20139 length fields that follow. However, if you omit the optional
20140 fields, the assembler outputs zeros for all optional fields
20141 anyways, giving each variable length field is minimum length
20142 (as defined in sys/debug.h). Thus we can not use the .tbtab
20143 pseudo-op at all. */
20145 /* An all-zero word flags the start of the tbtab, for debuggers
20146 that have to find it by searching forward from the entry
20147 point or from the current pc. */
20148 fputs ("\t.long 0\n", file);
20150 /* Tbtab format type. Use format type 0. */
20151 fputs ("\t.byte 0,", file);
20153 /* Language type. Unfortunately, there does not seem to be any
20154 official way to discover the language being compiled, so we
20155 use language_string.
20156 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20157 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20158 a number, so for now use 9. LTO isn't assigned a number either,
20159 so for now use 0. */
20160 if (! strcmp (language_string, "GNU C")
20161 || ! strcmp (language_string, "GNU GIMPLE"))
20163 else if (! strcmp (language_string, "GNU F77")
20164 || ! strcmp (language_string, "GNU Fortran"))
20166 else if (! strcmp (language_string, "GNU Pascal"))
20168 else if (! strcmp (language_string, "GNU Ada"))
20170 else if (! strcmp (language_string, "GNU C++")
20171 || ! strcmp (language_string, "GNU Objective-C++"))
20173 else if (! strcmp (language_string, "GNU Java"))
20175 else if (! strcmp (language_string, "GNU Objective-C"))
20178 gcc_unreachable ();
20179 fprintf (file, "%d,", i);
20181 /* 8 single bit fields: global linkage (not set for C extern linkage,
20182 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20183 from start of procedure stored in tbtab, internal function, function
20184 has controlled storage, function has no toc, function uses fp,
20185 function logs/aborts fp operations. */
20186 /* Assume that fp operations are used if any fp reg must be saved. */
20187 fprintf (file, "%d,",
20188 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
20190 /* 6 bitfields: function is interrupt handler, name present in
20191 proc table, function calls alloca, on condition directives
20192 (controls stack walks, 3 bits), saves condition reg, saves
20194 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20195 set up as a frame pointer, even when there is no alloca call. */
20196 fprintf (file, "%d,",
20197 ((optional_tbtab << 6)
20198 | ((optional_tbtab & frame_pointer_needed) << 5)
20199 | (info->cr_save_p << 1)
20200 | (info->lr_save_p)));
20202 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20204 fprintf (file, "%d,",
20205 (info->push_p << 7) | (64 - info->first_fp_reg_save));
20207 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20208 fprintf (file, "%d,", (32 - first_reg_to_save ()));
20210 if (optional_tbtab)
20212 /* Compute the parameter info from the function decl argument
20215 int next_parm_info_bit = 31;
20217 for (decl = DECL_ARGUMENTS (current_function_decl);
20218 decl; decl = TREE_CHAIN (decl))
20220 rtx parameter = DECL_INCOMING_RTL (decl);
20221 enum machine_mode mode = GET_MODE (parameter);
20223 if (GET_CODE (parameter) == REG)
20225 if (SCALAR_FLOAT_MODE_P (mode))
20246 gcc_unreachable ();
20249 /* If only one bit will fit, don't or in this entry. */
20250 if (next_parm_info_bit > 0)
20251 parm_info |= (bits << (next_parm_info_bit - 1));
20252 next_parm_info_bit -= 2;
20256 fixed_parms += ((GET_MODE_SIZE (mode)
20257 + (UNITS_PER_WORD - 1))
20259 next_parm_info_bit -= 1;
20265 /* Number of fixed point parameters. */
20266 /* This is actually the number of words of fixed point parameters; thus
20267 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20268 fprintf (file, "%d,", fixed_parms);
20270 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20272 /* This is actually the number of fp registers that hold parameters;
20273 and thus the maximum value is 13. */
20274 /* Set parameters on stack bit if parameters are not in their original
20275 registers, regardless of whether they are on the stack? Xlc
20276 seems to set the bit when not optimizing. */
20277 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
20279 if (! optional_tbtab)
20282 /* Optional fields follow. Some are variable length. */
20284 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20285 11 double float. */
20286 /* There is an entry for each parameter in a register, in the order that
20287 they occur in the parameter list. Any intervening arguments on the
20288 stack are ignored. If the list overflows a long (max possible length
20289 34 bits) then completely leave off all elements that don't fit. */
20290 /* Only emit this long if there was at least one parameter. */
20291 if (fixed_parms || float_parms)
20292 fprintf (file, "\t.long %d\n", parm_info);
20294 /* Offset from start of code to tb table. */
20295 fputs ("\t.long ", file);
20296 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20298 RS6000_OUTPUT_BASENAME (file, fname);
20300 assemble_name (file, fname);
20302 rs6000_output_function_entry (file, fname);
20305 /* Interrupt handler mask. */
20306 /* Omit this long, since we never set the interrupt handler bit
20309 /* Number of CTL (controlled storage) anchors. */
20310 /* Omit this long, since the has_ctl bit is never set above. */
20312 /* Displacement into stack of each CTL anchor. */
20313 /* Omit this list of longs, because there are no CTL anchors. */
20315 /* Length of function name. */
20318 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20320 /* Function name. */
20321 assemble_string (fname, strlen (fname));
20323 /* Register for alloca automatic storage; this is always reg 31.
20324 Only emit this if the alloca bit was set above. */
20325 if (frame_pointer_needed)
20326 fputs ("\t.byte 31\n", file);
20328 fputs ("\t.align 2\n", file);
20332 /* A C compound statement that outputs the assembler code for a thunk
20333 function, used to implement C++ virtual function calls with
20334 multiple inheritance. The thunk acts as a wrapper around a virtual
20335 function, adjusting the implicit object parameter before handing
20336 control off to the real function.
20338 First, emit code to add the integer DELTA to the location that
20339 contains the incoming first argument. Assume that this argument
20340 contains a pointer, and is the one used to pass the `this' pointer
20341 in C++. This is the incoming argument *before* the function
20342 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20343 values of all other incoming arguments.
20345 After the addition, emit code to jump to FUNCTION, which is a
20346 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20347 not touch the return address. Hence returning from FUNCTION will
20348 return to whoever called the current `thunk'.
20350 The effect must be as if FUNCTION had been called directly with the
20351 adjusted first argument. This macro is responsible for emitting
20352 all of the code for a thunk function; output_function_prologue()
20353 and output_function_epilogue() are not invoked.
20355 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20356 been extracted from it.) It might possibly be useful on some
20357 targets, but probably not.
20359 If you do not define this macro, the target-independent code in the
20360 C++ frontend will generate a less efficient heavyweight thunk that
20361 calls FUNCTION instead of jumping to it. The generic approach does
20362 not support varargs. */
20365 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
20366 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
20369 rtx this_rtx, insn, funexp;
20371 reload_completed = 1;
20372 epilogue_completed = 1;
20374 /* Mark the end of the (empty) prologue. */
20375 emit_note (NOTE_INSN_PROLOGUE_END);
20377 /* Find the "this" pointer. If the function returns a structure,
20378 the structure return pointer is in r3. */
20379 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
20380 this_rtx = gen_rtx_REG (Pmode, 4);
20382 this_rtx = gen_rtx_REG (Pmode, 3);
20384 /* Apply the constant offset, if required. */
20386 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
20388 /* Apply the offset from the vtable, if required. */
20391 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
20392 rtx tmp = gen_rtx_REG (Pmode, 12);
20394 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
20395 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
20397 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
20398 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
20402 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
20404 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
20406 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
20409 /* Generate a tail call to the target function. */
20410 if (!TREE_USED (function))
20412 assemble_external (function);
20413 TREE_USED (function) = 1;
20415 funexp = XEXP (DECL_RTL (function), 0);
20416 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
20419 if (MACHOPIC_INDIRECT)
20420 funexp = machopic_indirect_call_target (funexp);
20423 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
20424 generate sibcall RTL explicitly. */
20425 insn = emit_call_insn (
20426 gen_rtx_PARALLEL (VOIDmode,
20428 gen_rtx_CALL (VOIDmode,
20429 funexp, const0_rtx),
20430 gen_rtx_USE (VOIDmode, const0_rtx),
20431 gen_rtx_USE (VOIDmode,
20432 gen_rtx_REG (SImode,
20434 gen_rtx_RETURN (VOIDmode))));
20435 SIBLING_CALL_P (insn) = 1;
20438 /* Run just enough of rest_of_compilation to get the insns emitted.
20439 There's not really enough bulk here to make other passes such as
20440 instruction scheduling worth while. Note that use_thunk calls
20441 assemble_start_function and assemble_end_function. */
20442 insn = get_insns ();
20443 insn_locators_alloc ();
20444 shorten_branches (insn);
20445 final_start_function (insn, file, 1);
20446 final (insn, file, 1);
20447 final_end_function ();
20449 reload_completed = 0;
20450 epilogue_completed = 0;
20453 /* A quick summary of the various types of 'constant-pool tables'
20456 Target Flags Name One table per
20457 AIX (none) AIX TOC object file
20458 AIX -mfull-toc AIX TOC object file
20459 AIX -mminimal-toc AIX minimal TOC translation unit
20460 SVR4/EABI (none) SVR4 SDATA object file
20461 SVR4/EABI -fpic SVR4 pic object file
20462 SVR4/EABI -fPIC SVR4 PIC translation unit
20463 SVR4/EABI -mrelocatable EABI TOC function
20464 SVR4/EABI -maix AIX TOC object file
20465 SVR4/EABI -maix -mminimal-toc
20466 AIX minimal TOC translation unit
20468 Name Reg. Set by entries contains:
20469 made by addrs? fp? sum?
20471 AIX TOC 2 crt0 as Y option option
20472 AIX minimal TOC 30 prolog gcc Y Y option
20473 SVR4 SDATA 13 crt0 gcc N Y N
20474 SVR4 pic 30 prolog ld Y not yet N
20475 SVR4 PIC 30 prolog gcc Y option option
20476 EABI TOC 30 prolog gcc Y option option
20480 /* Hash functions for the hash table. */
20483 rs6000_hash_constant (rtx k)
20485 enum rtx_code code = GET_CODE (k);
20486 enum machine_mode mode = GET_MODE (k);
20487 unsigned result = (code << 3) ^ mode;
20488 const char *format;
20491 format = GET_RTX_FORMAT (code);
20492 flen = strlen (format);
20498 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
20501 if (mode != VOIDmode)
20502 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
20514 for (; fidx < flen; fidx++)
20515 switch (format[fidx])
20520 const char *str = XSTR (k, fidx);
20521 len = strlen (str);
20522 result = result * 613 + len;
20523 for (i = 0; i < len; i++)
20524 result = result * 613 + (unsigned) str[i];
20529 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
20533 result = result * 613 + (unsigned) XINT (k, fidx);
20536 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
20537 result = result * 613 + (unsigned) XWINT (k, fidx);
20541 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
20542 result = result * 613 + (unsigned) (XWINT (k, fidx)
20549 gcc_unreachable ();
20556 toc_hash_function (const void *hash_entry)
20558 const struct toc_hash_struct *thc =
20559 (const struct toc_hash_struct *) hash_entry;
20560 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
20563 /* Compare H1 and H2 for equivalence. */
20566 toc_hash_eq (const void *h1, const void *h2)
20568 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
20569 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
20571 if (((const struct toc_hash_struct *) h1)->key_mode
20572 != ((const struct toc_hash_struct *) h2)->key_mode)
20575 return rtx_equal_p (r1, r2);
20578 /* These are the names given by the C++ front-end to vtables, and
20579 vtable-like objects. Ideally, this logic should not be here;
20580 instead, there should be some programmatic way of inquiring as
20581 to whether or not an object is a vtable. */
20583 #define VTABLE_NAME_P(NAME) \
20584 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
20585 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
20586 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
20587 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
20588 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
20590 #ifdef NO_DOLLAR_IN_LABEL
20591 /* Return a GGC-allocated character string translating dollar signs in
20592 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
20595 rs6000_xcoff_strip_dollar (const char *name)
20600 p = strchr (name, '$');
20602 if (p == 0 || p == name)
20605 len = strlen (name);
20606 strip = (char *) alloca (len + 1);
20607 strcpy (strip, name);
20608 p = strchr (strip, '$');
20612 p = strchr (p + 1, '$');
20615 return ggc_alloc_string (strip, len);
20620 rs6000_output_symbol_ref (FILE *file, rtx x)
20622 /* Currently C++ toc references to vtables can be emitted before it
20623 is decided whether the vtable is public or private. If this is
20624 the case, then the linker will eventually complain that there is
20625 a reference to an unknown section. Thus, for vtables only,
20626 we emit the TOC reference to reference the symbol and not the
20628 const char *name = XSTR (x, 0);
20630 if (VTABLE_NAME_P (name))
20632 RS6000_OUTPUT_BASENAME (file, name);
20635 assemble_name (file, name);
20638 /* Output a TOC entry. We derive the entry name from what is being
20642 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
20645 const char *name = buf;
20647 HOST_WIDE_INT offset = 0;
20649 gcc_assert (!TARGET_NO_TOC);
20651 /* When the linker won't eliminate them, don't output duplicate
20652 TOC entries (this happens on AIX if there is any kind of TOC,
20653 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
20655 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
20657 struct toc_hash_struct *h;
20660 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
20661 time because GGC is not initialized at that point. */
20662 if (toc_hash_table == NULL)
20663 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
20664 toc_hash_eq, NULL);
20666 h = GGC_NEW (struct toc_hash_struct);
20668 h->key_mode = mode;
20669 h->labelno = labelno;
20671 found = htab_find_slot (toc_hash_table, h, INSERT);
20672 if (*found == NULL)
20674 else /* This is indeed a duplicate.
20675 Set this label equal to that label. */
20677 fputs ("\t.set ", file);
20678 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20679 fprintf (file, "%d,", labelno);
20680 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20681 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
20687 /* If we're going to put a double constant in the TOC, make sure it's
20688 aligned properly when strict alignment is on. */
20689 if (GET_CODE (x) == CONST_DOUBLE
20690 && STRICT_ALIGNMENT
20691 && GET_MODE_BITSIZE (mode) >= 64
20692 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
20693 ASM_OUTPUT_ALIGN (file, 3);
20696 (*targetm.asm_out.internal_label) (file, "LC", labelno);
20698 /* Handle FP constants specially. Note that if we have a minimal
20699 TOC, things we put here aren't actually in the TOC, so we can allow
20701 if (GET_CODE (x) == CONST_DOUBLE &&
20702 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
20704 REAL_VALUE_TYPE rv;
20707 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20708 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20709 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
20711 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
20715 if (TARGET_MINIMAL_TOC)
20716 fputs (DOUBLE_INT_ASM_OP, file);
20718 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20719 k[0] & 0xffffffff, k[1] & 0xffffffff,
20720 k[2] & 0xffffffff, k[3] & 0xffffffff);
20721 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
20722 k[0] & 0xffffffff, k[1] & 0xffffffff,
20723 k[2] & 0xffffffff, k[3] & 0xffffffff);
20728 if (TARGET_MINIMAL_TOC)
20729 fputs ("\t.long ", file);
20731 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20732 k[0] & 0xffffffff, k[1] & 0xffffffff,
20733 k[2] & 0xffffffff, k[3] & 0xffffffff);
20734 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
20735 k[0] & 0xffffffff, k[1] & 0xffffffff,
20736 k[2] & 0xffffffff, k[3] & 0xffffffff);
20740 else if (GET_CODE (x) == CONST_DOUBLE &&
20741 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
20743 REAL_VALUE_TYPE rv;
20746 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20748 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20749 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
20751 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
20755 if (TARGET_MINIMAL_TOC)
20756 fputs (DOUBLE_INT_ASM_OP, file);
20758 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20759 k[0] & 0xffffffff, k[1] & 0xffffffff);
20760 fprintf (file, "0x%lx%08lx\n",
20761 k[0] & 0xffffffff, k[1] & 0xffffffff);
20766 if (TARGET_MINIMAL_TOC)
20767 fputs ("\t.long ", file);
20769 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20770 k[0] & 0xffffffff, k[1] & 0xffffffff);
20771 fprintf (file, "0x%lx,0x%lx\n",
20772 k[0] & 0xffffffff, k[1] & 0xffffffff);
20776 else if (GET_CODE (x) == CONST_DOUBLE &&
20777 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
20779 REAL_VALUE_TYPE rv;
20782 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20783 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20784 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
20786 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
20790 if (TARGET_MINIMAL_TOC)
20791 fputs (DOUBLE_INT_ASM_OP, file);
20793 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20794 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
20799 if (TARGET_MINIMAL_TOC)
20800 fputs ("\t.long ", file);
20802 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20803 fprintf (file, "0x%lx\n", l & 0xffffffff);
20807 else if (GET_MODE (x) == VOIDmode
20808 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
20810 unsigned HOST_WIDE_INT low;
20811 HOST_WIDE_INT high;
20813 if (GET_CODE (x) == CONST_DOUBLE)
20815 low = CONST_DOUBLE_LOW (x);
20816 high = CONST_DOUBLE_HIGH (x);
20819 #if HOST_BITS_PER_WIDE_INT == 32
20822 high = (low & 0x80000000) ? ~0 : 0;
20826 low = INTVAL (x) & 0xffffffff;
20827 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
20831 /* TOC entries are always Pmode-sized, but since this
20832 is a bigendian machine then if we're putting smaller
20833 integer constants in the TOC we have to pad them.
20834 (This is still a win over putting the constants in
20835 a separate constant pool, because then we'd have
20836 to have both a TOC entry _and_ the actual constant.)
20838 For a 32-bit target, CONST_INT values are loaded and shifted
20839 entirely within `low' and can be stored in one TOC entry. */
20841 /* It would be easy to make this work, but it doesn't now. */
20842 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
20844 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
20846 #if HOST_BITS_PER_WIDE_INT == 32
20847 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
20848 POINTER_SIZE, &low, &high, 0);
20851 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
20852 high = (HOST_WIDE_INT) low >> 32;
20859 if (TARGET_MINIMAL_TOC)
20860 fputs (DOUBLE_INT_ASM_OP, file);
20862 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
20863 (long) high & 0xffffffff, (long) low & 0xffffffff);
20864 fprintf (file, "0x%lx%08lx\n",
20865 (long) high & 0xffffffff, (long) low & 0xffffffff);
20870 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
20872 if (TARGET_MINIMAL_TOC)
20873 fputs ("\t.long ", file);
20875 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
20876 (long) high & 0xffffffff, (long) low & 0xffffffff);
20877 fprintf (file, "0x%lx,0x%lx\n",
20878 (long) high & 0xffffffff, (long) low & 0xffffffff);
20882 if (TARGET_MINIMAL_TOC)
20883 fputs ("\t.long ", file);
20885 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
20886 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
20892 if (GET_CODE (x) == CONST)
20894 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
20895 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
20897 base = XEXP (XEXP (x, 0), 0);
20898 offset = INTVAL (XEXP (XEXP (x, 0), 1));
20901 switch (GET_CODE (base))
20904 name = XSTR (base, 0);
20908 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
20909 CODE_LABEL_NUMBER (XEXP (base, 0)));
20913 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
20917 gcc_unreachable ();
20920 if (TARGET_MINIMAL_TOC)
20921 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
20924 fputs ("\t.tc ", file);
20925 RS6000_OUTPUT_BASENAME (file, name);
20928 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
20930 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
20932 fputs ("[TC],", file);
20935 /* Currently C++ toc references to vtables can be emitted before it
20936 is decided whether the vtable is public or private. If this is
20937 the case, then the linker will eventually complain that there is
20938 a TOC reference to an unknown section. Thus, for vtables only,
20939 we emit the TOC reference to reference the symbol and not the
20941 if (VTABLE_NAME_P (name))
20943 RS6000_OUTPUT_BASENAME (file, name);
20945 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
20946 else if (offset > 0)
20947 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
20950 output_addr_const (file, x);
20954 /* Output an assembler pseudo-op to write an ASCII string of N characters
20955 starting at P to FILE.
20957 On the RS/6000, we have to do this using the .byte operation and
20958 write out special characters outside the quoted string.
20959 Also, the assembler is broken; very long strings are truncated,
20960 so we must artificially break them up early. */
20963 output_ascii (FILE *file, const char *p, int n)
20966 int i, count_string;
20967 const char *for_string = "\t.byte \"";
20968 const char *for_decimal = "\t.byte ";
20969 const char *to_close = NULL;
20972 for (i = 0; i < n; i++)
20975 if (c >= ' ' && c < 0177)
20978 fputs (for_string, file);
20981 /* Write two quotes to get one. */
20989 for_decimal = "\"\n\t.byte ";
20993 if (count_string >= 512)
20995 fputs (to_close, file);
20997 for_string = "\t.byte \"";
20998 for_decimal = "\t.byte ";
21006 fputs (for_decimal, file);
21007 fprintf (file, "%d", c);
21009 for_string = "\n\t.byte \"";
21010 for_decimal = ", ";
21016 /* Now close the string if we have written one. Then end the line. */
21018 fputs (to_close, file);
21021 /* Generate a unique section name for FILENAME for a section type
21022 represented by SECTION_DESC. Output goes into BUF.
21024 SECTION_DESC can be any string, as long as it is different for each
21025 possible section type.
21027 We name the section in the same manner as xlc. The name begins with an
21028 underscore followed by the filename (after stripping any leading directory
21029 names) with the last period replaced by the string SECTION_DESC. If
21030 FILENAME does not contain a period, SECTION_DESC is appended to the end of
21034 rs6000_gen_section_name (char **buf, const char *filename,
21035 const char *section_desc)
21037 const char *q, *after_last_slash, *last_period = 0;
21041 after_last_slash = filename;
21042 for (q = filename; *q; q++)
21045 after_last_slash = q + 1;
21046 else if (*q == '.')
21050 len = strlen (after_last_slash) + strlen (section_desc) + 2;
21051 *buf = (char *) xmalloc (len);
21056 for (q = after_last_slash; *q; q++)
21058 if (q == last_period)
21060 strcpy (p, section_desc);
21061 p += strlen (section_desc);
21065 else if (ISALNUM (*q))
21069 if (last_period == 0)
21070 strcpy (p, section_desc);
21075 /* Emit profile function. */
21078 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
21080 /* Non-standard profiling for kernels, which just saves LR then calls
21081 _mcount without worrying about arg saves. The idea is to change
21082 the function prologue as little as possible as it isn't easy to
21083 account for arg save/restore code added just for _mcount. */
21084 if (TARGET_PROFILE_KERNEL)
21087 if (DEFAULT_ABI == ABI_AIX)
21089 #ifndef NO_PROFILE_COUNTERS
21090 # define NO_PROFILE_COUNTERS 0
21092 if (NO_PROFILE_COUNTERS)
21093 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21094 LCT_NORMAL, VOIDmode, 0);
21098 const char *label_name;
21101 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21102 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21103 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21105 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21106 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21109 else if (DEFAULT_ABI == ABI_DARWIN)
21111 const char *mcount_name = RS6000_MCOUNT;
21112 int caller_addr_regno = LR_REGNO;
21114 /* Be conservative and always set this, at least for now. */
21115 crtl->uses_pic_offset_table = 1;
21118 /* For PIC code, set up a stub and collect the caller's address
21119 from r0, which is where the prologue puts it. */
21120 if (MACHOPIC_INDIRECT
21121 && crtl->uses_pic_offset_table)
21122 caller_addr_regno = 0;
21124 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21125 LCT_NORMAL, VOIDmode, 1,
21126 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21130 /* Write function profiler code. */
21133 output_function_profiler (FILE *file, int labelno)
21137 switch (DEFAULT_ABI)
21140 gcc_unreachable ();
21145 warning (0, "no profiling of 64-bit code for this ABI");
21148 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21149 fprintf (file, "\tmflr %s\n", reg_names[0]);
21150 if (NO_PROFILE_COUNTERS)
21152 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21153 reg_names[0], reg_names[1]);
21155 else if (TARGET_SECURE_PLT && flag_pic)
21157 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21158 reg_names[0], reg_names[1]);
21159 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21160 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21161 reg_names[12], reg_names[12]);
21162 assemble_name (file, buf);
21163 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21164 assemble_name (file, buf);
21165 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21167 else if (flag_pic == 1)
21169 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21170 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21171 reg_names[0], reg_names[1]);
21172 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21173 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
21174 assemble_name (file, buf);
21175 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
21177 else if (flag_pic > 1)
21179 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21180 reg_names[0], reg_names[1]);
21181 /* Now, we need to get the address of the label. */
21182 fputs ("\tbcl 20,31,1f\n\t.long ", file);
21183 assemble_name (file, buf);
21184 fputs ("-.\n1:", file);
21185 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
21186 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
21187 reg_names[0], reg_names[11]);
21188 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
21189 reg_names[0], reg_names[0], reg_names[11]);
21193 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
21194 assemble_name (file, buf);
21195 fputs ("@ha\n", file);
21196 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21197 reg_names[0], reg_names[1]);
21198 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
21199 assemble_name (file, buf);
21200 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
21203 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21204 fprintf (file, "\tbl %s%s\n",
21205 RS6000_MCOUNT, flag_pic ? "@plt" : "");
21210 if (!TARGET_PROFILE_KERNEL)
21212 /* Don't do anything, done in output_profile_hook (). */
21216 gcc_assert (!TARGET_32BIT);
21218 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
21219 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
21221 if (cfun->static_chain_decl != NULL)
21223 asm_fprintf (file, "\tstd %s,24(%s)\n",
21224 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21225 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21226 asm_fprintf (file, "\tld %s,24(%s)\n",
21227 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21230 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21238 /* The following variable value is the last issued insn. */
21240 static rtx last_scheduled_insn;
21242 /* The following variable helps to balance issuing of load and
21243 store instructions */
21245 static int load_store_pendulum;
21247 /* Power4 load update and store update instructions are cracked into a
21248 load or store and an integer insn which are executed in the same cycle.
21249 Branches have their own dispatch slot which does not count against the
21250 GCC issue rate, but it changes the program flow so there are no other
21251 instructions to issue in this cycle. */
21254 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
21255 int verbose ATTRIBUTE_UNUSED,
21256 rtx insn, int more)
21258 last_scheduled_insn = insn;
21259 if (GET_CODE (PATTERN (insn)) == USE
21260 || GET_CODE (PATTERN (insn)) == CLOBBER)
21262 cached_can_issue_more = more;
21263 return cached_can_issue_more;
21266 if (insn_terminates_group_p (insn, current_group))
21268 cached_can_issue_more = 0;
21269 return cached_can_issue_more;
21272 /* If no reservation, but reach here */
21273 if (recog_memoized (insn) < 0)
21276 if (rs6000_sched_groups)
21278 if (is_microcoded_insn (insn))
21279 cached_can_issue_more = 0;
21280 else if (is_cracked_insn (insn))
21281 cached_can_issue_more = more > 2 ? more - 2 : 0;
21283 cached_can_issue_more = more - 1;
21285 return cached_can_issue_more;
21288 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21291 cached_can_issue_more = more - 1;
21292 return cached_can_issue_more;
21295 /* Adjust the cost of a scheduling dependency. Return the new cost of
21296 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21299 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21301 enum attr_type attr_type;
21303 if (! recog_memoized (insn))
21306 switch (REG_NOTE_KIND (link))
21310 /* Data dependency; DEP_INSN writes a register that INSN reads
21311 some cycles later. */
21313 /* Separate a load from a narrower, dependent store. */
21314 if (rs6000_sched_groups
21315 && GET_CODE (PATTERN (insn)) == SET
21316 && GET_CODE (PATTERN (dep_insn)) == SET
21317 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21318 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21319 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21320 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21323 attr_type = get_attr_type (insn);
21328 /* Tell the first scheduling pass about the latency between
21329 a mtctr and bctr (and mtlr and br/blr). The first
21330 scheduling pass will not know about this latency since
21331 the mtctr instruction, which has the latency associated
21332 to it, will be generated by reload. */
21333 return TARGET_POWER ? 5 : 4;
21335 /* Leave some extra cycles between a compare and its
21336 dependent branch, to inhibit expensive mispredicts. */
21337 if ((rs6000_cpu_attr == CPU_PPC603
21338 || rs6000_cpu_attr == CPU_PPC604
21339 || rs6000_cpu_attr == CPU_PPC604E
21340 || rs6000_cpu_attr == CPU_PPC620
21341 || rs6000_cpu_attr == CPU_PPC630
21342 || rs6000_cpu_attr == CPU_PPC750
21343 || rs6000_cpu_attr == CPU_PPC7400
21344 || rs6000_cpu_attr == CPU_PPC7450
21345 || rs6000_cpu_attr == CPU_POWER4
21346 || rs6000_cpu_attr == CPU_POWER5
21347 || rs6000_cpu_attr == CPU_POWER7
21348 || rs6000_cpu_attr == CPU_CELL)
21349 && recog_memoized (dep_insn)
21350 && (INSN_CODE (dep_insn) >= 0))
21352 switch (get_attr_type (dep_insn))
21356 case TYPE_DELAYED_COMPARE:
21357 case TYPE_IMUL_COMPARE:
21358 case TYPE_LMUL_COMPARE:
21359 case TYPE_FPCOMPARE:
21360 case TYPE_CR_LOGICAL:
21361 case TYPE_DELAYED_CR:
21370 case TYPE_STORE_UX:
21372 case TYPE_FPSTORE_U:
21373 case TYPE_FPSTORE_UX:
21374 if ((rs6000_cpu == PROCESSOR_POWER6)
21375 && recog_memoized (dep_insn)
21376 && (INSN_CODE (dep_insn) >= 0))
21379 if (GET_CODE (PATTERN (insn)) != SET)
21380 /* If this happens, we have to extend this to schedule
21381 optimally. Return default for now. */
21384 /* Adjust the cost for the case where the value written
21385 by a fixed point operation is used as the address
21386 gen value on a store. */
21387 switch (get_attr_type (dep_insn))
21394 if (! store_data_bypass_p (dep_insn, insn))
21398 case TYPE_LOAD_EXT:
21399 case TYPE_LOAD_EXT_U:
21400 case TYPE_LOAD_EXT_UX:
21401 case TYPE_VAR_SHIFT_ROTATE:
21402 case TYPE_VAR_DELAYED_COMPARE:
21404 if (! store_data_bypass_p (dep_insn, insn))
21410 case TYPE_FAST_COMPARE:
21413 case TYPE_INSERT_WORD:
21414 case TYPE_INSERT_DWORD:
21415 case TYPE_FPLOAD_U:
21416 case TYPE_FPLOAD_UX:
21418 case TYPE_STORE_UX:
21419 case TYPE_FPSTORE_U:
21420 case TYPE_FPSTORE_UX:
21422 if (! store_data_bypass_p (dep_insn, insn))
21430 case TYPE_IMUL_COMPARE:
21431 case TYPE_LMUL_COMPARE:
21433 if (! store_data_bypass_p (dep_insn, insn))
21439 if (! store_data_bypass_p (dep_insn, insn))
21445 if (! store_data_bypass_p (dep_insn, insn))
21458 case TYPE_LOAD_EXT:
21459 case TYPE_LOAD_EXT_U:
21460 case TYPE_LOAD_EXT_UX:
21461 if ((rs6000_cpu == PROCESSOR_POWER6)
21462 && recog_memoized (dep_insn)
21463 && (INSN_CODE (dep_insn) >= 0))
21466 /* Adjust the cost for the case where the value written
21467 by a fixed point instruction is used within the address
21468 gen portion of a subsequent load(u)(x) */
21469 switch (get_attr_type (dep_insn))
21476 if (set_to_load_agen (dep_insn, insn))
21480 case TYPE_LOAD_EXT:
21481 case TYPE_LOAD_EXT_U:
21482 case TYPE_LOAD_EXT_UX:
21483 case TYPE_VAR_SHIFT_ROTATE:
21484 case TYPE_VAR_DELAYED_COMPARE:
21486 if (set_to_load_agen (dep_insn, insn))
21492 case TYPE_FAST_COMPARE:
21495 case TYPE_INSERT_WORD:
21496 case TYPE_INSERT_DWORD:
21497 case TYPE_FPLOAD_U:
21498 case TYPE_FPLOAD_UX:
21500 case TYPE_STORE_UX:
21501 case TYPE_FPSTORE_U:
21502 case TYPE_FPSTORE_UX:
21504 if (set_to_load_agen (dep_insn, insn))
21512 case TYPE_IMUL_COMPARE:
21513 case TYPE_LMUL_COMPARE:
21515 if (set_to_load_agen (dep_insn, insn))
21521 if (set_to_load_agen (dep_insn, insn))
21527 if (set_to_load_agen (dep_insn, insn))
21538 if ((rs6000_cpu == PROCESSOR_POWER6)
21539 && recog_memoized (dep_insn)
21540 && (INSN_CODE (dep_insn) >= 0)
21541 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
21548 /* Fall out to return default cost. */
21552 case REG_DEP_OUTPUT:
21553 /* Output dependency; DEP_INSN writes a register that INSN writes some
21555 if ((rs6000_cpu == PROCESSOR_POWER6)
21556 && recog_memoized (dep_insn)
21557 && (INSN_CODE (dep_insn) >= 0))
21559 attr_type = get_attr_type (insn);
21564 if (get_attr_type (dep_insn) == TYPE_FP)
21568 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
21576 /* Anti dependency; DEP_INSN reads a register that INSN writes some
21581 gcc_unreachable ();
21587 /* Debug version of rs6000_adjust_cost. */
21590 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21592 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
21598 switch (REG_NOTE_KIND (link))
21600 default: dep = "unknown depencency"; break;
21601 case REG_DEP_TRUE: dep = "data dependency"; break;
21602 case REG_DEP_OUTPUT: dep = "output dependency"; break;
21603 case REG_DEP_ANTI: dep = "anti depencency"; break;
21607 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
21608 "%s, insn:\n", ret, cost, dep);
21616 /* The function returns a true if INSN is microcoded.
21617 Return false otherwise. */
21620 is_microcoded_insn (rtx insn)
21622 if (!insn || !NONDEBUG_INSN_P (insn)
21623 || GET_CODE (PATTERN (insn)) == USE
21624 || GET_CODE (PATTERN (insn)) == CLOBBER)
21627 if (rs6000_cpu_attr == CPU_CELL)
21628 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
21630 if (rs6000_sched_groups)
21632 enum attr_type type = get_attr_type (insn);
21633 if (type == TYPE_LOAD_EXT_U
21634 || type == TYPE_LOAD_EXT_UX
21635 || type == TYPE_LOAD_UX
21636 || type == TYPE_STORE_UX
21637 || type == TYPE_MFCR)
21644 /* The function returns true if INSN is cracked into 2 instructions
21645 by the processor (and therefore occupies 2 issue slots). */
21648 is_cracked_insn (rtx insn)
21650 if (!insn || !NONDEBUG_INSN_P (insn)
21651 || GET_CODE (PATTERN (insn)) == USE
21652 || GET_CODE (PATTERN (insn)) == CLOBBER)
21655 if (rs6000_sched_groups)
21657 enum attr_type type = get_attr_type (insn);
21658 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
21659 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
21660 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
21661 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
21662 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
21663 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
21664 || type == TYPE_IDIV || type == TYPE_LDIV
21665 || type == TYPE_INSERT_WORD)
21672 /* The function returns true if INSN can be issued only from
21673 the branch slot. */
21676 is_branch_slot_insn (rtx insn)
21678 if (!insn || !NONDEBUG_INSN_P (insn)
21679 || GET_CODE (PATTERN (insn)) == USE
21680 || GET_CODE (PATTERN (insn)) == CLOBBER)
21683 if (rs6000_sched_groups)
21685 enum attr_type type = get_attr_type (insn);
21686 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
21694 /* The function returns true if out_inst sets a value that is
21695 used in the address generation computation of in_insn */
21697 set_to_load_agen (rtx out_insn, rtx in_insn)
21699 rtx out_set, in_set;
21701 /* For performance reasons, only handle the simple case where
21702 both loads are a single_set. */
21703 out_set = single_set (out_insn);
21706 in_set = single_set (in_insn);
21708 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
21714 /* The function returns true if the target storage location of
21715 out_insn is adjacent to the target storage location of in_insn */
21716 /* Return 1 if memory locations are adjacent. */
21719 adjacent_mem_locations (rtx insn1, rtx insn2)
21722 rtx a = get_store_dest (PATTERN (insn1));
21723 rtx b = get_store_dest (PATTERN (insn2));
21725 if ((GET_CODE (XEXP (a, 0)) == REG
21726 || (GET_CODE (XEXP (a, 0)) == PLUS
21727 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
21728 && (GET_CODE (XEXP (b, 0)) == REG
21729 || (GET_CODE (XEXP (b, 0)) == PLUS
21730 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
21732 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
21735 if (GET_CODE (XEXP (a, 0)) == PLUS)
21737 reg0 = XEXP (XEXP (a, 0), 0);
21738 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
21741 reg0 = XEXP (a, 0);
21743 if (GET_CODE (XEXP (b, 0)) == PLUS)
21745 reg1 = XEXP (XEXP (b, 0), 0);
21746 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
21749 reg1 = XEXP (b, 0);
21751 val_diff = val1 - val0;
21753 return ((REGNO (reg0) == REGNO (reg1))
21754 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
21755 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
21761 /* A C statement (sans semicolon) to update the integer scheduling
21762 priority INSN_PRIORITY (INSN). Increase the priority to execute the
21763 INSN earlier, reduce the priority to execute INSN later. Do not
21764 define this macro if you do not need to adjust the scheduling
21765 priorities of insns. */
21768 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
21770 /* On machines (like the 750) which have asymmetric integer units,
21771 where one integer unit can do multiply and divides and the other
21772 can't, reduce the priority of multiply/divide so it is scheduled
21773 before other integer operations. */
21776 if (! INSN_P (insn))
21779 if (GET_CODE (PATTERN (insn)) == USE)
21782 switch (rs6000_cpu_attr) {
21784 switch (get_attr_type (insn))
21791 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
21792 priority, priority);
21793 if (priority >= 0 && priority < 0x01000000)
21800 if (insn_must_be_first_in_group (insn)
21801 && reload_completed
21802 && current_sched_info->sched_max_insns_priority
21803 && rs6000_sched_restricted_insns_priority)
21806 /* Prioritize insns that can be dispatched only in the first
21808 if (rs6000_sched_restricted_insns_priority == 1)
21809 /* Attach highest priority to insn. This means that in
21810 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
21811 precede 'priority' (critical path) considerations. */
21812 return current_sched_info->sched_max_insns_priority;
21813 else if (rs6000_sched_restricted_insns_priority == 2)
21814 /* Increase priority of insn by a minimal amount. This means that in
21815 haifa-sched.c:ready_sort(), only 'priority' (critical path)
21816 considerations precede dispatch-slot restriction considerations. */
21817 return (priority + 1);
21820 if (rs6000_cpu == PROCESSOR_POWER6
21821 && ((load_store_pendulum == -2 && is_load_insn (insn))
21822 || (load_store_pendulum == 2 && is_store_insn (insn))))
21823 /* Attach highest priority to insn if the scheduler has just issued two
21824 stores and this instruction is a load, or two loads and this instruction
21825 is a store. Power6 wants loads and stores scheduled alternately
21827 return current_sched_info->sched_max_insns_priority;
21832 /* Return true if the instruction is nonpipelined on the Cell. */
21834 is_nonpipeline_insn (rtx insn)
21836 enum attr_type type;
21837 if (!insn || !NONDEBUG_INSN_P (insn)
21838 || GET_CODE (PATTERN (insn)) == USE
21839 || GET_CODE (PATTERN (insn)) == CLOBBER)
21842 type = get_attr_type (insn);
21843 if (type == TYPE_IMUL
21844 || type == TYPE_IMUL2
21845 || type == TYPE_IMUL3
21846 || type == TYPE_LMUL
21847 || type == TYPE_IDIV
21848 || type == TYPE_LDIV
21849 || type == TYPE_SDIV
21850 || type == TYPE_DDIV
21851 || type == TYPE_SSQRT
21852 || type == TYPE_DSQRT
21853 || type == TYPE_MFCR
21854 || type == TYPE_MFCRF
21855 || type == TYPE_MFJMPR)
21863 /* Return how many instructions the machine can issue per cycle. */
21866 rs6000_issue_rate (void)
21868 /* Unless scheduling for register pressure, use issue rate of 1 for
21869 first scheduling pass to decrease degradation. */
21870 if (!reload_completed && !flag_sched_pressure)
21873 switch (rs6000_cpu_attr) {
21874 case CPU_RIOS1: /* ? */
21876 case CPU_PPC601: /* ? */
21885 case CPU_PPCE300C2:
21886 case CPU_PPCE300C3:
21887 case CPU_PPCE500MC:
21906 /* Return how many instructions to look ahead for better insn
21910 rs6000_use_sched_lookahead (void)
21912 if (rs6000_cpu_attr == CPU_PPC8540)
21914 if (rs6000_cpu_attr == CPU_CELL)
21915 return (reload_completed ? 8 : 0);
21919 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
21921 rs6000_use_sched_lookahead_guard (rtx insn)
21923 if (rs6000_cpu_attr != CPU_CELL)
21926 if (insn == NULL_RTX || !INSN_P (insn))
21929 if (!reload_completed
21930 || is_nonpipeline_insn (insn)
21931 || is_microcoded_insn (insn))
21937 /* Determine is PAT refers to memory. */
21940 is_mem_ref (rtx pat)
21946 /* stack_tie does not produce any real memory traffic. */
21947 if (GET_CODE (pat) == UNSPEC
21948 && XINT (pat, 1) == UNSPEC_TIE)
21951 if (GET_CODE (pat) == MEM)
21954 /* Recursively process the pattern. */
21955 fmt = GET_RTX_FORMAT (GET_CODE (pat));
21957 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
21960 ret |= is_mem_ref (XEXP (pat, i));
21961 else if (fmt[i] == 'E')
21962 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
21963 ret |= is_mem_ref (XVECEXP (pat, i, j));
21969 /* Determine if PAT is a PATTERN of a load insn. */
21972 is_load_insn1 (rtx pat)
21974 if (!pat || pat == NULL_RTX)
21977 if (GET_CODE (pat) == SET)
21978 return is_mem_ref (SET_SRC (pat));
21980 if (GET_CODE (pat) == PARALLEL)
21984 for (i = 0; i < XVECLEN (pat, 0); i++)
21985 if (is_load_insn1 (XVECEXP (pat, 0, i)))
21992 /* Determine if INSN loads from memory. */
21995 is_load_insn (rtx insn)
21997 if (!insn || !INSN_P (insn))
22000 if (GET_CODE (insn) == CALL_INSN)
22003 return is_load_insn1 (PATTERN (insn));
22006 /* Determine if PAT is a PATTERN of a store insn. */
22009 is_store_insn1 (rtx pat)
22011 if (!pat || pat == NULL_RTX)
22014 if (GET_CODE (pat) == SET)
22015 return is_mem_ref (SET_DEST (pat));
22017 if (GET_CODE (pat) == PARALLEL)
22021 for (i = 0; i < XVECLEN (pat, 0); i++)
22022 if (is_store_insn1 (XVECEXP (pat, 0, i)))
22029 /* Determine if INSN stores to memory. */
22032 is_store_insn (rtx insn)
22034 if (!insn || !INSN_P (insn))
22037 return is_store_insn1 (PATTERN (insn));
22040 /* Return the dest of a store insn. */
22043 get_store_dest (rtx pat)
22045 gcc_assert (is_store_insn1 (pat));
22047 if (GET_CODE (pat) == SET)
22048 return SET_DEST (pat);
22049 else if (GET_CODE (pat) == PARALLEL)
22053 for (i = 0; i < XVECLEN (pat, 0); i++)
22055 rtx inner_pat = XVECEXP (pat, 0, i);
22056 if (GET_CODE (inner_pat) == SET
22057 && is_mem_ref (SET_DEST (inner_pat)))
22061 /* We shouldn't get here, because we should have either a simple
22062 store insn or a store with update which are covered above. */
22066 /* Returns whether the dependence between INSN and NEXT is considered
22067 costly by the given target. */
22070 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
22075 /* If the flag is not enabled - no dependence is considered costly;
22076 allow all dependent insns in the same group.
22077 This is the most aggressive option. */
22078 if (rs6000_sched_costly_dep == no_dep_costly)
22081 /* If the flag is set to 1 - a dependence is always considered costly;
22082 do not allow dependent instructions in the same group.
22083 This is the most conservative option. */
22084 if (rs6000_sched_costly_dep == all_deps_costly)
22087 insn = DEP_PRO (dep);
22088 next = DEP_CON (dep);
22090 if (rs6000_sched_costly_dep == store_to_load_dep_costly
22091 && is_load_insn (next)
22092 && is_store_insn (insn))
22093 /* Prevent load after store in the same group. */
22096 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
22097 && is_load_insn (next)
22098 && is_store_insn (insn)
22099 && DEP_TYPE (dep) == REG_DEP_TRUE)
22100 /* Prevent load after store in the same group if it is a true
22104 /* The flag is set to X; dependences with latency >= X are considered costly,
22105 and will not be scheduled in the same group. */
22106 if (rs6000_sched_costly_dep <= max_dep_latency
22107 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22113 /* Return the next insn after INSN that is found before TAIL is reached,
22114 skipping any "non-active" insns - insns that will not actually occupy
22115 an issue slot. Return NULL_RTX if such an insn is not found. */
22118 get_next_active_insn (rtx insn, rtx tail)
22120 if (insn == NULL_RTX || insn == tail)
22125 insn = NEXT_INSN (insn);
22126 if (insn == NULL_RTX || insn == tail)
22131 || (NONJUMP_INSN_P (insn)
22132 && GET_CODE (PATTERN (insn)) != USE
22133 && GET_CODE (PATTERN (insn)) != CLOBBER
22134 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22140 /* We are about to begin issuing insns for this clock cycle. */
22143 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22144 rtx *ready ATTRIBUTE_UNUSED,
22145 int *pn_ready ATTRIBUTE_UNUSED,
22146 int clock_var ATTRIBUTE_UNUSED)
22148 int n_ready = *pn_ready;
22151 fprintf (dump, "// rs6000_sched_reorder :\n");
22153 /* Reorder the ready list, if the second to last ready insn
22154 is a nonepipeline insn. */
22155 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22157 if (is_nonpipeline_insn (ready[n_ready - 1])
22158 && (recog_memoized (ready[n_ready - 2]) > 0))
22159 /* Simply swap first two insns. */
22161 rtx tmp = ready[n_ready - 1];
22162 ready[n_ready - 1] = ready[n_ready - 2];
22163 ready[n_ready - 2] = tmp;
22167 if (rs6000_cpu == PROCESSOR_POWER6)
22168 load_store_pendulum = 0;
22170 return rs6000_issue_rate ();
22173 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22176 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
22177 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
22180 fprintf (dump, "// rs6000_sched_reorder2 :\n");
22182 /* For Power6, we need to handle some special cases to try and keep the
22183 store queue from overflowing and triggering expensive flushes.
22185 This code monitors how load and store instructions are being issued
22186 and skews the ready list one way or the other to increase the likelihood
22187 that a desired instruction is issued at the proper time.
22189 A couple of things are done. First, we maintain a "load_store_pendulum"
22190 to track the current state of load/store issue.
22192 - If the pendulum is at zero, then no loads or stores have been
22193 issued in the current cycle so we do nothing.
22195 - If the pendulum is 1, then a single load has been issued in this
22196 cycle and we attempt to locate another load in the ready list to
22199 - If the pendulum is -2, then two stores have already been
22200 issued in this cycle, so we increase the priority of the first load
22201 in the ready list to increase it's likelihood of being chosen first
22204 - If the pendulum is -1, then a single store has been issued in this
22205 cycle and we attempt to locate another store in the ready list to
22206 issue with it, preferring a store to an adjacent memory location to
22207 facilitate store pairing in the store queue.
22209 - If the pendulum is 2, then two loads have already been
22210 issued in this cycle, so we increase the priority of the first store
22211 in the ready list to increase it's likelihood of being chosen first
22214 - If the pendulum < -2 or > 2, then do nothing.
22216 Note: This code covers the most common scenarios. There exist non
22217 load/store instructions which make use of the LSU and which
22218 would need to be accounted for to strictly model the behavior
22219 of the machine. Those instructions are currently unaccounted
22220 for to help minimize compile time overhead of this code.
22222 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
22228 if (is_store_insn (last_scheduled_insn))
22229 /* Issuing a store, swing the load_store_pendulum to the left */
22230 load_store_pendulum--;
22231 else if (is_load_insn (last_scheduled_insn))
22232 /* Issuing a load, swing the load_store_pendulum to the right */
22233 load_store_pendulum++;
22235 return cached_can_issue_more;
22237 /* If the pendulum is balanced, or there is only one instruction on
22238 the ready list, then all is well, so return. */
22239 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
22240 return cached_can_issue_more;
22242 if (load_store_pendulum == 1)
22244 /* A load has been issued in this cycle. Scan the ready list
22245 for another load to issue with it */
22250 if (is_load_insn (ready[pos]))
22252 /* Found a load. Move it to the head of the ready list,
22253 and adjust it's priority so that it is more likely to
22256 for (i=pos; i<*pn_ready-1; i++)
22257 ready[i] = ready[i + 1];
22258 ready[*pn_ready-1] = tmp;
22260 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22261 INSN_PRIORITY (tmp)++;
22267 else if (load_store_pendulum == -2)
22269 /* Two stores have been issued in this cycle. Increase the
22270 priority of the first load in the ready list to favor it for
22271 issuing in the next cycle. */
22276 if (is_load_insn (ready[pos])
22278 && INSN_PRIORITY_KNOWN (ready[pos]))
22280 INSN_PRIORITY (ready[pos])++;
22282 /* Adjust the pendulum to account for the fact that a load
22283 was found and increased in priority. This is to prevent
22284 increasing the priority of multiple loads */
22285 load_store_pendulum--;
22292 else if (load_store_pendulum == -1)
22294 /* A store has been issued in this cycle. Scan the ready list for
22295 another store to issue with it, preferring a store to an adjacent
22297 int first_store_pos = -1;
22303 if (is_store_insn (ready[pos]))
22305 /* Maintain the index of the first store found on the
22307 if (first_store_pos == -1)
22308 first_store_pos = pos;
22310 if (is_store_insn (last_scheduled_insn)
22311 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22313 /* Found an adjacent store. Move it to the head of the
22314 ready list, and adjust it's priority so that it is
22315 more likely to stay there */
22317 for (i=pos; i<*pn_ready-1; i++)
22318 ready[i] = ready[i + 1];
22319 ready[*pn_ready-1] = tmp;
22321 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22322 INSN_PRIORITY (tmp)++;
22324 first_store_pos = -1;
22332 if (first_store_pos >= 0)
22334 /* An adjacent store wasn't found, but a non-adjacent store was,
22335 so move the non-adjacent store to the front of the ready
22336 list, and adjust its priority so that it is more likely to
22338 tmp = ready[first_store_pos];
22339 for (i=first_store_pos; i<*pn_ready-1; i++)
22340 ready[i] = ready[i + 1];
22341 ready[*pn_ready-1] = tmp;
22342 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22343 INSN_PRIORITY (tmp)++;
22346 else if (load_store_pendulum == 2)
22348 /* Two loads have been issued in this cycle. Increase the priority
22349 of the first store in the ready list to favor it for issuing in
22355 if (is_store_insn (ready[pos])
22357 && INSN_PRIORITY_KNOWN (ready[pos]))
22359 INSN_PRIORITY (ready[pos])++;
22361 /* Adjust the pendulum to account for the fact that a store
22362 was found and increased in priority. This is to prevent
22363 increasing the priority of multiple stores */
22364 load_store_pendulum++;
22373 return cached_can_issue_more;
22376 /* Return whether the presence of INSN causes a dispatch group termination
22377 of group WHICH_GROUP.
22379 If WHICH_GROUP == current_group, this function will return true if INSN
22380 causes the termination of the current group (i.e, the dispatch group to
22381 which INSN belongs). This means that INSN will be the last insn in the
22382 group it belongs to.
22384 If WHICH_GROUP == previous_group, this function will return true if INSN
22385 causes the termination of the previous group (i.e, the dispatch group that
22386 precedes the group to which INSN belongs). This means that INSN will be
22387 the first insn in the group it belongs to). */
22390 insn_terminates_group_p (rtx insn, enum group_termination which_group)
22397 first = insn_must_be_first_in_group (insn);
22398 last = insn_must_be_last_in_group (insn);
22403 if (which_group == current_group)
22405 else if (which_group == previous_group)
22413 insn_must_be_first_in_group (rtx insn)
22415 enum attr_type type;
22418 || GET_CODE (insn) == NOTE
22419 || DEBUG_INSN_P (insn)
22420 || GET_CODE (PATTERN (insn)) == USE
22421 || GET_CODE (PATTERN (insn)) == CLOBBER)
22424 switch (rs6000_cpu)
22426 case PROCESSOR_POWER5:
22427 if (is_cracked_insn (insn))
22429 case PROCESSOR_POWER4:
22430 if (is_microcoded_insn (insn))
22433 if (!rs6000_sched_groups)
22436 type = get_attr_type (insn);
22443 case TYPE_DELAYED_CR:
22444 case TYPE_CR_LOGICAL:
22458 case PROCESSOR_POWER6:
22459 type = get_attr_type (insn);
22463 case TYPE_INSERT_DWORD:
22467 case TYPE_VAR_SHIFT_ROTATE:
22474 case TYPE_INSERT_WORD:
22475 case TYPE_DELAYED_COMPARE:
22476 case TYPE_IMUL_COMPARE:
22477 case TYPE_LMUL_COMPARE:
22478 case TYPE_FPCOMPARE:
22489 case TYPE_LOAD_EXT_UX:
22491 case TYPE_STORE_UX:
22492 case TYPE_FPLOAD_U:
22493 case TYPE_FPLOAD_UX:
22494 case TYPE_FPSTORE_U:
22495 case TYPE_FPSTORE_UX:
22501 case PROCESSOR_POWER7:
22502 type = get_attr_type (insn);
22506 case TYPE_CR_LOGICAL:
22513 case TYPE_DELAYED_COMPARE:
22514 case TYPE_VAR_DELAYED_COMPARE:
22520 case TYPE_LOAD_EXT:
22521 case TYPE_LOAD_EXT_U:
22522 case TYPE_LOAD_EXT_UX:
22524 case TYPE_STORE_UX:
22525 case TYPE_FPLOAD_U:
22526 case TYPE_FPLOAD_UX:
22527 case TYPE_FPSTORE_U:
22528 case TYPE_FPSTORE_UX:
22544 insn_must_be_last_in_group (rtx insn)
22546 enum attr_type type;
22549 || GET_CODE (insn) == NOTE
22550 || DEBUG_INSN_P (insn)
22551 || GET_CODE (PATTERN (insn)) == USE
22552 || GET_CODE (PATTERN (insn)) == CLOBBER)
22555 switch (rs6000_cpu) {
22556 case PROCESSOR_POWER4:
22557 case PROCESSOR_POWER5:
22558 if (is_microcoded_insn (insn))
22561 if (is_branch_slot_insn (insn))
22565 case PROCESSOR_POWER6:
22566 type = get_attr_type (insn);
22573 case TYPE_VAR_SHIFT_ROTATE:
22580 case TYPE_DELAYED_COMPARE:
22581 case TYPE_IMUL_COMPARE:
22582 case TYPE_LMUL_COMPARE:
22583 case TYPE_FPCOMPARE:
22597 case PROCESSOR_POWER7:
22598 type = get_attr_type (insn);
22606 case TYPE_LOAD_EXT_U:
22607 case TYPE_LOAD_EXT_UX:
22608 case TYPE_STORE_UX:
22621 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
22622 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
22625 is_costly_group (rtx *group_insns, rtx next_insn)
22628 int issue_rate = rs6000_issue_rate ();
22630 for (i = 0; i < issue_rate; i++)
22632 sd_iterator_def sd_it;
22634 rtx insn = group_insns[i];
22639 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
22641 rtx next = DEP_CON (dep);
22643 if (next == next_insn
22644 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
22652 /* Utility of the function redefine_groups.
22653 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
22654 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
22655 to keep it "far" (in a separate group) from GROUP_INSNS, following
22656 one of the following schemes, depending on the value of the flag
22657 -minsert_sched_nops = X:
22658 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
22659 in order to force NEXT_INSN into a separate group.
22660 (2) X < sched_finish_regroup_exact: insert exactly X nops.
22661 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
22662 insertion (has a group just ended, how many vacant issue slots remain in the
22663 last group, and how many dispatch groups were encountered so far). */
22666 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
22667 rtx next_insn, bool *group_end, int can_issue_more,
22672 int issue_rate = rs6000_issue_rate ();
22673 bool end = *group_end;
22676 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
22677 return can_issue_more;
22679 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
22680 return can_issue_more;
22682 force = is_costly_group (group_insns, next_insn);
22684 return can_issue_more;
22686 if (sched_verbose > 6)
22687 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
22688 *group_count ,can_issue_more);
22690 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
22693 can_issue_more = 0;
22695 /* Since only a branch can be issued in the last issue_slot, it is
22696 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
22697 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
22698 in this case the last nop will start a new group and the branch
22699 will be forced to the new group. */
22700 if (can_issue_more && !is_branch_slot_insn (next_insn))
22703 while (can_issue_more > 0)
22706 emit_insn_before (nop, next_insn);
22714 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
22716 int n_nops = rs6000_sched_insert_nops;
22718 /* Nops can't be issued from the branch slot, so the effective
22719 issue_rate for nops is 'issue_rate - 1'. */
22720 if (can_issue_more == 0)
22721 can_issue_more = issue_rate;
22723 if (can_issue_more == 0)
22725 can_issue_more = issue_rate - 1;
22728 for (i = 0; i < issue_rate; i++)
22730 group_insns[i] = 0;
22737 emit_insn_before (nop, next_insn);
22738 if (can_issue_more == issue_rate - 1) /* new group begins */
22741 if (can_issue_more == 0)
22743 can_issue_more = issue_rate - 1;
22746 for (i = 0; i < issue_rate; i++)
22748 group_insns[i] = 0;
22754 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
22757 /* Is next_insn going to start a new group? */
22760 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22761 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22762 || (can_issue_more < issue_rate &&
22763 insn_terminates_group_p (next_insn, previous_group)));
22764 if (*group_end && end)
22767 if (sched_verbose > 6)
22768 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
22769 *group_count, can_issue_more);
22770 return can_issue_more;
22773 return can_issue_more;
22776 /* This function tries to synch the dispatch groups that the compiler "sees"
22777 with the dispatch groups that the processor dispatcher is expected to
22778 form in practice. It tries to achieve this synchronization by forcing the
22779 estimated processor grouping on the compiler (as opposed to the function
22780 'pad_goups' which tries to force the scheduler's grouping on the processor).
22782 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
22783 examines the (estimated) dispatch groups that will be formed by the processor
22784 dispatcher. It marks these group boundaries to reflect the estimated
22785 processor grouping, overriding the grouping that the scheduler had marked.
22786 Depending on the value of the flag '-minsert-sched-nops' this function can
22787 force certain insns into separate groups or force a certain distance between
22788 them by inserting nops, for example, if there exists a "costly dependence"
22791 The function estimates the group boundaries that the processor will form as
22792 follows: It keeps track of how many vacant issue slots are available after
22793 each insn. A subsequent insn will start a new group if one of the following
22795 - no more vacant issue slots remain in the current dispatch group.
22796 - only the last issue slot, which is the branch slot, is vacant, but the next
22797 insn is not a branch.
22798 - only the last 2 or less issue slots, including the branch slot, are vacant,
22799 which means that a cracked insn (which occupies two issue slots) can't be
22800 issued in this group.
22801 - less than 'issue_rate' slots are vacant, and the next insn always needs to
22802 start a new group. */
22805 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22807 rtx insn, next_insn;
22809 int can_issue_more;
22812 int group_count = 0;
22816 issue_rate = rs6000_issue_rate ();
22817 group_insns = XALLOCAVEC (rtx, issue_rate);
22818 for (i = 0; i < issue_rate; i++)
22820 group_insns[i] = 0;
22822 can_issue_more = issue_rate;
22824 insn = get_next_active_insn (prev_head_insn, tail);
22827 while (insn != NULL_RTX)
22829 slot = (issue_rate - can_issue_more);
22830 group_insns[slot] = insn;
22832 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
22833 if (insn_terminates_group_p (insn, current_group))
22834 can_issue_more = 0;
22836 next_insn = get_next_active_insn (insn, tail);
22837 if (next_insn == NULL_RTX)
22838 return group_count + 1;
22840 /* Is next_insn going to start a new group? */
22842 = (can_issue_more == 0
22843 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22844 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22845 || (can_issue_more < issue_rate &&
22846 insn_terminates_group_p (next_insn, previous_group)));
22848 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
22849 next_insn, &group_end, can_issue_more,
22855 can_issue_more = 0;
22856 for (i = 0; i < issue_rate; i++)
22858 group_insns[i] = 0;
22862 if (GET_MODE (next_insn) == TImode && can_issue_more)
22863 PUT_MODE (next_insn, VOIDmode);
22864 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
22865 PUT_MODE (next_insn, TImode);
22868 if (can_issue_more == 0)
22869 can_issue_more = issue_rate;
22872 return group_count;
22875 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
22876 dispatch group boundaries that the scheduler had marked. Pad with nops
22877 any dispatch groups which have vacant issue slots, in order to force the
22878 scheduler's grouping on the processor dispatcher. The function
22879 returns the number of dispatch groups found. */
22882 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22884 rtx insn, next_insn;
22887 int can_issue_more;
22889 int group_count = 0;
22891 /* Initialize issue_rate. */
22892 issue_rate = rs6000_issue_rate ();
22893 can_issue_more = issue_rate;
22895 insn = get_next_active_insn (prev_head_insn, tail);
22896 next_insn = get_next_active_insn (insn, tail);
22898 while (insn != NULL_RTX)
22901 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
22903 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
22905 if (next_insn == NULL_RTX)
22910 /* If the scheduler had marked group termination at this location
22911 (between insn and next_insn), and neither insn nor next_insn will
22912 force group termination, pad the group with nops to force group
22915 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
22916 && !insn_terminates_group_p (insn, current_group)
22917 && !insn_terminates_group_p (next_insn, previous_group))
22919 if (!is_branch_slot_insn (next_insn))
22922 while (can_issue_more)
22925 emit_insn_before (nop, next_insn);
22930 can_issue_more = issue_rate;
22935 next_insn = get_next_active_insn (insn, tail);
22938 return group_count;
22941 /* We're beginning a new block. Initialize data structures as necessary. */
22944 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
22945 int sched_verbose ATTRIBUTE_UNUSED,
22946 int max_ready ATTRIBUTE_UNUSED)
22948 last_scheduled_insn = NULL_RTX;
22949 load_store_pendulum = 0;
22952 /* The following function is called at the end of scheduling BB.
22953 After reload, it inserts nops at insn group bundling. */
22956 rs6000_sched_finish (FILE *dump, int sched_verbose)
22961 fprintf (dump, "=== Finishing schedule.\n");
22963 if (reload_completed && rs6000_sched_groups)
22965 /* Do not run sched_finish hook when selective scheduling enabled. */
22966 if (sel_sched_p ())
22969 if (rs6000_sched_insert_nops == sched_finish_none)
22972 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
22973 n_groups = pad_groups (dump, sched_verbose,
22974 current_sched_info->prev_head,
22975 current_sched_info->next_tail);
22977 n_groups = redefine_groups (dump, sched_verbose,
22978 current_sched_info->prev_head,
22979 current_sched_info->next_tail);
22981 if (sched_verbose >= 6)
22983 fprintf (dump, "ngroups = %d\n", n_groups);
22984 print_rtl (dump, current_sched_info->prev_head);
22985 fprintf (dump, "Done finish_sched\n");
22990 struct _rs6000_sched_context
22992 short cached_can_issue_more;
22993 rtx last_scheduled_insn;
22994 int load_store_pendulum;
22997 typedef struct _rs6000_sched_context rs6000_sched_context_def;
22998 typedef rs6000_sched_context_def *rs6000_sched_context_t;
23000 /* Allocate store for new scheduling context. */
23002 rs6000_alloc_sched_context (void)
23004 return xmalloc (sizeof (rs6000_sched_context_def));
23007 /* If CLEAN_P is true then initializes _SC with clean data,
23008 and from the global context otherwise. */
23010 rs6000_init_sched_context (void *_sc, bool clean_p)
23012 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23016 sc->cached_can_issue_more = 0;
23017 sc->last_scheduled_insn = NULL_RTX;
23018 sc->load_store_pendulum = 0;
23022 sc->cached_can_issue_more = cached_can_issue_more;
23023 sc->last_scheduled_insn = last_scheduled_insn;
23024 sc->load_store_pendulum = load_store_pendulum;
23028 /* Sets the global scheduling context to the one pointed to by _SC. */
23030 rs6000_set_sched_context (void *_sc)
23032 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23034 gcc_assert (sc != NULL);
23036 cached_can_issue_more = sc->cached_can_issue_more;
23037 last_scheduled_insn = sc->last_scheduled_insn;
23038 load_store_pendulum = sc->load_store_pendulum;
23043 rs6000_free_sched_context (void *_sc)
23045 gcc_assert (_sc != NULL);
23051 /* Length in units of the trampoline for entering a nested function. */
23054 rs6000_trampoline_size (void)
23058 switch (DEFAULT_ABI)
23061 gcc_unreachable ();
23064 ret = (TARGET_32BIT) ? 12 : 24;
23069 ret = (TARGET_32BIT) ? 40 : 48;
23076 /* Emit RTL insns to initialize the variable parts of a trampoline.
23077 FNADDR is an RTX for the address of the function's pure code.
23078 CXT is an RTX for the static chain value for the function. */
23081 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
23083 int regsize = (TARGET_32BIT) ? 4 : 8;
23084 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
23085 rtx ctx_reg = force_reg (Pmode, cxt);
23086 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
23088 switch (DEFAULT_ABI)
23091 gcc_unreachable ();
23093 /* Under AIX, just build the 3 word function descriptor */
23096 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
23097 rtx fn_reg = gen_reg_rtx (Pmode);
23098 rtx toc_reg = gen_reg_rtx (Pmode);
23100 /* Macro to shorten the code expansions below. */
23101 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23103 m_tramp = replace_equiv_address (m_tramp, addr);
23105 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
23106 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23107 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23108 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23109 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23115 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23118 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23119 LCT_NORMAL, VOIDmode, 4,
23121 GEN_INT (rs6000_trampoline_size ()), SImode,
23129 /* Handle the "altivec" attribute. The attribute may have
23130 arguments as follows:
23132 __attribute__((altivec(vector__)))
23133 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23134 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23136 and may appear more than once (e.g., 'vector bool char') in a
23137 given declaration. */
23140 rs6000_handle_altivec_attribute (tree *node,
23141 tree name ATTRIBUTE_UNUSED,
23143 int flags ATTRIBUTE_UNUSED,
23144 bool *no_add_attrs)
23146 tree type = *node, result = NULL_TREE;
23147 enum machine_mode mode;
23150 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23151 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23152 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23155 while (POINTER_TYPE_P (type)
23156 || TREE_CODE (type) == FUNCTION_TYPE
23157 || TREE_CODE (type) == METHOD_TYPE
23158 || TREE_CODE (type) == ARRAY_TYPE)
23159 type = TREE_TYPE (type);
23161 mode = TYPE_MODE (type);
23163 /* Check for invalid AltiVec type qualifiers. */
23164 if (type == long_double_type_node)
23165 error ("use of %<long double%> in AltiVec types is invalid");
23166 else if (type == boolean_type_node)
23167 error ("use of boolean types in AltiVec types is invalid");
23168 else if (TREE_CODE (type) == COMPLEX_TYPE)
23169 error ("use of %<complex%> in AltiVec types is invalid");
23170 else if (DECIMAL_FLOAT_MODE_P (mode))
23171 error ("use of decimal floating point types in AltiVec types is invalid");
23172 else if (!TARGET_VSX)
23174 if (type == long_unsigned_type_node || type == long_integer_type_node)
23177 error ("use of %<long%> in AltiVec types is invalid for "
23178 "64-bit code without -mvsx");
23179 else if (rs6000_warn_altivec_long)
23180 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23183 else if (type == long_long_unsigned_type_node
23184 || type == long_long_integer_type_node)
23185 error ("use of %<long long%> in AltiVec types is invalid without "
23187 else if (type == double_type_node)
23188 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23191 switch (altivec_type)
23194 unsigned_p = TYPE_UNSIGNED (type);
23198 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
23201 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
23204 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
23207 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
23209 case SFmode: result = V4SF_type_node; break;
23210 case DFmode: result = V2DF_type_node; break;
23211 /* If the user says 'vector int bool', we may be handed the 'bool'
23212 attribute _before_ the 'vector' attribute, and so select the
23213 proper type in the 'b' case below. */
23214 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
23215 case V2DImode: case V2DFmode:
23223 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
23224 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
23225 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
23226 case QImode: case V16QImode: result = bool_V16QI_type_node;
23233 case V8HImode: result = pixel_V8HI_type_node;
23239 /* Propagate qualifiers attached to the element type
23240 onto the vector type. */
23241 if (result && result != type && TYPE_QUALS (type))
23242 result = build_qualified_type (result, TYPE_QUALS (type));
23244 *no_add_attrs = true; /* No need to hang on to the attribute. */
23247 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
23252 /* AltiVec defines four built-in scalar types that serve as vector
23253 elements; we must teach the compiler how to mangle them. */
23255 static const char *
23256 rs6000_mangle_type (const_tree type)
23258 type = TYPE_MAIN_VARIANT (type);
23260 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
23261 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
23264 if (type == bool_char_type_node) return "U6__boolc";
23265 if (type == bool_short_type_node) return "U6__bools";
23266 if (type == pixel_type_node) return "u7__pixel";
23267 if (type == bool_int_type_node) return "U6__booli";
23268 if (type == bool_long_type_node) return "U6__booll";
23270 /* Mangle IBM extended float long double as `g' (__float128) on
23271 powerpc*-linux where long-double-64 previously was the default. */
23272 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
23274 && TARGET_LONG_DOUBLE_128
23275 && !TARGET_IEEEQUAD)
23278 /* For all other types, use normal C++ mangling. */
23282 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23283 struct attribute_spec.handler. */
23286 rs6000_handle_longcall_attribute (tree *node, tree name,
23287 tree args ATTRIBUTE_UNUSED,
23288 int flags ATTRIBUTE_UNUSED,
23289 bool *no_add_attrs)
23291 if (TREE_CODE (*node) != FUNCTION_TYPE
23292 && TREE_CODE (*node) != FIELD_DECL
23293 && TREE_CODE (*node) != TYPE_DECL)
23295 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23297 *no_add_attrs = true;
23303 /* Set longcall attributes on all functions declared when
23304 rs6000_default_long_calls is true. */
23306 rs6000_set_default_type_attributes (tree type)
23308 if (rs6000_default_long_calls
23309 && (TREE_CODE (type) == FUNCTION_TYPE
23310 || TREE_CODE (type) == METHOD_TYPE))
23311 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23313 TYPE_ATTRIBUTES (type));
23316 darwin_set_default_type_attributes (type);
23320 /* Return a reference suitable for calling a function with the
23321 longcall attribute. */
23324 rs6000_longcall_ref (rtx call_ref)
23326 const char *call_name;
23329 if (GET_CODE (call_ref) != SYMBOL_REF)
23332 /* System V adds '.' to the internal name, so skip them. */
23333 call_name = XSTR (call_ref, 0);
23334 if (*call_name == '.')
23336 while (*call_name == '.')
23339 node = get_identifier (call_name);
23340 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
23343 return force_reg (Pmode, call_ref);
23346 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23347 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23350 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23351 struct attribute_spec.handler. */
23353 rs6000_handle_struct_attribute (tree *node, tree name,
23354 tree args ATTRIBUTE_UNUSED,
23355 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
23358 if (DECL_P (*node))
23360 if (TREE_CODE (*node) == TYPE_DECL)
23361 type = &TREE_TYPE (*node);
23366 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
23367 || TREE_CODE (*type) == UNION_TYPE)))
23369 warning (OPT_Wattributes, "%qE attribute ignored", name);
23370 *no_add_attrs = true;
23373 else if ((is_attribute_p ("ms_struct", name)
23374 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
23375 || ((is_attribute_p ("gcc_struct", name)
23376 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
23378 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
23380 *no_add_attrs = true;
23387 rs6000_ms_bitfield_layout_p (const_tree record_type)
23389 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
23390 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
23391 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
23394 #ifdef USING_ELFOS_H
23396 /* A get_unnamed_section callback, used for switching to toc_section. */
23399 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23401 if (DEFAULT_ABI == ABI_AIX
23402 && TARGET_MINIMAL_TOC
23403 && !TARGET_RELOCATABLE)
23405 if (!toc_initialized)
23407 toc_initialized = 1;
23408 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23409 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
23410 fprintf (asm_out_file, "\t.tc ");
23411 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
23412 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23413 fprintf (asm_out_file, "\n");
23415 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23416 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23417 fprintf (asm_out_file, " = .+32768\n");
23420 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23422 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
23423 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23426 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23427 if (!toc_initialized)
23429 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23430 fprintf (asm_out_file, " = .+32768\n");
23431 toc_initialized = 1;
23436 /* Implement TARGET_ASM_INIT_SECTIONS. */
23439 rs6000_elf_asm_init_sections (void)
23442 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
23445 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
23446 SDATA2_SECTION_ASM_OP);
23449 /* Implement TARGET_SELECT_RTX_SECTION. */
23452 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
23453 unsigned HOST_WIDE_INT align)
23455 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23456 return toc_section;
23458 return default_elf_select_rtx_section (mode, x, align);
23461 /* For a SYMBOL_REF, set generic flags and then perform some
23462 target-specific processing.
23464 When the AIX ABI is requested on a non-AIX system, replace the
23465 function name with the real name (with a leading .) rather than the
23466 function descriptor name. This saves a lot of overriding code to
23467 read the prefixes. */
23470 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
23472 default_encode_section_info (decl, rtl, first);
23475 && TREE_CODE (decl) == FUNCTION_DECL
23477 && DEFAULT_ABI == ABI_AIX)
23479 rtx sym_ref = XEXP (rtl, 0);
23480 size_t len = strlen (XSTR (sym_ref, 0));
23481 char *str = XALLOCAVEC (char, len + 2);
23483 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
23484 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
23489 compare_section_name (const char *section, const char *templ)
23493 len = strlen (templ);
23494 return (strncmp (section, templ, len) == 0
23495 && (section[len] == 0 || section[len] == '.'));
23499 rs6000_elf_in_small_data_p (const_tree decl)
23501 if (rs6000_sdata == SDATA_NONE)
23504 /* We want to merge strings, so we never consider them small data. */
23505 if (TREE_CODE (decl) == STRING_CST)
23508 /* Functions are never in the small data area. */
23509 if (TREE_CODE (decl) == FUNCTION_DECL)
23512 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
23514 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
23515 if (compare_section_name (section, ".sdata")
23516 || compare_section_name (section, ".sdata2")
23517 || compare_section_name (section, ".gnu.linkonce.s")
23518 || compare_section_name (section, ".sbss")
23519 || compare_section_name (section, ".sbss2")
23520 || compare_section_name (section, ".gnu.linkonce.sb")
23521 || strcmp (section, ".PPC.EMB.sdata0") == 0
23522 || strcmp (section, ".PPC.EMB.sbss0") == 0)
23527 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
23530 && (unsigned HOST_WIDE_INT) size <= g_switch_value
23531 /* If it's not public, and we're not going to reference it there,
23532 there's no need to put it in the small data section. */
23533 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
23540 #endif /* USING_ELFOS_H */
23542 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
23545 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
23547 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
23550 /* Return a REG that occurs in ADDR with coefficient 1.
23551 ADDR can be effectively incremented by incrementing REG.
23553 r0 is special and we must not select it as an address
23554 register by this routine since our caller will try to
23555 increment the returned register via an "la" instruction. */
23558 find_addr_reg (rtx addr)
23560 while (GET_CODE (addr) == PLUS)
23562 if (GET_CODE (XEXP (addr, 0)) == REG
23563 && REGNO (XEXP (addr, 0)) != 0)
23564 addr = XEXP (addr, 0);
23565 else if (GET_CODE (XEXP (addr, 1)) == REG
23566 && REGNO (XEXP (addr, 1)) != 0)
23567 addr = XEXP (addr, 1);
23568 else if (CONSTANT_P (XEXP (addr, 0)))
23569 addr = XEXP (addr, 1);
23570 else if (CONSTANT_P (XEXP (addr, 1)))
23571 addr = XEXP (addr, 0);
23573 gcc_unreachable ();
23575 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
23580 rs6000_fatal_bad_address (rtx op)
23582 fatal_insn ("bad address", op);
23587 static tree branch_island_list = 0;
23589 /* Remember to generate a branch island for far calls to the given
23593 add_compiler_branch_island (tree label_name, tree function_name,
23596 tree branch_island = build_tree_list (function_name, label_name);
23597 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
23598 TREE_CHAIN (branch_island) = branch_island_list;
23599 branch_island_list = branch_island;
23602 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
23603 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
23604 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
23605 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
23607 /* Generate far-jump branch islands for everything on the
23608 branch_island_list. Invoked immediately after the last instruction
23609 of the epilogue has been emitted; the branch-islands must be
23610 appended to, and contiguous with, the function body. Mach-O stubs
23611 are generated in machopic_output_stub(). */
23614 macho_branch_islands (void)
23617 tree branch_island;
23619 for (branch_island = branch_island_list;
23621 branch_island = TREE_CHAIN (branch_island))
23623 const char *label =
23624 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
23626 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
23627 char name_buf[512];
23628 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
23629 if (name[0] == '*' || name[0] == '&')
23630 strcpy (name_buf, name+1);
23634 strcpy (name_buf+1, name);
23636 strcpy (tmp_buf, "\n");
23637 strcat (tmp_buf, label);
23638 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23639 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23640 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23641 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23644 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
23645 strcat (tmp_buf, label);
23646 strcat (tmp_buf, "_pic\n");
23647 strcat (tmp_buf, label);
23648 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
23650 strcat (tmp_buf, "\taddis r11,r11,ha16(");
23651 strcat (tmp_buf, name_buf);
23652 strcat (tmp_buf, " - ");
23653 strcat (tmp_buf, label);
23654 strcat (tmp_buf, "_pic)\n");
23656 strcat (tmp_buf, "\tmtlr r0\n");
23658 strcat (tmp_buf, "\taddi r12,r11,lo16(");
23659 strcat (tmp_buf, name_buf);
23660 strcat (tmp_buf, " - ");
23661 strcat (tmp_buf, label);
23662 strcat (tmp_buf, "_pic)\n");
23664 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
23668 strcat (tmp_buf, ":\nlis r12,hi16(");
23669 strcat (tmp_buf, name_buf);
23670 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
23671 strcat (tmp_buf, name_buf);
23672 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
23674 output_asm_insn (tmp_buf, 0);
23675 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23676 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23677 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23678 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23681 branch_island_list = 0;
23684 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
23685 already there or not. */
23688 no_previous_def (tree function_name)
23690 tree branch_island;
23691 for (branch_island = branch_island_list;
23693 branch_island = TREE_CHAIN (branch_island))
23694 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23699 /* GET_PREV_LABEL gets the label name from the previous definition of
23703 get_prev_label (tree function_name)
23705 tree branch_island;
23706 for (branch_island = branch_island_list;
23708 branch_island = TREE_CHAIN (branch_island))
23709 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23710 return BRANCH_ISLAND_LABEL_NAME (branch_island);
23714 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
23715 #define DARWIN_LINKER_GENERATES_ISLANDS 0
23718 /* KEXTs still need branch islands. */
23719 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
23720 || flag_mkernel || flag_apple_kext)
23722 /* INSN is either a function call or a millicode call. It may have an
23723 unconditional jump in its delay slot.
23725 CALL_DEST is the routine we are calling. */
23728 output_call (rtx insn, rtx *operands, int dest_operand_number,
23729 int cookie_operand_number)
23731 static char buf[256];
23732 if (DARWIN_GENERATE_ISLANDS
23733 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
23734 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
23737 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
23739 if (no_previous_def (funname))
23741 rtx label_rtx = gen_label_rtx ();
23742 char *label_buf, temp_buf[256];
23743 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
23744 CODE_LABEL_NUMBER (label_rtx));
23745 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
23746 labelname = get_identifier (label_buf);
23747 add_compiler_branch_island (labelname, funname, insn_line (insn));
23750 labelname = get_prev_label (funname);
23752 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
23753 instruction will reach 'foo', otherwise link as 'bl L42'".
23754 "L42" should be a 'branch island', that will do a far jump to
23755 'foo'. Branch islands are generated in
23756 macho_branch_islands(). */
23757 sprintf (buf, "jbsr %%z%d,%.246s",
23758 dest_operand_number, IDENTIFIER_POINTER (labelname));
23761 sprintf (buf, "bl %%z%d", dest_operand_number);
23765 /* Generate PIC and indirect symbol stubs. */
23768 machopic_output_stub (FILE *file, const char *symb, const char *stub)
23770 unsigned int length;
23771 char *symbol_name, *lazy_ptr_name;
23772 char *local_label_0;
23773 static int label = 0;
23775 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
23776 symb = (*targetm.strip_name_encoding) (symb);
23779 length = strlen (symb);
23780 symbol_name = XALLOCAVEC (char, length + 32);
23781 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
23783 lazy_ptr_name = XALLOCAVEC (char, length + 32);
23784 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
23787 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
23789 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
23793 fprintf (file, "\t.align 5\n");
23795 fprintf (file, "%s:\n", stub);
23796 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23799 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
23800 sprintf (local_label_0, "\"L%011d$spb\"", label);
23802 fprintf (file, "\tmflr r0\n");
23803 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
23804 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
23805 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
23806 lazy_ptr_name, local_label_0);
23807 fprintf (file, "\tmtlr r0\n");
23808 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
23809 (TARGET_64BIT ? "ldu" : "lwzu"),
23810 lazy_ptr_name, local_label_0);
23811 fprintf (file, "\tmtctr r12\n");
23812 fprintf (file, "\tbctr\n");
23816 fprintf (file, "\t.align 4\n");
23818 fprintf (file, "%s:\n", stub);
23819 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23821 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
23822 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
23823 (TARGET_64BIT ? "ldu" : "lwzu"),
23825 fprintf (file, "\tmtctr r12\n");
23826 fprintf (file, "\tbctr\n");
23829 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
23830 fprintf (file, "%s:\n", lazy_ptr_name);
23831 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23832 fprintf (file, "%sdyld_stub_binding_helper\n",
23833 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
23836 /* Legitimize PIC addresses. If the address is already
23837 position-independent, we return ORIG. Newly generated
23838 position-independent addresses go into a reg. This is REG if non
23839 zero, otherwise we allocate register(s) as necessary. */
23841 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
23844 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
23849 if (reg == NULL && ! reload_in_progress && ! reload_completed)
23850 reg = gen_reg_rtx (Pmode);
23852 if (GET_CODE (orig) == CONST)
23856 if (GET_CODE (XEXP (orig, 0)) == PLUS
23857 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
23860 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
23862 /* Use a different reg for the intermediate value, as
23863 it will be marked UNCHANGING. */
23864 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
23865 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
23868 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
23871 if (GET_CODE (offset) == CONST_INT)
23873 if (SMALL_INT (offset))
23874 return plus_constant (base, INTVAL (offset));
23875 else if (! reload_in_progress && ! reload_completed)
23876 offset = force_reg (Pmode, offset);
23879 rtx mem = force_const_mem (Pmode, orig);
23880 return machopic_legitimize_pic_address (mem, Pmode, reg);
23883 return gen_rtx_PLUS (Pmode, base, offset);
23886 /* Fall back on generic machopic code. */
23887 return machopic_legitimize_pic_address (orig, mode, reg);
23890 /* Output a .machine directive for the Darwin assembler, and call
23891 the generic start_file routine. */
23894 rs6000_darwin_file_start (void)
23896 static const struct
23902 { "ppc64", "ppc64", MASK_64BIT },
23903 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
23904 { "power4", "ppc970", 0 },
23905 { "G5", "ppc970", 0 },
23906 { "7450", "ppc7450", 0 },
23907 { "7400", "ppc7400", MASK_ALTIVEC },
23908 { "G4", "ppc7400", 0 },
23909 { "750", "ppc750", 0 },
23910 { "740", "ppc750", 0 },
23911 { "G3", "ppc750", 0 },
23912 { "604e", "ppc604e", 0 },
23913 { "604", "ppc604", 0 },
23914 { "603e", "ppc603", 0 },
23915 { "603", "ppc603", 0 },
23916 { "601", "ppc601", 0 },
23917 { NULL, "ppc", 0 } };
23918 const char *cpu_id = "";
23921 rs6000_file_start ();
23922 darwin_file_start ();
23924 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
23925 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
23926 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
23927 && rs6000_select[i].string[0] != '\0')
23928 cpu_id = rs6000_select[i].string;
23930 /* Look through the mapping array. Pick the first name that either
23931 matches the argument, has a bit set in IF_SET that is also set
23932 in the target flags, or has a NULL name. */
23935 while (mapping[i].arg != NULL
23936 && strcmp (mapping[i].arg, cpu_id) != 0
23937 && (mapping[i].if_set & target_flags) == 0)
23940 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
23943 #endif /* TARGET_MACHO */
23947 rs6000_elf_reloc_rw_mask (void)
23951 else if (DEFAULT_ABI == ABI_AIX)
23957 /* Record an element in the table of global constructors. SYMBOL is
23958 a SYMBOL_REF of the function to be called; PRIORITY is a number
23959 between 0 and MAX_INIT_PRIORITY.
23961 This differs from default_named_section_asm_out_constructor in
23962 that we have special handling for -mrelocatable. */
23965 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
23967 const char *section = ".ctors";
23970 if (priority != DEFAULT_INIT_PRIORITY)
23972 sprintf (buf, ".ctors.%.5u",
23973 /* Invert the numbering so the linker puts us in the proper
23974 order; constructors are run from right to left, and the
23975 linker sorts in increasing order. */
23976 MAX_INIT_PRIORITY - priority);
23980 switch_to_section (get_section (section, SECTION_WRITE, NULL));
23981 assemble_align (POINTER_SIZE);
23983 if (TARGET_RELOCATABLE)
23985 fputs ("\t.long (", asm_out_file);
23986 output_addr_const (asm_out_file, symbol);
23987 fputs (")@fixup\n", asm_out_file);
23990 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
23994 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
23996 const char *section = ".dtors";
23999 if (priority != DEFAULT_INIT_PRIORITY)
24001 sprintf (buf, ".dtors.%.5u",
24002 /* Invert the numbering so the linker puts us in the proper
24003 order; constructors are run from right to left, and the
24004 linker sorts in increasing order. */
24005 MAX_INIT_PRIORITY - priority);
24009 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24010 assemble_align (POINTER_SIZE);
24012 if (TARGET_RELOCATABLE)
24014 fputs ("\t.long (", asm_out_file);
24015 output_addr_const (asm_out_file, symbol);
24016 fputs (")@fixup\n", asm_out_file);
24019 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24023 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
24027 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
24028 ASM_OUTPUT_LABEL (file, name);
24029 fputs (DOUBLE_INT_ASM_OP, file);
24030 rs6000_output_function_entry (file, name);
24031 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
24034 fputs ("\t.size\t", file);
24035 assemble_name (file, name);
24036 fputs (",24\n\t.type\t.", file);
24037 assemble_name (file, name);
24038 fputs (",@function\n", file);
24039 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
24041 fputs ("\t.globl\t.", file);
24042 assemble_name (file, name);
24047 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24048 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24049 rs6000_output_function_entry (file, name);
24050 fputs (":\n", file);
24054 if (TARGET_RELOCATABLE
24055 && !TARGET_SECURE_PLT
24056 && (get_pool_size () != 0 || crtl->profile)
24061 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
24063 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
24064 fprintf (file, "\t.long ");
24065 assemble_name (file, buf);
24067 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
24068 assemble_name (file, buf);
24072 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24073 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24075 if (DEFAULT_ABI == ABI_AIX)
24077 const char *desc_name, *orig_name;
24079 orig_name = (*targetm.strip_name_encoding) (name);
24080 desc_name = orig_name;
24081 while (*desc_name == '.')
24084 if (TREE_PUBLIC (decl))
24085 fprintf (file, "\t.globl %s\n", desc_name);
24087 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24088 fprintf (file, "%s:\n", desc_name);
24089 fprintf (file, "\t.long %s\n", orig_name);
24090 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
24091 if (DEFAULT_ABI == ABI_AIX)
24092 fputs ("\t.long 0\n", file);
24093 fprintf (file, "\t.previous\n");
24095 ASM_OUTPUT_LABEL (file, name);
24099 rs6000_elf_end_indicate_exec_stack (void)
24102 file_end_indicate_exec_stack ();
24108 rs6000_xcoff_asm_output_anchor (rtx symbol)
24112 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24113 SYMBOL_REF_BLOCK_OFFSET (symbol));
24114 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24118 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24120 fputs (GLOBAL_ASM_OP, stream);
24121 RS6000_OUTPUT_BASENAME (stream, name);
24122 putc ('\n', stream);
24125 /* A get_unnamed_decl callback, used for read-only sections. PTR
24126 points to the section string variable. */
24129 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24131 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24132 *(const char *const *) directive,
24133 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24136 /* Likewise for read-write sections. */
24139 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24141 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24142 *(const char *const *) directive,
24143 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24146 /* A get_unnamed_section callback, used for switching to toc_section. */
24149 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24151 if (TARGET_MINIMAL_TOC)
24153 /* toc_section is always selected at least once from
24154 rs6000_xcoff_file_start, so this is guaranteed to
24155 always be defined once and only once in each file. */
24156 if (!toc_initialized)
24158 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24159 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24160 toc_initialized = 1;
24162 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
24163 (TARGET_32BIT ? "" : ",3"));
24166 fputs ("\t.toc\n", asm_out_file);
24169 /* Implement TARGET_ASM_INIT_SECTIONS. */
24172 rs6000_xcoff_asm_init_sections (void)
24174 read_only_data_section
24175 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24176 &xcoff_read_only_section_name);
24178 private_data_section
24179 = get_unnamed_section (SECTION_WRITE,
24180 rs6000_xcoff_output_readwrite_section_asm_op,
24181 &xcoff_private_data_section_name);
24183 read_only_private_data_section
24184 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24185 &xcoff_private_data_section_name);
24188 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
24190 readonly_data_section = read_only_data_section;
24191 exception_section = data_section;
24195 rs6000_xcoff_reloc_rw_mask (void)
24201 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
24202 tree decl ATTRIBUTE_UNUSED)
24205 static const char * const suffix[3] = { "PR", "RO", "RW" };
24207 if (flags & SECTION_CODE)
24209 else if (flags & SECTION_WRITE)
24214 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
24215 (flags & SECTION_CODE) ? "." : "",
24216 name, suffix[smclass], flags & SECTION_ENTSIZE);
24220 rs6000_xcoff_select_section (tree decl, int reloc,
24221 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24223 if (decl_readonly_section (decl, reloc))
24225 if (TREE_PUBLIC (decl))
24226 return read_only_data_section;
24228 return read_only_private_data_section;
24232 if (TREE_PUBLIC (decl))
24233 return data_section;
24235 return private_data_section;
24240 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
24244 /* Use select_section for private and uninitialized data. */
24245 if (!TREE_PUBLIC (decl)
24246 || DECL_COMMON (decl)
24247 || DECL_INITIAL (decl) == NULL_TREE
24248 || DECL_INITIAL (decl) == error_mark_node
24249 || (flag_zero_initialized_in_bss
24250 && initializer_zerop (DECL_INITIAL (decl))))
24253 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
24254 name = (*targetm.strip_name_encoding) (name);
24255 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
24258 /* Select section for constant in constant pool.
24260 On RS/6000, all constants are in the private read-only data area.
24261 However, if this is being placed in the TOC it must be output as a
24265 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
24266 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24268 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24269 return toc_section;
24271 return read_only_private_data_section;
24274 /* Remove any trailing [DS] or the like from the symbol name. */
24276 static const char *
24277 rs6000_xcoff_strip_name_encoding (const char *name)
24282 len = strlen (name);
24283 if (name[len - 1] == ']')
24284 return ggc_alloc_string (name, len - 4);
24289 /* Section attributes. AIX is always PIC. */
24291 static unsigned int
24292 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24294 unsigned int align;
24295 unsigned int flags = default_section_type_flags (decl, name, reloc);
24297 /* Align to at least UNIT size. */
24298 if (flags & SECTION_CODE)
24299 align = MIN_UNITS_PER_WORD;
24301 /* Increase alignment of large objects if not already stricter. */
24302 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24303 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24304 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24306 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24309 /* Output at beginning of assembler file.
24311 Initialize the section names for the RS/6000 at this point.
24313 Specify filename, including full path, to assembler.
24315 We want to go into the TOC section so at least one .toc will be emitted.
24316 Also, in order to output proper .bs/.es pairs, we need at least one static
24317 [RW] section emitted.
24319 Finally, declare mcount when profiling to make the assembler happy. */
24322 rs6000_xcoff_file_start (void)
24324 rs6000_gen_section_name (&xcoff_bss_section_name,
24325 main_input_filename, ".bss_");
24326 rs6000_gen_section_name (&xcoff_private_data_section_name,
24327 main_input_filename, ".rw_");
24328 rs6000_gen_section_name (&xcoff_read_only_section_name,
24329 main_input_filename, ".ro_");
24331 fputs ("\t.file\t", asm_out_file);
24332 output_quoted_string (asm_out_file, main_input_filename);
24333 fputc ('\n', asm_out_file);
24334 if (write_symbols != NO_DEBUG)
24335 switch_to_section (private_data_section);
24336 switch_to_section (text_section);
24338 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
24339 rs6000_file_start ();
24342 /* Output at end of assembler file.
24343 On the RS/6000, referencing data should automatically pull in text. */
24346 rs6000_xcoff_file_end (void)
24348 switch_to_section (text_section);
24349 fputs ("_section_.text:\n", asm_out_file);
24350 switch_to_section (data_section);
24351 fputs (TARGET_32BIT
24352 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24355 #endif /* TARGET_XCOFF */
24357 /* Compute a (partial) cost for rtx X. Return true if the complete
24358 cost has been computed, and false if subexpressions should be
24359 scanned. In either case, *TOTAL contains the cost result. */
24362 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
24365 enum machine_mode mode = GET_MODE (x);
24369 /* On the RS/6000, if it is valid in the insn, it is free. */
24371 if (((outer_code == SET
24372 || outer_code == PLUS
24373 || outer_code == MINUS)
24374 && (satisfies_constraint_I (x)
24375 || satisfies_constraint_L (x)))
24376 || (outer_code == AND
24377 && (satisfies_constraint_K (x)
24379 ? satisfies_constraint_L (x)
24380 : satisfies_constraint_J (x))
24381 || mask_operand (x, mode)
24383 && mask64_operand (x, DImode))))
24384 || ((outer_code == IOR || outer_code == XOR)
24385 && (satisfies_constraint_K (x)
24387 ? satisfies_constraint_L (x)
24388 : satisfies_constraint_J (x))))
24389 || outer_code == ASHIFT
24390 || outer_code == ASHIFTRT
24391 || outer_code == LSHIFTRT
24392 || outer_code == ROTATE
24393 || outer_code == ROTATERT
24394 || outer_code == ZERO_EXTRACT
24395 || (outer_code == MULT
24396 && satisfies_constraint_I (x))
24397 || ((outer_code == DIV || outer_code == UDIV
24398 || outer_code == MOD || outer_code == UMOD)
24399 && exact_log2 (INTVAL (x)) >= 0)
24400 || (outer_code == COMPARE
24401 && (satisfies_constraint_I (x)
24402 || satisfies_constraint_K (x)))
24403 || (outer_code == EQ
24404 && (satisfies_constraint_I (x)
24405 || satisfies_constraint_K (x)
24407 ? satisfies_constraint_L (x)
24408 : satisfies_constraint_J (x))))
24409 || (outer_code == GTU
24410 && satisfies_constraint_I (x))
24411 || (outer_code == LTU
24412 && satisfies_constraint_P (x)))
24417 else if ((outer_code == PLUS
24418 && reg_or_add_cint_operand (x, VOIDmode))
24419 || (outer_code == MINUS
24420 && reg_or_sub_cint_operand (x, VOIDmode))
24421 || ((outer_code == SET
24422 || outer_code == IOR
24423 || outer_code == XOR)
24425 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
24427 *total = COSTS_N_INSNS (1);
24433 if (mode == DImode && code == CONST_DOUBLE)
24435 if ((outer_code == IOR || outer_code == XOR)
24436 && CONST_DOUBLE_HIGH (x) == 0
24437 && (CONST_DOUBLE_LOW (x)
24438 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
24443 else if ((outer_code == AND && and64_2_operand (x, DImode))
24444 || ((outer_code == SET
24445 || outer_code == IOR
24446 || outer_code == XOR)
24447 && CONST_DOUBLE_HIGH (x) == 0))
24449 *total = COSTS_N_INSNS (1);
24459 /* When optimizing for size, MEM should be slightly more expensive
24460 than generating address, e.g., (plus (reg) (const)).
24461 L1 cache latency is about two instructions. */
24462 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
24470 if (mode == DFmode)
24472 if (GET_CODE (XEXP (x, 0)) == MULT)
24474 /* FNMA accounted in outer NEG. */
24475 if (outer_code == NEG)
24476 *total = rs6000_cost->dmul - rs6000_cost->fp;
24478 *total = rs6000_cost->dmul;
24481 *total = rs6000_cost->fp;
24483 else if (mode == SFmode)
24485 /* FNMA accounted in outer NEG. */
24486 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24489 *total = rs6000_cost->fp;
24492 *total = COSTS_N_INSNS (1);
24496 if (mode == DFmode)
24498 if (GET_CODE (XEXP (x, 0)) == MULT
24499 || GET_CODE (XEXP (x, 1)) == MULT)
24501 /* FNMA accounted in outer NEG. */
24502 if (outer_code == NEG)
24503 *total = rs6000_cost->dmul - rs6000_cost->fp;
24505 *total = rs6000_cost->dmul;
24508 *total = rs6000_cost->fp;
24510 else if (mode == SFmode)
24512 /* FNMA accounted in outer NEG. */
24513 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24516 *total = rs6000_cost->fp;
24519 *total = COSTS_N_INSNS (1);
24523 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24524 && satisfies_constraint_I (XEXP (x, 1)))
24526 if (INTVAL (XEXP (x, 1)) >= -256
24527 && INTVAL (XEXP (x, 1)) <= 255)
24528 *total = rs6000_cost->mulsi_const9;
24530 *total = rs6000_cost->mulsi_const;
24532 /* FMA accounted in outer PLUS/MINUS. */
24533 else if ((mode == DFmode || mode == SFmode)
24534 && (outer_code == PLUS || outer_code == MINUS))
24536 else if (mode == DFmode)
24537 *total = rs6000_cost->dmul;
24538 else if (mode == SFmode)
24539 *total = rs6000_cost->fp;
24540 else if (mode == DImode)
24541 *total = rs6000_cost->muldi;
24543 *total = rs6000_cost->mulsi;
24548 if (FLOAT_MODE_P (mode))
24550 *total = mode == DFmode ? rs6000_cost->ddiv
24551 : rs6000_cost->sdiv;
24558 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24559 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
24561 if (code == DIV || code == MOD)
24563 *total = COSTS_N_INSNS (2);
24566 *total = COSTS_N_INSNS (1);
24570 if (GET_MODE (XEXP (x, 1)) == DImode)
24571 *total = rs6000_cost->divdi;
24573 *total = rs6000_cost->divsi;
24575 /* Add in shift and subtract for MOD. */
24576 if (code == MOD || code == UMOD)
24577 *total += COSTS_N_INSNS (2);
24582 *total = COSTS_N_INSNS (4);
24586 *total = COSTS_N_INSNS (6);
24590 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
24602 *total = COSTS_N_INSNS (1);
24610 /* Handle mul_highpart. */
24611 if (outer_code == TRUNCATE
24612 && GET_CODE (XEXP (x, 0)) == MULT)
24614 if (mode == DImode)
24615 *total = rs6000_cost->muldi;
24617 *total = rs6000_cost->mulsi;
24620 else if (outer_code == AND)
24623 *total = COSTS_N_INSNS (1);
24628 if (GET_CODE (XEXP (x, 0)) == MEM)
24631 *total = COSTS_N_INSNS (1);
24637 if (!FLOAT_MODE_P (mode))
24639 *total = COSTS_N_INSNS (1);
24645 case UNSIGNED_FLOAT:
24648 case FLOAT_TRUNCATE:
24649 *total = rs6000_cost->fp;
24653 if (mode == DFmode)
24656 *total = rs6000_cost->fp;
24660 switch (XINT (x, 1))
24663 *total = rs6000_cost->fp;
24675 *total = COSTS_N_INSNS (1);
24678 else if (FLOAT_MODE_P (mode)
24679 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
24681 *total = rs6000_cost->fp;
24689 /* Carry bit requires mode == Pmode.
24690 NEG or PLUS already counted so only add one. */
24692 && (outer_code == NEG || outer_code == PLUS))
24694 *total = COSTS_N_INSNS (1);
24697 if (outer_code == SET)
24699 if (XEXP (x, 1) == const0_rtx)
24701 *total = COSTS_N_INSNS (2);
24704 else if (mode == Pmode)
24706 *total = COSTS_N_INSNS (3);
24715 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
24717 *total = COSTS_N_INSNS (2);
24721 if (outer_code == COMPARE)
24735 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
24738 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
24741 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
24744 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
24745 "total = %d, speed = %s, x:\n",
24746 ret ? "complete" : "scan inner",
24747 GET_RTX_NAME (code),
24748 GET_RTX_NAME (outer_code),
24750 speed ? "true" : "false");
24757 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
24760 rs6000_debug_address_cost (rtx x, bool speed)
24762 int ret = TARGET_ADDRESS_COST (x, speed);
24764 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
24765 ret, speed ? "true" : "false");
24772 /* A C expression returning the cost of moving data from a register of class
24773 CLASS1 to one of CLASS2. */
24776 rs6000_register_move_cost (enum machine_mode mode,
24777 enum reg_class from, enum reg_class to)
24781 /* Moves from/to GENERAL_REGS. */
24782 if (reg_classes_intersect_p (to, GENERAL_REGS)
24783 || reg_classes_intersect_p (from, GENERAL_REGS))
24785 if (! reg_classes_intersect_p (to, GENERAL_REGS))
24788 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
24789 ret = (rs6000_memory_move_cost (mode, from, 0)
24790 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
24792 /* It's more expensive to move CR_REGS than CR0_REGS because of the
24794 else if (from == CR_REGS)
24797 /* Power6 has slower LR/CTR moves so make them more expensive than
24798 memory in order to bias spills to memory .*/
24799 else if (rs6000_cpu == PROCESSOR_POWER6
24800 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
24801 ret = 6 * hard_regno_nregs[0][mode];
24804 /* A move will cost one instruction per GPR moved. */
24805 ret = 2 * hard_regno_nregs[0][mode];
24808 /* If we have VSX, we can easily move between FPR or Altivec registers. */
24809 else if (VECTOR_UNIT_VSX_P (mode)
24810 && reg_classes_intersect_p (to, VSX_REGS)
24811 && reg_classes_intersect_p (from, VSX_REGS))
24812 ret = 2 * hard_regno_nregs[32][mode];
24814 /* Moving between two similar registers is just one instruction. */
24815 else if (reg_classes_intersect_p (to, from))
24816 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
24818 /* Everything else has to go through GENERAL_REGS. */
24820 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
24821 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
24823 if (TARGET_DEBUG_COST)
24825 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
24826 ret, GET_MODE_NAME (mode), reg_class_names[from],
24827 reg_class_names[to]);
24832 /* A C expressions returning the cost of moving data of MODE from a register to
24836 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
24837 int in ATTRIBUTE_UNUSED)
24841 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
24842 ret = 4 * hard_regno_nregs[0][mode];
24843 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
24844 ret = 4 * hard_regno_nregs[32][mode];
24845 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
24846 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
24848 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
24850 if (TARGET_DEBUG_COST)
24852 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
24853 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
24858 /* Returns a code for a target-specific builtin that implements
24859 reciprocal of the function, or NULL_TREE if not available. */
24862 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
24863 bool sqrt ATTRIBUTE_UNUSED)
24865 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
24866 && flag_finite_math_only && !flag_trapping_math
24867 && flag_unsafe_math_optimizations))
24875 case BUILT_IN_SQRTF:
24876 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
24883 /* Newton-Raphson approximation of single-precision floating point divide n/d.
24884 Assumes no trapping math and finite arguments. */
24887 rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
24889 rtx x0, e0, e1, y1, u0, v0, one;
24891 x0 = gen_reg_rtx (SFmode);
24892 e0 = gen_reg_rtx (SFmode);
24893 e1 = gen_reg_rtx (SFmode);
24894 y1 = gen_reg_rtx (SFmode);
24895 u0 = gen_reg_rtx (SFmode);
24896 v0 = gen_reg_rtx (SFmode);
24897 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
24899 /* x0 = 1./d estimate */
24900 emit_insn (gen_rtx_SET (VOIDmode, x0,
24901 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
24903 /* e0 = 1. - d * x0 */
24904 emit_insn (gen_rtx_SET (VOIDmode, e0,
24905 gen_rtx_MINUS (SFmode, one,
24906 gen_rtx_MULT (SFmode, d, x0))));
24907 /* e1 = e0 + e0 * e0 */
24908 emit_insn (gen_rtx_SET (VOIDmode, e1,
24909 gen_rtx_PLUS (SFmode,
24910 gen_rtx_MULT (SFmode, e0, e0), e0)));
24911 /* y1 = x0 + e1 * x0 */
24912 emit_insn (gen_rtx_SET (VOIDmode, y1,
24913 gen_rtx_PLUS (SFmode,
24914 gen_rtx_MULT (SFmode, e1, x0), x0)));
24916 emit_insn (gen_rtx_SET (VOIDmode, u0,
24917 gen_rtx_MULT (SFmode, n, y1)));
24918 /* v0 = n - d * u0 */
24919 emit_insn (gen_rtx_SET (VOIDmode, v0,
24920 gen_rtx_MINUS (SFmode, n,
24921 gen_rtx_MULT (SFmode, d, u0))));
24922 /* dst = u0 + v0 * y1 */
24923 emit_insn (gen_rtx_SET (VOIDmode, dst,
24924 gen_rtx_PLUS (SFmode,
24925 gen_rtx_MULT (SFmode, v0, y1), u0)));
24928 /* Newton-Raphson approximation of double-precision floating point divide n/d.
24929 Assumes no trapping math and finite arguments. */
24932 rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
24934 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
24936 x0 = gen_reg_rtx (DFmode);
24937 e0 = gen_reg_rtx (DFmode);
24938 e1 = gen_reg_rtx (DFmode);
24939 e2 = gen_reg_rtx (DFmode);
24940 y1 = gen_reg_rtx (DFmode);
24941 y2 = gen_reg_rtx (DFmode);
24942 y3 = gen_reg_rtx (DFmode);
24943 u0 = gen_reg_rtx (DFmode);
24944 v0 = gen_reg_rtx (DFmode);
24945 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
24947 /* x0 = 1./d estimate */
24948 emit_insn (gen_rtx_SET (VOIDmode, x0,
24949 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
24951 /* e0 = 1. - d * x0 */
24952 emit_insn (gen_rtx_SET (VOIDmode, e0,
24953 gen_rtx_MINUS (DFmode, one,
24954 gen_rtx_MULT (SFmode, d, x0))));
24955 /* y1 = x0 + e0 * x0 */
24956 emit_insn (gen_rtx_SET (VOIDmode, y1,
24957 gen_rtx_PLUS (DFmode,
24958 gen_rtx_MULT (DFmode, e0, x0), x0)));
24960 emit_insn (gen_rtx_SET (VOIDmode, e1,
24961 gen_rtx_MULT (DFmode, e0, e0)));
24962 /* y2 = y1 + e1 * y1 */
24963 emit_insn (gen_rtx_SET (VOIDmode, y2,
24964 gen_rtx_PLUS (DFmode,
24965 gen_rtx_MULT (DFmode, e1, y1), y1)));
24967 emit_insn (gen_rtx_SET (VOIDmode, e2,
24968 gen_rtx_MULT (DFmode, e1, e1)));
24969 /* y3 = y2 + e2 * y2 */
24970 emit_insn (gen_rtx_SET (VOIDmode, y3,
24971 gen_rtx_PLUS (DFmode,
24972 gen_rtx_MULT (DFmode, e2, y2), y2)));
24974 emit_insn (gen_rtx_SET (VOIDmode, u0,
24975 gen_rtx_MULT (DFmode, n, y3)));
24976 /* v0 = n - d * u0 */
24977 emit_insn (gen_rtx_SET (VOIDmode, v0,
24978 gen_rtx_MINUS (DFmode, n,
24979 gen_rtx_MULT (DFmode, d, u0))));
24980 /* dst = u0 + v0 * y3 */
24981 emit_insn (gen_rtx_SET (VOIDmode, dst,
24982 gen_rtx_PLUS (DFmode,
24983 gen_rtx_MULT (DFmode, v0, y3), u0)));
24987 /* Newton-Raphson approximation of single-precision floating point rsqrt.
24988 Assumes no trapping math and finite arguments. */
24991 rs6000_emit_swrsqrtsf (rtx dst, rtx src)
24993 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
24994 half, one, halfthree, c1, cond, label;
24996 x0 = gen_reg_rtx (SFmode);
24997 x1 = gen_reg_rtx (SFmode);
24998 x2 = gen_reg_rtx (SFmode);
24999 y1 = gen_reg_rtx (SFmode);
25000 u0 = gen_reg_rtx (SFmode);
25001 u1 = gen_reg_rtx (SFmode);
25002 u2 = gen_reg_rtx (SFmode);
25003 v0 = gen_reg_rtx (SFmode);
25004 v1 = gen_reg_rtx (SFmode);
25005 v2 = gen_reg_rtx (SFmode);
25006 t0 = gen_reg_rtx (SFmode);
25007 halfthree = gen_reg_rtx (SFmode);
25008 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
25009 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
25011 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
25012 emit_insn (gen_rtx_SET (VOIDmode, t0,
25013 gen_rtx_MULT (SFmode, src, src)));
25015 emit_insn (gen_rtx_SET (VOIDmode, cond,
25016 gen_rtx_COMPARE (CCFPmode, t0, src)));
25017 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
25018 emit_unlikely_jump (c1, label);
25020 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
25021 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
25023 /* halfthree = 1.5 = 1.0 + 0.5 */
25024 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
25025 gen_rtx_PLUS (SFmode, one, half)));
25027 /* x0 = rsqrt estimate */
25028 emit_insn (gen_rtx_SET (VOIDmode, x0,
25029 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
25032 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
25033 emit_insn (gen_rtx_SET (VOIDmode, y1,
25034 gen_rtx_MINUS (SFmode,
25035 gen_rtx_MULT (SFmode, src, halfthree),
25038 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
25039 emit_insn (gen_rtx_SET (VOIDmode, u0,
25040 gen_rtx_MULT (SFmode, x0, x0)));
25041 emit_insn (gen_rtx_SET (VOIDmode, v0,
25042 gen_rtx_MINUS (SFmode,
25044 gen_rtx_MULT (SFmode, y1, u0))));
25045 emit_insn (gen_rtx_SET (VOIDmode, x1,
25046 gen_rtx_MULT (SFmode, x0, v0)));
25048 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
25049 emit_insn (gen_rtx_SET (VOIDmode, u1,
25050 gen_rtx_MULT (SFmode, x1, x1)));
25051 emit_insn (gen_rtx_SET (VOIDmode, v1,
25052 gen_rtx_MINUS (SFmode,
25054 gen_rtx_MULT (SFmode, y1, u1))));
25055 emit_insn (gen_rtx_SET (VOIDmode, x2,
25056 gen_rtx_MULT (SFmode, x1, v1)));
25058 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
25059 emit_insn (gen_rtx_SET (VOIDmode, u2,
25060 gen_rtx_MULT (SFmode, x2, x2)));
25061 emit_insn (gen_rtx_SET (VOIDmode, v2,
25062 gen_rtx_MINUS (SFmode,
25064 gen_rtx_MULT (SFmode, y1, u2))));
25065 emit_insn (gen_rtx_SET (VOIDmode, dst,
25066 gen_rtx_MULT (SFmode, x2, v2)));
25068 emit_label (XEXP (label, 0));
25071 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
25072 (Power7) targets. DST is the target, and SRC is the argument operand. */
25075 rs6000_emit_popcount (rtx dst, rtx src)
25077 enum machine_mode mode = GET_MODE (dst);
25080 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
25081 if (TARGET_POPCNTD)
25083 if (mode == SImode)
25084 emit_insn (gen_popcntwsi2 (dst, src));
25086 emit_insn (gen_popcntddi2 (dst, src));
25090 tmp1 = gen_reg_rtx (mode);
25092 if (mode == SImode)
25094 emit_insn (gen_popcntbsi2 (tmp1, src));
25095 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
25097 tmp2 = force_reg (SImode, tmp2);
25098 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
25102 emit_insn (gen_popcntbdi2 (tmp1, src));
25103 tmp2 = expand_mult (DImode, tmp1,
25104 GEN_INT ((HOST_WIDE_INT)
25105 0x01010101 << 32 | 0x01010101),
25107 tmp2 = force_reg (DImode, tmp2);
25108 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
25113 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25114 target, and SRC is the argument operand. */
25117 rs6000_emit_parity (rtx dst, rtx src)
25119 enum machine_mode mode = GET_MODE (dst);
25122 tmp = gen_reg_rtx (mode);
25123 if (mode == SImode)
25125 /* Is mult+shift >= shift+xor+shift+xor? */
25126 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
25128 rtx tmp1, tmp2, tmp3, tmp4;
25130 tmp1 = gen_reg_rtx (SImode);
25131 emit_insn (gen_popcntbsi2 (tmp1, src));
25133 tmp2 = gen_reg_rtx (SImode);
25134 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
25135 tmp3 = gen_reg_rtx (SImode);
25136 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
25138 tmp4 = gen_reg_rtx (SImode);
25139 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
25140 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
25143 rs6000_emit_popcount (tmp, src);
25144 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
25148 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25149 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
25151 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
25153 tmp1 = gen_reg_rtx (DImode);
25154 emit_insn (gen_popcntbdi2 (tmp1, src));
25156 tmp2 = gen_reg_rtx (DImode);
25157 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
25158 tmp3 = gen_reg_rtx (DImode);
25159 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
25161 tmp4 = gen_reg_rtx (DImode);
25162 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
25163 tmp5 = gen_reg_rtx (DImode);
25164 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
25166 tmp6 = gen_reg_rtx (DImode);
25167 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
25168 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
25171 rs6000_emit_popcount (tmp, src);
25172 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
25176 /* Return an RTX representing where to find the function value of a
25177 function returning MODE. */
25179 rs6000_complex_function_value (enum machine_mode mode)
25181 unsigned int regno;
25183 enum machine_mode inner = GET_MODE_INNER (mode);
25184 unsigned int inner_bytes = GET_MODE_SIZE (inner);
25186 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25187 regno = FP_ARG_RETURN;
25190 regno = GP_ARG_RETURN;
25192 /* 32-bit is OK since it'll go in r3/r4. */
25193 if (TARGET_32BIT && inner_bytes >= 4)
25194 return gen_rtx_REG (mode, regno);
25197 if (inner_bytes >= 8)
25198 return gen_rtx_REG (mode, regno);
25200 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
25202 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
25203 GEN_INT (inner_bytes));
25204 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
25207 /* Target hook for TARGET_FUNCTION_VALUE.
25209 On the SPE, both FPs and vectors are returned in r3.
25211 On RS/6000 an integer value is in r3 and a floating-point value is in
25212 fp1, unless -msoft-float. */
25215 rs6000_function_value (const_tree valtype,
25216 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
25217 bool outgoing ATTRIBUTE_UNUSED)
25219 enum machine_mode mode;
25220 unsigned int regno;
25222 /* Special handling for structs in darwin64. */
25223 if (rs6000_darwin64_abi
25224 && TYPE_MODE (valtype) == BLKmode
25225 && TREE_CODE (valtype) == RECORD_TYPE
25226 && int_size_in_bytes (valtype) > 0)
25228 CUMULATIVE_ARGS valcum;
25232 valcum.fregno = FP_ARG_MIN_REG;
25233 valcum.vregno = ALTIVEC_ARG_MIN_REG;
25234 /* Do a trial code generation as if this were going to be passed as
25235 an argument; if any part goes in memory, we return NULL. */
25236 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
25239 /* Otherwise fall through to standard ABI rules. */
25242 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
25244 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25245 return gen_rtx_PARALLEL (DImode,
25247 gen_rtx_EXPR_LIST (VOIDmode,
25248 gen_rtx_REG (SImode, GP_ARG_RETURN),
25250 gen_rtx_EXPR_LIST (VOIDmode,
25251 gen_rtx_REG (SImode,
25252 GP_ARG_RETURN + 1),
25255 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
25257 return gen_rtx_PARALLEL (DCmode,
25259 gen_rtx_EXPR_LIST (VOIDmode,
25260 gen_rtx_REG (SImode, GP_ARG_RETURN),
25262 gen_rtx_EXPR_LIST (VOIDmode,
25263 gen_rtx_REG (SImode,
25264 GP_ARG_RETURN + 1),
25266 gen_rtx_EXPR_LIST (VOIDmode,
25267 gen_rtx_REG (SImode,
25268 GP_ARG_RETURN + 2),
25270 gen_rtx_EXPR_LIST (VOIDmode,
25271 gen_rtx_REG (SImode,
25272 GP_ARG_RETURN + 3),
25276 mode = TYPE_MODE (valtype);
25277 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
25278 || POINTER_TYPE_P (valtype))
25279 mode = TARGET_32BIT ? SImode : DImode;
25281 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25282 /* _Decimal128 must use an even/odd register pair. */
25283 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25284 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
25285 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
25286 regno = FP_ARG_RETURN;
25287 else if (TREE_CODE (valtype) == COMPLEX_TYPE
25288 && targetm.calls.split_complex_arg)
25289 return rs6000_complex_function_value (mode);
25290 else if (TREE_CODE (valtype) == VECTOR_TYPE
25291 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
25292 && ALTIVEC_VECTOR_MODE (mode))
25293 regno = ALTIVEC_ARG_RETURN;
25294 else if (TREE_CODE (valtype) == VECTOR_TYPE
25295 && TARGET_VSX && TARGET_ALTIVEC_ABI
25296 && VSX_VECTOR_MODE (mode))
25297 regno = ALTIVEC_ARG_RETURN;
25298 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25299 && (mode == DFmode || mode == DCmode
25300 || mode == TFmode || mode == TCmode))
25301 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25303 regno = GP_ARG_RETURN;
25305 return gen_rtx_REG (mode, regno);
25308 /* Define how to find the value returned by a library function
25309 assuming the value has mode MODE. */
25311 rs6000_libcall_value (enum machine_mode mode)
25313 unsigned int regno;
25315 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
25317 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25318 return gen_rtx_PARALLEL (DImode,
25320 gen_rtx_EXPR_LIST (VOIDmode,
25321 gen_rtx_REG (SImode, GP_ARG_RETURN),
25323 gen_rtx_EXPR_LIST (VOIDmode,
25324 gen_rtx_REG (SImode,
25325 GP_ARG_RETURN + 1),
25329 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25330 /* _Decimal128 must use an even/odd register pair. */
25331 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25332 else if (SCALAR_FLOAT_MODE_P (mode)
25333 && TARGET_HARD_FLOAT && TARGET_FPRS
25334 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
25335 regno = FP_ARG_RETURN;
25336 else if (ALTIVEC_VECTOR_MODE (mode)
25337 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
25338 regno = ALTIVEC_ARG_RETURN;
25339 else if (VSX_VECTOR_MODE (mode)
25340 && TARGET_VSX && TARGET_ALTIVEC_ABI)
25341 regno = ALTIVEC_ARG_RETURN;
25342 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
25343 return rs6000_complex_function_value (mode);
25344 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25345 && (mode == DFmode || mode == DCmode
25346 || mode == TFmode || mode == TCmode))
25347 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25349 regno = GP_ARG_RETURN;
25351 return gen_rtx_REG (mode, regno);
25355 /* Given FROM and TO register numbers, say whether this elimination is allowed.
25356 Frame pointer elimination is automatically handled.
25358 For the RS/6000, if frame pointer elimination is being done, we would like
25359 to convert ap into fp, not sp.
25361 We need r30 if -mminimal-toc was specified, and there are constant pool
25365 rs6000_can_eliminate (const int from, const int to)
25367 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
25368 ? ! frame_pointer_needed
25369 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
25370 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
25374 /* Define the offset between two registers, FROM to be eliminated and its
25375 replacement TO, at the start of a routine. */
25377 rs6000_initial_elimination_offset (int from, int to)
25379 rs6000_stack_t *info = rs6000_stack_info ();
25380 HOST_WIDE_INT offset;
25382 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25383 offset = info->push_p ? 0 : -info->total_size;
25384 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25386 offset = info->push_p ? 0 : -info->total_size;
25387 if (FRAME_GROWS_DOWNWARD)
25388 offset += info->fixed_size + info->vars_size + info->parm_size;
25390 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25391 offset = FRAME_GROWS_DOWNWARD
25392 ? info->fixed_size + info->vars_size + info->parm_size
25394 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25395 offset = info->total_size;
25396 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25397 offset = info->push_p ? info->total_size : 0;
25398 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
25401 gcc_unreachable ();
25407 rs6000_dwarf_register_span (rtx reg)
25411 unsigned regno = REGNO (reg);
25412 enum machine_mode mode = GET_MODE (reg);
25416 && (SPE_VECTOR_MODE (GET_MODE (reg))
25417 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
25418 && mode != SFmode && mode != SDmode && mode != SCmode)))
25423 regno = REGNO (reg);
25425 /* The duality of the SPE register size wreaks all kinds of havoc.
25426 This is a way of distinguishing r0 in 32-bits from r0 in
25428 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
25429 gcc_assert (words <= 4);
25430 for (i = 0; i < words; i++, regno++)
25432 if (BYTES_BIG_ENDIAN)
25434 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
25435 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
25439 parts[2 * i] = gen_rtx_REG (SImode, regno);
25440 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
25444 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
25447 /* Fill in sizes for SPE register high parts in table used by unwinder. */
25450 rs6000_init_dwarf_reg_sizes_extra (tree address)
25455 enum machine_mode mode = TYPE_MODE (char_type_node);
25456 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
25457 rtx mem = gen_rtx_MEM (BLKmode, addr);
25458 rtx value = gen_int_mode (4, mode);
25460 for (i = 1201; i < 1232; i++)
25462 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
25463 HOST_WIDE_INT offset
25464 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
25466 emit_move_insn (adjust_address (mem, mode, offset), value);
25471 /* Map internal gcc register numbers to DWARF2 register numbers. */
25474 rs6000_dbx_register_number (unsigned int regno)
25476 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
25478 if (regno == MQ_REGNO)
25480 if (regno == LR_REGNO)
25482 if (regno == CTR_REGNO)
25484 if (CR_REGNO_P (regno))
25485 return regno - CR0_REGNO + 86;
25486 if (regno == XER_REGNO)
25488 if (ALTIVEC_REGNO_P (regno))
25489 return regno - FIRST_ALTIVEC_REGNO + 1124;
25490 if (regno == VRSAVE_REGNO)
25492 if (regno == VSCR_REGNO)
25494 if (regno == SPE_ACC_REGNO)
25496 if (regno == SPEFSCR_REGNO)
25498 /* SPE high reg number. We get these values of regno from
25499 rs6000_dwarf_register_span. */
25500 gcc_assert (regno >= 1200 && regno < 1232);
25504 /* target hook eh_return_filter_mode */
25505 static enum machine_mode
25506 rs6000_eh_return_filter_mode (void)
25508 return TARGET_32BIT ? SImode : word_mode;
25511 /* Target hook for scalar_mode_supported_p. */
25513 rs6000_scalar_mode_supported_p (enum machine_mode mode)
25515 if (DECIMAL_FLOAT_MODE_P (mode))
25516 return default_decimal_float_supported_p ();
25518 return default_scalar_mode_supported_p (mode);
25521 /* Target hook for vector_mode_supported_p. */
25523 rs6000_vector_mode_supported_p (enum machine_mode mode)
25526 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
25529 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
25532 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
25539 /* Target hook for invalid_arg_for_unprototyped_fn. */
25540 static const char *
25541 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
25543 return (!rs6000_darwin64_abi
25545 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
25546 && (funcdecl == NULL_TREE
25547 || (TREE_CODE (funcdecl) == FUNCTION_DECL
25548 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
25549 ? N_("AltiVec argument passed to unprototyped function")
25553 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
25554 setup by using __stack_chk_fail_local hidden function instead of
25555 calling __stack_chk_fail directly. Otherwise it is better to call
25556 __stack_chk_fail directly. */
25559 rs6000_stack_protect_fail (void)
25561 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
25562 ? default_hidden_stack_protect_fail ()
25563 : default_external_stack_protect_fail ();
25567 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
25568 int num_operands ATTRIBUTE_UNUSED)
25570 if (rs6000_warn_cell_microcode)
25573 int insn_code_number = recog_memoized (insn);
25574 location_t location = locator_location (INSN_LOCATOR (insn));
25576 /* Punt on insns we cannot recognize. */
25577 if (insn_code_number < 0)
25580 temp = get_insn_template (insn_code_number, insn);
25582 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
25583 warning_at (location, OPT_mwarn_cell_microcode,
25584 "emitting microcode insn %s\t[%s] #%d",
25585 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25586 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
25587 warning_at (location, OPT_mwarn_cell_microcode,
25588 "emitting conditional microcode insn %s\t[%s] #%d",
25589 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25593 #include "gt-rs6000.h"