1 /* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
29 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-attr.h"
43 #include "basic-block.h"
44 #include "integrate.h"
50 #include "target-def.h"
51 #include "langhooks.h"
53 #include "cfglayout.h"
54 #include "sched-int.h"
56 #include "tree-flow.h"
59 #include "tm-constrs.h"
61 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
64 #include "gstab.h" /* for N_SLINE */
67 #ifndef TARGET_NO_PROTOTYPE
68 #define TARGET_NO_PROTOTYPE 0
71 #define min(A,B) ((A) < (B) ? (A) : (B))
72 #define max(A,B) ((A) > (B) ? (A) : (B))
74 /* Structure used to define the rs6000 stack */
75 typedef struct rs6000_stack {
76 int first_gp_reg_save; /* first callee saved GP register used */
77 int first_fp_reg_save; /* first callee saved FP register used */
78 int first_altivec_reg_save; /* first callee saved AltiVec register used */
79 int lr_save_p; /* true if the link reg needs to be saved */
80 int cr_save_p; /* true if the CR reg needs to be saved */
81 unsigned int vrsave_mask; /* mask of vec registers to save */
82 int push_p; /* true if we need to allocate stack space */
83 int calls_p; /* true if the function makes any calls */
84 int world_save_p; /* true if we're saving *everything*:
85 r13-r31, cr, f14-f31, vrsave, v20-v31 */
86 enum rs6000_abi abi; /* which ABI to use */
87 int gp_save_offset; /* offset to save GP regs from initial SP */
88 int fp_save_offset; /* offset to save FP regs from initial SP */
89 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
90 int lr_save_offset; /* offset to save LR from initial SP */
91 int cr_save_offset; /* offset to save CR from initial SP */
92 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
93 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
94 int varargs_save_offset; /* offset to save the varargs registers */
95 int ehrd_offset; /* offset to EH return data */
96 int reg_size; /* register size (4 or 8) */
97 HOST_WIDE_INT vars_size; /* variable save area size */
98 int parm_size; /* outgoing parameter size */
99 int save_size; /* save area size */
100 int fixed_size; /* fixed size of stack frame */
101 int gp_size; /* size of saved GP registers */
102 int fp_size; /* size of saved FP registers */
103 int altivec_size; /* size of saved AltiVec registers */
104 int cr_size; /* size to hold CR if not in save_size */
105 int vrsave_size; /* size to hold VRSAVE if not in save_size */
106 int altivec_padding_size; /* size of altivec alignment padding if
108 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
109 int spe_padding_size;
110 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
111 int spe_64bit_regs_used;
114 /* A C structure for machine-specific, per-function data.
115 This is added to the cfun structure. */
116 typedef struct GTY(()) machine_function
118 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
119 int ra_needs_full_frame;
120 /* Some local-dynamic symbol. */
121 const char *some_ld_name;
122 /* Whether the instruction chain has been scanned already. */
123 int insn_chain_scanned_p;
124 /* Flags if __builtin_return_address (0) was used. */
126 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
127 varargs save area. */
128 HOST_WIDE_INT varargs_save_offset;
129 /* Temporary stack slot to use for SDmode copies. This slot is
130 64-bits wide and is allocated early enough so that the offset
131 does not overflow the 16-bit load/store offset field. */
132 rtx sdmode_stack_slot;
135 /* Target cpu type */
137 enum processor_type rs6000_cpu;
138 struct rs6000_cpu_select rs6000_select[3] =
140 /* switch name, tune arch */
141 { (const char *)0, "--with-cpu=", 1, 1 },
142 { (const char *)0, "-mcpu=", 1, 1 },
143 { (const char *)0, "-mtune=", 1, 0 },
146 /* Always emit branch hint bits. */
147 static GTY(()) bool rs6000_always_hint;
149 /* Schedule instructions for group formation. */
150 static GTY(()) bool rs6000_sched_groups;
152 /* Align branch targets. */
153 static GTY(()) bool rs6000_align_branch_targets;
155 /* Support for -msched-costly-dep option. */
156 const char *rs6000_sched_costly_dep_str;
157 enum rs6000_dependence_cost rs6000_sched_costly_dep;
159 /* Support for -minsert-sched-nops option. */
160 const char *rs6000_sched_insert_nops_str;
161 enum rs6000_nop_insertion rs6000_sched_insert_nops;
163 /* Support targetm.vectorize.builtin_mask_for_load. */
164 static GTY(()) tree altivec_builtin_mask_for_load;
166 /* Size of long double. */
167 int rs6000_long_double_type_size;
169 /* IEEE quad extended precision long double. */
172 /* Nonzero to use AltiVec ABI. */
173 int rs6000_altivec_abi;
175 /* Nonzero if we want SPE SIMD instructions. */
178 /* Nonzero if we want SPE ABI extensions. */
181 /* Nonzero if floating point operations are done in the GPRs. */
182 int rs6000_float_gprs = 0;
184 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
185 int rs6000_darwin64_abi;
187 /* Set to nonzero once AIX common-mode calls have been defined. */
188 static GTY(()) int common_mode_defined;
190 /* Label number of label created for -mrelocatable, to call to so we can
191 get the address of the GOT section */
192 int rs6000_pic_labelno;
195 /* Which abi to adhere to */
196 const char *rs6000_abi_name;
198 /* Semantics of the small data area */
199 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
201 /* Which small data model to use */
202 const char *rs6000_sdata_name = (char *)0;
204 /* Counter for labels which are to be placed in .fixup. */
205 int fixuplabelno = 0;
208 /* Bit size of immediate TLS offsets and string from which it is decoded. */
209 int rs6000_tls_size = 32;
210 const char *rs6000_tls_size_string;
212 /* ABI enumeration available for subtarget to use. */
213 enum rs6000_abi rs6000_current_abi;
215 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
219 const char *rs6000_debug_name;
220 int rs6000_debug_stack; /* debug stack applications */
221 int rs6000_debug_arg; /* debug argument handling */
222 int rs6000_debug_reg; /* debug register classes */
223 int rs6000_debug_addr; /* debug memory addressing */
224 int rs6000_debug_cost; /* debug rtx_costs */
226 /* Specify the machine mode that pointers have. After generation of rtl, the
227 compiler makes no further distinction between pointers and any other objects
228 of this machine mode. The type is unsigned since not all things that
229 include rs6000.h also include machmode.h. */
230 unsigned rs6000_pmode;
232 /* Width in bits of a pointer. */
233 unsigned rs6000_pointer_size;
236 /* Value is TRUE if register/mode pair is acceptable. */
237 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
239 /* Maximum number of registers needed for a given register class and mode. */
240 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
242 /* How many registers are needed for a given register and mode. */
243 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
245 /* Map register number to register class. */
246 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
248 /* Reload functions based on the type and the vector unit. */
249 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
251 /* Built in types. */
252 tree rs6000_builtin_types[RS6000_BTI_MAX];
253 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
255 const char *rs6000_traceback_name;
257 traceback_default = 0,
263 /* Flag to say the TOC is initialized */
265 char toc_label_name[10];
267 /* Cached value of rs6000_variable_issue. This is cached in
268 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
269 static short cached_can_issue_more;
271 static GTY(()) section *read_only_data_section;
272 static GTY(()) section *private_data_section;
273 static GTY(()) section *read_only_private_data_section;
274 static GTY(()) section *sdata2_section;
275 static GTY(()) section *toc_section;
277 /* Control alignment for fields within structures. */
278 /* String from -malign-XXXXX. */
279 int rs6000_alignment_flags;
281 /* True for any options that were explicitly set. */
283 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
284 bool alignment; /* True if -malign- was used. */
285 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
286 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
287 bool spe; /* True if -mspe= was used. */
288 bool float_gprs; /* True if -mfloat-gprs= was used. */
289 bool long_double; /* True if -mlong-double- was used. */
290 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
291 bool vrsave; /* True if -mvrsave was used. */
292 } rs6000_explicit_options;
294 struct builtin_description
296 /* mask is not const because we're going to alter it below. This
297 nonsense will go away when we rewrite the -march infrastructure
298 to give us more target flag bits. */
300 const enum insn_code icode;
301 const char *const name;
302 const enum rs6000_builtins code;
305 /* Describe the vector unit used for modes. */
306 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
307 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
309 /* Register classes for various constraints that are based on the target
311 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
313 /* Describe the alignment of a vector. */
314 int rs6000_vector_align[NUM_MACHINE_MODES];
316 /* Map selected modes to types for builtins. */
317 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
319 /* Target cpu costs. */
321 struct processor_costs {
322 const int mulsi; /* cost of SImode multiplication. */
323 const int mulsi_const; /* cost of SImode multiplication by constant. */
324 const int mulsi_const9; /* cost of SImode mult by short constant. */
325 const int muldi; /* cost of DImode multiplication. */
326 const int divsi; /* cost of SImode division. */
327 const int divdi; /* cost of DImode division. */
328 const int fp; /* cost of simple SFmode and DFmode insns. */
329 const int dmul; /* cost of DFmode multiplication (and fmadd). */
330 const int sdiv; /* cost of SFmode division (fdivs). */
331 const int ddiv; /* cost of DFmode division (fdiv). */
332 const int cache_line_size; /* cache line size in bytes. */
333 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
334 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
335 const int simultaneous_prefetches; /* number of parallel prefetch
339 const struct processor_costs *rs6000_cost;
341 /* Processor costs (relative to an add) */
343 /* Instruction size costs on 32bit processors. */
345 struct processor_costs size32_cost = {
346 COSTS_N_INSNS (1), /* mulsi */
347 COSTS_N_INSNS (1), /* mulsi_const */
348 COSTS_N_INSNS (1), /* mulsi_const9 */
349 COSTS_N_INSNS (1), /* muldi */
350 COSTS_N_INSNS (1), /* divsi */
351 COSTS_N_INSNS (1), /* divdi */
352 COSTS_N_INSNS (1), /* fp */
353 COSTS_N_INSNS (1), /* dmul */
354 COSTS_N_INSNS (1), /* sdiv */
355 COSTS_N_INSNS (1), /* ddiv */
362 /* Instruction size costs on 64bit processors. */
364 struct processor_costs size64_cost = {
365 COSTS_N_INSNS (1), /* mulsi */
366 COSTS_N_INSNS (1), /* mulsi_const */
367 COSTS_N_INSNS (1), /* mulsi_const9 */
368 COSTS_N_INSNS (1), /* muldi */
369 COSTS_N_INSNS (1), /* divsi */
370 COSTS_N_INSNS (1), /* divdi */
371 COSTS_N_INSNS (1), /* fp */
372 COSTS_N_INSNS (1), /* dmul */
373 COSTS_N_INSNS (1), /* sdiv */
374 COSTS_N_INSNS (1), /* ddiv */
381 /* Instruction costs on RIOS1 processors. */
383 struct processor_costs rios1_cost = {
384 COSTS_N_INSNS (5), /* mulsi */
385 COSTS_N_INSNS (4), /* mulsi_const */
386 COSTS_N_INSNS (3), /* mulsi_const9 */
387 COSTS_N_INSNS (5), /* muldi */
388 COSTS_N_INSNS (19), /* divsi */
389 COSTS_N_INSNS (19), /* divdi */
390 COSTS_N_INSNS (2), /* fp */
391 COSTS_N_INSNS (2), /* dmul */
392 COSTS_N_INSNS (19), /* sdiv */
393 COSTS_N_INSNS (19), /* ddiv */
394 128, /* cache line size */
400 /* Instruction costs on RIOS2 processors. */
402 struct processor_costs rios2_cost = {
403 COSTS_N_INSNS (2), /* mulsi */
404 COSTS_N_INSNS (2), /* mulsi_const */
405 COSTS_N_INSNS (2), /* mulsi_const9 */
406 COSTS_N_INSNS (2), /* muldi */
407 COSTS_N_INSNS (13), /* divsi */
408 COSTS_N_INSNS (13), /* divdi */
409 COSTS_N_INSNS (2), /* fp */
410 COSTS_N_INSNS (2), /* dmul */
411 COSTS_N_INSNS (17), /* sdiv */
412 COSTS_N_INSNS (17), /* ddiv */
413 256, /* cache line size */
419 /* Instruction costs on RS64A processors. */
421 struct processor_costs rs64a_cost = {
422 COSTS_N_INSNS (20), /* mulsi */
423 COSTS_N_INSNS (12), /* mulsi_const */
424 COSTS_N_INSNS (8), /* mulsi_const9 */
425 COSTS_N_INSNS (34), /* muldi */
426 COSTS_N_INSNS (65), /* divsi */
427 COSTS_N_INSNS (67), /* divdi */
428 COSTS_N_INSNS (4), /* fp */
429 COSTS_N_INSNS (4), /* dmul */
430 COSTS_N_INSNS (31), /* sdiv */
431 COSTS_N_INSNS (31), /* ddiv */
432 128, /* cache line size */
438 /* Instruction costs on MPCCORE processors. */
440 struct processor_costs mpccore_cost = {
441 COSTS_N_INSNS (2), /* mulsi */
442 COSTS_N_INSNS (2), /* mulsi_const */
443 COSTS_N_INSNS (2), /* mulsi_const9 */
444 COSTS_N_INSNS (2), /* muldi */
445 COSTS_N_INSNS (6), /* divsi */
446 COSTS_N_INSNS (6), /* divdi */
447 COSTS_N_INSNS (4), /* fp */
448 COSTS_N_INSNS (5), /* dmul */
449 COSTS_N_INSNS (10), /* sdiv */
450 COSTS_N_INSNS (17), /* ddiv */
451 32, /* cache line size */
457 /* Instruction costs on PPC403 processors. */
459 struct processor_costs ppc403_cost = {
460 COSTS_N_INSNS (4), /* mulsi */
461 COSTS_N_INSNS (4), /* mulsi_const */
462 COSTS_N_INSNS (4), /* mulsi_const9 */
463 COSTS_N_INSNS (4), /* muldi */
464 COSTS_N_INSNS (33), /* divsi */
465 COSTS_N_INSNS (33), /* divdi */
466 COSTS_N_INSNS (11), /* fp */
467 COSTS_N_INSNS (11), /* dmul */
468 COSTS_N_INSNS (11), /* sdiv */
469 COSTS_N_INSNS (11), /* ddiv */
470 32, /* cache line size */
476 /* Instruction costs on PPC405 processors. */
478 struct processor_costs ppc405_cost = {
479 COSTS_N_INSNS (5), /* mulsi */
480 COSTS_N_INSNS (4), /* mulsi_const */
481 COSTS_N_INSNS (3), /* mulsi_const9 */
482 COSTS_N_INSNS (5), /* muldi */
483 COSTS_N_INSNS (35), /* divsi */
484 COSTS_N_INSNS (35), /* divdi */
485 COSTS_N_INSNS (11), /* fp */
486 COSTS_N_INSNS (11), /* dmul */
487 COSTS_N_INSNS (11), /* sdiv */
488 COSTS_N_INSNS (11), /* ddiv */
489 32, /* cache line size */
495 /* Instruction costs on PPC440 processors. */
497 struct processor_costs ppc440_cost = {
498 COSTS_N_INSNS (3), /* mulsi */
499 COSTS_N_INSNS (2), /* mulsi_const */
500 COSTS_N_INSNS (2), /* mulsi_const9 */
501 COSTS_N_INSNS (3), /* muldi */
502 COSTS_N_INSNS (34), /* divsi */
503 COSTS_N_INSNS (34), /* divdi */
504 COSTS_N_INSNS (5), /* fp */
505 COSTS_N_INSNS (5), /* dmul */
506 COSTS_N_INSNS (19), /* sdiv */
507 COSTS_N_INSNS (33), /* ddiv */
508 32, /* cache line size */
514 /* Instruction costs on PPC601 processors. */
516 struct processor_costs ppc601_cost = {
517 COSTS_N_INSNS (5), /* mulsi */
518 COSTS_N_INSNS (5), /* mulsi_const */
519 COSTS_N_INSNS (5), /* mulsi_const9 */
520 COSTS_N_INSNS (5), /* muldi */
521 COSTS_N_INSNS (36), /* divsi */
522 COSTS_N_INSNS (36), /* divdi */
523 COSTS_N_INSNS (4), /* fp */
524 COSTS_N_INSNS (5), /* dmul */
525 COSTS_N_INSNS (17), /* sdiv */
526 COSTS_N_INSNS (31), /* ddiv */
527 32, /* cache line size */
533 /* Instruction costs on PPC603 processors. */
535 struct processor_costs ppc603_cost = {
536 COSTS_N_INSNS (5), /* mulsi */
537 COSTS_N_INSNS (3), /* mulsi_const */
538 COSTS_N_INSNS (2), /* mulsi_const9 */
539 COSTS_N_INSNS (5), /* muldi */
540 COSTS_N_INSNS (37), /* divsi */
541 COSTS_N_INSNS (37), /* divdi */
542 COSTS_N_INSNS (3), /* fp */
543 COSTS_N_INSNS (4), /* dmul */
544 COSTS_N_INSNS (18), /* sdiv */
545 COSTS_N_INSNS (33), /* ddiv */
546 32, /* cache line size */
552 /* Instruction costs on PPC604 processors. */
554 struct processor_costs ppc604_cost = {
555 COSTS_N_INSNS (4), /* mulsi */
556 COSTS_N_INSNS (4), /* mulsi_const */
557 COSTS_N_INSNS (4), /* mulsi_const9 */
558 COSTS_N_INSNS (4), /* muldi */
559 COSTS_N_INSNS (20), /* divsi */
560 COSTS_N_INSNS (20), /* divdi */
561 COSTS_N_INSNS (3), /* fp */
562 COSTS_N_INSNS (3), /* dmul */
563 COSTS_N_INSNS (18), /* sdiv */
564 COSTS_N_INSNS (32), /* ddiv */
565 32, /* cache line size */
571 /* Instruction costs on PPC604e processors. */
573 struct processor_costs ppc604e_cost = {
574 COSTS_N_INSNS (2), /* mulsi */
575 COSTS_N_INSNS (2), /* mulsi_const */
576 COSTS_N_INSNS (2), /* mulsi_const9 */
577 COSTS_N_INSNS (2), /* muldi */
578 COSTS_N_INSNS (20), /* divsi */
579 COSTS_N_INSNS (20), /* divdi */
580 COSTS_N_INSNS (3), /* fp */
581 COSTS_N_INSNS (3), /* dmul */
582 COSTS_N_INSNS (18), /* sdiv */
583 COSTS_N_INSNS (32), /* ddiv */
584 32, /* cache line size */
590 /* Instruction costs on PPC620 processors. */
592 struct processor_costs ppc620_cost = {
593 COSTS_N_INSNS (5), /* mulsi */
594 COSTS_N_INSNS (4), /* mulsi_const */
595 COSTS_N_INSNS (3), /* mulsi_const9 */
596 COSTS_N_INSNS (7), /* muldi */
597 COSTS_N_INSNS (21), /* divsi */
598 COSTS_N_INSNS (37), /* divdi */
599 COSTS_N_INSNS (3), /* fp */
600 COSTS_N_INSNS (3), /* dmul */
601 COSTS_N_INSNS (18), /* sdiv */
602 COSTS_N_INSNS (32), /* ddiv */
603 128, /* cache line size */
609 /* Instruction costs on PPC630 processors. */
611 struct processor_costs ppc630_cost = {
612 COSTS_N_INSNS (5), /* mulsi */
613 COSTS_N_INSNS (4), /* mulsi_const */
614 COSTS_N_INSNS (3), /* mulsi_const9 */
615 COSTS_N_INSNS (7), /* muldi */
616 COSTS_N_INSNS (21), /* divsi */
617 COSTS_N_INSNS (37), /* divdi */
618 COSTS_N_INSNS (3), /* fp */
619 COSTS_N_INSNS (3), /* dmul */
620 COSTS_N_INSNS (17), /* sdiv */
621 COSTS_N_INSNS (21), /* ddiv */
622 128, /* cache line size */
628 /* Instruction costs on Cell processor. */
629 /* COSTS_N_INSNS (1) ~ one add. */
631 struct processor_costs ppccell_cost = {
632 COSTS_N_INSNS (9/2)+2, /* mulsi */
633 COSTS_N_INSNS (6/2), /* mulsi_const */
634 COSTS_N_INSNS (6/2), /* mulsi_const9 */
635 COSTS_N_INSNS (15/2)+2, /* muldi */
636 COSTS_N_INSNS (38/2), /* divsi */
637 COSTS_N_INSNS (70/2), /* divdi */
638 COSTS_N_INSNS (10/2), /* fp */
639 COSTS_N_INSNS (10/2), /* dmul */
640 COSTS_N_INSNS (74/2), /* sdiv */
641 COSTS_N_INSNS (74/2), /* ddiv */
642 128, /* cache line size */
648 /* Instruction costs on PPC750 and PPC7400 processors. */
650 struct processor_costs ppc750_cost = {
651 COSTS_N_INSNS (5), /* mulsi */
652 COSTS_N_INSNS (3), /* mulsi_const */
653 COSTS_N_INSNS (2), /* mulsi_const9 */
654 COSTS_N_INSNS (5), /* muldi */
655 COSTS_N_INSNS (17), /* divsi */
656 COSTS_N_INSNS (17), /* divdi */
657 COSTS_N_INSNS (3), /* fp */
658 COSTS_N_INSNS (3), /* dmul */
659 COSTS_N_INSNS (17), /* sdiv */
660 COSTS_N_INSNS (31), /* ddiv */
661 32, /* cache line size */
667 /* Instruction costs on PPC7450 processors. */
669 struct processor_costs ppc7450_cost = {
670 COSTS_N_INSNS (4), /* mulsi */
671 COSTS_N_INSNS (3), /* mulsi_const */
672 COSTS_N_INSNS (3), /* mulsi_const9 */
673 COSTS_N_INSNS (4), /* muldi */
674 COSTS_N_INSNS (23), /* divsi */
675 COSTS_N_INSNS (23), /* divdi */
676 COSTS_N_INSNS (5), /* fp */
677 COSTS_N_INSNS (5), /* dmul */
678 COSTS_N_INSNS (21), /* sdiv */
679 COSTS_N_INSNS (35), /* ddiv */
680 32, /* cache line size */
686 /* Instruction costs on PPC8540 processors. */
688 struct processor_costs ppc8540_cost = {
689 COSTS_N_INSNS (4), /* mulsi */
690 COSTS_N_INSNS (4), /* mulsi_const */
691 COSTS_N_INSNS (4), /* mulsi_const9 */
692 COSTS_N_INSNS (4), /* muldi */
693 COSTS_N_INSNS (19), /* divsi */
694 COSTS_N_INSNS (19), /* divdi */
695 COSTS_N_INSNS (4), /* fp */
696 COSTS_N_INSNS (4), /* dmul */
697 COSTS_N_INSNS (29), /* sdiv */
698 COSTS_N_INSNS (29), /* ddiv */
699 32, /* cache line size */
702 1, /* prefetch streams /*/
705 /* Instruction costs on E300C2 and E300C3 cores. */
707 struct processor_costs ppce300c2c3_cost = {
708 COSTS_N_INSNS (4), /* mulsi */
709 COSTS_N_INSNS (4), /* mulsi_const */
710 COSTS_N_INSNS (4), /* mulsi_const9 */
711 COSTS_N_INSNS (4), /* muldi */
712 COSTS_N_INSNS (19), /* divsi */
713 COSTS_N_INSNS (19), /* divdi */
714 COSTS_N_INSNS (3), /* fp */
715 COSTS_N_INSNS (4), /* dmul */
716 COSTS_N_INSNS (18), /* sdiv */
717 COSTS_N_INSNS (33), /* ddiv */
721 1, /* prefetch streams /*/
724 /* Instruction costs on PPCE500MC processors. */
726 struct processor_costs ppce500mc_cost = {
727 COSTS_N_INSNS (4), /* mulsi */
728 COSTS_N_INSNS (4), /* mulsi_const */
729 COSTS_N_INSNS (4), /* mulsi_const9 */
730 COSTS_N_INSNS (4), /* muldi */
731 COSTS_N_INSNS (14), /* divsi */
732 COSTS_N_INSNS (14), /* divdi */
733 COSTS_N_INSNS (8), /* fp */
734 COSTS_N_INSNS (10), /* dmul */
735 COSTS_N_INSNS (36), /* sdiv */
736 COSTS_N_INSNS (66), /* ddiv */
737 64, /* cache line size */
740 1, /* prefetch streams /*/
743 /* Instruction costs on POWER4 and POWER5 processors. */
745 struct processor_costs power4_cost = {
746 COSTS_N_INSNS (3), /* mulsi */
747 COSTS_N_INSNS (2), /* mulsi_const */
748 COSTS_N_INSNS (2), /* mulsi_const9 */
749 COSTS_N_INSNS (4), /* muldi */
750 COSTS_N_INSNS (18), /* divsi */
751 COSTS_N_INSNS (34), /* divdi */
752 COSTS_N_INSNS (3), /* fp */
753 COSTS_N_INSNS (3), /* dmul */
754 COSTS_N_INSNS (17), /* sdiv */
755 COSTS_N_INSNS (17), /* ddiv */
756 128, /* cache line size */
759 8, /* prefetch streams /*/
762 /* Instruction costs on POWER6 processors. */
764 struct processor_costs power6_cost = {
765 COSTS_N_INSNS (8), /* mulsi */
766 COSTS_N_INSNS (8), /* mulsi_const */
767 COSTS_N_INSNS (8), /* mulsi_const9 */
768 COSTS_N_INSNS (8), /* muldi */
769 COSTS_N_INSNS (22), /* divsi */
770 COSTS_N_INSNS (28), /* divdi */
771 COSTS_N_INSNS (3), /* fp */
772 COSTS_N_INSNS (3), /* dmul */
773 COSTS_N_INSNS (13), /* sdiv */
774 COSTS_N_INSNS (16), /* ddiv */
775 128, /* cache line size */
778 16, /* prefetch streams */
781 /* Instruction costs on POWER7 processors. */
783 struct processor_costs power7_cost = {
784 COSTS_N_INSNS (2), /* mulsi */
785 COSTS_N_INSNS (2), /* mulsi_const */
786 COSTS_N_INSNS (2), /* mulsi_const9 */
787 COSTS_N_INSNS (2), /* muldi */
788 COSTS_N_INSNS (18), /* divsi */
789 COSTS_N_INSNS (34), /* divdi */
790 COSTS_N_INSNS (3), /* fp */
791 COSTS_N_INSNS (3), /* dmul */
792 COSTS_N_INSNS (13), /* sdiv */
793 COSTS_N_INSNS (16), /* ddiv */
794 128, /* cache line size */
797 12, /* prefetch streams */
801 static bool rs6000_function_ok_for_sibcall (tree, tree);
802 static const char *rs6000_invalid_within_doloop (const_rtx);
803 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
804 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
805 static rtx rs6000_generate_compare (rtx, enum machine_mode);
806 static void rs6000_emit_stack_tie (void);
807 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
808 static bool spe_func_has_64bit_regs_p (void);
809 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
811 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
812 static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int, int);
813 static unsigned rs6000_hash_constant (rtx);
814 static unsigned toc_hash_function (const void *);
815 static int toc_hash_eq (const void *, const void *);
816 static bool reg_offset_addressing_ok_p (enum machine_mode);
817 static bool virtual_stack_registers_memory_p (rtx);
818 static bool constant_pool_expr_p (rtx);
819 static bool legitimate_small_data_p (enum machine_mode, rtx);
820 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
821 static struct machine_function * rs6000_init_machine_status (void);
822 static bool rs6000_assemble_integer (rtx, unsigned int, int);
823 static bool no_global_regs_above (int, bool);
824 #ifdef HAVE_GAS_HIDDEN
825 static void rs6000_assemble_visibility (tree, int);
827 static int rs6000_ra_ever_killed (void);
828 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
829 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
830 static bool rs6000_ms_bitfield_layout_p (const_tree);
831 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
832 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
833 static const char *rs6000_mangle_type (const_tree);
834 static void rs6000_set_default_type_attributes (tree);
835 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
836 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
837 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
838 enum machine_mode, bool, bool, bool);
839 static bool rs6000_reg_live_or_pic_offset_p (int);
840 static tree rs6000_builtin_vectorized_function (unsigned int, tree, tree);
841 static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
842 static void rs6000_restore_saved_cr (rtx, int);
843 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
844 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
845 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
847 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
848 static bool rs6000_return_in_memory (const_tree, const_tree);
849 static void rs6000_file_start (void);
851 static int rs6000_elf_reloc_rw_mask (void);
852 static void rs6000_elf_asm_out_constructor (rtx, int);
853 static void rs6000_elf_asm_out_destructor (rtx, int);
854 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
855 static void rs6000_elf_asm_init_sections (void);
856 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
857 unsigned HOST_WIDE_INT);
858 static void rs6000_elf_encode_section_info (tree, rtx, int)
861 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
862 static void rs6000_alloc_sdmode_stack_slot (void);
863 static void rs6000_instantiate_decls (void);
865 static void rs6000_xcoff_asm_output_anchor (rtx);
866 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
867 static void rs6000_xcoff_asm_init_sections (void);
868 static int rs6000_xcoff_reloc_rw_mask (void);
869 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
870 static section *rs6000_xcoff_select_section (tree, int,
871 unsigned HOST_WIDE_INT);
872 static void rs6000_xcoff_unique_section (tree, int);
873 static section *rs6000_xcoff_select_rtx_section
874 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
875 static const char * rs6000_xcoff_strip_name_encoding (const char *);
876 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
877 static void rs6000_xcoff_file_start (void);
878 static void rs6000_xcoff_file_end (void);
880 static int rs6000_variable_issue (FILE *, int, rtx, int);
881 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
882 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
883 static int rs6000_debug_address_cost (rtx, bool);
884 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
885 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
886 static void rs6000_sched_init (FILE *, int, int);
887 static bool is_microcoded_insn (rtx);
888 static bool is_nonpipeline_insn (rtx);
889 static bool is_cracked_insn (rtx);
890 static bool is_branch_slot_insn (rtx);
891 static bool is_load_insn (rtx);
892 static rtx get_store_dest (rtx pat);
893 static bool is_store_insn (rtx);
894 static bool set_to_load_agen (rtx,rtx);
895 static bool adjacent_mem_locations (rtx,rtx);
896 static int rs6000_adjust_priority (rtx, int);
897 static int rs6000_issue_rate (void);
898 static bool rs6000_is_costly_dependence (dep_t, int, int);
899 static rtx get_next_active_insn (rtx, rtx);
900 static bool insn_terminates_group_p (rtx , enum group_termination);
901 static bool insn_must_be_first_in_group (rtx);
902 static bool insn_must_be_last_in_group (rtx);
903 static bool is_costly_group (rtx *, rtx);
904 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
905 static int redefine_groups (FILE *, int, rtx, rtx);
906 static int pad_groups (FILE *, int, rtx, rtx);
907 static void rs6000_sched_finish (FILE *, int);
908 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
909 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
910 static int rs6000_use_sched_lookahead (void);
911 static int rs6000_use_sched_lookahead_guard (rtx);
912 static void * rs6000_alloc_sched_context (void);
913 static void rs6000_init_sched_context (void *, bool);
914 static void rs6000_set_sched_context (void *);
915 static void rs6000_free_sched_context (void *);
916 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
917 static tree rs6000_builtin_mask_for_load (void);
918 static tree rs6000_builtin_mul_widen_even (tree);
919 static tree rs6000_builtin_mul_widen_odd (tree);
920 static tree rs6000_builtin_conversion (unsigned int, tree);
921 static tree rs6000_builtin_vec_perm (tree, tree *);
923 static void def_builtin (int, const char *, tree, int);
924 static bool rs6000_vector_alignment_reachable (const_tree, bool);
925 static void rs6000_init_builtins (void);
926 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
927 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
928 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
929 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
930 static void altivec_init_builtins (void);
931 static unsigned builtin_hash_function (const void *);
932 static int builtin_hash_eq (const void *, const void *);
933 static tree builtin_function_type (enum machine_mode, enum machine_mode,
934 enum machine_mode, enum machine_mode,
935 enum rs6000_builtins, const char *name);
936 static void rs6000_common_init_builtins (void);
937 static void rs6000_init_libfuncs (void);
939 static void paired_init_builtins (void);
940 static rtx paired_expand_builtin (tree, rtx, bool *);
941 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
942 static rtx paired_expand_stv_builtin (enum insn_code, tree);
943 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
945 static void enable_mask_for_builtins (struct builtin_description *, int,
946 enum rs6000_builtins,
947 enum rs6000_builtins);
948 static void spe_init_builtins (void);
949 static rtx spe_expand_builtin (tree, rtx, bool *);
950 static rtx spe_expand_stv_builtin (enum insn_code, tree);
951 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
952 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
953 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
954 static rs6000_stack_t *rs6000_stack_info (void);
955 static void debug_stack_info (rs6000_stack_t *);
957 static rtx altivec_expand_builtin (tree, rtx, bool *);
958 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
959 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
960 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
961 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
962 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
963 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
964 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
965 static rtx altivec_expand_vec_set_builtin (tree);
966 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
967 static int get_element_number (tree, tree);
968 static bool rs6000_handle_option (size_t, const char *, int);
969 static void rs6000_parse_tls_size_option (void);
970 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
971 static int first_altivec_reg_to_save (void);
972 static unsigned int compute_vrsave_mask (void);
973 static void compute_save_world_info (rs6000_stack_t *info_ptr);
974 static void is_altivec_return_reg (rtx, void *);
975 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
976 int easy_vector_constant (rtx, enum machine_mode);
977 static rtx rs6000_dwarf_register_span (rtx);
978 static void rs6000_init_dwarf_reg_sizes_extra (tree);
979 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
980 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
981 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
982 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
983 static rtx rs6000_tls_get_addr (void);
984 static rtx rs6000_got_sym (void);
985 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
986 static const char *rs6000_get_some_local_dynamic_name (void);
987 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
988 static rtx rs6000_complex_function_value (enum machine_mode);
989 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
990 enum machine_mode, tree);
991 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
993 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
994 tree, HOST_WIDE_INT);
995 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
998 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
999 const_tree, HOST_WIDE_INT,
1001 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
1002 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
1003 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1004 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1005 enum machine_mode, tree,
1007 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1009 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1011 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1013 static void macho_branch_islands (void);
1014 static int no_previous_def (tree function_name);
1015 static tree get_prev_label (tree function_name);
1016 static void rs6000_darwin_file_start (void);
1019 static tree rs6000_build_builtin_va_list (void);
1020 static void rs6000_va_start (tree, rtx);
1021 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1022 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1023 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1024 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1025 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1026 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1028 static tree rs6000_stack_protect_fail (void);
1030 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1033 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1036 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1038 = rs6000_legitimize_reload_address;
1040 static bool rs6000_mode_dependent_address (rtx);
1041 static bool rs6000_debug_mode_dependent_address (rtx);
1042 bool (*rs6000_mode_dependent_address_ptr) (rtx)
1043 = rs6000_mode_dependent_address;
1045 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1046 enum machine_mode, rtx);
1047 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1050 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1051 enum machine_mode, rtx)
1052 = rs6000_secondary_reload_class;
1054 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1055 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1057 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1058 = rs6000_preferred_reload_class;
1060 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1063 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1067 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1069 = rs6000_secondary_memory_needed;
1071 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1074 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1078 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1081 = rs6000_cannot_change_mode_class;
1083 static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class,
1085 struct secondary_reload_info *);
1087 static const enum reg_class *rs6000_ira_cover_classes (void);
1089 const int INSN_NOT_AVAILABLE = -1;
1090 static enum machine_mode rs6000_eh_return_filter_mode (void);
1091 static bool rs6000_can_eliminate (const int, const int);
1093 /* Hash table stuff for keeping track of TOC entries. */
1095 struct GTY(()) toc_hash_struct
1097 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1098 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1100 enum machine_mode key_mode;
1104 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1106 /* Hash table to keep track of the argument types for builtin functions. */
1108 struct GTY(()) builtin_hash_struct
1111 enum machine_mode mode[4]; /* return value + 3 arguments. */
1112 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1115 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1117 /* Default register names. */
1118 char rs6000_reg_names[][8] =
1120 "0", "1", "2", "3", "4", "5", "6", "7",
1121 "8", "9", "10", "11", "12", "13", "14", "15",
1122 "16", "17", "18", "19", "20", "21", "22", "23",
1123 "24", "25", "26", "27", "28", "29", "30", "31",
1124 "0", "1", "2", "3", "4", "5", "6", "7",
1125 "8", "9", "10", "11", "12", "13", "14", "15",
1126 "16", "17", "18", "19", "20", "21", "22", "23",
1127 "24", "25", "26", "27", "28", "29", "30", "31",
1128 "mq", "lr", "ctr","ap",
1129 "0", "1", "2", "3", "4", "5", "6", "7",
1131 /* AltiVec registers. */
1132 "0", "1", "2", "3", "4", "5", "6", "7",
1133 "8", "9", "10", "11", "12", "13", "14", "15",
1134 "16", "17", "18", "19", "20", "21", "22", "23",
1135 "24", "25", "26", "27", "28", "29", "30", "31",
1137 /* SPE registers. */
1138 "spe_acc", "spefscr",
1139 /* Soft frame pointer. */
1143 #ifdef TARGET_REGNAMES
1144 static const char alt_reg_names[][8] =
1146 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1147 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1148 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1149 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1150 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1151 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1152 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1153 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1154 "mq", "lr", "ctr", "ap",
1155 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1157 /* AltiVec registers. */
1158 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1159 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1160 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1161 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1163 /* SPE registers. */
1164 "spe_acc", "spefscr",
1165 /* Soft frame pointer. */
1170 /* Table of valid machine attributes. */
1172 static const struct attribute_spec rs6000_attribute_table[] =
1174 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1175 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1176 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1177 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1178 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1179 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1180 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1181 SUBTARGET_ATTRIBUTE_TABLE,
1183 { NULL, 0, 0, false, false, false, NULL }
1186 #ifndef MASK_STRICT_ALIGN
1187 #define MASK_STRICT_ALIGN 0
1189 #ifndef TARGET_PROFILE_KERNEL
1190 #define TARGET_PROFILE_KERNEL 0
1191 #define SET_PROFILE_KERNEL(N)
1193 #define SET_PROFILE_KERNEL(N) TARGET_PROFILE_KERNEL = (N)
1196 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1197 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1199 /* Initialize the GCC target structure. */
1200 #undef TARGET_ATTRIBUTE_TABLE
1201 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1202 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1203 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1205 #undef TARGET_ASM_ALIGNED_DI_OP
1206 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1208 /* Default unaligned ops are only provided for ELF. Find the ops needed
1209 for non-ELF systems. */
1210 #ifndef OBJECT_FORMAT_ELF
1212 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1214 #undef TARGET_ASM_UNALIGNED_HI_OP
1215 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1216 #undef TARGET_ASM_UNALIGNED_SI_OP
1217 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1218 #undef TARGET_ASM_UNALIGNED_DI_OP
1219 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1222 #undef TARGET_ASM_UNALIGNED_HI_OP
1223 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1224 #undef TARGET_ASM_UNALIGNED_SI_OP
1225 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1226 #undef TARGET_ASM_UNALIGNED_DI_OP
1227 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1228 #undef TARGET_ASM_ALIGNED_DI_OP
1229 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1233 /* This hook deals with fixups for relocatable code and DI-mode objects
1235 #undef TARGET_ASM_INTEGER
1236 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1238 #ifdef HAVE_GAS_HIDDEN
1239 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1240 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1243 #undef TARGET_HAVE_TLS
1244 #define TARGET_HAVE_TLS HAVE_AS_TLS
1246 #undef TARGET_CANNOT_FORCE_CONST_MEM
1247 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1249 #undef TARGET_ASM_FUNCTION_PROLOGUE
1250 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1251 #undef TARGET_ASM_FUNCTION_EPILOGUE
1252 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1254 #undef TARGET_LEGITIMIZE_ADDRESS
1255 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1257 #undef TARGET_SCHED_VARIABLE_ISSUE
1258 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1260 #undef TARGET_SCHED_ISSUE_RATE
1261 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1262 #undef TARGET_SCHED_ADJUST_COST
1263 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1264 #undef TARGET_SCHED_ADJUST_PRIORITY
1265 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1266 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1267 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1268 #undef TARGET_SCHED_INIT
1269 #define TARGET_SCHED_INIT rs6000_sched_init
1270 #undef TARGET_SCHED_FINISH
1271 #define TARGET_SCHED_FINISH rs6000_sched_finish
1272 #undef TARGET_SCHED_REORDER
1273 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1274 #undef TARGET_SCHED_REORDER2
1275 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1277 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1278 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1280 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1281 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1283 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1284 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1285 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1286 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1287 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1288 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1289 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1290 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1292 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1293 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1294 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1295 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1296 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1297 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1298 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1299 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1300 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1301 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1303 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1304 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1306 #undef TARGET_INIT_BUILTINS
1307 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1309 #undef TARGET_EXPAND_BUILTIN
1310 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1312 #undef TARGET_MANGLE_TYPE
1313 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1315 #undef TARGET_INIT_LIBFUNCS
1316 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1319 #undef TARGET_BINDS_LOCAL_P
1320 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1323 #undef TARGET_MS_BITFIELD_LAYOUT_P
1324 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1326 #undef TARGET_ASM_OUTPUT_MI_THUNK
1327 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1329 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1330 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1332 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1333 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1335 #undef TARGET_INVALID_WITHIN_DOLOOP
1336 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1338 #undef TARGET_RTX_COSTS
1339 #define TARGET_RTX_COSTS rs6000_rtx_costs
1340 #undef TARGET_ADDRESS_COST
1341 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1343 #undef TARGET_DWARF_REGISTER_SPAN
1344 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1346 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1347 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1349 /* On rs6000, function arguments are promoted, as are function return
1351 #undef TARGET_PROMOTE_FUNCTION_MODE
1352 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1354 #undef TARGET_RETURN_IN_MEMORY
1355 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1357 #undef TARGET_SETUP_INCOMING_VARARGS
1358 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1360 /* Always strict argument naming on rs6000. */
1361 #undef TARGET_STRICT_ARGUMENT_NAMING
1362 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1363 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1364 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1365 #undef TARGET_SPLIT_COMPLEX_ARG
1366 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1367 #undef TARGET_MUST_PASS_IN_STACK
1368 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1369 #undef TARGET_PASS_BY_REFERENCE
1370 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1371 #undef TARGET_ARG_PARTIAL_BYTES
1372 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1374 #undef TARGET_BUILD_BUILTIN_VA_LIST
1375 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1377 #undef TARGET_EXPAND_BUILTIN_VA_START
1378 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1380 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1381 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1383 #undef TARGET_EH_RETURN_FILTER_MODE
1384 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1386 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1387 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1389 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1390 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1392 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1393 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1395 #undef TARGET_HANDLE_OPTION
1396 #define TARGET_HANDLE_OPTION rs6000_handle_option
1398 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1399 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1400 rs6000_builtin_vectorized_function
1402 #undef TARGET_DEFAULT_TARGET_FLAGS
1403 #define TARGET_DEFAULT_TARGET_FLAGS \
1406 #undef TARGET_STACK_PROTECT_FAIL
1407 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1409 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1410 The PowerPC architecture requires only weak consistency among
1411 processors--that is, memory accesses between processors need not be
1412 sequentially consistent and memory accesses among processors can occur
1413 in any order. The ability to order memory accesses weakly provides
1414 opportunities for more efficient use of the system bus. Unless a
1415 dependency exists, the 604e allows read operations to precede store
1417 #undef TARGET_RELAXED_ORDERING
1418 #define TARGET_RELAXED_ORDERING true
1421 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1422 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1425 /* Use a 32-bit anchor range. This leads to sequences like:
1427 addis tmp,anchor,high
1430 where tmp itself acts as an anchor, and can be shared between
1431 accesses to the same 64k page. */
1432 #undef TARGET_MIN_ANCHOR_OFFSET
1433 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1434 #undef TARGET_MAX_ANCHOR_OFFSET
1435 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1436 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1437 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1439 #undef TARGET_BUILTIN_RECIPROCAL
1440 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1442 #undef TARGET_EXPAND_TO_RTL_HOOK
1443 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1445 #undef TARGET_INSTANTIATE_DECLS
1446 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1448 #undef TARGET_SECONDARY_RELOAD
1449 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1451 #undef TARGET_IRA_COVER_CLASSES
1452 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1454 #undef TARGET_LEGITIMATE_ADDRESS_P
1455 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1457 #undef TARGET_CAN_ELIMINATE
1458 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1460 struct gcc_target targetm = TARGET_INITIALIZER;
1462 /* Return number of consecutive hard regs needed starting at reg REGNO
1463 to hold something of mode MODE.
1464 This is ordinarily the length in words of a value of mode MODE
1465 but can be less for certain modes in special long registers.
1467 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1468 scalar instructions. The upper 32 bits are only available to the
1471 POWER and PowerPC GPRs hold 32 bits worth;
1472 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1475 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1477 unsigned HOST_WIDE_INT reg_size;
1479 if (FP_REGNO_P (regno))
1480 reg_size = (VECTOR_MEM_VSX_P (mode)
1481 ? UNITS_PER_VSX_WORD
1482 : UNITS_PER_FP_WORD);
1484 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1485 reg_size = UNITS_PER_SPE_WORD;
1487 else if (ALTIVEC_REGNO_P (regno))
1488 reg_size = UNITS_PER_ALTIVEC_WORD;
1490 /* The value returned for SCmode in the E500 double case is 2 for
1491 ABI compatibility; storing an SCmode value in a single register
1492 would require function_arg and rs6000_spe_function_arg to handle
1493 SCmode so as to pass the value correctly in a pair of
1495 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1496 && !DECIMAL_FLOAT_MODE_P (mode))
1497 reg_size = UNITS_PER_FP_WORD;
1500 reg_size = UNITS_PER_WORD;
1502 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1505 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1508 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1510 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1512 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1513 implementations. Don't allow an item to be split between a FP register
1514 and an Altivec register. */
1515 if (VECTOR_MEM_VSX_P (mode))
1517 if (FP_REGNO_P (regno))
1518 return FP_REGNO_P (last_regno);
1520 if (ALTIVEC_REGNO_P (regno))
1521 return ALTIVEC_REGNO_P (last_regno);
1524 /* The GPRs can hold any mode, but values bigger than one register
1525 cannot go past R31. */
1526 if (INT_REGNO_P (regno))
1527 return INT_REGNO_P (last_regno);
1529 /* The float registers (except for VSX vector modes) can only hold floating
1530 modes and DImode. This excludes the 32-bit decimal float mode for
1532 if (FP_REGNO_P (regno))
1534 if (SCALAR_FLOAT_MODE_P (mode)
1535 && (mode != TDmode || (regno % 2) == 0)
1536 && FP_REGNO_P (last_regno))
1539 if (GET_MODE_CLASS (mode) == MODE_INT
1540 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1543 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1544 && PAIRED_VECTOR_MODE (mode))
1550 /* The CR register can only hold CC modes. */
1551 if (CR_REGNO_P (regno))
1552 return GET_MODE_CLASS (mode) == MODE_CC;
1554 if (XER_REGNO_P (regno))
1555 return mode == PSImode;
1557 /* AltiVec only in AldyVec registers. */
1558 if (ALTIVEC_REGNO_P (regno))
1559 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1561 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1562 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1565 /* We cannot put TImode anywhere except general register and it must be able
1566 to fit within the register set. In the future, allow TImode in the
1567 Altivec or VSX registers. */
1569 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1572 /* Print interesting facts about registers. */
1574 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1578 for (r = first_regno; r <= last_regno; ++r)
1580 const char *comma = "";
1583 if (first_regno == last_regno)
1584 fprintf (stderr, "%s:\t", reg_name);
1586 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1589 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1590 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1594 fprintf (stderr, ",\n\t");
1599 if (rs6000_hard_regno_nregs[m][r] > 1)
1600 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1601 rs6000_hard_regno_nregs[m][r]);
1603 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1608 if (call_used_regs[r])
1612 fprintf (stderr, ",\n\t");
1617 len += fprintf (stderr, "%s%s", comma, "call-used");
1625 fprintf (stderr, ",\n\t");
1630 len += fprintf (stderr, "%s%s", comma, "fixed");
1636 fprintf (stderr, ",\n\t");
1640 fprintf (stderr, "%sregno = %d\n", comma, r);
1644 /* Print various interesting information with -mdebug=reg. */
1646 rs6000_debug_reg_global (void)
1648 const char *nl = (const char *)0;
1650 char costly_num[20];
1652 const char *costly_str;
1653 const char *nop_str;
1655 /* Map enum rs6000_vector to string. */
1656 static const char *rs6000_debug_vector_unit[] = {
1665 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1666 LAST_VIRTUAL_REGISTER);
1667 rs6000_debug_reg_print (0, 31, "gr");
1668 rs6000_debug_reg_print (32, 63, "fp");
1669 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1672 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1673 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1674 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1675 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1676 rs6000_debug_reg_print (XER_REGNO, XER_REGNO, "xer");
1677 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1678 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1679 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1680 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1684 "d reg_class = %s\n"
1685 "f reg_class = %s\n"
1686 "v reg_class = %s\n"
1687 "wa reg_class = %s\n"
1688 "wd reg_class = %s\n"
1689 "wf reg_class = %s\n"
1690 "ws reg_class = %s\n\n",
1691 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1692 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1693 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1694 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1695 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1696 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1697 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1699 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1700 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1703 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1705 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1706 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1712 switch (rs6000_sched_costly_dep)
1714 case max_dep_latency:
1715 costly_str = "max_dep_latency";
1719 costly_str = "no_dep_costly";
1722 case all_deps_costly:
1723 costly_str = "all_deps_costly";
1726 case true_store_to_load_dep_costly:
1727 costly_str = "true_store_to_load_dep_costly";
1730 case store_to_load_dep_costly:
1731 costly_str = "store_to_load_dep_costly";
1735 costly_str = costly_num;
1736 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1740 switch (rs6000_sched_insert_nops)
1742 case sched_finish_regroup_exact:
1743 nop_str = "sched_finish_regroup_exact";
1746 case sched_finish_pad_groups:
1747 nop_str = "sched_finish_pad_groups";
1750 case sched_finish_none:
1751 nop_str = "sched_finish_none";
1756 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1761 "always_hint = %s\n"
1762 "align_branch_targets = %s\n"
1763 "sched_restricted_insns_priority = %d\n"
1764 "sched_costly_dep = %s\n"
1765 "sched_insert_nops = %s\n\n",
1766 rs6000_always_hint ? "true" : "false",
1767 rs6000_align_branch_targets ? "true" : "false",
1768 (int)rs6000_sched_restricted_insns_priority,
1769 costly_str, nop_str);
1772 /* Initialize the various global tables that are based on register size. */
1774 rs6000_init_hard_regno_mode_ok (void)
1780 /* Precalculate REGNO_REG_CLASS. */
1781 rs6000_regno_regclass[0] = GENERAL_REGS;
1782 for (r = 1; r < 32; ++r)
1783 rs6000_regno_regclass[r] = BASE_REGS;
1785 for (r = 32; r < 64; ++r)
1786 rs6000_regno_regclass[r] = FLOAT_REGS;
1788 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1789 rs6000_regno_regclass[r] = NO_REGS;
1791 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
1792 rs6000_regno_regclass[r] = ALTIVEC_REGS;
1794 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
1795 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
1796 rs6000_regno_regclass[r] = CR_REGS;
1798 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
1799 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
1800 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
1801 rs6000_regno_regclass[XER_REGNO] = XER_REGS;
1802 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
1803 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
1804 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
1805 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
1806 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
1807 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
1809 /* Precalculate vector information, this must be set up before the
1810 rs6000_hard_regno_nregs_internal below. */
1811 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1813 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
1814 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
1815 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
1818 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
1819 rs6000_constraints[c] = NO_REGS;
1821 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
1822 believes it can use native alignment or still uses 128-bit alignment. */
1823 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
1834 /* V2DF mode, VSX only. */
1837 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
1838 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
1839 rs6000_vector_align[V2DFmode] = align64;
1842 /* V4SF mode, either VSX or Altivec. */
1845 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
1846 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
1847 rs6000_vector_align[V4SFmode] = align32;
1849 else if (TARGET_ALTIVEC)
1851 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
1852 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
1853 rs6000_vector_align[V4SFmode] = align32;
1856 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
1860 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
1861 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
1862 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
1863 rs6000_vector_align[V4SImode] = align32;
1864 rs6000_vector_align[V8HImode] = align32;
1865 rs6000_vector_align[V16QImode] = align32;
1869 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
1870 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
1871 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
1875 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
1876 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
1877 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
1881 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
1882 Altivec doesn't have 64-bit support. */
1885 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
1886 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
1887 rs6000_vector_align[V2DImode] = align64;
1890 /* DFmode, see if we want to use the VSX unit. */
1891 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
1893 rs6000_vector_unit[DFmode] = VECTOR_VSX;
1894 rs6000_vector_mem[DFmode]
1895 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
1896 rs6000_vector_align[DFmode] = align64;
1899 /* TODO add SPE and paired floating point vector support. */
1901 /* Register class constaints for the constraints that depend on compile
1903 if (TARGET_HARD_FLOAT && TARGET_FPRS)
1904 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
1906 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
1907 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
1911 /* At present, we just use VSX_REGS, but we have different constraints
1912 based on the use, in case we want to fine tune the default register
1913 class used. wa = any VSX register, wf = register class to use for
1914 V4SF, wd = register class to use for V2DF, and ws = register classs to
1915 use for DF scalars. */
1916 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
1917 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
1918 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
1919 if (TARGET_VSX_SCALAR_DOUBLE)
1920 rs6000_constraints[RS6000_CONSTRAINT_ws] = VSX_REGS;
1924 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
1926 /* Set up the reload helper functions. */
1927 if (TARGET_VSX || TARGET_ALTIVEC)
1931 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
1932 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
1933 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
1934 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
1935 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
1936 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
1937 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
1938 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
1939 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
1940 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
1941 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
1942 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
1946 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
1947 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
1948 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
1949 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
1950 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
1951 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
1952 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
1953 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
1954 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
1955 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
1956 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
1957 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
1961 /* Precalculate HARD_REGNO_NREGS. */
1962 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
1963 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1964 rs6000_hard_regno_nregs[m][r]
1965 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
1967 /* Precalculate HARD_REGNO_MODE_OK. */
1968 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
1969 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1970 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
1971 rs6000_hard_regno_mode_ok_p[m][r] = true;
1973 /* Precalculate CLASS_MAX_NREGS sizes. */
1974 for (c = 0; c < LIM_REG_CLASSES; ++c)
1978 if (TARGET_VSX && VSX_REG_CLASS_P (c))
1979 reg_size = UNITS_PER_VSX_WORD;
1981 else if (c == ALTIVEC_REGS)
1982 reg_size = UNITS_PER_ALTIVEC_WORD;
1984 else if (c == FLOAT_REGS)
1985 reg_size = UNITS_PER_FP_WORD;
1988 reg_size = UNITS_PER_WORD;
1990 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1991 rs6000_class_max_nregs[m][c]
1992 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
1995 if (TARGET_E500_DOUBLE)
1996 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
1998 if (TARGET_DEBUG_REG)
1999 rs6000_debug_reg_global ();
2003 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2006 darwin_rs6000_override_options (void)
2008 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2010 rs6000_altivec_abi = 1;
2011 TARGET_ALTIVEC_VRSAVE = 1;
2012 if (DEFAULT_ABI == ABI_DARWIN)
2014 if (MACHO_DYNAMIC_NO_PIC_P)
2017 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2020 else if (flag_pic == 1)
2025 if (TARGET_64BIT && ! TARGET_POWERPC64)
2027 target_flags |= MASK_POWERPC64;
2028 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2032 rs6000_default_long_calls = 1;
2033 target_flags |= MASK_SOFT_FLOAT;
2036 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2038 if (!flag_mkernel && !flag_apple_kext
2040 && ! (target_flags_explicit & MASK_ALTIVEC))
2041 target_flags |= MASK_ALTIVEC;
2043 /* Unless the user (not the configurer) has explicitly overridden
2044 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2045 G4 unless targetting the kernel. */
2048 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2049 && ! (target_flags_explicit & MASK_ALTIVEC)
2050 && ! rs6000_select[1].string)
2052 target_flags |= MASK_ALTIVEC;
2057 /* If not otherwise specified by a target, make 'long double' equivalent to
2060 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2061 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2064 /* Override command line options. Mostly we process the processor
2065 type and sometimes adjust other TARGET_ options. */
2068 rs6000_override_options (const char *default_cpu)
2071 struct rs6000_cpu_select *ptr;
2074 /* Simplifications for entries below. */
2077 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2078 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2081 /* This table occasionally claims that a processor does not support
2082 a particular feature even though it does, but the feature is slower
2083 than the alternative. Thus, it shouldn't be relied on as a
2084 complete description of the processor's support.
2086 Please keep this list in order, and don't forget to update the
2087 documentation in invoke.texi when adding a new processor or
2091 const char *const name; /* Canonical processor name. */
2092 const enum processor_type processor; /* Processor type enum value. */
2093 const int target_enable; /* Target flags to enable. */
2094 } const processor_target_table[]
2095 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2096 {"403", PROCESSOR_PPC403,
2097 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2098 {"405", PROCESSOR_PPC405,
2099 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2100 {"405fp", PROCESSOR_PPC405,
2101 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2102 {"440", PROCESSOR_PPC440,
2103 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2104 {"440fp", PROCESSOR_PPC440,
2105 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2106 {"464", PROCESSOR_PPC440,
2107 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2108 {"464fp", PROCESSOR_PPC440,
2109 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2110 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2111 {"601", PROCESSOR_PPC601,
2112 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2113 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2114 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2115 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2116 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2117 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2118 {"620", PROCESSOR_PPC620,
2119 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2120 {"630", PROCESSOR_PPC630,
2121 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2122 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2123 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2124 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2125 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2126 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2127 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2128 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2129 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2131 /* 8548 has a dummy entry for now. */
2132 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2134 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2135 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2136 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2138 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2139 {"970", PROCESSOR_POWER4,
2140 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2141 {"cell", PROCESSOR_CELL,
2142 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2143 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2144 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2145 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2146 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2147 {"G5", PROCESSOR_POWER4,
2148 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2149 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2150 {"power2", PROCESSOR_POWER,
2151 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2152 {"power3", PROCESSOR_PPC630,
2153 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2154 {"power4", PROCESSOR_POWER4,
2155 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2157 {"power5", PROCESSOR_POWER5,
2158 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2159 | MASK_MFCRF | MASK_POPCNTB},
2160 {"power5+", PROCESSOR_POWER5,
2161 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2162 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2163 {"power6", PROCESSOR_POWER6,
2164 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2165 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP},
2166 {"power6x", PROCESSOR_POWER6,
2167 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2168 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2170 {"power7", PROCESSOR_POWER7,
2171 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2172 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2173 | MASK_VSX}, /* Don't add MASK_ISEL by default */
2174 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2175 {"powerpc64", PROCESSOR_POWERPC64,
2176 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2177 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2178 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2179 {"rios2", PROCESSOR_RIOS2,
2180 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2181 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2182 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2183 {"rs64", PROCESSOR_RS64A,
2184 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2187 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2189 /* Some OSs don't support saving the high part of 64-bit registers on
2190 context switch. Other OSs don't support saving Altivec registers.
2191 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2192 settings; if the user wants either, the user must explicitly specify
2193 them and we won't interfere with the user's specification. */
2196 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2197 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2198 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2199 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2200 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2201 | MASK_POPCNTD | MASK_VSX | MASK_ISEL)
2204 /* Set the pointer size. */
2207 rs6000_pmode = (int)DImode;
2208 rs6000_pointer_size = 64;
2212 rs6000_pmode = (int)SImode;
2213 rs6000_pointer_size = 32;
2216 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2217 #ifdef OS_MISSING_POWERPC64
2218 if (OS_MISSING_POWERPC64)
2219 set_masks &= ~MASK_POWERPC64;
2221 #ifdef OS_MISSING_ALTIVEC
2222 if (OS_MISSING_ALTIVEC)
2223 set_masks &= ~MASK_ALTIVEC;
2226 /* Don't override by the processor default if given explicitly. */
2227 set_masks &= ~target_flags_explicit;
2229 /* Identify the processor type. */
2230 rs6000_select[0].string = default_cpu;
2231 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2233 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2235 ptr = &rs6000_select[i];
2236 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2238 for (j = 0; j < ptt_size; j++)
2239 if (! strcmp (ptr->string, processor_target_table[j].name))
2241 if (ptr->set_tune_p)
2242 rs6000_cpu = processor_target_table[j].processor;
2244 if (ptr->set_arch_p)
2246 target_flags &= ~set_masks;
2247 target_flags |= (processor_target_table[j].target_enable
2254 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2258 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2259 || rs6000_cpu == PROCESSOR_PPCE500MC)
2262 error ("AltiVec not supported in this target");
2264 error ("Spe not supported in this target");
2267 /* Disable Cell microcode if we are optimizing for the Cell
2268 and not optimizing for size. */
2269 if (rs6000_gen_cell_microcode == -1)
2270 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2273 /* If we are optimizing big endian systems for space, use the load/store
2274 multiple and string instructions unless we are not generating
2276 if (BYTES_BIG_ENDIAN && optimize_size && !rs6000_gen_cell_microcode)
2277 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2279 /* Don't allow -mmultiple or -mstring on little endian systems
2280 unless the cpu is a 750, because the hardware doesn't support the
2281 instructions used in little endian mode, and causes an alignment
2282 trap. The 750 does not cause an alignment trap (except when the
2283 target is unaligned). */
2285 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2287 if (TARGET_MULTIPLE)
2289 target_flags &= ~MASK_MULTIPLE;
2290 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2291 warning (0, "-mmultiple is not supported on little endian systems");
2296 target_flags &= ~MASK_STRING;
2297 if ((target_flags_explicit & MASK_STRING) != 0)
2298 warning (0, "-mstring is not supported on little endian systems");
2302 /* Add some warnings for VSX. Enable -maltivec unless the user explicitly
2303 used -mno-altivec */
2306 const char *msg = NULL;
2307 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2308 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2310 if (target_flags_explicit & MASK_VSX)
2311 msg = N_("-mvsx requires hardware floating point");
2313 target_flags &= ~ MASK_VSX;
2315 else if (TARGET_PAIRED_FLOAT)
2316 msg = N_("-mvsx and -mpaired are incompatible");
2317 /* The hardware will allow VSX and little endian, but until we make sure
2318 things like vector select, etc. work don't allow VSX on little endian
2319 systems at this point. */
2320 else if (!BYTES_BIG_ENDIAN)
2321 msg = N_("-mvsx used with little endian code");
2322 else if (TARGET_AVOID_XFORM > 0)
2323 msg = N_("-mvsx needs indexed addressing");
2328 target_flags &= ~ MASK_VSX;
2330 else if (TARGET_VSX && !TARGET_ALTIVEC
2331 && (target_flags_explicit & MASK_ALTIVEC) == 0)
2332 target_flags |= MASK_ALTIVEC;
2335 /* Set debug flags */
2336 if (rs6000_debug_name)
2338 if (! strcmp (rs6000_debug_name, "all"))
2339 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2340 = rs6000_debug_addr = rs6000_debug_cost = 1;
2341 else if (! strcmp (rs6000_debug_name, "stack"))
2342 rs6000_debug_stack = 1;
2343 else if (! strcmp (rs6000_debug_name, "arg"))
2344 rs6000_debug_arg = 1;
2345 else if (! strcmp (rs6000_debug_name, "reg"))
2346 rs6000_debug_reg = 1;
2347 else if (! strcmp (rs6000_debug_name, "addr"))
2348 rs6000_debug_addr = 1;
2349 else if (! strcmp (rs6000_debug_name, "cost"))
2350 rs6000_debug_cost = 1;
2352 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2354 /* If the appropriate debug option is enabled, replace the target hooks
2355 with debug versions that call the real version and then prints
2356 debugging information. */
2357 if (TARGET_DEBUG_COST)
2359 targetm.rtx_costs = rs6000_debug_rtx_costs;
2360 targetm.address_cost = rs6000_debug_address_cost;
2361 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2364 if (TARGET_DEBUG_ADDR)
2366 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2367 targetm.legitimize_address = rs6000_debug_legitimize_address;
2368 rs6000_secondary_reload_class_ptr
2369 = rs6000_debug_secondary_reload_class;
2370 rs6000_secondary_memory_needed_ptr
2371 = rs6000_debug_secondary_memory_needed;
2372 rs6000_cannot_change_mode_class_ptr
2373 = rs6000_debug_cannot_change_mode_class;
2374 rs6000_preferred_reload_class_ptr
2375 = rs6000_debug_preferred_reload_class;
2376 rs6000_legitimize_reload_address_ptr
2377 = rs6000_debug_legitimize_reload_address;
2378 rs6000_mode_dependent_address_ptr
2379 = rs6000_debug_mode_dependent_address;
2383 if (rs6000_traceback_name)
2385 if (! strncmp (rs6000_traceback_name, "full", 4))
2386 rs6000_traceback = traceback_full;
2387 else if (! strncmp (rs6000_traceback_name, "part", 4))
2388 rs6000_traceback = traceback_part;
2389 else if (! strncmp (rs6000_traceback_name, "no", 2))
2390 rs6000_traceback = traceback_none;
2392 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2393 rs6000_traceback_name);
2396 if (!rs6000_explicit_options.long_double)
2397 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2399 #ifndef POWERPC_LINUX
2400 if (!rs6000_explicit_options.ieee)
2401 rs6000_ieeequad = 1;
2404 /* Enable Altivec ABI for AIX -maltivec. */
2405 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2406 rs6000_altivec_abi = 1;
2408 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2409 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2410 be explicitly overridden in either case. */
2413 if (!rs6000_explicit_options.altivec_abi
2414 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2415 rs6000_altivec_abi = 1;
2417 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2418 if (!rs6000_explicit_options.vrsave)
2419 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2422 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2423 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2425 rs6000_darwin64_abi = 1;
2427 darwin_one_byte_bool = 1;
2429 /* Default to natural alignment, for better performance. */
2430 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2433 /* Place FP constants in the constant pool instead of TOC
2434 if section anchors enabled. */
2435 if (flag_section_anchors)
2436 TARGET_NO_FP_IN_TOC = 1;
2438 /* Handle -mtls-size option. */
2439 rs6000_parse_tls_size_option ();
2441 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2442 SUBTARGET_OVERRIDE_OPTIONS;
2444 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2445 SUBSUBTARGET_OVERRIDE_OPTIONS;
2447 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2448 SUB3TARGET_OVERRIDE_OPTIONS;
2451 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC)
2453 /* The e500 and e500mc do not have string instructions, and we set
2454 MASK_STRING above when optimizing for size. */
2455 if ((target_flags & MASK_STRING) != 0)
2456 target_flags = target_flags & ~MASK_STRING;
2458 else if (rs6000_select[1].string != NULL)
2460 /* For the powerpc-eabispe configuration, we set all these by
2461 default, so let's unset them if we manually set another
2462 CPU that is not the E500. */
2463 if (!rs6000_explicit_options.spe_abi)
2465 if (!rs6000_explicit_options.spe)
2467 if (!rs6000_explicit_options.float_gprs)
2468 rs6000_float_gprs = 0;
2469 if (!(target_flags_explicit & MASK_ISEL))
2470 target_flags &= ~MASK_ISEL;
2473 /* Detect invalid option combinations with E500. */
2476 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2477 && rs6000_cpu != PROCESSOR_POWER5
2478 && rs6000_cpu != PROCESSOR_POWER6
2479 && rs6000_cpu != PROCESSOR_POWER7
2480 && rs6000_cpu != PROCESSOR_CELL);
2481 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2482 || rs6000_cpu == PROCESSOR_POWER5
2483 || rs6000_cpu == PROCESSOR_POWER7);
2484 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2485 || rs6000_cpu == PROCESSOR_POWER5
2486 || rs6000_cpu == PROCESSOR_POWER6
2487 || rs6000_cpu == PROCESSOR_POWER7);
2489 /* Allow debug switches to override the above settings. */
2490 if (TARGET_ALWAYS_HINT > 0)
2491 rs6000_always_hint = TARGET_ALWAYS_HINT;
2493 if (TARGET_SCHED_GROUPS > 0)
2494 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2496 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2497 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2499 rs6000_sched_restricted_insns_priority
2500 = (rs6000_sched_groups ? 1 : 0);
2502 /* Handle -msched-costly-dep option. */
2503 rs6000_sched_costly_dep
2504 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2506 if (rs6000_sched_costly_dep_str)
2508 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2509 rs6000_sched_costly_dep = no_dep_costly;
2510 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2511 rs6000_sched_costly_dep = all_deps_costly;
2512 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2513 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2514 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2515 rs6000_sched_costly_dep = store_to_load_dep_costly;
2517 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2518 atoi (rs6000_sched_costly_dep_str));
2521 /* Handle -minsert-sched-nops option. */
2522 rs6000_sched_insert_nops
2523 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2525 if (rs6000_sched_insert_nops_str)
2527 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2528 rs6000_sched_insert_nops = sched_finish_none;
2529 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2530 rs6000_sched_insert_nops = sched_finish_pad_groups;
2531 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2532 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2534 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2535 atoi (rs6000_sched_insert_nops_str));
2538 #ifdef TARGET_REGNAMES
2539 /* If the user desires alternate register names, copy in the
2540 alternate names now. */
2541 if (TARGET_REGNAMES)
2542 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2545 /* Set aix_struct_return last, after the ABI is determined.
2546 If -maix-struct-return or -msvr4-struct-return was explicitly
2547 used, don't override with the ABI default. */
2548 if (!rs6000_explicit_options.aix_struct_ret)
2549 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2551 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2552 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2555 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2557 /* We can only guarantee the availability of DI pseudo-ops when
2558 assembling for 64-bit targets. */
2561 targetm.asm_out.aligned_op.di = NULL;
2562 targetm.asm_out.unaligned_op.di = NULL;
2565 /* Set branch target alignment, if not optimizing for size. */
2568 /* Cell wants to be aligned 8byte for dual issue. */
2569 if (rs6000_cpu == PROCESSOR_CELL)
2571 if (align_functions <= 0)
2572 align_functions = 8;
2573 if (align_jumps <= 0)
2575 if (align_loops <= 0)
2578 if (rs6000_align_branch_targets)
2580 if (align_functions <= 0)
2581 align_functions = 16;
2582 if (align_jumps <= 0)
2584 if (align_loops <= 0)
2587 if (align_jumps_max_skip <= 0)
2588 align_jumps_max_skip = 15;
2589 if (align_loops_max_skip <= 0)
2590 align_loops_max_skip = 15;
2593 /* Arrange to save and restore machine status around nested functions. */
2594 init_machine_status = rs6000_init_machine_status;
2596 /* We should always be splitting complex arguments, but we can't break
2597 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2598 if (DEFAULT_ABI != ABI_AIX)
2599 targetm.calls.split_complex_arg = NULL;
2601 /* Initialize rs6000_cost with the appropriate target costs. */
2603 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2607 case PROCESSOR_RIOS1:
2608 rs6000_cost = &rios1_cost;
2611 case PROCESSOR_RIOS2:
2612 rs6000_cost = &rios2_cost;
2615 case PROCESSOR_RS64A:
2616 rs6000_cost = &rs64a_cost;
2619 case PROCESSOR_MPCCORE:
2620 rs6000_cost = &mpccore_cost;
2623 case PROCESSOR_PPC403:
2624 rs6000_cost = &ppc403_cost;
2627 case PROCESSOR_PPC405:
2628 rs6000_cost = &ppc405_cost;
2631 case PROCESSOR_PPC440:
2632 rs6000_cost = &ppc440_cost;
2635 case PROCESSOR_PPC601:
2636 rs6000_cost = &ppc601_cost;
2639 case PROCESSOR_PPC603:
2640 rs6000_cost = &ppc603_cost;
2643 case PROCESSOR_PPC604:
2644 rs6000_cost = &ppc604_cost;
2647 case PROCESSOR_PPC604e:
2648 rs6000_cost = &ppc604e_cost;
2651 case PROCESSOR_PPC620:
2652 rs6000_cost = &ppc620_cost;
2655 case PROCESSOR_PPC630:
2656 rs6000_cost = &ppc630_cost;
2659 case PROCESSOR_CELL:
2660 rs6000_cost = &ppccell_cost;
2663 case PROCESSOR_PPC750:
2664 case PROCESSOR_PPC7400:
2665 rs6000_cost = &ppc750_cost;
2668 case PROCESSOR_PPC7450:
2669 rs6000_cost = &ppc7450_cost;
2672 case PROCESSOR_PPC8540:
2673 rs6000_cost = &ppc8540_cost;
2676 case PROCESSOR_PPCE300C2:
2677 case PROCESSOR_PPCE300C3:
2678 rs6000_cost = &ppce300c2c3_cost;
2681 case PROCESSOR_PPCE500MC:
2682 rs6000_cost = &ppce500mc_cost;
2685 case PROCESSOR_POWER4:
2686 case PROCESSOR_POWER5:
2687 rs6000_cost = &power4_cost;
2690 case PROCESSOR_POWER6:
2691 rs6000_cost = &power6_cost;
2694 case PROCESSOR_POWER7:
2695 rs6000_cost = &power7_cost;
2702 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
2703 set_param_value ("simultaneous-prefetches",
2704 rs6000_cost->simultaneous_prefetches);
2705 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
2706 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
2707 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
2708 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
2709 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
2710 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
2712 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
2713 can be optimized to ap = __builtin_next_arg (0). */
2714 if (DEFAULT_ABI != ABI_V4)
2715 targetm.expand_builtin_va_start = NULL;
2717 /* Set up single/double float flags.
2718 If TARGET_HARD_FLOAT is set, but neither single or double is set,
2719 then set both flags. */
2720 if (TARGET_HARD_FLOAT && TARGET_FPRS
2721 && rs6000_single_float == 0 && rs6000_double_float == 0)
2722 rs6000_single_float = rs6000_double_float = 1;
2724 /* Reset single and double FP flags if target is E500. */
2727 rs6000_single_float = rs6000_double_float = 0;
2728 if (TARGET_E500_SINGLE)
2729 rs6000_single_float = 1;
2730 if (TARGET_E500_DOUBLE)
2731 rs6000_single_float = rs6000_double_float = 1;
2734 /* If not explicitly specified via option, decide whether to generate indexed
2735 load/store instructions. */
2736 if (TARGET_AVOID_XFORM == -1)
2737 /* Avoid indexed addressing when targeting Power6 in order to avoid
2738 the DERAT mispredict penalty. */
2739 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
2741 rs6000_init_hard_regno_mode_ok ();
2744 /* Implement targetm.vectorize.builtin_mask_for_load. */
2746 rs6000_builtin_mask_for_load (void)
2748 if (TARGET_ALTIVEC || TARGET_VSX)
2749 return altivec_builtin_mask_for_load;
2754 /* Implement targetm.vectorize.builtin_conversion.
2755 Returns a decl of a function that implements conversion of an integer vector
2756 into a floating-point vector, or vice-versa. TYPE is the type of the integer
2757 side of the conversion.
2758 Return NULL_TREE if it is not available. */
2760 rs6000_builtin_conversion (unsigned int tcode, tree type)
2762 enum tree_code code = (enum tree_code) tcode;
2766 case FIX_TRUNC_EXPR:
2767 switch (TYPE_MODE (type))
2770 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2773 return TYPE_UNSIGNED (type)
2774 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
2775 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
2778 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2781 return TYPE_UNSIGNED (type)
2782 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
2783 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
2790 switch (TYPE_MODE (type))
2793 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2796 return TYPE_UNSIGNED (type)
2797 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
2798 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
2801 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2804 return TYPE_UNSIGNED (type)
2805 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
2806 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
2817 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2819 rs6000_builtin_mul_widen_even (tree type)
2821 if (!TARGET_ALTIVEC)
2824 switch (TYPE_MODE (type))
2827 return TYPE_UNSIGNED (type)
2828 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
2829 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
2832 return TYPE_UNSIGNED (type)
2833 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
2834 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
2840 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2842 rs6000_builtin_mul_widen_odd (tree type)
2844 if (!TARGET_ALTIVEC)
2847 switch (TYPE_MODE (type))
2850 return TYPE_UNSIGNED (type)
2851 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
2852 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
2855 return TYPE_UNSIGNED (type)
2856 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
2857 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
2864 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2865 after applying N number of iterations. This routine does not determine
2866 how may iterations are required to reach desired alignment. */
2869 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
2876 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
2879 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
2889 /* Assuming that all other types are naturally aligned. CHECKME! */
2894 /* Implement targetm.vectorize.builtin_vec_perm. */
2896 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
2898 tree inner_type = TREE_TYPE (type);
2899 bool uns_p = TYPE_UNSIGNED (inner_type);
2902 *mask_element_type = unsigned_char_type_node;
2904 switch (TYPE_MODE (type))
2908 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
2909 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
2914 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
2915 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
2920 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
2921 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
2925 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
2929 if (!TARGET_ALLOW_DF_PERMUTE)
2932 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
2936 if (!TARGET_ALLOW_DF_PERMUTE)
2940 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
2941 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
2952 /* Handle generic options of the form -mfoo=yes/no.
2953 NAME is the option name.
2954 VALUE is the option value.
2955 FLAG is the pointer to the flag where to store a 1 or 0, depending on
2956 whether the option value is 'yes' or 'no' respectively. */
2958 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
2962 else if (!strcmp (value, "yes"))
2964 else if (!strcmp (value, "no"))
2967 error ("unknown -m%s= option specified: '%s'", name, value);
2970 /* Validate and record the size specified with the -mtls-size option. */
2973 rs6000_parse_tls_size_option (void)
2975 if (rs6000_tls_size_string == 0)
2977 else if (strcmp (rs6000_tls_size_string, "16") == 0)
2978 rs6000_tls_size = 16;
2979 else if (strcmp (rs6000_tls_size_string, "32") == 0)
2980 rs6000_tls_size = 32;
2981 else if (strcmp (rs6000_tls_size_string, "64") == 0)
2982 rs6000_tls_size = 64;
2984 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
2988 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
2990 if (DEFAULT_ABI == ABI_DARWIN)
2991 /* The Darwin libraries never set errno, so we might as well
2992 avoid calling them when that's the only reason we would. */
2993 flag_errno_math = 0;
2995 /* Double growth factor to counter reduced min jump length. */
2996 set_param_value ("max-grow-copy-bb-insns", 16);
2998 /* Enable section anchors by default.
2999 Skip section anchors for Objective C and Objective C++
3000 until front-ends fixed. */
3001 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3002 flag_section_anchors = 2;
3005 static enum fpu_type_t
3006 rs6000_parse_fpu_option (const char *option)
3008 if (!strcmp("none", option)) return FPU_NONE;
3009 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3010 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3011 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3012 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3013 error("unknown value %s for -mfpu", option);
3017 /* Returns a function decl for a vectorized version of the builtin function
3018 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3019 if it is not available. */
3022 rs6000_builtin_vectorized_function (unsigned int fn, tree type_out,
3025 enum machine_mode in_mode, out_mode;
3028 if (TREE_CODE (type_out) != VECTOR_TYPE
3029 || TREE_CODE (type_in) != VECTOR_TYPE
3030 || !TARGET_VECTORIZE_BUILTINS)
3033 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3034 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3035 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3036 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3040 case BUILT_IN_COPYSIGN:
3041 if (VECTOR_UNIT_VSX_P (V2DFmode)
3042 && out_mode == DFmode && out_n == 2
3043 && in_mode == DFmode && in_n == 2)
3044 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3046 case BUILT_IN_COPYSIGNF:
3047 if (out_mode != SFmode || out_n != 4
3048 || in_mode != SFmode || in_n != 4)
3050 if (VECTOR_UNIT_VSX_P (V4SFmode))
3051 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3052 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3053 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3056 if (VECTOR_UNIT_VSX_P (V2DFmode)
3057 && out_mode == DFmode && out_n == 2
3058 && in_mode == DFmode && in_n == 2)
3059 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3061 case BUILT_IN_SQRTF:
3062 if (VECTOR_UNIT_VSX_P (V4SFmode)
3063 && out_mode == SFmode && out_n == 4
3064 && in_mode == SFmode && in_n == 4)
3065 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3068 if (VECTOR_UNIT_VSX_P (V2DFmode)
3069 && out_mode == DFmode && out_n == 2
3070 && in_mode == DFmode && in_n == 2)
3071 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3073 case BUILT_IN_CEILF:
3074 if (out_mode != SFmode || out_n != 4
3075 || in_mode != SFmode || in_n != 4)
3077 if (VECTOR_UNIT_VSX_P (V4SFmode))
3078 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3079 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3080 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3082 case BUILT_IN_FLOOR:
3083 if (VECTOR_UNIT_VSX_P (V2DFmode)
3084 && out_mode == DFmode && out_n == 2
3085 && in_mode == DFmode && in_n == 2)
3086 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3088 case BUILT_IN_FLOORF:
3089 if (out_mode != SFmode || out_n != 4
3090 || in_mode != SFmode || in_n != 4)
3092 if (VECTOR_UNIT_VSX_P (V4SFmode))
3093 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3094 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3095 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3097 case BUILT_IN_TRUNC:
3098 if (VECTOR_UNIT_VSX_P (V2DFmode)
3099 && out_mode == DFmode && out_n == 2
3100 && in_mode == DFmode && in_n == 2)
3101 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3103 case BUILT_IN_TRUNCF:
3104 if (out_mode != SFmode || out_n != 4
3105 || in_mode != SFmode || in_n != 4)
3107 if (VECTOR_UNIT_VSX_P (V4SFmode))
3108 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3109 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3110 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3112 case BUILT_IN_NEARBYINT:
3113 if (VECTOR_UNIT_VSX_P (V2DFmode)
3114 && flag_unsafe_math_optimizations
3115 && out_mode == DFmode && out_n == 2
3116 && in_mode == DFmode && in_n == 2)
3117 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3119 case BUILT_IN_NEARBYINTF:
3120 if (VECTOR_UNIT_VSX_P (V4SFmode)
3121 && flag_unsafe_math_optimizations
3122 && out_mode == SFmode && out_n == 4
3123 && in_mode == SFmode && in_n == 4)
3124 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3127 if (VECTOR_UNIT_VSX_P (V2DFmode)
3128 && !flag_trapping_math
3129 && out_mode == DFmode && out_n == 2
3130 && in_mode == DFmode && in_n == 2)
3131 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3133 case BUILT_IN_RINTF:
3134 if (VECTOR_UNIT_VSX_P (V4SFmode)
3135 && !flag_trapping_math
3136 && out_mode == SFmode && out_n == 4
3137 && in_mode == SFmode && in_n == 4)
3138 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3147 /* Implement TARGET_HANDLE_OPTION. */
3150 rs6000_handle_option (size_t code, const char *arg, int value)
3152 enum fpu_type_t fpu_type = FPU_NONE;
3158 target_flags &= ~(MASK_POWER | MASK_POWER2
3159 | MASK_MULTIPLE | MASK_STRING);
3160 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3161 | MASK_MULTIPLE | MASK_STRING);
3163 case OPT_mno_powerpc:
3164 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3165 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3166 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3167 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3170 target_flags &= ~MASK_MINIMAL_TOC;
3171 TARGET_NO_FP_IN_TOC = 0;
3172 TARGET_NO_SUM_IN_TOC = 0;
3173 target_flags_explicit |= MASK_MINIMAL_TOC;
3174 #ifdef TARGET_USES_SYSV4_OPT
3175 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3176 just the same as -mminimal-toc. */
3177 target_flags |= MASK_MINIMAL_TOC;
3178 target_flags_explicit |= MASK_MINIMAL_TOC;
3182 #ifdef TARGET_USES_SYSV4_OPT
3184 /* Make -mtoc behave like -mminimal-toc. */
3185 target_flags |= MASK_MINIMAL_TOC;
3186 target_flags_explicit |= MASK_MINIMAL_TOC;
3190 #ifdef TARGET_USES_AIX64_OPT
3195 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3196 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3197 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3200 #ifdef TARGET_USES_AIX64_OPT
3205 target_flags &= ~MASK_POWERPC64;
3206 target_flags_explicit |= MASK_POWERPC64;
3209 case OPT_minsert_sched_nops_:
3210 rs6000_sched_insert_nops_str = arg;
3213 case OPT_mminimal_toc:
3216 TARGET_NO_FP_IN_TOC = 0;
3217 TARGET_NO_SUM_IN_TOC = 0;
3224 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3225 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3232 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3233 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3237 case OPT_mpowerpc_gpopt:
3238 case OPT_mpowerpc_gfxopt:
3241 target_flags |= MASK_POWERPC;
3242 target_flags_explicit |= MASK_POWERPC;
3246 case OPT_maix_struct_return:
3247 case OPT_msvr4_struct_return:
3248 rs6000_explicit_options.aix_struct_ret = true;
3252 rs6000_explicit_options.vrsave = true;
3253 TARGET_ALTIVEC_VRSAVE = value;
3257 rs6000_explicit_options.vrsave = true;
3258 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3262 target_flags_explicit |= MASK_ISEL;
3264 rs6000_parse_yes_no_option ("isel", arg, &isel);
3266 target_flags |= MASK_ISEL;
3268 target_flags &= ~MASK_ISEL;
3272 rs6000_explicit_options.spe = true;
3277 rs6000_explicit_options.spe = true;
3278 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3282 rs6000_debug_name = arg;
3285 #ifdef TARGET_USES_SYSV4_OPT
3287 rs6000_abi_name = arg;
3291 rs6000_sdata_name = arg;
3294 case OPT_mtls_size_:
3295 rs6000_tls_size_string = arg;
3298 case OPT_mrelocatable:
3301 target_flags |= MASK_MINIMAL_TOC;
3302 target_flags_explicit |= MASK_MINIMAL_TOC;
3303 TARGET_NO_FP_IN_TOC = 1;
3307 case OPT_mrelocatable_lib:
3310 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3311 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3312 TARGET_NO_FP_IN_TOC = 1;
3316 target_flags &= ~MASK_RELOCATABLE;
3317 target_flags_explicit |= MASK_RELOCATABLE;
3323 if (!strcmp (arg, "altivec"))
3325 rs6000_explicit_options.altivec_abi = true;
3326 rs6000_altivec_abi = 1;
3328 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3331 else if (! strcmp (arg, "no-altivec"))
3333 rs6000_explicit_options.altivec_abi = true;
3334 rs6000_altivec_abi = 0;
3336 else if (! strcmp (arg, "spe"))
3338 rs6000_explicit_options.spe_abi = true;
3340 rs6000_altivec_abi = 0;
3341 if (!TARGET_SPE_ABI)
3342 error ("not configured for ABI: '%s'", arg);
3344 else if (! strcmp (arg, "no-spe"))
3346 rs6000_explicit_options.spe_abi = true;
3350 /* These are here for testing during development only, do not
3351 document in the manual please. */
3352 else if (! strcmp (arg, "d64"))
3354 rs6000_darwin64_abi = 1;
3355 warning (0, "Using darwin64 ABI");
3357 else if (! strcmp (arg, "d32"))
3359 rs6000_darwin64_abi = 0;
3360 warning (0, "Using old darwin ABI");
3363 else if (! strcmp (arg, "ibmlongdouble"))
3365 rs6000_explicit_options.ieee = true;
3366 rs6000_ieeequad = 0;
3367 warning (0, "Using IBM extended precision long double");
3369 else if (! strcmp (arg, "ieeelongdouble"))
3371 rs6000_explicit_options.ieee = true;
3372 rs6000_ieeequad = 1;
3373 warning (0, "Using IEEE extended precision long double");
3378 error ("unknown ABI specified: '%s'", arg);
3384 rs6000_select[1].string = arg;
3388 rs6000_select[2].string = arg;
3391 case OPT_mtraceback_:
3392 rs6000_traceback_name = arg;
3395 case OPT_mfloat_gprs_:
3396 rs6000_explicit_options.float_gprs = true;
3397 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3398 rs6000_float_gprs = 1;
3399 else if (! strcmp (arg, "double"))
3400 rs6000_float_gprs = 2;
3401 else if (! strcmp (arg, "no"))
3402 rs6000_float_gprs = 0;
3405 error ("invalid option for -mfloat-gprs: '%s'", arg);
3410 case OPT_mlong_double_:
3411 rs6000_explicit_options.long_double = true;
3412 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3413 if (value != 64 && value != 128)
3415 error ("Unknown switch -mlong-double-%s", arg);
3416 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3420 rs6000_long_double_type_size = value;
3423 case OPT_msched_costly_dep_:
3424 rs6000_sched_costly_dep_str = arg;
3428 rs6000_explicit_options.alignment = true;
3429 if (! strcmp (arg, "power"))
3431 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3432 some C library functions, so warn about it. The flag may be
3433 useful for performance studies from time to time though, so
3434 don't disable it entirely. */
3435 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3436 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3437 " it is incompatible with the installed C and C++ libraries");
3438 rs6000_alignment_flags = MASK_ALIGN_POWER;
3440 else if (! strcmp (arg, "natural"))
3441 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3444 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3449 case OPT_msingle_float:
3450 if (!TARGET_SINGLE_FPU)
3451 warning (0, "-msingle-float option equivalent to -mhard-float");
3452 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3453 rs6000_double_float = 0;
3454 target_flags &= ~MASK_SOFT_FLOAT;
3455 target_flags_explicit |= MASK_SOFT_FLOAT;
3458 case OPT_mdouble_float:
3459 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3460 rs6000_single_float = 1;
3461 target_flags &= ~MASK_SOFT_FLOAT;
3462 target_flags_explicit |= MASK_SOFT_FLOAT;
3465 case OPT_msimple_fpu:
3466 if (!TARGET_SINGLE_FPU)
3467 warning (0, "-msimple-fpu option ignored");
3470 case OPT_mhard_float:
3471 /* -mhard_float implies -msingle-float and -mdouble-float. */
3472 rs6000_single_float = rs6000_double_float = 1;
3475 case OPT_msoft_float:
3476 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3477 rs6000_single_float = rs6000_double_float = 0;
3481 fpu_type = rs6000_parse_fpu_option(arg);
3482 if (fpu_type != FPU_NONE)
3483 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3485 target_flags &= ~MASK_SOFT_FLOAT;
3486 target_flags_explicit |= MASK_SOFT_FLOAT;
3487 rs6000_xilinx_fpu = 1;
3488 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3489 rs6000_single_float = 1;
3490 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3491 rs6000_single_float = rs6000_double_float = 1;
3492 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3493 rs6000_simple_fpu = 1;
3497 /* -mfpu=none is equivalent to -msoft-float */
3498 target_flags |= MASK_SOFT_FLOAT;
3499 target_flags_explicit |= MASK_SOFT_FLOAT;
3500 rs6000_single_float = rs6000_double_float = 0;
3507 /* Do anything needed at the start of the asm file. */
3510 rs6000_file_start (void)
3514 const char *start = buffer;
3515 struct rs6000_cpu_select *ptr;
3516 const char *default_cpu = TARGET_CPU_DEFAULT;
3517 FILE *file = asm_out_file;
3519 default_file_start ();
3521 #ifdef TARGET_BI_ARCH
3522 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3526 if (flag_verbose_asm)
3528 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3529 rs6000_select[0].string = default_cpu;
3531 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3533 ptr = &rs6000_select[i];
3534 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
3536 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
3541 if (PPC405_ERRATUM77)
3543 fprintf (file, "%s PPC405CR_ERRATUM77", start);
3547 #ifdef USING_ELFOS_H
3548 switch (rs6000_sdata)
3550 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
3551 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
3552 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
3553 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
3556 if (rs6000_sdata && g_switch_value)
3558 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
3568 #ifdef HAVE_AS_GNU_ATTRIBUTE
3569 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
3571 fprintf (file, "\t.gnu_attribute 4, %d\n",
3572 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
3573 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
3575 fprintf (file, "\t.gnu_attribute 8, %d\n",
3576 (TARGET_ALTIVEC_ABI ? 2
3577 : TARGET_SPE_ABI ? 3
3579 fprintf (file, "\t.gnu_attribute 12, %d\n",
3580 aix_struct_return ? 2 : 1);
3585 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
3587 switch_to_section (toc_section);
3588 switch_to_section (text_section);
3593 /* Return nonzero if this function is known to have a null epilogue. */
3596 direct_return (void)
3598 if (reload_completed)
3600 rs6000_stack_t *info = rs6000_stack_info ();
3602 if (info->first_gp_reg_save == 32
3603 && info->first_fp_reg_save == 64
3604 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
3605 && ! info->lr_save_p
3606 && ! info->cr_save_p
3607 && info->vrsave_mask == 0
3615 /* Return the number of instructions it takes to form a constant in an
3616 integer register. */
3619 num_insns_constant_wide (HOST_WIDE_INT value)
3621 /* signed constant loadable with {cal|addi} */
3622 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
3625 /* constant loadable with {cau|addis} */
3626 else if ((value & 0xffff) == 0
3627 && (value >> 31 == -1 || value >> 31 == 0))
3630 #if HOST_BITS_PER_WIDE_INT == 64
3631 else if (TARGET_POWERPC64)
3633 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
3634 HOST_WIDE_INT high = value >> 31;
3636 if (high == 0 || high == -1)
3642 return num_insns_constant_wide (high) + 1;
3644 return (num_insns_constant_wide (high)
3645 + num_insns_constant_wide (low) + 1);
3654 num_insns_constant (rtx op, enum machine_mode mode)
3656 HOST_WIDE_INT low, high;
3658 switch (GET_CODE (op))
3661 #if HOST_BITS_PER_WIDE_INT == 64
3662 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
3663 && mask64_operand (op, mode))
3667 return num_insns_constant_wide (INTVAL (op));
3670 if (mode == SFmode || mode == SDmode)
3675 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3676 if (DECIMAL_FLOAT_MODE_P (mode))
3677 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
3679 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
3680 return num_insns_constant_wide ((HOST_WIDE_INT) l);
3683 if (mode == VOIDmode || mode == DImode)
3685 high = CONST_DOUBLE_HIGH (op);
3686 low = CONST_DOUBLE_LOW (op);
3693 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3694 if (DECIMAL_FLOAT_MODE_P (mode))
3695 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
3697 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
3698 high = l[WORDS_BIG_ENDIAN == 0];
3699 low = l[WORDS_BIG_ENDIAN != 0];
3703 return (num_insns_constant_wide (low)
3704 + num_insns_constant_wide (high));
3707 if ((high == 0 && low >= 0)
3708 || (high == -1 && low < 0))
3709 return num_insns_constant_wide (low);
3711 else if (mask64_operand (op, mode))
3715 return num_insns_constant_wide (high) + 1;
3718 return (num_insns_constant_wide (high)
3719 + num_insns_constant_wide (low) + 1);
3727 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
3728 If the mode of OP is MODE_VECTOR_INT, this simply returns the
3729 corresponding element of the vector, but for V4SFmode and V2SFmode,
3730 the corresponding "float" is interpreted as an SImode integer. */
3733 const_vector_elt_as_int (rtx op, unsigned int elt)
3735 rtx tmp = CONST_VECTOR_ELT (op, elt);
3736 if (GET_MODE (op) == V4SFmode
3737 || GET_MODE (op) == V2SFmode)
3738 tmp = gen_lowpart (SImode, tmp);
3739 return INTVAL (tmp);
3742 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
3743 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
3744 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
3745 all items are set to the same value and contain COPIES replicas of the
3746 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
3747 operand and the others are set to the value of the operand's msb. */
3750 vspltis_constant (rtx op, unsigned step, unsigned copies)
3752 enum machine_mode mode = GET_MODE (op);
3753 enum machine_mode inner = GET_MODE_INNER (mode);
3756 unsigned nunits = GET_MODE_NUNITS (mode);
3757 unsigned bitsize = GET_MODE_BITSIZE (inner);
3758 unsigned mask = GET_MODE_MASK (inner);
3760 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
3761 HOST_WIDE_INT splat_val = val;
3762 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
3764 /* Construct the value to be splatted, if possible. If not, return 0. */
3765 for (i = 2; i <= copies; i *= 2)
3767 HOST_WIDE_INT small_val;
3769 small_val = splat_val >> bitsize;
3771 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
3773 splat_val = small_val;
3776 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
3777 if (EASY_VECTOR_15 (splat_val))
3780 /* Also check if we can splat, and then add the result to itself. Do so if
3781 the value is positive, of if the splat instruction is using OP's mode;
3782 for splat_val < 0, the splat and the add should use the same mode. */
3783 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
3784 && (splat_val >= 0 || (step == 1 && copies == 1)))
3787 /* Also check if are loading up the most significant bit which can be done by
3788 loading up -1 and shifting the value left by -1. */
3789 else if (EASY_VECTOR_MSB (splat_val, inner))
3795 /* Check if VAL is present in every STEP-th element, and the
3796 other elements are filled with its most significant bit. */
3797 for (i = 0; i < nunits - 1; ++i)
3799 HOST_WIDE_INT desired_val;
3800 if (((i + 1) & (step - 1)) == 0)
3803 desired_val = msb_val;
3805 if (desired_val != const_vector_elt_as_int (op, i))
3813 /* Return true if OP is of the given MODE and can be synthesized
3814 with a vspltisb, vspltish or vspltisw. */
3817 easy_altivec_constant (rtx op, enum machine_mode mode)
3819 unsigned step, copies;
3821 if (mode == VOIDmode)
3822 mode = GET_MODE (op);
3823 else if (mode != GET_MODE (op))
3826 /* Start with a vspltisw. */
3827 step = GET_MODE_NUNITS (mode) / 4;
3830 if (vspltis_constant (op, step, copies))
3833 /* Then try with a vspltish. */
3839 if (vspltis_constant (op, step, copies))
3842 /* And finally a vspltisb. */
3848 if (vspltis_constant (op, step, copies))
3854 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
3855 result is OP. Abort if it is not possible. */
3858 gen_easy_altivec_constant (rtx op)
3860 enum machine_mode mode = GET_MODE (op);
3861 int nunits = GET_MODE_NUNITS (mode);
3862 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
3863 unsigned step = nunits / 4;
3864 unsigned copies = 1;
3866 /* Start with a vspltisw. */
3867 if (vspltis_constant (op, step, copies))
3868 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
3870 /* Then try with a vspltish. */
3876 if (vspltis_constant (op, step, copies))
3877 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
3879 /* And finally a vspltisb. */
3885 if (vspltis_constant (op, step, copies))
3886 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
3892 output_vec_const_move (rtx *operands)
3895 enum machine_mode mode;
3900 mode = GET_MODE (dest);
3902 if (TARGET_VSX && zero_constant (vec, mode))
3903 return "xxlxor %x0,%x0,%x0";
3908 if (zero_constant (vec, mode))
3909 return "vxor %0,%0,%0";
3911 splat_vec = gen_easy_altivec_constant (vec);
3912 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
3913 operands[1] = XEXP (splat_vec, 0);
3914 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
3917 switch (GET_MODE (splat_vec))
3920 return "vspltisw %0,%1";
3923 return "vspltish %0,%1";
3926 return "vspltisb %0,%1";
3933 gcc_assert (TARGET_SPE);
3935 /* Vector constant 0 is handled as a splitter of V2SI, and in the
3936 pattern of V1DI, V4HI, and V2SF.
3938 FIXME: We should probably return # and add post reload
3939 splitters for these, but this way is so easy ;-). */
3940 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
3941 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
3942 operands[1] = CONST_VECTOR_ELT (vec, 0);
3943 operands[2] = CONST_VECTOR_ELT (vec, 1);
3945 return "li %0,%1\n\tevmergelo %0,%0,%0";
3947 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
3950 /* Initialize TARGET of vector PAIRED to VALS. */
3953 paired_expand_vector_init (rtx target, rtx vals)
3955 enum machine_mode mode = GET_MODE (target);
3956 int n_elts = GET_MODE_NUNITS (mode);
3958 rtx x, new_rtx, tmp, constant_op, op1, op2;
3961 for (i = 0; i < n_elts; ++i)
3963 x = XVECEXP (vals, 0, i);
3964 if (!CONSTANT_P (x))
3969 /* Load from constant pool. */
3970 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
3976 /* The vector is initialized only with non-constants. */
3977 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
3978 XVECEXP (vals, 0, 1));
3980 emit_move_insn (target, new_rtx);
3984 /* One field is non-constant and the other one is a constant. Load the
3985 constant from the constant pool and use ps_merge instruction to
3986 construct the whole vector. */
3987 op1 = XVECEXP (vals, 0, 0);
3988 op2 = XVECEXP (vals, 0, 1);
3990 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
3992 tmp = gen_reg_rtx (GET_MODE (constant_op));
3993 emit_move_insn (tmp, constant_op);
3995 if (CONSTANT_P (op1))
3996 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
3998 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4000 emit_move_insn (target, new_rtx);
4004 paired_expand_vector_move (rtx operands[])
4006 rtx op0 = operands[0], op1 = operands[1];
4008 emit_move_insn (op0, op1);
4011 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4012 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4013 operands for the relation operation COND. This is a recursive
4017 paired_emit_vector_compare (enum rtx_code rcode,
4018 rtx dest, rtx op0, rtx op1,
4019 rtx cc_op0, rtx cc_op1)
4021 rtx tmp = gen_reg_rtx (V2SFmode);
4022 rtx tmp1, max, min, equal_zero;
4024 gcc_assert (TARGET_PAIRED_FLOAT);
4025 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4031 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4035 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4036 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4040 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4043 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4046 tmp1 = gen_reg_rtx (V2SFmode);
4047 max = gen_reg_rtx (V2SFmode);
4048 min = gen_reg_rtx (V2SFmode);
4049 equal_zero = gen_reg_rtx (V2SFmode);
4051 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4052 emit_insn (gen_selv2sf4
4053 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4054 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4055 emit_insn (gen_selv2sf4
4056 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4057 emit_insn (gen_subv2sf3 (tmp1, min, max));
4058 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4061 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4064 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4067 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4070 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4073 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4082 /* Emit vector conditional expression.
4083 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4084 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4087 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4088 rtx cond, rtx cc_op0, rtx cc_op1)
4090 enum rtx_code rcode = GET_CODE (cond);
4092 if (!TARGET_PAIRED_FLOAT)
4095 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4100 /* Initialize vector TARGET to VALS. */
4103 rs6000_expand_vector_init (rtx target, rtx vals)
4105 enum machine_mode mode = GET_MODE (target);
4106 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4107 int n_elts = GET_MODE_NUNITS (mode);
4108 int n_var = 0, one_var = -1;
4109 bool all_same = true, all_const_zero = true;
4113 for (i = 0; i < n_elts; ++i)
4115 x = XVECEXP (vals, 0, i);
4116 if (!CONSTANT_P (x))
4117 ++n_var, one_var = i;
4118 else if (x != CONST0_RTX (inner_mode))
4119 all_const_zero = false;
4121 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4127 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4128 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4129 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4131 /* Zero register. */
4132 emit_insn (gen_rtx_SET (VOIDmode, target,
4133 gen_rtx_XOR (mode, target, target)));
4136 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4138 /* Splat immediate. */
4139 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4144 /* Load from constant pool. */
4145 emit_move_insn (target, const_vec);
4150 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4151 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4155 rtx element = XVECEXP (vals, 0, 0);
4156 if (mode == V2DFmode)
4157 emit_insn (gen_vsx_splat_v2df (target, element));
4159 emit_insn (gen_vsx_splat_v2di (target, element));
4163 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4164 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4165 if (mode == V2DFmode)
4166 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4168 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4173 /* With single precision floating point on VSX, know that internally single
4174 precision is actually represented as a double, and either make 2 V2DF
4175 vectors, and convert these vectors to single precision, or do one
4176 conversion, and splat the result to the other elements. */
4177 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4181 rtx freg = gen_reg_rtx (V4SFmode);
4182 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4184 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4185 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4189 rtx dbl_even = gen_reg_rtx (V2DFmode);
4190 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4191 rtx flt_even = gen_reg_rtx (V4SFmode);
4192 rtx flt_odd = gen_reg_rtx (V4SFmode);
4194 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4195 copy_to_reg (XVECEXP (vals, 0, 0)),
4196 copy_to_reg (XVECEXP (vals, 0, 1))));
4197 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4198 copy_to_reg (XVECEXP (vals, 0, 2)),
4199 copy_to_reg (XVECEXP (vals, 0, 3))));
4200 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4201 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4202 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4207 /* Store value to stack temp. Load vector element. Splat. However, splat
4208 of 64-bit items is not supported on Altivec. */
4209 if (all_same && GET_MODE_SIZE (mode) <= 4)
4211 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4212 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4213 XVECEXP (vals, 0, 0));
4214 x = gen_rtx_UNSPEC (VOIDmode,
4215 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4216 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4218 gen_rtx_SET (VOIDmode,
4221 x = gen_rtx_VEC_SELECT (inner_mode, target,
4222 gen_rtx_PARALLEL (VOIDmode,
4223 gen_rtvec (1, const0_rtx)));
4224 emit_insn (gen_rtx_SET (VOIDmode, target,
4225 gen_rtx_VEC_DUPLICATE (mode, x)));
4229 /* One field is non-constant. Load constant then overwrite
4233 rtx copy = copy_rtx (vals);
4235 /* Load constant part of vector, substitute neighboring value for
4237 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4238 rs6000_expand_vector_init (target, copy);
4240 /* Insert variable. */
4241 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4245 /* Construct the vector in memory one field at a time
4246 and load the whole vector. */
4247 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4248 for (i = 0; i < n_elts; i++)
4249 emit_move_insn (adjust_address_nv (mem, inner_mode,
4250 i * GET_MODE_SIZE (inner_mode)),
4251 XVECEXP (vals, 0, i));
4252 emit_move_insn (target, mem);
4255 /* Set field ELT of TARGET to VAL. */
4258 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4260 enum machine_mode mode = GET_MODE (target);
4261 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4262 rtx reg = gen_reg_rtx (mode);
4264 int width = GET_MODE_SIZE (inner_mode);
4267 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4269 rtx (*set_func) (rtx, rtx, rtx, rtx)
4270 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4271 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4275 /* Load single variable value. */
4276 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4277 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4278 x = gen_rtx_UNSPEC (VOIDmode,
4279 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4280 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4282 gen_rtx_SET (VOIDmode,
4286 /* Linear sequence. */
4287 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4288 for (i = 0; i < 16; ++i)
4289 XVECEXP (mask, 0, i) = GEN_INT (i);
4291 /* Set permute mask to insert element into target. */
4292 for (i = 0; i < width; ++i)
4293 XVECEXP (mask, 0, elt*width + i)
4294 = GEN_INT (i + 0x10);
4295 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4296 x = gen_rtx_UNSPEC (mode,
4297 gen_rtvec (3, target, reg,
4298 force_reg (V16QImode, x)),
4300 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4303 /* Extract field ELT from VEC into TARGET. */
4306 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4308 enum machine_mode mode = GET_MODE (vec);
4309 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4312 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4314 rtx (*extract_func) (rtx, rtx, rtx)
4315 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4316 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4320 /* Allocate mode-sized buffer. */
4321 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4323 /* Add offset to field within buffer matching vector element. */
4324 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4326 /* Store single field into mode-sized buffer. */
4327 x = gen_rtx_UNSPEC (VOIDmode,
4328 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4329 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4331 gen_rtx_SET (VOIDmode,
4334 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4337 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4338 implement ANDing by the mask IN. */
4340 build_mask64_2_operands (rtx in, rtx *out)
4342 #if HOST_BITS_PER_WIDE_INT >= 64
4343 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4346 gcc_assert (GET_CODE (in) == CONST_INT);
4351 /* Assume c initially something like 0x00fff000000fffff. The idea
4352 is to rotate the word so that the middle ^^^^^^ group of zeros
4353 is at the MS end and can be cleared with an rldicl mask. We then
4354 rotate back and clear off the MS ^^ group of zeros with a
4356 c = ~c; /* c == 0xff000ffffff00000 */
4357 lsb = c & -c; /* lsb == 0x0000000000100000 */
4358 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4359 c = ~c; /* c == 0x00fff000000fffff */
4360 c &= -lsb; /* c == 0x00fff00000000000 */
4361 lsb = c & -c; /* lsb == 0x0000100000000000 */
4362 c = ~c; /* c == 0xff000fffffffffff */
4363 c &= -lsb; /* c == 0xff00000000000000 */
4365 while ((lsb >>= 1) != 0)
4366 shift++; /* shift == 44 on exit from loop */
4367 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4368 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4369 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4373 /* Assume c initially something like 0xff000f0000000000. The idea
4374 is to rotate the word so that the ^^^ middle group of zeros
4375 is at the LS end and can be cleared with an rldicr mask. We then
4376 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4378 lsb = c & -c; /* lsb == 0x0000010000000000 */
4379 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4380 c = ~c; /* c == 0x00fff0ffffffffff */
4381 c &= -lsb; /* c == 0x00fff00000000000 */
4382 lsb = c & -c; /* lsb == 0x0000100000000000 */
4383 c = ~c; /* c == 0xff000fffffffffff */
4384 c &= -lsb; /* c == 0xff00000000000000 */
4386 while ((lsb >>= 1) != 0)
4387 shift++; /* shift == 44 on exit from loop */
4388 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4389 m1 >>= shift; /* m1 == 0x0000000000000fff */
4390 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4393 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4394 masks will be all 1's. We are guaranteed more than one transition. */
4395 out[0] = GEN_INT (64 - shift);
4396 out[1] = GEN_INT (m1);
4397 out[2] = GEN_INT (shift);
4398 out[3] = GEN_INT (m2);
4406 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4409 invalid_e500_subreg (rtx op, enum machine_mode mode)
4411 if (TARGET_E500_DOUBLE)
4413 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4414 subreg:TI and reg:TF. Decimal float modes are like integer
4415 modes (only low part of each register used) for this
4417 if (GET_CODE (op) == SUBREG
4418 && (mode == SImode || mode == DImode || mode == TImode
4419 || mode == DDmode || mode == TDmode)
4420 && REG_P (SUBREG_REG (op))
4421 && (GET_MODE (SUBREG_REG (op)) == DFmode
4422 || GET_MODE (SUBREG_REG (op)) == TFmode))
4425 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4427 if (GET_CODE (op) == SUBREG
4428 && (mode == DFmode || mode == TFmode)
4429 && REG_P (SUBREG_REG (op))
4430 && (GET_MODE (SUBREG_REG (op)) == DImode
4431 || GET_MODE (SUBREG_REG (op)) == TImode
4432 || GET_MODE (SUBREG_REG (op)) == DDmode
4433 || GET_MODE (SUBREG_REG (op)) == TDmode))
4438 && GET_CODE (op) == SUBREG
4440 && REG_P (SUBREG_REG (op))
4441 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4447 /* AIX increases natural record alignment to doubleword if the first
4448 field is an FP double while the FP fields remain word aligned. */
4451 rs6000_special_round_type_align (tree type, unsigned int computed,
4452 unsigned int specified)
4454 unsigned int align = MAX (computed, specified);
4455 tree field = TYPE_FIELDS (type);
4457 /* Skip all non field decls */
4458 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4459 field = TREE_CHAIN (field);
4461 if (field != NULL && field != type)
4463 type = TREE_TYPE (field);
4464 while (TREE_CODE (type) == ARRAY_TYPE)
4465 type = TREE_TYPE (type);
4467 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4468 align = MAX (align, 64);
4474 /* Darwin increases record alignment to the natural alignment of
4478 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4479 unsigned int specified)
4481 unsigned int align = MAX (computed, specified);
4483 if (TYPE_PACKED (type))
4486 /* Find the first field, looking down into aggregates. */
4488 tree field = TYPE_FIELDS (type);
4489 /* Skip all non field decls */
4490 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4491 field = TREE_CHAIN (field);
4494 type = TREE_TYPE (field);
4495 while (TREE_CODE (type) == ARRAY_TYPE)
4496 type = TREE_TYPE (type);
4497 } while (AGGREGATE_TYPE_P (type));
4499 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
4500 align = MAX (align, TYPE_ALIGN (type));
4505 /* Return 1 for an operand in small memory on V.4/eabi. */
4508 small_data_operand (rtx op ATTRIBUTE_UNUSED,
4509 enum machine_mode mode ATTRIBUTE_UNUSED)
4514 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
4517 if (DEFAULT_ABI != ABI_V4)
4520 /* Vector and float memory instructions have a limited offset on the
4521 SPE, so using a vector or float variable directly as an operand is
4524 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
4527 if (GET_CODE (op) == SYMBOL_REF)
4530 else if (GET_CODE (op) != CONST
4531 || GET_CODE (XEXP (op, 0)) != PLUS
4532 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
4533 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
4538 rtx sum = XEXP (op, 0);
4539 HOST_WIDE_INT summand;
4541 /* We have to be careful here, because it is the referenced address
4542 that must be 32k from _SDA_BASE_, not just the symbol. */
4543 summand = INTVAL (XEXP (sum, 1));
4544 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
4547 sym_ref = XEXP (sum, 0);
4550 return SYMBOL_REF_SMALL_P (sym_ref);
4556 /* Return true if either operand is a general purpose register. */
4559 gpr_or_gpr_p (rtx op0, rtx op1)
4561 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
4562 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
4566 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
4569 reg_offset_addressing_ok_p (enum machine_mode mode)
4579 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
4580 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
4588 /* Paired vector modes. Only reg+reg addressing is valid. */
4589 if (TARGET_PAIRED_FLOAT)
4601 virtual_stack_registers_memory_p (rtx op)
4605 if (GET_CODE (op) == REG)
4606 regnum = REGNO (op);
4608 else if (GET_CODE (op) == PLUS
4609 && GET_CODE (XEXP (op, 0)) == REG
4610 && GET_CODE (XEXP (op, 1)) == CONST_INT)
4611 regnum = REGNO (XEXP (op, 0));
4616 return (regnum >= FIRST_VIRTUAL_REGISTER
4617 && regnum <= LAST_VIRTUAL_REGISTER);
4621 constant_pool_expr_p (rtx op)
4625 split_const (op, &base, &offset);
4626 return (GET_CODE (base) == SYMBOL_REF
4627 && CONSTANT_POOL_ADDRESS_P (base)
4628 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
4632 toc_relative_expr_p (rtx op)
4636 if (GET_CODE (op) != CONST)
4639 split_const (op, &base, &offset);
4640 return (GET_CODE (base) == UNSPEC
4641 && XINT (base, 1) == UNSPEC_TOCREL);
4645 legitimate_constant_pool_address_p (rtx x)
4648 && GET_CODE (x) == PLUS
4649 && GET_CODE (XEXP (x, 0)) == REG
4650 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
4651 && toc_relative_expr_p (XEXP (x, 1)));
4655 legitimate_small_data_p (enum machine_mode mode, rtx x)
4657 return (DEFAULT_ABI == ABI_V4
4658 && !flag_pic && !TARGET_TOC
4659 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
4660 && small_data_operand (x, mode));
4663 /* SPE offset addressing is limited to 5-bits worth of double words. */
4664 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
4667 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
4669 unsigned HOST_WIDE_INT offset, extra;
4671 if (GET_CODE (x) != PLUS)
4673 if (GET_CODE (XEXP (x, 0)) != REG)
4675 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4677 if (!reg_offset_addressing_ok_p (mode))
4678 return virtual_stack_registers_memory_p (x);
4679 if (legitimate_constant_pool_address_p (x))
4681 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4684 offset = INTVAL (XEXP (x, 1));
4692 /* SPE vector modes. */
4693 return SPE_CONST_OFFSET_OK (offset);
4696 if (TARGET_E500_DOUBLE)
4697 return SPE_CONST_OFFSET_OK (offset);
4699 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
4701 if (VECTOR_MEM_VSX_P (DFmode))
4706 /* On e500v2, we may have:
4708 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
4710 Which gets addressed with evldd instructions. */
4711 if (TARGET_E500_DOUBLE)
4712 return SPE_CONST_OFFSET_OK (offset);
4714 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
4716 else if (offset & 3)
4721 if (TARGET_E500_DOUBLE)
4722 return (SPE_CONST_OFFSET_OK (offset)
4723 && SPE_CONST_OFFSET_OK (offset + 8));
4727 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
4729 else if (offset & 3)
4740 return (offset < 0x10000) && (offset + extra < 0x10000);
4744 legitimate_indexed_address_p (rtx x, int strict)
4748 if (GET_CODE (x) != PLUS)
4754 /* Recognize the rtl generated by reload which we know will later be
4755 replaced with proper base and index regs. */
4757 && reload_in_progress
4758 && (REG_P (op0) || GET_CODE (op0) == PLUS)
4762 return (REG_P (op0) && REG_P (op1)
4763 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
4764 && INT_REG_OK_FOR_INDEX_P (op1, strict))
4765 || (INT_REG_OK_FOR_BASE_P (op1, strict)
4766 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
4770 avoiding_indexed_address_p (enum machine_mode mode)
4772 /* Avoid indexed addressing for modes that have non-indexed
4773 load/store instruction forms. */
4774 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
4778 legitimate_indirect_address_p (rtx x, int strict)
4780 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
4784 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
4786 if (!TARGET_MACHO || !flag_pic
4787 || mode != SImode || GET_CODE (x) != MEM)
4791 if (GET_CODE (x) != LO_SUM)
4793 if (GET_CODE (XEXP (x, 0)) != REG)
4795 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
4799 return CONSTANT_P (x);
4803 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
4805 if (GET_CODE (x) != LO_SUM)
4807 if (GET_CODE (XEXP (x, 0)) != REG)
4809 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4811 /* Restrict addressing for DI because of our SUBREG hackery. */
4812 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4813 || mode == DDmode || mode == TDmode
4818 if (TARGET_ELF || TARGET_MACHO)
4820 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
4824 if (GET_MODE_NUNITS (mode) != 1)
4826 if (GET_MODE_BITSIZE (mode) > 64
4827 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
4828 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4829 && (mode == DFmode || mode == DDmode))))
4832 return CONSTANT_P (x);
4839 /* Try machine-dependent ways of modifying an illegitimate address
4840 to be legitimate. If we find one, return the new, valid address.
4841 This is used from only one place: `memory_address' in explow.c.
4843 OLDX is the address as it was before break_out_memory_refs was
4844 called. In some cases it is useful to look at this to decide what
4847 It is always safe for this function to do nothing. It exists to
4848 recognize opportunities to optimize the output.
4850 On RS/6000, first check for the sum of a register with a constant
4851 integer that is out of range. If so, generate code to add the
4852 constant with the low-order 16 bits masked to the register and force
4853 this result into another register (this can be done with `cau').
4854 Then generate an address of REG+(CONST&0xffff), allowing for the
4855 possibility of bit 16 being a one.
4857 Then check for the sum of a register and something not constant, try to
4858 load the other things into a register and return the sum. */
4861 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
4862 enum machine_mode mode)
4864 unsigned int extra = 0;
4866 if (!reg_offset_addressing_ok_p (mode))
4868 if (virtual_stack_registers_memory_p (x))
4871 /* In theory we should not be seeing addresses of the form reg+0,
4872 but just in case it is generated, optimize it away. */
4873 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
4874 return force_reg (Pmode, XEXP (x, 0));
4876 /* Make sure both operands are registers. */
4877 else if (GET_CODE (x) == PLUS)
4878 return gen_rtx_PLUS (Pmode,
4879 force_reg (Pmode, XEXP (x, 0)),
4880 force_reg (Pmode, XEXP (x, 1)));
4882 return force_reg (Pmode, x);
4884 if (GET_CODE (x) == SYMBOL_REF)
4886 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
4888 return rs6000_legitimize_tls_address (x, model);
4898 if (!TARGET_POWERPC64)
4906 extra = TARGET_POWERPC64 ? 8 : 12;
4912 if (GET_CODE (x) == PLUS
4913 && GET_CODE (XEXP (x, 0)) == REG
4914 && GET_CODE (XEXP (x, 1)) == CONST_INT
4915 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
4917 && !((TARGET_POWERPC64
4918 && (mode == DImode || mode == TImode)
4919 && (INTVAL (XEXP (x, 1)) & 3) != 0)
4920 || SPE_VECTOR_MODE (mode)
4921 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4922 || mode == DImode || mode == DDmode
4923 || mode == TDmode))))
4925 HOST_WIDE_INT high_int, low_int;
4927 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
4928 if (low_int >= 0x8000 - extra)
4930 high_int = INTVAL (XEXP (x, 1)) - low_int;
4931 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
4932 GEN_INT (high_int)), 0);
4933 return plus_constant (sum, low_int);
4935 else if (GET_CODE (x) == PLUS
4936 && GET_CODE (XEXP (x, 0)) == REG
4937 && GET_CODE (XEXP (x, 1)) != CONST_INT
4938 && GET_MODE_NUNITS (mode) == 1
4939 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
4941 || ((mode != DImode && mode != DFmode && mode != DDmode)
4942 || (TARGET_E500_DOUBLE && mode != DDmode)))
4943 && (TARGET_POWERPC64 || mode != DImode)
4944 && !avoiding_indexed_address_p (mode)
4949 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
4950 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
4952 else if (SPE_VECTOR_MODE (mode)
4953 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4954 || mode == DDmode || mode == TDmode
4955 || mode == DImode)))
4959 /* We accept [reg + reg] and [reg + OFFSET]. */
4961 if (GET_CODE (x) == PLUS)
4963 rtx op1 = XEXP (x, 0);
4964 rtx op2 = XEXP (x, 1);
4967 op1 = force_reg (Pmode, op1);
4969 if (GET_CODE (op2) != REG
4970 && (GET_CODE (op2) != CONST_INT
4971 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
4972 || (GET_MODE_SIZE (mode) > 8
4973 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
4974 op2 = force_reg (Pmode, op2);
4976 /* We can't always do [reg + reg] for these, because [reg +
4977 reg + offset] is not a legitimate addressing mode. */
4978 y = gen_rtx_PLUS (Pmode, op1, op2);
4980 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
4981 return force_reg (Pmode, y);
4986 return force_reg (Pmode, x);
4992 && GET_CODE (x) != CONST_INT
4993 && GET_CODE (x) != CONST_DOUBLE
4995 && GET_MODE_NUNITS (mode) == 1
4996 && (GET_MODE_BITSIZE (mode) <= 32
4997 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
4998 && (mode == DFmode || mode == DDmode))))
5000 rtx reg = gen_reg_rtx (Pmode);
5001 emit_insn (gen_elf_high (reg, x));
5002 return gen_rtx_LO_SUM (Pmode, reg, x);
5004 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5007 && ! MACHO_DYNAMIC_NO_PIC_P
5009 && GET_CODE (x) != CONST_INT
5010 && GET_CODE (x) != CONST_DOUBLE
5012 && GET_MODE_NUNITS (mode) == 1
5013 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5014 || (mode != DFmode && mode != DDmode))
5018 rtx reg = gen_reg_rtx (Pmode);
5019 emit_insn (gen_macho_high (reg, x));
5020 return gen_rtx_LO_SUM (Pmode, reg, x);
5023 && GET_CODE (x) == SYMBOL_REF
5024 && constant_pool_expr_p (x)
5025 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5027 return create_TOC_reference (x);
5033 /* Debug version of rs6000_legitimize_address. */
5035 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5041 ret = rs6000_legitimize_address (x, oldx, mode);
5042 insns = get_insns ();
5048 "\nrs6000_legitimize_address: mode %s, old code %s, "
5049 "new code %s, modified\n",
5050 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5051 GET_RTX_NAME (GET_CODE (ret)));
5053 fprintf (stderr, "Original address:\n");
5056 fprintf (stderr, "oldx:\n");
5059 fprintf (stderr, "New address:\n");
5064 fprintf (stderr, "Insns added:\n");
5065 debug_rtx_list (insns, 20);
5071 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5072 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5083 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5084 We need to emit DTP-relative relocations. */
5087 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5092 fputs ("\t.long\t", file);
5095 fputs (DOUBLE_INT_ASM_OP, file);
5100 output_addr_const (file, x);
5101 fputs ("@dtprel+0x8000", file);
5104 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5106 static GTY(()) rtx rs6000_tls_symbol;
5108 rs6000_tls_get_addr (void)
5110 if (!rs6000_tls_symbol)
5111 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5113 return rs6000_tls_symbol;
5116 /* Construct the SYMBOL_REF for TLS GOT references. */
5118 static GTY(()) rtx rs6000_got_symbol;
5120 rs6000_got_sym (void)
5122 if (!rs6000_got_symbol)
5124 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5125 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5126 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5129 return rs6000_got_symbol;
5132 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5133 this (thread-local) address. */
5136 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5140 dest = gen_reg_rtx (Pmode);
5141 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5147 tlsreg = gen_rtx_REG (Pmode, 13);
5148 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5152 tlsreg = gen_rtx_REG (Pmode, 2);
5153 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5157 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5161 tmp = gen_reg_rtx (Pmode);
5164 tlsreg = gen_rtx_REG (Pmode, 13);
5165 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5169 tlsreg = gen_rtx_REG (Pmode, 2);
5170 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5174 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5176 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5181 rtx r3, got, tga, tmp1, tmp2, eqv;
5183 /* We currently use relocations like @got@tlsgd for tls, which
5184 means the linker will handle allocation of tls entries, placing
5185 them in the .got section. So use a pointer to the .got section,
5186 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5187 or to secondary GOT sections used by 32-bit -fPIC. */
5189 got = gen_rtx_REG (Pmode, 2);
5193 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5196 rtx gsym = rs6000_got_sym ();
5197 got = gen_reg_rtx (Pmode);
5199 rs6000_emit_move (got, gsym, Pmode);
5205 tmp1 = gen_reg_rtx (Pmode);
5206 tmp2 = gen_reg_rtx (Pmode);
5207 tmp3 = gen_reg_rtx (Pmode);
5208 mem = gen_const_mem (Pmode, tmp1);
5210 first = emit_insn (gen_load_toc_v4_PIC_1b (gsym));
5211 emit_move_insn (tmp1,
5212 gen_rtx_REG (Pmode, LR_REGNO));
5213 emit_move_insn (tmp2, mem);
5214 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
5215 last = emit_move_insn (got, tmp3);
5216 set_unique_reg_note (last, REG_EQUAL, gsym);
5221 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5223 r3 = gen_rtx_REG (Pmode, 3);
5224 tga = rs6000_tls_get_addr ();
5226 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5227 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5228 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5229 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5230 else if (DEFAULT_ABI == ABI_V4)
5231 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5236 insn = emit_call_insn (insn);
5237 RTL_CONST_CALL_P (insn) = 1;
5238 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5239 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5240 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5241 insn = get_insns ();
5243 emit_libcall_block (insn, dest, r3, addr);
5245 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5247 r3 = gen_rtx_REG (Pmode, 3);
5248 tga = rs6000_tls_get_addr ();
5250 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5251 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5252 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5253 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5254 else if (DEFAULT_ABI == ABI_V4)
5255 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5260 insn = emit_call_insn (insn);
5261 RTL_CONST_CALL_P (insn) = 1;
5262 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5263 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5264 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5265 insn = get_insns ();
5267 tmp1 = gen_reg_rtx (Pmode);
5268 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
5270 emit_libcall_block (insn, tmp1, r3, eqv);
5271 if (rs6000_tls_size == 16)
5274 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5276 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5278 else if (rs6000_tls_size == 32)
5280 tmp2 = gen_reg_rtx (Pmode);
5282 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5284 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5287 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5289 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5293 tmp2 = gen_reg_rtx (Pmode);
5295 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5297 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5299 insn = gen_rtx_SET (Pmode, dest,
5300 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5306 /* IE, or 64-bit offset LE. */
5307 tmp2 = gen_reg_rtx (Pmode);
5309 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5311 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5314 insn = gen_tls_tls_64 (dest, tmp2, addr);
5316 insn = gen_tls_tls_32 (dest, tmp2, addr);
5324 /* Return 1 if X contains a thread-local symbol. */
5327 rs6000_tls_referenced_p (rtx x)
5329 if (! TARGET_HAVE_TLS)
5332 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5335 /* Return 1 if *X is a thread-local symbol. This is the same as
5336 rs6000_tls_symbol_ref except for the type of the unused argument. */
5339 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5341 return RS6000_SYMBOL_REF_TLS_P (*x);
5344 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5345 replace the input X, or the original X if no replacement is called for.
5346 The output parameter *WIN is 1 if the calling macro should goto WIN,
5349 For RS/6000, we wish to handle large displacements off a base
5350 register by splitting the addend across an addiu/addis and the mem insn.
5351 This cuts number of extra insns needed from 3 to 1.
5353 On Darwin, we use this to generate code for floating point constants.
5354 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5355 The Darwin code is inside #if TARGET_MACHO because only then are the
5356 machopic_* functions defined. */
5358 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5359 int opnum, int type,
5360 int ind_levels ATTRIBUTE_UNUSED, int *win)
5362 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5364 /* We must recognize output that we have already generated ourselves. */
5365 if (GET_CODE (x) == PLUS
5366 && GET_CODE (XEXP (x, 0)) == PLUS
5367 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5368 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5369 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5371 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5372 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5373 opnum, (enum reload_type)type);
5379 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5380 && GET_CODE (x) == LO_SUM
5381 && GET_CODE (XEXP (x, 0)) == PLUS
5382 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5383 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5384 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5385 && machopic_operand_p (XEXP (x, 1)))
5387 /* Result of previous invocation of this function on Darwin
5388 floating point constant. */
5389 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5390 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5391 opnum, (enum reload_type)type);
5397 /* Force ld/std non-word aligned offset into base register by wrapping
5399 if (GET_CODE (x) == PLUS
5400 && GET_CODE (XEXP (x, 0)) == REG
5401 && REGNO (XEXP (x, 0)) < 32
5402 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5403 && GET_CODE (XEXP (x, 1)) == CONST_INT
5405 && (INTVAL (XEXP (x, 1)) & 3) != 0
5406 && VECTOR_MEM_NONE_P (mode)
5407 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5408 && TARGET_POWERPC64)
5410 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5411 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5412 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5413 opnum, (enum reload_type) type);
5418 if (GET_CODE (x) == PLUS
5419 && GET_CODE (XEXP (x, 0)) == REG
5420 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5421 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5422 && GET_CODE (XEXP (x, 1)) == CONST_INT
5424 && !SPE_VECTOR_MODE (mode)
5425 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5426 || mode == DDmode || mode == TDmode
5428 && VECTOR_MEM_NONE_P (mode))
5430 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5431 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5433 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5435 /* Check for 32-bit overflow. */
5436 if (high + low != val)
5442 /* Reload the high part into a base reg; leave the low part
5443 in the mem directly. */
5445 x = gen_rtx_PLUS (GET_MODE (x),
5446 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5450 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5451 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5452 opnum, (enum reload_type)type);
5457 if (GET_CODE (x) == SYMBOL_REF
5459 && VECTOR_MEM_NONE_P (mode)
5460 && !SPE_VECTOR_MODE (mode)
5462 && DEFAULT_ABI == ABI_DARWIN
5463 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
5465 && DEFAULT_ABI == ABI_V4
5468 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
5469 The same goes for DImode without 64-bit gprs and DFmode and DDmode
5473 && (mode != DImode || TARGET_POWERPC64)
5474 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
5475 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
5480 rtx offset = machopic_gen_offset (x);
5481 x = gen_rtx_LO_SUM (GET_MODE (x),
5482 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
5483 gen_rtx_HIGH (Pmode, offset)), offset);
5487 x = gen_rtx_LO_SUM (GET_MODE (x),
5488 gen_rtx_HIGH (Pmode, x), x);
5490 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5491 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5492 opnum, (enum reload_type)type);
5497 /* Reload an offset address wrapped by an AND that represents the
5498 masking of the lower bits. Strip the outer AND and let reload
5499 convert the offset address into an indirect address. For VSX,
5500 force reload to create the address with an AND in a separate
5501 register, because we can't guarantee an altivec register will
5503 if (VECTOR_MEM_ALTIVEC_P (mode)
5504 && GET_CODE (x) == AND
5505 && GET_CODE (XEXP (x, 0)) == PLUS
5506 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5507 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5508 && GET_CODE (XEXP (x, 1)) == CONST_INT
5509 && INTVAL (XEXP (x, 1)) == -16)
5518 && GET_CODE (x) == SYMBOL_REF
5519 && constant_pool_expr_p (x)
5520 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
5522 x = create_TOC_reference (x);
5530 /* Debug version of rs6000_legitimize_reload_address. */
5532 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
5533 int opnum, int type,
5534 int ind_levels, int *win)
5536 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
5539 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
5540 "type = %d, ind_levels = %d, win = %d, original addr:\n",
5541 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
5545 fprintf (stderr, "Same address returned\n");
5547 fprintf (stderr, "NULL returned\n");
5550 fprintf (stderr, "New address:\n");
5557 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
5558 that is a valid memory address for an instruction.
5559 The MODE argument is the machine mode for the MEM expression
5560 that wants to use this address.
5562 On the RS/6000, there are four valid address: a SYMBOL_REF that
5563 refers to a constant pool entry of an address (or the sum of it
5564 plus a constant), a short (16-bit signed) constant plus a register,
5565 the sum of two registers, or a register indirect, possibly with an
5566 auto-increment. For DFmode, DDmode and DImode with a constant plus
5567 register, we must ensure that both words are addressable or PowerPC64
5568 with offset word aligned.
5570 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
5571 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
5572 because adjacent memory cells are accessed by adding word-sized offsets
5573 during assembly output. */
5575 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
5577 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5579 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
5580 if (VECTOR_MEM_ALTIVEC_P (mode)
5581 && GET_CODE (x) == AND
5582 && GET_CODE (XEXP (x, 1)) == CONST_INT
5583 && INTVAL (XEXP (x, 1)) == -16)
5586 if (RS6000_SYMBOL_REF_TLS_P (x))
5588 if (legitimate_indirect_address_p (x, reg_ok_strict))
5590 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
5591 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5592 && !SPE_VECTOR_MODE (mode)
5595 /* Restrict addressing for DI because of our SUBREG hackery. */
5596 && !(TARGET_E500_DOUBLE
5597 && (mode == DFmode || mode == DDmode || mode == DImode))
5599 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
5601 if (virtual_stack_registers_memory_p (x))
5603 if (reg_offset_p && legitimate_small_data_p (mode, x))
5605 if (reg_offset_p && legitimate_constant_pool_address_p (x))
5607 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
5610 && GET_CODE (x) == PLUS
5611 && GET_CODE (XEXP (x, 0)) == REG
5612 && (XEXP (x, 0) == virtual_stack_vars_rtx
5613 || XEXP (x, 0) == arg_pointer_rtx)
5614 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5616 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
5621 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5623 || (mode != DFmode && mode != DDmode)
5624 || (TARGET_E500_DOUBLE && mode != DDmode))
5625 && (TARGET_POWERPC64 || mode != DImode)
5626 && !avoiding_indexed_address_p (mode)
5627 && legitimate_indexed_address_p (x, reg_ok_strict))
5629 if (GET_CODE (x) == PRE_MODIFY
5630 && VECTOR_MEM_VSX_P (mode)
5632 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)
5633 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5635 if (GET_CODE (x) == PRE_MODIFY
5639 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5641 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
5642 && (TARGET_POWERPC64 || mode != DImode)
5643 && !VECTOR_MEM_ALTIVEC_P (mode)
5644 && !SPE_VECTOR_MODE (mode)
5645 /* Restrict addressing for DI because of our SUBREG hackery. */
5646 && !(TARGET_E500_DOUBLE
5647 && (mode == DFmode || mode == DDmode || mode == DImode))
5649 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
5650 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
5651 || (!avoiding_indexed_address_p (mode)
5652 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
5653 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5655 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
5660 /* Debug version of rs6000_legitimate_address_p. */
5662 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
5665 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
5667 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
5668 "strict = %d, code = %s\n",
5669 ret ? "true" : "false",
5670 GET_MODE_NAME (mode),
5672 GET_RTX_NAME (GET_CODE (x)));
5678 /* Go to LABEL if ADDR (a legitimate address expression)
5679 has an effect that depends on the machine mode it is used for.
5681 On the RS/6000 this is true of all integral offsets (since AltiVec
5682 and VSX modes don't allow them) or is a pre-increment or decrement.
5684 ??? Except that due to conceptual problems in offsettable_address_p
5685 we can't really report the problems of integral offsets. So leave
5686 this assuming that the adjustable offset must be valid for the
5687 sub-words of a TFmode operand, which is what we had before. */
5690 rs6000_mode_dependent_address (rtx addr)
5692 switch (GET_CODE (addr))
5695 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
5696 is considered a legitimate address before reload, so there
5697 are no offset restrictions in that case. Note that this
5698 condition is safe in strict mode because any address involving
5699 virtual_stack_vars_rtx or arg_pointer_rtx would already have
5700 been rejected as illegitimate. */
5701 if (XEXP (addr, 0) != virtual_stack_vars_rtx
5702 && XEXP (addr, 0) != arg_pointer_rtx
5703 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5705 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
5706 return val + 12 + 0x8000 >= 0x10000;
5713 /* Auto-increment cases are now treated generically in recog.c. */
5715 return TARGET_UPDATE;
5717 /* AND is only allowed in Altivec loads. */
5728 /* Debug version of rs6000_mode_dependent_address. */
5730 rs6000_debug_mode_dependent_address (rtx addr)
5732 bool ret = rs6000_mode_dependent_address (addr);
5734 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
5735 ret ? "true" : "false");
5741 /* Implement FIND_BASE_TERM. */
5744 rs6000_find_base_term (rtx op)
5748 split_const (op, &base, &offset);
5749 if (GET_CODE (base) == UNSPEC)
5750 switch (XINT (base, 1))
5753 case UNSPEC_MACHOPIC_OFFSET:
5754 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
5755 for aliasing purposes. */
5756 return XVECEXP (base, 0, 0);
5762 /* More elaborate version of recog's offsettable_memref_p predicate
5763 that works around the ??? note of rs6000_mode_dependent_address.
5764 In particular it accepts
5766 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
5768 in 32-bit mode, that the recog predicate rejects. */
5771 rs6000_offsettable_memref_p (rtx op)
5776 /* First mimic offsettable_memref_p. */
5777 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
5780 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
5781 the latter predicate knows nothing about the mode of the memory
5782 reference and, therefore, assumes that it is the largest supported
5783 mode (TFmode). As a consequence, legitimate offsettable memory
5784 references are rejected. rs6000_legitimate_offset_address_p contains
5785 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
5786 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
5789 /* Change register usage conditional on target flags. */
5791 rs6000_conditional_register_usage (void)
5795 /* Set MQ register fixed (already call_used) if not POWER
5796 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
5801 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
5803 fixed_regs[13] = call_used_regs[13]
5804 = call_really_used_regs[13] = 1;
5806 /* Conditionally disable FPRs. */
5807 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
5808 for (i = 32; i < 64; i++)
5809 fixed_regs[i] = call_used_regs[i]
5810 = call_really_used_regs[i] = 1;
5812 /* The TOC register is not killed across calls in a way that is
5813 visible to the compiler. */
5814 if (DEFAULT_ABI == ABI_AIX)
5815 call_really_used_regs[2] = 0;
5817 if (DEFAULT_ABI == ABI_V4
5818 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
5820 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5822 if (DEFAULT_ABI == ABI_V4
5823 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
5825 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5826 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5827 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5829 if (DEFAULT_ABI == ABI_DARWIN
5830 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
5831 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5832 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5833 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5835 if (TARGET_TOC && TARGET_MINIMAL_TOC)
5836 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5837 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5841 global_regs[SPEFSCR_REGNO] = 1;
5842 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
5843 registers in prologues and epilogues. We no longer use r14
5844 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
5845 pool for link-compatibility with older versions of GCC. Once
5846 "old" code has died out, we can return r14 to the allocation
5849 = call_used_regs[14]
5850 = call_really_used_regs[14] = 1;
5853 if (!TARGET_ALTIVEC && !TARGET_VSX)
5855 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
5856 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
5857 call_really_used_regs[VRSAVE_REGNO] = 1;
5860 if (TARGET_ALTIVEC || TARGET_VSX)
5861 global_regs[VSCR_REGNO] = 1;
5863 if (TARGET_ALTIVEC_ABI)
5865 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
5866 call_used_regs[i] = call_really_used_regs[i] = 1;
5868 /* AIX reserves VR20:31 in non-extended ABI mode. */
5870 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
5871 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
5875 /* Try to output insns to set TARGET equal to the constant C if it can
5876 be done in less than N insns. Do all computations in MODE.
5877 Returns the place where the output has been placed if it can be
5878 done and the insns have been emitted. If it would take more than N
5879 insns, zero is returned and no insns and emitted. */
5882 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
5883 rtx source, int n ATTRIBUTE_UNUSED)
5885 rtx result, insn, set;
5886 HOST_WIDE_INT c0, c1;
5893 dest = gen_reg_rtx (mode);
5894 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
5898 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
5900 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
5901 GEN_INT (INTVAL (source)
5902 & (~ (HOST_WIDE_INT) 0xffff))));
5903 emit_insn (gen_rtx_SET (VOIDmode, dest,
5904 gen_rtx_IOR (SImode, copy_rtx (result),
5905 GEN_INT (INTVAL (source) & 0xffff))));
5910 switch (GET_CODE (source))
5913 c0 = INTVAL (source);
5918 #if HOST_BITS_PER_WIDE_INT >= 64
5919 c0 = CONST_DOUBLE_LOW (source);
5922 c0 = CONST_DOUBLE_LOW (source);
5923 c1 = CONST_DOUBLE_HIGH (source);
5931 result = rs6000_emit_set_long_const (dest, c0, c1);
5938 insn = get_last_insn ();
5939 set = single_set (insn);
5940 if (! CONSTANT_P (SET_SRC (set)))
5941 set_unique_reg_note (insn, REG_EQUAL, source);
5946 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
5947 fall back to a straight forward decomposition. We do this to avoid
5948 exponential run times encountered when looking for longer sequences
5949 with rs6000_emit_set_const. */
5951 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
5953 if (!TARGET_POWERPC64)
5955 rtx operand1, operand2;
5957 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
5959 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
5961 emit_move_insn (operand1, GEN_INT (c1));
5962 emit_move_insn (operand2, GEN_INT (c2));
5966 HOST_WIDE_INT ud1, ud2, ud3, ud4;
5969 ud2 = (c1 & 0xffff0000) >> 16;
5970 #if HOST_BITS_PER_WIDE_INT >= 64
5974 ud4 = (c2 & 0xffff0000) >> 16;
5976 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
5977 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
5980 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
5982 emit_move_insn (dest, GEN_INT (ud1));
5985 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
5986 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
5989 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
5992 emit_move_insn (dest, GEN_INT (ud2 << 16));
5994 emit_move_insn (copy_rtx (dest),
5995 gen_rtx_IOR (DImode, copy_rtx (dest),
5998 else if ((ud4 == 0xffff && (ud3 & 0x8000))
5999 || (ud4 == 0 && ! (ud3 & 0x8000)))
6002 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6005 emit_move_insn (dest, GEN_INT (ud3 << 16));
6008 emit_move_insn (copy_rtx (dest),
6009 gen_rtx_IOR (DImode, copy_rtx (dest),
6011 emit_move_insn (copy_rtx (dest),
6012 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6015 emit_move_insn (copy_rtx (dest),
6016 gen_rtx_IOR (DImode, copy_rtx (dest),
6022 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6025 emit_move_insn (dest, GEN_INT (ud4 << 16));
6028 emit_move_insn (copy_rtx (dest),
6029 gen_rtx_IOR (DImode, copy_rtx (dest),
6032 emit_move_insn (copy_rtx (dest),
6033 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6036 emit_move_insn (copy_rtx (dest),
6037 gen_rtx_IOR (DImode, copy_rtx (dest),
6038 GEN_INT (ud2 << 16)));
6040 emit_move_insn (copy_rtx (dest),
6041 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6047 /* Helper for the following. Get rid of [r+r] memory refs
6048 in cases where it won't work (TImode, TFmode, TDmode). */
6051 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6053 if (GET_CODE (operands[0]) == MEM
6054 && GET_CODE (XEXP (operands[0], 0)) != REG
6055 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
6056 && ! reload_in_progress)
6058 = replace_equiv_address (operands[0],
6059 copy_addr_to_reg (XEXP (operands[0], 0)));
6061 if (GET_CODE (operands[1]) == MEM
6062 && GET_CODE (XEXP (operands[1], 0)) != REG
6063 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
6064 && ! reload_in_progress)
6066 = replace_equiv_address (operands[1],
6067 copy_addr_to_reg (XEXP (operands[1], 0)));
6070 /* Emit a move from SOURCE to DEST in mode MODE. */
6072 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6076 operands[1] = source;
6078 if (TARGET_DEBUG_ADDR)
6081 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6082 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6083 GET_MODE_NAME (mode),
6086 can_create_pseudo_p ());
6088 fprintf (stderr, "source:\n");
6092 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6093 if (GET_CODE (operands[1]) == CONST_DOUBLE
6094 && ! FLOAT_MODE_P (mode)
6095 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6097 /* FIXME. This should never happen. */
6098 /* Since it seems that it does, do the safe thing and convert
6100 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6102 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6103 || FLOAT_MODE_P (mode)
6104 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6105 || CONST_DOUBLE_LOW (operands[1]) < 0)
6106 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6107 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6109 /* Check if GCC is setting up a block move that will end up using FP
6110 registers as temporaries. We must make sure this is acceptable. */
6111 if (GET_CODE (operands[0]) == MEM
6112 && GET_CODE (operands[1]) == MEM
6114 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6115 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6116 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6117 ? 32 : MEM_ALIGN (operands[0])))
6118 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6120 : MEM_ALIGN (operands[1]))))
6121 && ! MEM_VOLATILE_P (operands [0])
6122 && ! MEM_VOLATILE_P (operands [1]))
6124 emit_move_insn (adjust_address (operands[0], SImode, 0),
6125 adjust_address (operands[1], SImode, 0));
6126 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6127 adjust_address (copy_rtx (operands[1]), SImode, 4));
6131 /* Fix up invalid (const (plus (symbol_ref) (reg))) that seems to be created
6132 in the secondary_reload phase, which evidently overwrites the CONST_INT
6134 if (GET_CODE (source) == CONST && GET_CODE (XEXP (source, 0)) == PLUS
6137 rtx add_op0 = XEXP (XEXP (source, 0), 0);
6138 rtx add_op1 = XEXP (XEXP (source, 0), 1);
6140 if (GET_CODE (add_op0) == SYMBOL_REF && GET_CODE (add_op1) == REG)
6142 rtx tmp = (can_create_pseudo_p ()) ? gen_reg_rtx (Pmode) : dest;
6144 if (TARGET_DEBUG_ADDR)
6146 fprintf (stderr, "\nrs6000_emit_move: bad source\n");
6150 rs6000_emit_move (tmp, add_op0, Pmode);
6151 emit_insn (gen_rtx_SET (VOIDmode, dest,
6152 gen_rtx_PLUS (Pmode, tmp, add_op1)));
6157 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6158 && !gpc_reg_operand (operands[1], mode))
6159 operands[1] = force_reg (mode, operands[1]);
6161 if (mode == SFmode && ! TARGET_POWERPC
6162 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6163 && GET_CODE (operands[0]) == MEM)
6167 if (reload_in_progress || reload_completed)
6168 regnum = true_regnum (operands[1]);
6169 else if (GET_CODE (operands[1]) == REG)
6170 regnum = REGNO (operands[1]);
6174 /* If operands[1] is a register, on POWER it may have
6175 double-precision data in it, so truncate it to single
6177 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6180 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6181 : gen_reg_rtx (mode));
6182 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6183 operands[1] = newreg;
6187 /* Recognize the case where operand[1] is a reference to thread-local
6188 data and load its address to a register. */
6189 if (rs6000_tls_referenced_p (operands[1]))
6191 enum tls_model model;
6192 rtx tmp = operands[1];
6195 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6197 addend = XEXP (XEXP (tmp, 0), 1);
6198 tmp = XEXP (XEXP (tmp, 0), 0);
6201 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6202 model = SYMBOL_REF_TLS_MODEL (tmp);
6203 gcc_assert (model != 0);
6205 tmp = rs6000_legitimize_tls_address (tmp, model);
6208 tmp = gen_rtx_PLUS (mode, tmp, addend);
6209 tmp = force_operand (tmp, operands[0]);
6214 /* Handle the case where reload calls us with an invalid address. */
6215 if (reload_in_progress && mode == Pmode
6216 && (! general_operand (operands[1], mode)
6217 || ! nonimmediate_operand (operands[0], mode)))
6220 /* 128-bit constant floating-point values on Darwin should really be
6221 loaded as two parts. */
6222 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6223 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6225 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6226 know how to get a DFmode SUBREG of a TFmode. */
6227 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6228 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6229 simplify_gen_subreg (imode, operands[1], mode, 0),
6231 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6232 GET_MODE_SIZE (imode)),
6233 simplify_gen_subreg (imode, operands[1], mode,
6234 GET_MODE_SIZE (imode)),
6239 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6240 cfun->machine->sdmode_stack_slot =
6241 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6243 if (reload_in_progress
6245 && MEM_P (operands[0])
6246 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6247 && REG_P (operands[1]))
6249 if (FP_REGNO_P (REGNO (operands[1])))
6251 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6252 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6253 emit_insn (gen_movsd_store (mem, operands[1]));
6255 else if (INT_REGNO_P (REGNO (operands[1])))
6257 rtx mem = adjust_address_nv (operands[0], mode, 4);
6258 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6259 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6265 if (reload_in_progress
6267 && REG_P (operands[0])
6268 && MEM_P (operands[1])
6269 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6271 if (FP_REGNO_P (REGNO (operands[0])))
6273 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6274 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6275 emit_insn (gen_movsd_load (operands[0], mem));
6277 else if (INT_REGNO_P (REGNO (operands[0])))
6279 rtx mem = adjust_address_nv (operands[1], mode, 4);
6280 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6281 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6288 /* FIXME: In the long term, this switch statement should go away
6289 and be replaced by a sequence of tests based on things like
6295 if (CONSTANT_P (operands[1])
6296 && GET_CODE (operands[1]) != CONST_INT)
6297 operands[1] = force_const_mem (mode, operands[1]);
6302 rs6000_eliminate_indexed_memrefs (operands);
6309 if (CONSTANT_P (operands[1])
6310 && ! easy_fp_constant (operands[1], mode))
6311 operands[1] = force_const_mem (mode, operands[1]);
6324 if (CONSTANT_P (operands[1])
6325 && !easy_vector_constant (operands[1], mode))
6326 operands[1] = force_const_mem (mode, operands[1]);
6331 /* Use default pattern for address of ELF small data */
6334 && DEFAULT_ABI == ABI_V4
6335 && (GET_CODE (operands[1]) == SYMBOL_REF
6336 || GET_CODE (operands[1]) == CONST)
6337 && small_data_operand (operands[1], mode))
6339 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6343 if (DEFAULT_ABI == ABI_V4
6344 && mode == Pmode && mode == SImode
6345 && flag_pic == 1 && got_operand (operands[1], mode))
6347 emit_insn (gen_movsi_got (operands[0], operands[1]));
6351 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6355 && CONSTANT_P (operands[1])
6356 && GET_CODE (operands[1]) != HIGH
6357 && GET_CODE (operands[1]) != CONST_INT)
6359 rtx target = (!can_create_pseudo_p ()
6361 : gen_reg_rtx (mode));
6363 /* If this is a function address on -mcall-aixdesc,
6364 convert it to the address of the descriptor. */
6365 if (DEFAULT_ABI == ABI_AIX
6366 && GET_CODE (operands[1]) == SYMBOL_REF
6367 && XSTR (operands[1], 0)[0] == '.')
6369 const char *name = XSTR (operands[1], 0);
6371 while (*name == '.')
6373 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6374 CONSTANT_POOL_ADDRESS_P (new_ref)
6375 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6376 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6377 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6378 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6379 operands[1] = new_ref;
6382 if (DEFAULT_ABI == ABI_DARWIN)
6385 if (MACHO_DYNAMIC_NO_PIC_P)
6387 /* Take care of any required data indirection. */
6388 operands[1] = rs6000_machopic_legitimize_pic_address (
6389 operands[1], mode, operands[0]);
6390 if (operands[0] != operands[1])
6391 emit_insn (gen_rtx_SET (VOIDmode,
6392 operands[0], operands[1]));
6396 emit_insn (gen_macho_high (target, operands[1]));
6397 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6401 emit_insn (gen_elf_high (target, operands[1]));
6402 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6406 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6407 and we have put it in the TOC, we just need to make a TOC-relative
6410 && GET_CODE (operands[1]) == SYMBOL_REF
6411 && constant_pool_expr_p (operands[1])
6412 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6413 get_pool_mode (operands[1])))
6415 operands[1] = create_TOC_reference (operands[1]);
6417 else if (mode == Pmode
6418 && CONSTANT_P (operands[1])
6419 && ((GET_CODE (operands[1]) != CONST_INT
6420 && ! easy_fp_constant (operands[1], mode))
6421 || (GET_CODE (operands[1]) == CONST_INT
6422 && num_insns_constant (operands[1], mode) > 2)
6423 || (GET_CODE (operands[0]) == REG
6424 && FP_REGNO_P (REGNO (operands[0]))))
6425 && GET_CODE (operands[1]) != HIGH
6426 && ! legitimate_constant_pool_address_p (operands[1])
6427 && ! toc_relative_expr_p (operands[1]))
6431 /* Darwin uses a special PIC legitimizer. */
6432 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
6435 rs6000_machopic_legitimize_pic_address (operands[1], mode,
6437 if (operands[0] != operands[1])
6438 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6443 /* If we are to limit the number of things we put in the TOC and
6444 this is a symbol plus a constant we can add in one insn,
6445 just put the symbol in the TOC and add the constant. Don't do
6446 this if reload is in progress. */
6447 if (GET_CODE (operands[1]) == CONST
6448 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
6449 && GET_CODE (XEXP (operands[1], 0)) == PLUS
6450 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
6451 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
6452 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
6453 && ! side_effects_p (operands[0]))
6456 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
6457 rtx other = XEXP (XEXP (operands[1], 0), 1);
6459 sym = force_reg (mode, sym);
6461 emit_insn (gen_addsi3 (operands[0], sym, other));
6463 emit_insn (gen_adddi3 (operands[0], sym, other));
6467 operands[1] = force_const_mem (mode, operands[1]);
6470 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6471 && constant_pool_expr_p (XEXP (operands[1], 0))
6472 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
6473 get_pool_constant (XEXP (operands[1], 0)),
6474 get_pool_mode (XEXP (operands[1], 0))))
6477 = gen_const_mem (mode,
6478 create_TOC_reference (XEXP (operands[1], 0)));
6479 set_mem_alias_set (operands[1], get_TOC_alias_set ());
6485 rs6000_eliminate_indexed_memrefs (operands);
6489 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6491 gen_rtx_SET (VOIDmode,
6492 operands[0], operands[1]),
6493 gen_rtx_CLOBBER (VOIDmode,
6494 gen_rtx_SCRATCH (SImode)))));
6500 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
6503 /* Above, we may have called force_const_mem which may have returned
6504 an invalid address. If we can, fix this up; otherwise, reload will
6505 have to deal with it. */
6506 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
6507 operands[1] = validize_mem (operands[1]);
6510 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6513 /* Nonzero if we can use a floating-point register to pass this arg. */
6514 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
6515 (SCALAR_FLOAT_MODE_P (MODE) \
6516 && (CUM)->fregno <= FP_ARG_MAX_REG \
6517 && TARGET_HARD_FLOAT && TARGET_FPRS)
6519 /* Nonzero if we can use an AltiVec register to pass this arg. */
6520 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
6521 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
6522 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
6523 && TARGET_ALTIVEC_ABI \
6526 /* Return a nonzero value to say to return the function value in
6527 memory, just as large structures are always returned. TYPE will be
6528 the data type of the value, and FNTYPE will be the type of the
6529 function doing the returning, or @code{NULL} for libcalls.
6531 The AIX ABI for the RS/6000 specifies that all structures are
6532 returned in memory. The Darwin ABI does the same. The SVR4 ABI
6533 specifies that structures <= 8 bytes are returned in r3/r4, but a
6534 draft put them in memory, and GCC used to implement the draft
6535 instead of the final standard. Therefore, aix_struct_return
6536 controls this instead of DEFAULT_ABI; V.4 targets needing backward
6537 compatibility can change DRAFT_V4_STRUCT_RET to override the
6538 default, and -m switches get the final word. See
6539 rs6000_override_options for more details.
6541 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
6542 long double support is enabled. These values are returned in memory.
6544 int_size_in_bytes returns -1 for variable size objects, which go in
6545 memory always. The cast to unsigned makes -1 > 8. */
6548 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6550 /* In the darwin64 abi, try to use registers for larger structs
6552 if (rs6000_darwin64_abi
6553 && TREE_CODE (type) == RECORD_TYPE
6554 && int_size_in_bytes (type) > 0)
6556 CUMULATIVE_ARGS valcum;
6560 valcum.fregno = FP_ARG_MIN_REG;
6561 valcum.vregno = ALTIVEC_ARG_MIN_REG;
6562 /* Do a trial code generation as if this were going to be passed
6563 as an argument; if any part goes in memory, we return NULL. */
6564 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
6567 /* Otherwise fall through to more conventional ABI rules. */
6570 if (AGGREGATE_TYPE_P (type)
6571 && (aix_struct_return
6572 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
6575 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6576 modes only exist for GCC vector types if -maltivec. */
6577 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
6578 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6581 /* Return synthetic vectors in memory. */
6582 if (TREE_CODE (type) == VECTOR_TYPE
6583 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
6585 static bool warned_for_return_big_vectors = false;
6586 if (!warned_for_return_big_vectors)
6588 warning (0, "GCC vector returned by reference: "
6589 "non-standard ABI extension with no compatibility guarantee");
6590 warned_for_return_big_vectors = true;
6595 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
6601 /* Initialize a variable CUM of type CUMULATIVE_ARGS
6602 for a call to a function whose data type is FNTYPE.
6603 For a library call, FNTYPE is 0.
6605 For incoming args we set the number of arguments in the prototype large
6606 so we never return a PARALLEL. */
6609 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
6610 rtx libname ATTRIBUTE_UNUSED, int incoming,
6611 int libcall, int n_named_args)
6613 static CUMULATIVE_ARGS zero_cumulative;
6615 *cum = zero_cumulative;
6617 cum->fregno = FP_ARG_MIN_REG;
6618 cum->vregno = ALTIVEC_ARG_MIN_REG;
6619 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
6620 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
6621 ? CALL_LIBCALL : CALL_NORMAL);
6622 cum->sysv_gregno = GP_ARG_MIN_REG;
6623 cum->stdarg = fntype
6624 && (TYPE_ARG_TYPES (fntype) != 0
6625 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
6626 != void_type_node));
6628 cum->nargs_prototype = 0;
6629 if (incoming || cum->prototype)
6630 cum->nargs_prototype = n_named_args;
6632 /* Check for a longcall attribute. */
6633 if ((!fntype && rs6000_default_long_calls)
6635 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
6636 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
6637 cum->call_cookie |= CALL_LONG;
6639 if (TARGET_DEBUG_ARG)
6641 fprintf (stderr, "\ninit_cumulative_args:");
6644 tree ret_type = TREE_TYPE (fntype);
6645 fprintf (stderr, " ret code = %s,",
6646 tree_code_name[ (int)TREE_CODE (ret_type) ]);
6649 if (cum->call_cookie & CALL_LONG)
6650 fprintf (stderr, " longcall,");
6652 fprintf (stderr, " proto = %d, nargs = %d\n",
6653 cum->prototype, cum->nargs_prototype);
6658 && TARGET_ALTIVEC_ABI
6659 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
6661 error ("cannot return value in vector register because"
6662 " altivec instructions are disabled, use -maltivec"
6667 /* Return true if TYPE must be passed on the stack and not in registers. */
6670 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
6672 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
6673 return must_pass_in_stack_var_size (mode, type);
6675 return must_pass_in_stack_var_size_or_pad (mode, type);
6678 /* If defined, a C expression which determines whether, and in which
6679 direction, to pad out an argument with extra space. The value
6680 should be of type `enum direction': either `upward' to pad above
6681 the argument, `downward' to pad below, or `none' to inhibit
6684 For the AIX ABI structs are always stored left shifted in their
6688 function_arg_padding (enum machine_mode mode, const_tree type)
6690 #ifndef AGGREGATE_PADDING_FIXED
6691 #define AGGREGATE_PADDING_FIXED 0
6693 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
6694 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
6697 if (!AGGREGATE_PADDING_FIXED)
6699 /* GCC used to pass structures of the same size as integer types as
6700 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
6701 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6702 passed padded downward, except that -mstrict-align further
6703 muddied the water in that multi-component structures of 2 and 4
6704 bytes in size were passed padded upward.
6706 The following arranges for best compatibility with previous
6707 versions of gcc, but removes the -mstrict-align dependency. */
6708 if (BYTES_BIG_ENDIAN)
6710 HOST_WIDE_INT size = 0;
6712 if (mode == BLKmode)
6714 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
6715 size = int_size_in_bytes (type);
6718 size = GET_MODE_SIZE (mode);
6720 if (size == 1 || size == 2 || size == 4)
6726 if (AGGREGATES_PAD_UPWARD_ALWAYS)
6728 if (type != 0 && AGGREGATE_TYPE_P (type))
6732 /* Fall back to the default. */
6733 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
6736 /* If defined, a C expression that gives the alignment boundary, in bits,
6737 of an argument with the specified mode and type. If it is not defined,
6738 PARM_BOUNDARY is used for all arguments.
6740 V.4 wants long longs and doubles to be double word aligned. Just
6741 testing the mode size is a boneheaded way to do this as it means
6742 that other types such as complex int are also double word aligned.
6743 However, we're stuck with this because changing the ABI might break
6744 existing library interfaces.
6746 Doubleword align SPE vectors.
6747 Quadword align Altivec vectors.
6748 Quadword align large synthetic vector types. */
6751 function_arg_boundary (enum machine_mode mode, tree type)
6753 if (DEFAULT_ABI == ABI_V4
6754 && (GET_MODE_SIZE (mode) == 8
6755 || (TARGET_HARD_FLOAT
6757 && (mode == TFmode || mode == TDmode))))
6759 else if (SPE_VECTOR_MODE (mode)
6760 || (type && TREE_CODE (type) == VECTOR_TYPE
6761 && int_size_in_bytes (type) >= 8
6762 && int_size_in_bytes (type) < 16))
6764 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
6765 || (type && TREE_CODE (type) == VECTOR_TYPE
6766 && int_size_in_bytes (type) >= 16))
6768 else if (rs6000_darwin64_abi && mode == BLKmode
6769 && type && TYPE_ALIGN (type) > 64)
6772 return PARM_BOUNDARY;
6775 /* For a function parm of MODE and TYPE, return the starting word in
6776 the parameter area. NWORDS of the parameter area are already used. */
6779 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
6782 unsigned int parm_offset;
6784 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
6785 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
6786 return nwords + (-(parm_offset + nwords) & align);
6789 /* Compute the size (in words) of a function argument. */
6791 static unsigned long
6792 rs6000_arg_size (enum machine_mode mode, tree type)
6796 if (mode != BLKmode)
6797 size = GET_MODE_SIZE (mode);
6799 size = int_size_in_bytes (type);
6802 return (size + 3) >> 2;
6804 return (size + 7) >> 3;
6807 /* Use this to flush pending int fields. */
6810 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
6811 HOST_WIDE_INT bitpos)
6813 unsigned int startbit, endbit;
6814 int intregs, intoffset;
6815 enum machine_mode mode;
6817 if (cum->intoffset == -1)
6820 intoffset = cum->intoffset;
6821 cum->intoffset = -1;
6823 if (intoffset % BITS_PER_WORD != 0)
6825 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
6827 if (mode == BLKmode)
6829 /* We couldn't find an appropriate mode, which happens,
6830 e.g., in packed structs when there are 3 bytes to load.
6831 Back intoffset back to the beginning of the word in this
6833 intoffset = intoffset & -BITS_PER_WORD;
6837 startbit = intoffset & -BITS_PER_WORD;
6838 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
6839 intregs = (endbit - startbit) / BITS_PER_WORD;
6840 cum->words += intregs;
6843 /* The darwin64 ABI calls for us to recurse down through structs,
6844 looking for elements passed in registers. Unfortunately, we have
6845 to track int register count here also because of misalignments
6846 in powerpc alignment mode. */
6849 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
6851 HOST_WIDE_INT startbitpos)
6855 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
6856 if (TREE_CODE (f) == FIELD_DECL)
6858 HOST_WIDE_INT bitpos = startbitpos;
6859 tree ftype = TREE_TYPE (f);
6860 enum machine_mode mode;
6861 if (ftype == error_mark_node)
6863 mode = TYPE_MODE (ftype);
6865 if (DECL_SIZE (f) != 0
6866 && host_integerp (bit_position (f), 1))
6867 bitpos += int_bit_position (f);
6869 /* ??? FIXME: else assume zero offset. */
6871 if (TREE_CODE (ftype) == RECORD_TYPE)
6872 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
6873 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
6875 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
6876 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
6877 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
6879 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
6881 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
6885 else if (cum->intoffset == -1)
6886 cum->intoffset = bitpos;
6890 /* Update the data in CUM to advance over an argument
6891 of mode MODE and data type TYPE.
6892 (TYPE is null for libcalls where that information may not be available.)
6894 Note that for args passed by reference, function_arg will be called
6895 with MODE and TYPE set to that of the pointer to the arg, not the arg
6899 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
6900 tree type, int named, int depth)
6904 /* Only tick off an argument if we're not recursing. */
6906 cum->nargs_prototype--;
6908 if (TARGET_ALTIVEC_ABI
6909 && (ALTIVEC_VECTOR_MODE (mode)
6910 || VSX_VECTOR_MODE (mode)
6911 || (type && TREE_CODE (type) == VECTOR_TYPE
6912 && int_size_in_bytes (type) == 16)))
6916 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
6919 if (!TARGET_ALTIVEC)
6920 error ("cannot pass argument in vector register because"
6921 " altivec instructions are disabled, use -maltivec"
6924 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
6925 even if it is going to be passed in a vector register.
6926 Darwin does the same for variable-argument functions. */
6927 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6928 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
6938 /* Vector parameters must be 16-byte aligned. This places
6939 them at 2 mod 4 in terms of words in 32-bit mode, since
6940 the parameter save area starts at offset 24 from the
6941 stack. In 64-bit mode, they just have to start on an
6942 even word, since the parameter save area is 16-byte
6943 aligned. Space for GPRs is reserved even if the argument
6944 will be passed in memory. */
6946 align = (2 - cum->words) & 3;
6948 align = cum->words & 1;
6949 cum->words += align + rs6000_arg_size (mode, type);
6951 if (TARGET_DEBUG_ARG)
6953 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
6955 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
6956 cum->nargs_prototype, cum->prototype,
6957 GET_MODE_NAME (mode));
6961 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
6963 && cum->sysv_gregno <= GP_ARG_MAX_REG)
6966 else if (rs6000_darwin64_abi
6968 && TREE_CODE (type) == RECORD_TYPE
6969 && (size = int_size_in_bytes (type)) > 0)
6971 /* Variable sized types have size == -1 and are
6972 treated as if consisting entirely of ints.
6973 Pad to 16 byte boundary if needed. */
6974 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
6975 && (cum->words % 2) != 0)
6977 /* For varargs, we can just go up by the size of the struct. */
6979 cum->words += (size + 7) / 8;
6982 /* It is tempting to say int register count just goes up by
6983 sizeof(type)/8, but this is wrong in a case such as
6984 { int; double; int; } [powerpc alignment]. We have to
6985 grovel through the fields for these too. */
6987 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
6988 rs6000_darwin64_record_arg_advance_flush (cum,
6989 size * BITS_PER_UNIT);
6992 else if (DEFAULT_ABI == ABI_V4)
6994 if (TARGET_HARD_FLOAT && TARGET_FPRS
6995 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
6996 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
6997 || (mode == TFmode && !TARGET_IEEEQUAD)
6998 || mode == SDmode || mode == DDmode || mode == TDmode))
7000 /* _Decimal128 must use an even/odd register pair. This assumes
7001 that the register number is odd when fregno is odd. */
7002 if (mode == TDmode && (cum->fregno % 2) == 1)
7005 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7006 <= FP_ARG_V4_MAX_REG)
7007 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7010 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7011 if (mode == DFmode || mode == TFmode
7012 || mode == DDmode || mode == TDmode)
7013 cum->words += cum->words & 1;
7014 cum->words += rs6000_arg_size (mode, type);
7019 int n_words = rs6000_arg_size (mode, type);
7020 int gregno = cum->sysv_gregno;
7022 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7023 (r7,r8) or (r9,r10). As does any other 2 word item such
7024 as complex int due to a historical mistake. */
7026 gregno += (1 - gregno) & 1;
7028 /* Multi-reg args are not split between registers and stack. */
7029 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7031 /* Long long and SPE vectors are aligned on the stack.
7032 So are other 2 word items such as complex int due to
7033 a historical mistake. */
7035 cum->words += cum->words & 1;
7036 cum->words += n_words;
7039 /* Note: continuing to accumulate gregno past when we've started
7040 spilling to the stack indicates the fact that we've started
7041 spilling to the stack to expand_builtin_saveregs. */
7042 cum->sysv_gregno = gregno + n_words;
7045 if (TARGET_DEBUG_ARG)
7047 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7048 cum->words, cum->fregno);
7049 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7050 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7051 fprintf (stderr, "mode = %4s, named = %d\n",
7052 GET_MODE_NAME (mode), named);
7057 int n_words = rs6000_arg_size (mode, type);
7058 int start_words = cum->words;
7059 int align_words = rs6000_parm_start (mode, type, start_words);
7061 cum->words = align_words + n_words;
7063 if (SCALAR_FLOAT_MODE_P (mode)
7064 && TARGET_HARD_FLOAT && TARGET_FPRS)
7066 /* _Decimal128 must be passed in an even/odd float register pair.
7067 This assumes that the register number is odd when fregno is
7069 if (mode == TDmode && (cum->fregno % 2) == 1)
7071 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7074 if (TARGET_DEBUG_ARG)
7076 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7077 cum->words, cum->fregno);
7078 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7079 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7080 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7081 named, align_words - start_words, depth);
7087 spe_build_register_parallel (enum machine_mode mode, int gregno)
7094 r1 = gen_rtx_REG (DImode, gregno);
7095 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7096 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7100 r1 = gen_rtx_REG (DImode, gregno);
7101 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7102 r3 = gen_rtx_REG (DImode, gregno + 2);
7103 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7104 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7107 r1 = gen_rtx_REG (DImode, gregno);
7108 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7109 r3 = gen_rtx_REG (DImode, gregno + 2);
7110 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7111 r5 = gen_rtx_REG (DImode, gregno + 4);
7112 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7113 r7 = gen_rtx_REG (DImode, gregno + 6);
7114 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7115 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7122 /* Determine where to put a SIMD argument on the SPE. */
7124 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7127 int gregno = cum->sysv_gregno;
7129 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7130 are passed and returned in a pair of GPRs for ABI compatibility. */
7131 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7132 || mode == DCmode || mode == TCmode))
7134 int n_words = rs6000_arg_size (mode, type);
7136 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7138 gregno += (1 - gregno) & 1;
7140 /* Multi-reg args are not split between registers and stack. */
7141 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7144 return spe_build_register_parallel (mode, gregno);
7148 int n_words = rs6000_arg_size (mode, type);
7150 /* SPE vectors are put in odd registers. */
7151 if (n_words == 2 && (gregno & 1) == 0)
7154 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7157 enum machine_mode m = SImode;
7159 r1 = gen_rtx_REG (m, gregno);
7160 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7161 r2 = gen_rtx_REG (m, gregno + 1);
7162 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7163 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7170 if (gregno <= GP_ARG_MAX_REG)
7171 return gen_rtx_REG (mode, gregno);
7177 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7178 structure between cum->intoffset and bitpos to integer registers. */
7181 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7182 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7184 enum machine_mode mode;
7186 unsigned int startbit, endbit;
7187 int this_regno, intregs, intoffset;
7190 if (cum->intoffset == -1)
7193 intoffset = cum->intoffset;
7194 cum->intoffset = -1;
7196 /* If this is the trailing part of a word, try to only load that
7197 much into the register. Otherwise load the whole register. Note
7198 that in the latter case we may pick up unwanted bits. It's not a
7199 problem at the moment but may wish to revisit. */
7201 if (intoffset % BITS_PER_WORD != 0)
7203 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7205 if (mode == BLKmode)
7207 /* We couldn't find an appropriate mode, which happens,
7208 e.g., in packed structs when there are 3 bytes to load.
7209 Back intoffset back to the beginning of the word in this
7211 intoffset = intoffset & -BITS_PER_WORD;
7218 startbit = intoffset & -BITS_PER_WORD;
7219 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7220 intregs = (endbit - startbit) / BITS_PER_WORD;
7221 this_regno = cum->words + intoffset / BITS_PER_WORD;
7223 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7226 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7230 intoffset /= BITS_PER_UNIT;
7233 regno = GP_ARG_MIN_REG + this_regno;
7234 reg = gen_rtx_REG (mode, regno);
7236 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7239 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7243 while (intregs > 0);
7246 /* Recursive workhorse for the following. */
7249 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7250 HOST_WIDE_INT startbitpos, rtx rvec[],
7255 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7256 if (TREE_CODE (f) == FIELD_DECL)
7258 HOST_WIDE_INT bitpos = startbitpos;
7259 tree ftype = TREE_TYPE (f);
7260 enum machine_mode mode;
7261 if (ftype == error_mark_node)
7263 mode = TYPE_MODE (ftype);
7265 if (DECL_SIZE (f) != 0
7266 && host_integerp (bit_position (f), 1))
7267 bitpos += int_bit_position (f);
7269 /* ??? FIXME: else assume zero offset. */
7271 if (TREE_CODE (ftype) == RECORD_TYPE)
7272 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7273 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7278 case SCmode: mode = SFmode; break;
7279 case DCmode: mode = DFmode; break;
7280 case TCmode: mode = TFmode; break;
7284 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7286 = gen_rtx_EXPR_LIST (VOIDmode,
7287 gen_rtx_REG (mode, cum->fregno++),
7288 GEN_INT (bitpos / BITS_PER_UNIT));
7289 if (mode == TFmode || mode == TDmode)
7292 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7294 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7296 = gen_rtx_EXPR_LIST (VOIDmode,
7297 gen_rtx_REG (mode, cum->vregno++),
7298 GEN_INT (bitpos / BITS_PER_UNIT));
7300 else if (cum->intoffset == -1)
7301 cum->intoffset = bitpos;
7305 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7306 the register(s) to be used for each field and subfield of a struct
7307 being passed by value, along with the offset of where the
7308 register's value may be found in the block. FP fields go in FP
7309 register, vector fields go in vector registers, and everything
7310 else goes in int registers, packed as in memory.
7312 This code is also used for function return values. RETVAL indicates
7313 whether this is the case.
7315 Much of this is taken from the SPARC V9 port, which has a similar
7316 calling convention. */
7319 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7320 int named, bool retval)
7322 rtx rvec[FIRST_PSEUDO_REGISTER];
7323 int k = 1, kbase = 1;
7324 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7325 /* This is a copy; modifications are not visible to our caller. */
7326 CUMULATIVE_ARGS copy_cum = *orig_cum;
7327 CUMULATIVE_ARGS *cum = ©_cum;
7329 /* Pad to 16 byte boundary if needed. */
7330 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7331 && (cum->words % 2) != 0)
7338 /* Put entries into rvec[] for individual FP and vector fields, and
7339 for the chunks of memory that go in int regs. Note we start at
7340 element 1; 0 is reserved for an indication of using memory, and
7341 may or may not be filled in below. */
7342 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7343 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7345 /* If any part of the struct went on the stack put all of it there.
7346 This hack is because the generic code for
7347 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7348 parts of the struct are not at the beginning. */
7352 return NULL_RTX; /* doesn't go in registers at all */
7354 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7356 if (k > 1 || cum->use_stack)
7357 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7362 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7365 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7369 rtx rvec[GP_ARG_NUM_REG + 1];
7371 if (align_words >= GP_ARG_NUM_REG)
7374 n_units = rs6000_arg_size (mode, type);
7376 /* Optimize the simple case where the arg fits in one gpr, except in
7377 the case of BLKmode due to assign_parms assuming that registers are
7378 BITS_PER_WORD wide. */
7380 || (n_units == 1 && mode != BLKmode))
7381 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7384 if (align_words + n_units > GP_ARG_NUM_REG)
7385 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7386 using a magic NULL_RTX component.
7387 This is not strictly correct. Only some of the arg belongs in
7388 memory, not all of it. However, the normal scheme using
7389 function_arg_partial_nregs can result in unusual subregs, eg.
7390 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7391 store the whole arg to memory is often more efficient than code
7392 to store pieces, and we know that space is available in the right
7393 place for the whole arg. */
7394 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7399 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7400 rtx off = GEN_INT (i++ * 4);
7401 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7403 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7405 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7408 /* Determine where to put an argument to a function.
7409 Value is zero to push the argument on the stack,
7410 or a hard register in which to store the argument.
7412 MODE is the argument's machine mode.
7413 TYPE is the data type of the argument (as a tree).
7414 This is null for libcalls where that information may
7416 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7417 the preceding args and about the function being called. It is
7418 not modified in this routine.
7419 NAMED is nonzero if this argument is a named parameter
7420 (otherwise it is an extra parameter matching an ellipsis).
7422 On RS/6000 the first eight words of non-FP are normally in registers
7423 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7424 Under V.4, the first 8 FP args are in registers.
7426 If this is floating-point and no prototype is specified, we use
7427 both an FP and integer register (or possibly FP reg and stack). Library
7428 functions (when CALL_LIBCALL is set) always have the proper types for args,
7429 so we can pass the FP value just in one register. emit_library_function
7430 doesn't support PARALLEL anyway.
7432 Note that for args passed by reference, function_arg will be called
7433 with MODE and TYPE set to that of the pointer to the arg, not the arg
7437 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7438 tree type, int named)
7440 enum rs6000_abi abi = DEFAULT_ABI;
7442 /* Return a marker to indicate whether CR1 needs to set or clear the
7443 bit that V.4 uses to say fp args were passed in registers.
7444 Assume that we don't need the marker for software floating point,
7445 or compiler generated library calls. */
7446 if (mode == VOIDmode)
7449 && (cum->call_cookie & CALL_LIBCALL) == 0
7451 || (cum->nargs_prototype < 0
7452 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7454 /* For the SPE, we need to crxor CR6 always. */
7456 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
7457 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
7458 return GEN_INT (cum->call_cookie
7459 | ((cum->fregno == FP_ARG_MIN_REG)
7460 ? CALL_V4_SET_FP_ARGS
7461 : CALL_V4_CLEAR_FP_ARGS));
7464 return GEN_INT (cum->call_cookie);
7467 if (rs6000_darwin64_abi && mode == BLKmode
7468 && TREE_CODE (type) == RECORD_TYPE)
7470 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
7471 if (rslt != NULL_RTX)
7473 /* Else fall through to usual handling. */
7476 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7477 if (TARGET_64BIT && ! cum->prototype)
7479 /* Vector parameters get passed in vector register
7480 and also in GPRs or memory, in absence of prototype. */
7483 align_words = (cum->words + 1) & ~1;
7485 if (align_words >= GP_ARG_NUM_REG)
7491 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7493 return gen_rtx_PARALLEL (mode,
7495 gen_rtx_EXPR_LIST (VOIDmode,
7497 gen_rtx_EXPR_LIST (VOIDmode,
7498 gen_rtx_REG (mode, cum->vregno),
7502 return gen_rtx_REG (mode, cum->vregno);
7503 else if (TARGET_ALTIVEC_ABI
7504 && (ALTIVEC_VECTOR_MODE (mode)
7505 || VSX_VECTOR_MODE (mode)
7506 || (type && TREE_CODE (type) == VECTOR_TYPE
7507 && int_size_in_bytes (type) == 16)))
7509 if (named || abi == ABI_V4)
7513 /* Vector parameters to varargs functions under AIX or Darwin
7514 get passed in memory and possibly also in GPRs. */
7515 int align, align_words, n_words;
7516 enum machine_mode part_mode;
7518 /* Vector parameters must be 16-byte aligned. This places them at
7519 2 mod 4 in terms of words in 32-bit mode, since the parameter
7520 save area starts at offset 24 from the stack. In 64-bit mode,
7521 they just have to start on an even word, since the parameter
7522 save area is 16-byte aligned. */
7524 align = (2 - cum->words) & 3;
7526 align = cum->words & 1;
7527 align_words = cum->words + align;
7529 /* Out of registers? Memory, then. */
7530 if (align_words >= GP_ARG_NUM_REG)
7533 if (TARGET_32BIT && TARGET_POWERPC64)
7534 return rs6000_mixed_function_arg (mode, type, align_words);
7536 /* The vector value goes in GPRs. Only the part of the
7537 value in GPRs is reported here. */
7539 n_words = rs6000_arg_size (mode, type);
7540 if (align_words + n_words > GP_ARG_NUM_REG)
7541 /* Fortunately, there are only two possibilities, the value
7542 is either wholly in GPRs or half in GPRs and half not. */
7545 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
7548 else if (TARGET_SPE_ABI && TARGET_SPE
7549 && (SPE_VECTOR_MODE (mode)
7550 || (TARGET_E500_DOUBLE && (mode == DFmode
7553 || mode == TCmode))))
7554 return rs6000_spe_function_arg (cum, mode, type);
7556 else if (abi == ABI_V4)
7558 if (TARGET_HARD_FLOAT && TARGET_FPRS
7559 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7560 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7561 || (mode == TFmode && !TARGET_IEEEQUAD)
7562 || mode == SDmode || mode == DDmode || mode == TDmode))
7564 /* _Decimal128 must use an even/odd register pair. This assumes
7565 that the register number is odd when fregno is odd. */
7566 if (mode == TDmode && (cum->fregno % 2) == 1)
7569 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7570 <= FP_ARG_V4_MAX_REG)
7571 return gen_rtx_REG (mode, cum->fregno);
7577 int n_words = rs6000_arg_size (mode, type);
7578 int gregno = cum->sysv_gregno;
7580 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7581 (r7,r8) or (r9,r10). As does any other 2 word item such
7582 as complex int due to a historical mistake. */
7584 gregno += (1 - gregno) & 1;
7586 /* Multi-reg args are not split between registers and stack. */
7587 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7590 if (TARGET_32BIT && TARGET_POWERPC64)
7591 return rs6000_mixed_function_arg (mode, type,
7592 gregno - GP_ARG_MIN_REG);
7593 return gen_rtx_REG (mode, gregno);
7598 int align_words = rs6000_parm_start (mode, type, cum->words);
7600 /* _Decimal128 must be passed in an even/odd float register pair.
7601 This assumes that the register number is odd when fregno is odd. */
7602 if (mode == TDmode && (cum->fregno % 2) == 1)
7605 if (USE_FP_FOR_ARG_P (cum, mode, type))
7607 rtx rvec[GP_ARG_NUM_REG + 1];
7611 enum machine_mode fmode = mode;
7612 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
7614 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
7616 /* Currently, we only ever need one reg here because complex
7617 doubles are split. */
7618 gcc_assert (cum->fregno == FP_ARG_MAX_REG
7619 && (fmode == TFmode || fmode == TDmode));
7621 /* Long double or _Decimal128 split over regs and memory. */
7622 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
7625 /* Do we also need to pass this arg in the parameter save
7628 && (cum->nargs_prototype <= 0
7629 || (DEFAULT_ABI == ABI_AIX
7631 && align_words >= GP_ARG_NUM_REG)));
7633 if (!needs_psave && mode == fmode)
7634 return gen_rtx_REG (fmode, cum->fregno);
7639 /* Describe the part that goes in gprs or the stack.
7640 This piece must come first, before the fprs. */
7641 if (align_words < GP_ARG_NUM_REG)
7643 unsigned long n_words = rs6000_arg_size (mode, type);
7645 if (align_words + n_words > GP_ARG_NUM_REG
7646 || (TARGET_32BIT && TARGET_POWERPC64))
7648 /* If this is partially on the stack, then we only
7649 include the portion actually in registers here. */
7650 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
7653 if (align_words + n_words > GP_ARG_NUM_REG)
7654 /* Not all of the arg fits in gprs. Say that it
7655 goes in memory too, using a magic NULL_RTX
7656 component. Also see comment in
7657 rs6000_mixed_function_arg for why the normal
7658 function_arg_partial_nregs scheme doesn't work
7660 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
7664 r = gen_rtx_REG (rmode,
7665 GP_ARG_MIN_REG + align_words);
7666 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
7667 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7669 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
7673 /* The whole arg fits in gprs. */
7674 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7675 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7679 /* It's entirely in memory. */
7680 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7683 /* Describe where this piece goes in the fprs. */
7684 r = gen_rtx_REG (fmode, cum->fregno);
7685 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7687 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7689 else if (align_words < GP_ARG_NUM_REG)
7691 if (TARGET_32BIT && TARGET_POWERPC64)
7692 return rs6000_mixed_function_arg (mode, type, align_words);
7694 if (mode == BLKmode)
7697 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7704 /* For an arg passed partly in registers and partly in memory, this is
7705 the number of bytes passed in registers. For args passed entirely in
7706 registers or entirely in memory, zero. When an arg is described by a
7707 PARALLEL, perhaps using more than one register type, this function
7708 returns the number of bytes used by the first element of the PARALLEL. */
7711 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7712 tree type, bool named)
7717 if (DEFAULT_ABI == ABI_V4)
7720 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
7721 && cum->nargs_prototype >= 0)
7724 /* In this complicated case we just disable the partial_nregs code. */
7725 if (rs6000_darwin64_abi && mode == BLKmode
7726 && TREE_CODE (type) == RECORD_TYPE
7727 && int_size_in_bytes (type) > 0)
7730 align_words = rs6000_parm_start (mode, type, cum->words);
7732 if (USE_FP_FOR_ARG_P (cum, mode, type))
7734 /* If we are passing this arg in the fixed parameter save area
7735 (gprs or memory) as well as fprs, then this function should
7736 return the number of partial bytes passed in the parameter
7737 save area rather than partial bytes passed in fprs. */
7739 && (cum->nargs_prototype <= 0
7740 || (DEFAULT_ABI == ABI_AIX
7742 && align_words >= GP_ARG_NUM_REG)))
7744 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
7745 > FP_ARG_MAX_REG + 1)
7746 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
7747 else if (cum->nargs_prototype >= 0)
7751 if (align_words < GP_ARG_NUM_REG
7752 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
7753 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
7755 if (ret != 0 && TARGET_DEBUG_ARG)
7756 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
7761 /* A C expression that indicates when an argument must be passed by
7762 reference. If nonzero for an argument, a copy of that argument is
7763 made in memory and a pointer to the argument is passed instead of
7764 the argument itself. The pointer is passed in whatever way is
7765 appropriate for passing a pointer to that type.
7767 Under V.4, aggregates and long double are passed by reference.
7769 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
7770 reference unless the AltiVec vector extension ABI is in force.
7772 As an extension to all ABIs, variable sized types are passed by
7776 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
7777 enum machine_mode mode, const_tree type,
7778 bool named ATTRIBUTE_UNUSED)
7780 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
7782 if (TARGET_DEBUG_ARG)
7783 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
7790 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
7792 if (TARGET_DEBUG_ARG)
7793 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
7797 if (int_size_in_bytes (type) < 0)
7799 if (TARGET_DEBUG_ARG)
7800 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
7804 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7805 modes only exist for GCC vector types if -maltivec. */
7806 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
7808 if (TARGET_DEBUG_ARG)
7809 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
7813 /* Pass synthetic vectors in memory. */
7814 if (TREE_CODE (type) == VECTOR_TYPE
7815 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7817 static bool warned_for_pass_big_vectors = false;
7818 if (TARGET_DEBUG_ARG)
7819 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
7820 if (!warned_for_pass_big_vectors)
7822 warning (0, "GCC vector passed by reference: "
7823 "non-standard ABI extension with no compatibility guarantee");
7824 warned_for_pass_big_vectors = true;
7833 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
7836 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
7841 for (i = 0; i < nregs; i++)
7843 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
7844 if (reload_completed)
7846 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
7849 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
7850 i * GET_MODE_SIZE (reg_mode));
7853 tem = replace_equiv_address (tem, XEXP (tem, 0));
7857 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
7861 /* Perform any needed actions needed for a function that is receiving a
7862 variable number of arguments.
7866 MODE and TYPE are the mode and type of the current parameter.
7868 PRETEND_SIZE is a variable that should be set to the amount of stack
7869 that must be pushed by the prolog to pretend that our caller pushed
7872 Normally, this macro will push all remaining incoming registers on the
7873 stack and set PRETEND_SIZE to the length of the registers pushed. */
7876 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7877 tree type, int *pretend_size ATTRIBUTE_UNUSED,
7880 CUMULATIVE_ARGS next_cum;
7881 int reg_size = TARGET_32BIT ? 4 : 8;
7882 rtx save_area = NULL_RTX, mem;
7883 int first_reg_offset;
7886 /* Skip the last named argument. */
7888 function_arg_advance (&next_cum, mode, type, 1, 0);
7890 if (DEFAULT_ABI == ABI_V4)
7892 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
7896 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
7897 HOST_WIDE_INT offset = 0;
7899 /* Try to optimize the size of the varargs save area.
7900 The ABI requires that ap.reg_save_area is doubleword
7901 aligned, but we don't need to allocate space for all
7902 the bytes, only those to which we actually will save
7904 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
7905 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
7906 if (TARGET_HARD_FLOAT && TARGET_FPRS
7907 && next_cum.fregno <= FP_ARG_V4_MAX_REG
7908 && cfun->va_list_fpr_size)
7911 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
7912 * UNITS_PER_FP_WORD;
7913 if (cfun->va_list_fpr_size
7914 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
7915 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
7917 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
7918 * UNITS_PER_FP_WORD;
7922 offset = -((first_reg_offset * reg_size) & ~7);
7923 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
7925 gpr_reg_num = cfun->va_list_gpr_size;
7926 if (reg_size == 4 && (first_reg_offset & 1))
7929 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
7932 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
7934 - (int) (GP_ARG_NUM_REG * reg_size);
7936 if (gpr_size + fpr_size)
7939 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
7940 gcc_assert (GET_CODE (reg_save_area) == MEM);
7941 reg_save_area = XEXP (reg_save_area, 0);
7942 if (GET_CODE (reg_save_area) == PLUS)
7944 gcc_assert (XEXP (reg_save_area, 0)
7945 == virtual_stack_vars_rtx);
7946 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
7947 offset += INTVAL (XEXP (reg_save_area, 1));
7950 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
7953 cfun->machine->varargs_save_offset = offset;
7954 save_area = plus_constant (virtual_stack_vars_rtx, offset);
7959 first_reg_offset = next_cum.words;
7960 save_area = virtual_incoming_args_rtx;
7962 if (targetm.calls.must_pass_in_stack (mode, type))
7963 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
7966 set = get_varargs_alias_set ();
7967 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
7968 && cfun->va_list_gpr_size)
7970 int nregs = GP_ARG_NUM_REG - first_reg_offset;
7972 if (va_list_gpr_counter_field)
7974 /* V4 va_list_gpr_size counts number of registers needed. */
7975 if (nregs > cfun->va_list_gpr_size)
7976 nregs = cfun->va_list_gpr_size;
7980 /* char * va_list instead counts number of bytes needed. */
7981 if (nregs > cfun->va_list_gpr_size / reg_size)
7982 nregs = cfun->va_list_gpr_size / reg_size;
7985 mem = gen_rtx_MEM (BLKmode,
7986 plus_constant (save_area,
7987 first_reg_offset * reg_size));
7988 MEM_NOTRAP_P (mem) = 1;
7989 set_mem_alias_set (mem, set);
7990 set_mem_align (mem, BITS_PER_WORD);
7992 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
7996 /* Save FP registers if needed. */
7997 if (DEFAULT_ABI == ABI_V4
7998 && TARGET_HARD_FLOAT && TARGET_FPRS
8000 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8001 && cfun->va_list_fpr_size)
8003 int fregno = next_cum.fregno, nregs;
8004 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8005 rtx lab = gen_label_rtx ();
8006 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8007 * UNITS_PER_FP_WORD);
8010 (gen_rtx_SET (VOIDmode,
8012 gen_rtx_IF_THEN_ELSE (VOIDmode,
8013 gen_rtx_NE (VOIDmode, cr1,
8015 gen_rtx_LABEL_REF (VOIDmode, lab),
8019 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8020 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8022 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8024 plus_constant (save_area, off));
8025 MEM_NOTRAP_P (mem) = 1;
8026 set_mem_alias_set (mem, set);
8027 set_mem_align (mem, GET_MODE_ALIGNMENT (
8028 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8029 ? DFmode : SFmode));
8030 emit_move_insn (mem, gen_rtx_REG (
8031 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8032 ? DFmode : SFmode, fregno));
8039 /* Create the va_list data type. */
8042 rs6000_build_builtin_va_list (void)
8044 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8046 /* For AIX, prefer 'char *' because that's what the system
8047 header files like. */
8048 if (DEFAULT_ABI != ABI_V4)
8049 return build_pointer_type (char_type_node);
8051 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8052 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8053 get_identifier ("__va_list_tag"), record);
8055 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8056 unsigned_char_type_node);
8057 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8058 unsigned_char_type_node);
8059 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8061 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8062 get_identifier ("reserved"), short_unsigned_type_node);
8063 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8064 get_identifier ("overflow_arg_area"),
8066 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8067 get_identifier ("reg_save_area"),
8070 va_list_gpr_counter_field = f_gpr;
8071 va_list_fpr_counter_field = f_fpr;
8073 DECL_FIELD_CONTEXT (f_gpr) = record;
8074 DECL_FIELD_CONTEXT (f_fpr) = record;
8075 DECL_FIELD_CONTEXT (f_res) = record;
8076 DECL_FIELD_CONTEXT (f_ovf) = record;
8077 DECL_FIELD_CONTEXT (f_sav) = record;
8079 TREE_CHAIN (record) = type_decl;
8080 TYPE_NAME (record) = type_decl;
8081 TYPE_FIELDS (record) = f_gpr;
8082 TREE_CHAIN (f_gpr) = f_fpr;
8083 TREE_CHAIN (f_fpr) = f_res;
8084 TREE_CHAIN (f_res) = f_ovf;
8085 TREE_CHAIN (f_ovf) = f_sav;
8087 layout_type (record);
8089 /* The correct type is an array type of one element. */
8090 return build_array_type (record, build_index_type (size_zero_node));
8093 /* Implement va_start. */
8096 rs6000_va_start (tree valist, rtx nextarg)
8098 HOST_WIDE_INT words, n_gpr, n_fpr;
8099 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8100 tree gpr, fpr, ovf, sav, t;
8102 /* Only SVR4 needs something special. */
8103 if (DEFAULT_ABI != ABI_V4)
8105 std_expand_builtin_va_start (valist, nextarg);
8109 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8110 f_fpr = TREE_CHAIN (f_gpr);
8111 f_res = TREE_CHAIN (f_fpr);
8112 f_ovf = TREE_CHAIN (f_res);
8113 f_sav = TREE_CHAIN (f_ovf);
8115 valist = build_va_arg_indirect_ref (valist);
8116 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8117 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8119 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8121 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8124 /* Count number of gp and fp argument registers used. */
8125 words = crtl->args.info.words;
8126 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8128 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8131 if (TARGET_DEBUG_ARG)
8132 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8133 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8134 words, n_gpr, n_fpr);
8136 if (cfun->va_list_gpr_size)
8138 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8139 build_int_cst (NULL_TREE, n_gpr));
8140 TREE_SIDE_EFFECTS (t) = 1;
8141 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8144 if (cfun->va_list_fpr_size)
8146 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8147 build_int_cst (NULL_TREE, n_fpr));
8148 TREE_SIDE_EFFECTS (t) = 1;
8149 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8152 /* Find the overflow area. */
8153 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8155 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8156 size_int (words * UNITS_PER_WORD));
8157 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8158 TREE_SIDE_EFFECTS (t) = 1;
8159 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8161 /* If there were no va_arg invocations, don't set up the register
8163 if (!cfun->va_list_gpr_size
8164 && !cfun->va_list_fpr_size
8165 && n_gpr < GP_ARG_NUM_REG
8166 && n_fpr < FP_ARG_V4_MAX_REG)
8169 /* Find the register save area. */
8170 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8171 if (cfun->machine->varargs_save_offset)
8172 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8173 size_int (cfun->machine->varargs_save_offset));
8174 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8175 TREE_SIDE_EFFECTS (t) = 1;
8176 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8179 /* Implement va_arg. */
8182 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8185 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8186 tree gpr, fpr, ovf, sav, reg, t, u;
8187 int size, rsize, n_reg, sav_ofs, sav_scale;
8188 tree lab_false, lab_over, addr;
8190 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8194 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8196 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8197 return build_va_arg_indirect_ref (t);
8200 if (DEFAULT_ABI != ABI_V4)
8202 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8204 tree elem_type = TREE_TYPE (type);
8205 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8206 int elem_size = GET_MODE_SIZE (elem_mode);
8208 if (elem_size < UNITS_PER_WORD)
8210 tree real_part, imag_part;
8211 gimple_seq post = NULL;
8213 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8215 /* Copy the value into a temporary, lest the formal temporary
8216 be reused out from under us. */
8217 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8218 gimple_seq_add_seq (pre_p, post);
8220 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8223 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8227 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8230 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8231 f_fpr = TREE_CHAIN (f_gpr);
8232 f_res = TREE_CHAIN (f_fpr);
8233 f_ovf = TREE_CHAIN (f_res);
8234 f_sav = TREE_CHAIN (f_ovf);
8236 valist = build_va_arg_indirect_ref (valist);
8237 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8238 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8240 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8242 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8245 size = int_size_in_bytes (type);
8246 rsize = (size + 3) / 4;
8249 if (TARGET_HARD_FLOAT && TARGET_FPRS
8250 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8251 || (TARGET_DOUBLE_FLOAT
8252 && (TYPE_MODE (type) == DFmode
8253 || TYPE_MODE (type) == TFmode
8254 || TYPE_MODE (type) == SDmode
8255 || TYPE_MODE (type) == DDmode
8256 || TYPE_MODE (type) == TDmode))))
8258 /* FP args go in FP registers, if present. */
8260 n_reg = (size + 7) / 8;
8261 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8262 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8263 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8268 /* Otherwise into GP registers. */
8277 /* Pull the value out of the saved registers.... */
8280 addr = create_tmp_var (ptr_type_node, "addr");
8282 /* AltiVec vectors never go in registers when -mabi=altivec. */
8283 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8287 lab_false = create_artificial_label (input_location);
8288 lab_over = create_artificial_label (input_location);
8290 /* Long long and SPE vectors are aligned in the registers.
8291 As are any other 2 gpr item such as complex int due to a
8292 historical mistake. */
8294 if (n_reg == 2 && reg == gpr)
8297 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8298 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8299 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8300 unshare_expr (reg), u);
8302 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8303 reg number is 0 for f1, so we want to make it odd. */
8304 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8306 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8307 build_int_cst (TREE_TYPE (reg), 1));
8308 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8311 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8312 t = build2 (GE_EXPR, boolean_type_node, u, t);
8313 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8314 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8315 gimplify_and_add (t, pre_p);
8319 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8321 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8322 build_int_cst (TREE_TYPE (reg), n_reg));
8323 u = fold_convert (sizetype, u);
8324 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8325 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8327 /* _Decimal32 varargs are located in the second word of the 64-bit
8328 FP register for 32-bit binaries. */
8329 if (!TARGET_POWERPC64
8330 && TARGET_HARD_FLOAT && TARGET_FPRS
8331 && TYPE_MODE (type) == SDmode)
8332 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8334 gimplify_assign (addr, t, pre_p);
8336 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8338 stmt = gimple_build_label (lab_false);
8339 gimple_seq_add_stmt (pre_p, stmt);
8341 if ((n_reg == 2 && !regalign) || n_reg > 2)
8343 /* Ensure that we don't find any more args in regs.
8344 Alignment has taken care of for special cases. */
8345 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8349 /* ... otherwise out of the overflow area. */
8351 /* Care for on-stack alignment if needed. */
8355 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8356 t = fold_convert (sizetype, t);
8357 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8359 t = fold_convert (TREE_TYPE (ovf), t);
8361 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8363 gimplify_assign (unshare_expr (addr), t, pre_p);
8365 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8366 gimplify_assign (unshare_expr (ovf), t, pre_p);
8370 stmt = gimple_build_label (lab_over);
8371 gimple_seq_add_stmt (pre_p, stmt);
8374 if (STRICT_ALIGNMENT
8375 && (TYPE_ALIGN (type)
8376 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8378 /* The value (of type complex double, for example) may not be
8379 aligned in memory in the saved registers, so copy via a
8380 temporary. (This is the same code as used for SPARC.) */
8381 tree tmp = create_tmp_var (type, "va_arg_tmp");
8382 tree dest_addr = build_fold_addr_expr (tmp);
8384 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8385 3, dest_addr, addr, size_int (rsize * 4));
8387 gimplify_and_add (copy, pre_p);
8391 addr = fold_convert (ptrtype, addr);
8392 return build_va_arg_indirect_ref (addr);
8398 def_builtin (int mask, const char *name, tree type, int code)
8400 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8402 if (rs6000_builtin_decls[code])
8403 fatal_error ("internal error: builtin function to %s already processed.",
8406 rs6000_builtin_decls[code] =
8407 add_builtin_function (name, type, code, BUILT_IN_MD,
8412 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
8414 static const struct builtin_description bdesc_3arg[] =
8416 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
8417 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
8418 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
8419 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
8420 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
8421 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
8422 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
8423 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
8424 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
8425 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
8426 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
8427 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
8428 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
8429 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
8430 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
8431 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
8432 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
8433 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
8434 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
8435 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
8436 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
8437 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
8438 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
8439 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
8440 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
8441 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
8442 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
8443 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
8444 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
8445 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
8446 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
8447 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
8448 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
8449 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
8450 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
8452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
8453 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
8454 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
8455 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
8456 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
8457 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
8458 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
8459 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
8460 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
8461 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
8462 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
8463 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
8464 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
8465 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
8466 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
8468 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
8469 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
8470 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
8471 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
8473 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
8474 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
8475 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
8476 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
8478 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
8479 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
8481 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
8482 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
8483 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
8484 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
8485 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
8486 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
8487 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
8488 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
8489 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
8490 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
8492 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
8493 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
8494 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
8495 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
8496 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
8497 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
8498 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
8499 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
8500 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
8501 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
8503 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
8504 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
8505 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
8506 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
8507 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
8508 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
8509 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
8510 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
8511 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
8513 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
8514 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
8515 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
8516 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
8517 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
8518 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
8519 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
8521 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
8522 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
8523 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
8524 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
8525 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
8526 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
8527 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
8528 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
8529 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
8532 /* DST operations: void foo (void *, const int, const char). */
8534 static const struct builtin_description bdesc_dst[] =
8536 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
8537 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
8538 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
8539 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
8541 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
8542 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
8543 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
8544 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
8547 /* Simple binary operations: VECc = foo (VECa, VECb). */
8549 static struct builtin_description bdesc_2arg[] =
8551 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
8552 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
8553 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
8554 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
8555 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
8556 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
8557 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
8558 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
8559 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
8560 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
8561 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
8562 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
8563 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
8564 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
8565 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
8566 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
8567 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
8568 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
8569 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
8570 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
8571 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
8572 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
8573 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
8574 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
8575 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
8576 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
8577 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
8578 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
8579 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
8580 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
8581 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
8582 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
8583 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
8584 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
8585 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
8586 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
8587 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
8588 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
8589 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
8590 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
8591 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
8592 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
8593 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
8594 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
8595 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
8596 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
8597 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
8598 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
8599 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
8600 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
8601 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
8602 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
8603 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
8604 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
8605 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
8606 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
8607 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
8608 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
8609 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
8610 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
8611 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
8612 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
8613 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
8614 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
8615 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
8616 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
8617 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
8618 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
8619 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
8620 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
8621 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
8622 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
8623 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
8624 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
8625 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
8626 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
8627 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
8628 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
8629 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
8630 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
8631 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
8632 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
8633 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
8634 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
8635 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
8636 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
8637 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
8638 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
8639 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
8640 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
8641 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
8642 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
8643 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
8644 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
8645 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
8646 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
8647 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
8648 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
8649 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
8650 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
8651 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
8652 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
8653 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
8654 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
8655 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
8656 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
8657 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
8658 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
8659 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
8660 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
8661 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
8662 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
8663 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
8664 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
8665 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
8666 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
8668 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
8669 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
8670 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
8671 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
8672 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
8673 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
8674 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
8675 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
8676 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
8677 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
8678 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
8680 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
8681 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
8682 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
8683 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
8684 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
8685 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
8686 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
8687 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
8688 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
8689 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
8690 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
8692 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
8693 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
8694 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
8695 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
8696 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
8697 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
8699 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
8700 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
8701 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
8702 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
8703 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
8704 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
8705 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
8706 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
8708 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
8709 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
8710 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
8711 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
8712 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
8713 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
8714 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
8715 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
8716 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
8717 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
8718 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
8719 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
8720 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
8721 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
8722 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
8723 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
8724 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
8725 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
8726 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
8727 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
8728 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
8729 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
8730 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
8731 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
8732 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
8733 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
8734 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
8735 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
8736 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
8737 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
8738 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
8739 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
8740 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
8741 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
8742 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
8743 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
8744 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
8745 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
8746 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
8747 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
8748 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
8749 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
8750 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
8751 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
8752 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
8753 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
8754 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
8755 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
8756 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
8757 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
8758 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
8759 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
8760 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
8761 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
8762 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
8763 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
8764 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
8765 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
8766 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
8767 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
8768 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
8769 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
8770 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
8771 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
8772 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
8773 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
8774 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
8775 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
8776 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
8777 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
8778 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
8779 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
8780 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
8781 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
8782 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
8783 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
8784 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
8785 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
8786 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
8787 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
8788 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
8789 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
8790 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
8791 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
8792 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
8793 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
8794 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
8795 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
8796 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
8797 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
8798 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
8799 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
8800 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
8801 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
8802 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
8803 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
8804 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
8805 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
8806 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
8807 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
8808 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
8809 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
8810 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
8811 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
8812 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
8813 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
8814 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
8815 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
8816 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
8817 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
8818 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
8819 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
8820 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
8821 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
8822 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
8823 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
8824 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
8825 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
8826 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
8827 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
8828 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
8829 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
8830 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
8831 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
8832 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
8833 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
8834 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
8835 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
8837 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
8838 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
8840 { 0, CODE_FOR_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
8841 { 0, CODE_FOR_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
8842 { 0, CODE_FOR_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
8843 { 0, CODE_FOR_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
8844 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
8845 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
8846 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
8847 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
8848 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
8849 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
8851 /* Place holder, leave as first spe builtin. */
8852 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
8853 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
8854 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
8855 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
8856 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
8857 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
8858 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
8859 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
8860 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
8861 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
8862 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
8863 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
8864 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
8865 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
8866 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
8867 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
8868 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
8869 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
8870 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
8871 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
8872 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
8873 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
8874 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
8875 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
8876 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
8877 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
8878 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
8879 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
8880 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
8881 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
8882 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
8883 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
8884 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
8885 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
8886 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
8887 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
8888 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
8889 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
8890 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
8891 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
8892 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
8893 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
8894 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
8895 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
8896 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
8897 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
8898 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
8899 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
8900 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
8901 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
8902 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
8903 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
8904 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
8905 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
8906 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
8907 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
8908 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
8909 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
8910 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
8911 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
8912 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
8913 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
8914 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
8915 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
8916 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
8917 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
8918 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
8919 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
8920 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
8921 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
8922 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
8923 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
8924 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
8925 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
8926 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
8927 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
8928 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
8929 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
8930 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
8931 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
8932 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
8933 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
8934 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
8935 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
8936 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
8937 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
8938 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
8939 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
8940 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
8941 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
8942 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
8943 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
8944 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
8945 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
8946 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
8947 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
8948 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
8949 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
8950 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
8951 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
8952 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
8953 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
8954 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
8955 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
8956 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
8957 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
8958 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
8959 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
8960 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
8962 /* SPE binary operations expecting a 5-bit unsigned literal. */
8963 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
8965 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
8966 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
8967 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
8968 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
8969 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
8970 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
8971 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
8972 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
8973 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
8974 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
8975 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
8976 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
8977 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
8978 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
8979 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
8980 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
8981 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
8982 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
8983 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
8984 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
8985 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
8986 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
8987 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
8988 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
8989 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
8990 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
8992 /* Place-holder. Leave as last binary SPE builtin. */
8993 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
8996 /* AltiVec predicates. */
8998 struct builtin_description_predicates
9000 const unsigned int mask;
9001 const enum insn_code icode;
9002 const char *const name;
9003 const enum rs6000_builtins code;
9006 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9008 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9009 ALTIVEC_BUILTIN_VCMPBFP_P },
9010 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9011 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9012 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9013 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9014 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9015 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9016 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9017 ALTIVEC_BUILTIN_VCMPEQUW_P },
9018 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9019 ALTIVEC_BUILTIN_VCMPGTSW_P },
9020 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9021 ALTIVEC_BUILTIN_VCMPGTUW_P },
9022 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9023 ALTIVEC_BUILTIN_VCMPEQUH_P },
9024 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9025 ALTIVEC_BUILTIN_VCMPGTSH_P },
9026 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9027 ALTIVEC_BUILTIN_VCMPGTUH_P },
9028 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9029 ALTIVEC_BUILTIN_VCMPEQUB_P },
9030 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9031 ALTIVEC_BUILTIN_VCMPGTSB_P },
9032 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9033 ALTIVEC_BUILTIN_VCMPGTUB_P },
9035 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9036 VSX_BUILTIN_XVCMPEQSP_P },
9037 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9038 VSX_BUILTIN_XVCMPGESP_P },
9039 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9040 VSX_BUILTIN_XVCMPGTSP_P },
9041 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9042 VSX_BUILTIN_XVCMPEQDP_P },
9043 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9044 VSX_BUILTIN_XVCMPGEDP_P },
9045 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9046 VSX_BUILTIN_XVCMPGTDP_P },
9048 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9049 ALTIVEC_BUILTIN_VCMPEQ_P },
9050 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9051 ALTIVEC_BUILTIN_VCMPGT_P },
9052 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9053 ALTIVEC_BUILTIN_VCMPGE_P }
9056 /* SPE predicates. */
9057 static struct builtin_description bdesc_spe_predicates[] =
9059 /* Place-holder. Leave as first. */
9060 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9061 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9062 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9063 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9064 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9065 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9066 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9067 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9068 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9069 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9070 /* Place-holder. Leave as last. */
9071 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9074 /* SPE evsel predicates. */
9075 static struct builtin_description bdesc_spe_evsel[] =
9077 /* Place-holder. Leave as first. */
9078 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9079 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9080 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9081 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9082 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9083 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9084 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9085 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9086 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9087 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9088 /* Place-holder. Leave as last. */
9089 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9092 /* PAIRED predicates. */
9093 static const struct builtin_description bdesc_paired_preds[] =
9095 /* Place-holder. Leave as first. */
9096 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9097 /* Place-holder. Leave as last. */
9098 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9101 /* ABS* operations. */
9103 static const struct builtin_description bdesc_abs[] =
9105 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9106 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9107 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9108 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9109 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9110 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9111 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9112 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9113 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9114 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9115 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9118 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9121 static struct builtin_description bdesc_1arg[] =
9123 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9124 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9125 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9126 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9127 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9128 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9129 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9130 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9131 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9132 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9133 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9134 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9135 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9136 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9137 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9138 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9139 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9141 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9142 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9143 { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9144 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9145 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9146 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9148 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9149 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9150 { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9151 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9152 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9153 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9155 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9156 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9157 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9158 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9159 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9160 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9162 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9163 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9164 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9165 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9166 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9167 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9169 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9170 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9171 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9172 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9174 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9175 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9176 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9177 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9178 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9179 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9180 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9181 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9182 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9184 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9185 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9186 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9187 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9188 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9189 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9190 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9191 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9192 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9194 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9195 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9196 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9197 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9198 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9200 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9201 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9202 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9203 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9204 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9205 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9206 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9207 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9208 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9209 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9210 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9211 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9212 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9213 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9214 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9215 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9216 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9217 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9218 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9220 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9221 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9222 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9224 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9225 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9226 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9227 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9229 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9230 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9231 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9232 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9233 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9234 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9235 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9236 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9237 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9238 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9239 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9240 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9241 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9242 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9243 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9244 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9245 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9246 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9247 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9248 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9249 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9250 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9251 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9252 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9253 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9254 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9255 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9256 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9257 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9258 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9260 /* Place-holder. Leave as last unary SPE builtin. */
9261 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9263 { 0, CODE_FOR_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9264 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9265 { 0, CODE_FOR_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9266 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9267 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9271 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9274 tree arg0 = CALL_EXPR_ARG (exp, 0);
9275 rtx op0 = expand_normal (arg0);
9276 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9277 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9279 if (icode == CODE_FOR_nothing)
9280 /* Builtin not supported on this processor. */
9283 /* If we got invalid arguments bail out before generating bad rtl. */
9284 if (arg0 == error_mark_node)
9287 if (icode == CODE_FOR_altivec_vspltisb
9288 || icode == CODE_FOR_altivec_vspltish
9289 || icode == CODE_FOR_altivec_vspltisw
9290 || icode == CODE_FOR_spe_evsplatfi
9291 || icode == CODE_FOR_spe_evsplati)
9293 /* Only allow 5-bit *signed* literals. */
9294 if (GET_CODE (op0) != CONST_INT
9295 || INTVAL (op0) > 15
9296 || INTVAL (op0) < -16)
9298 error ("argument 1 must be a 5-bit signed literal");
9304 || GET_MODE (target) != tmode
9305 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9306 target = gen_reg_rtx (tmode);
9308 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9309 op0 = copy_to_mode_reg (mode0, op0);
9311 pat = GEN_FCN (icode) (target, op0);
9320 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9322 rtx pat, scratch1, scratch2;
9323 tree arg0 = CALL_EXPR_ARG (exp, 0);
9324 rtx op0 = expand_normal (arg0);
9325 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9326 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9328 /* If we have invalid arguments, bail out before generating bad rtl. */
9329 if (arg0 == error_mark_node)
9333 || GET_MODE (target) != tmode
9334 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9335 target = gen_reg_rtx (tmode);
9337 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9338 op0 = copy_to_mode_reg (mode0, op0);
9340 scratch1 = gen_reg_rtx (mode0);
9341 scratch2 = gen_reg_rtx (mode0);
9343 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9352 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
9355 tree arg0 = CALL_EXPR_ARG (exp, 0);
9356 tree arg1 = CALL_EXPR_ARG (exp, 1);
9357 rtx op0 = expand_normal (arg0);
9358 rtx op1 = expand_normal (arg1);
9359 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9360 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9361 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9363 if (icode == CODE_FOR_nothing)
9364 /* Builtin not supported on this processor. */
9367 /* If we got invalid arguments bail out before generating bad rtl. */
9368 if (arg0 == error_mark_node || arg1 == error_mark_node)
9371 if (icode == CODE_FOR_altivec_vcfux
9372 || icode == CODE_FOR_altivec_vcfsx
9373 || icode == CODE_FOR_altivec_vctsxs
9374 || icode == CODE_FOR_altivec_vctuxs
9375 || icode == CODE_FOR_altivec_vspltb
9376 || icode == CODE_FOR_altivec_vsplth
9377 || icode == CODE_FOR_altivec_vspltw
9378 || icode == CODE_FOR_spe_evaddiw
9379 || icode == CODE_FOR_spe_evldd
9380 || icode == CODE_FOR_spe_evldh
9381 || icode == CODE_FOR_spe_evldw
9382 || icode == CODE_FOR_spe_evlhhesplat
9383 || icode == CODE_FOR_spe_evlhhossplat
9384 || icode == CODE_FOR_spe_evlhhousplat
9385 || icode == CODE_FOR_spe_evlwhe
9386 || icode == CODE_FOR_spe_evlwhos
9387 || icode == CODE_FOR_spe_evlwhou
9388 || icode == CODE_FOR_spe_evlwhsplat
9389 || icode == CODE_FOR_spe_evlwwsplat
9390 || icode == CODE_FOR_spe_evrlwi
9391 || icode == CODE_FOR_spe_evslwi
9392 || icode == CODE_FOR_spe_evsrwis
9393 || icode == CODE_FOR_spe_evsubifw
9394 || icode == CODE_FOR_spe_evsrwiu)
9396 /* Only allow 5-bit unsigned literals. */
9398 if (TREE_CODE (arg1) != INTEGER_CST
9399 || TREE_INT_CST_LOW (arg1) & ~0x1f)
9401 error ("argument 2 must be a 5-bit unsigned literal");
9407 || GET_MODE (target) != tmode
9408 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9409 target = gen_reg_rtx (tmode);
9411 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9412 op0 = copy_to_mode_reg (mode0, op0);
9413 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9414 op1 = copy_to_mode_reg (mode1, op1);
9416 pat = GEN_FCN (icode) (target, op0, op1);
9425 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
9428 tree cr6_form = CALL_EXPR_ARG (exp, 0);
9429 tree arg0 = CALL_EXPR_ARG (exp, 1);
9430 tree arg1 = CALL_EXPR_ARG (exp, 2);
9431 rtx op0 = expand_normal (arg0);
9432 rtx op1 = expand_normal (arg1);
9433 enum machine_mode tmode = SImode;
9434 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9435 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9438 if (TREE_CODE (cr6_form) != INTEGER_CST)
9440 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9444 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
9446 gcc_assert (mode0 == mode1);
9448 /* If we have invalid arguments, bail out before generating bad rtl. */
9449 if (arg0 == error_mark_node || arg1 == error_mark_node)
9453 || GET_MODE (target) != tmode
9454 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9455 target = gen_reg_rtx (tmode);
9457 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9458 op0 = copy_to_mode_reg (mode0, op0);
9459 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9460 op1 = copy_to_mode_reg (mode1, op1);
9462 scratch = gen_reg_rtx (mode0);
9464 pat = GEN_FCN (icode) (scratch, op0, op1);
9469 /* The vec_any* and vec_all* predicates use the same opcodes for two
9470 different operations, but the bits in CR6 will be different
9471 depending on what information we want. So we have to play tricks
9472 with CR6 to get the right bits out.
9474 If you think this is disgusting, look at the specs for the
9475 AltiVec predicates. */
9477 switch (cr6_form_int)
9480 emit_insn (gen_cr6_test_for_zero (target));
9483 emit_insn (gen_cr6_test_for_zero_reverse (target));
9486 emit_insn (gen_cr6_test_for_lt (target));
9489 emit_insn (gen_cr6_test_for_lt_reverse (target));
9492 error ("argument 1 of __builtin_altivec_predicate is out of range");
9500 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
9503 tree arg0 = CALL_EXPR_ARG (exp, 0);
9504 tree arg1 = CALL_EXPR_ARG (exp, 1);
9505 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9506 enum machine_mode mode0 = Pmode;
9507 enum machine_mode mode1 = Pmode;
9508 rtx op0 = expand_normal (arg0);
9509 rtx op1 = expand_normal (arg1);
9511 if (icode == CODE_FOR_nothing)
9512 /* Builtin not supported on this processor. */
9515 /* If we got invalid arguments bail out before generating bad rtl. */
9516 if (arg0 == error_mark_node || arg1 == error_mark_node)
9520 || GET_MODE (target) != tmode
9521 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9522 target = gen_reg_rtx (tmode);
9524 op1 = copy_to_mode_reg (mode1, op1);
9526 if (op0 == const0_rtx)
9528 addr = gen_rtx_MEM (tmode, op1);
9532 op0 = copy_to_mode_reg (mode0, op0);
9533 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
9536 pat = GEN_FCN (icode) (target, addr);
9546 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
9549 tree arg0 = CALL_EXPR_ARG (exp, 0);
9550 tree arg1 = CALL_EXPR_ARG (exp, 1);
9551 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9552 enum machine_mode mode0 = Pmode;
9553 enum machine_mode mode1 = Pmode;
9554 rtx op0 = expand_normal (arg0);
9555 rtx op1 = expand_normal (arg1);
9557 if (icode == CODE_FOR_nothing)
9558 /* Builtin not supported on this processor. */
9561 /* If we got invalid arguments bail out before generating bad rtl. */
9562 if (arg0 == error_mark_node || arg1 == error_mark_node)
9566 || GET_MODE (target) != tmode
9567 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9568 target = gen_reg_rtx (tmode);
9570 op1 = copy_to_mode_reg (mode1, op1);
9572 if (op0 == const0_rtx)
9574 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
9578 op0 = copy_to_mode_reg (mode0, op0);
9579 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
9582 pat = GEN_FCN (icode) (target, addr);
9592 spe_expand_stv_builtin (enum insn_code icode, tree exp)
9594 tree arg0 = CALL_EXPR_ARG (exp, 0);
9595 tree arg1 = CALL_EXPR_ARG (exp, 1);
9596 tree arg2 = CALL_EXPR_ARG (exp, 2);
9597 rtx op0 = expand_normal (arg0);
9598 rtx op1 = expand_normal (arg1);
9599 rtx op2 = expand_normal (arg2);
9601 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
9602 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
9603 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
9605 /* Invalid arguments. Bail before doing anything stoopid! */
9606 if (arg0 == error_mark_node
9607 || arg1 == error_mark_node
9608 || arg2 == error_mark_node)
9611 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
9612 op0 = copy_to_mode_reg (mode2, op0);
9613 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
9614 op1 = copy_to_mode_reg (mode0, op1);
9615 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
9616 op2 = copy_to_mode_reg (mode1, op2);
9618 pat = GEN_FCN (icode) (op1, op2, op0);
9625 paired_expand_stv_builtin (enum insn_code icode, tree exp)
9627 tree arg0 = CALL_EXPR_ARG (exp, 0);
9628 tree arg1 = CALL_EXPR_ARG (exp, 1);
9629 tree arg2 = CALL_EXPR_ARG (exp, 2);
9630 rtx op0 = expand_normal (arg0);
9631 rtx op1 = expand_normal (arg1);
9632 rtx op2 = expand_normal (arg2);
9634 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9635 enum machine_mode mode1 = Pmode;
9636 enum machine_mode mode2 = Pmode;
9638 /* Invalid arguments. Bail before doing anything stoopid! */
9639 if (arg0 == error_mark_node
9640 || arg1 == error_mark_node
9641 || arg2 == error_mark_node)
9644 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9645 op0 = copy_to_mode_reg (tmode, op0);
9647 op2 = copy_to_mode_reg (mode2, op2);
9649 if (op1 == const0_rtx)
9651 addr = gen_rtx_MEM (tmode, op2);
9655 op1 = copy_to_mode_reg (mode1, op1);
9656 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9659 pat = GEN_FCN (icode) (addr, op0);
9666 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
9668 tree arg0 = CALL_EXPR_ARG (exp, 0);
9669 tree arg1 = CALL_EXPR_ARG (exp, 1);
9670 tree arg2 = CALL_EXPR_ARG (exp, 2);
9671 rtx op0 = expand_normal (arg0);
9672 rtx op1 = expand_normal (arg1);
9673 rtx op2 = expand_normal (arg2);
9675 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9676 enum machine_mode mode1 = Pmode;
9677 enum machine_mode mode2 = Pmode;
9679 /* Invalid arguments. Bail before doing anything stoopid! */
9680 if (arg0 == error_mark_node
9681 || arg1 == error_mark_node
9682 || arg2 == error_mark_node)
9685 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9686 op0 = copy_to_mode_reg (tmode, op0);
9688 op2 = copy_to_mode_reg (mode2, op2);
9690 if (op1 == const0_rtx)
9692 addr = gen_rtx_MEM (tmode, op2);
9696 op1 = copy_to_mode_reg (mode1, op1);
9697 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9700 pat = GEN_FCN (icode) (addr, op0);
9707 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
9710 tree arg0 = CALL_EXPR_ARG (exp, 0);
9711 tree arg1 = CALL_EXPR_ARG (exp, 1);
9712 tree arg2 = CALL_EXPR_ARG (exp, 2);
9713 rtx op0 = expand_normal (arg0);
9714 rtx op1 = expand_normal (arg1);
9715 rtx op2 = expand_normal (arg2);
9716 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9717 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9718 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9719 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
9721 if (icode == CODE_FOR_nothing)
9722 /* Builtin not supported on this processor. */
9725 /* If we got invalid arguments bail out before generating bad rtl. */
9726 if (arg0 == error_mark_node
9727 || arg1 == error_mark_node
9728 || arg2 == error_mark_node)
9733 case CODE_FOR_altivec_vsldoi_v4sf:
9734 case CODE_FOR_altivec_vsldoi_v4si:
9735 case CODE_FOR_altivec_vsldoi_v8hi:
9736 case CODE_FOR_altivec_vsldoi_v16qi:
9737 /* Only allow 4-bit unsigned literals. */
9739 if (TREE_CODE (arg2) != INTEGER_CST
9740 || TREE_INT_CST_LOW (arg2) & ~0xf)
9742 error ("argument 3 must be a 4-bit unsigned literal");
9747 case CODE_FOR_vsx_xxpermdi_v2df:
9748 case CODE_FOR_vsx_xxpermdi_v2di:
9749 case CODE_FOR_vsx_xxsldwi_v16qi:
9750 case CODE_FOR_vsx_xxsldwi_v8hi:
9751 case CODE_FOR_vsx_xxsldwi_v4si:
9752 case CODE_FOR_vsx_xxsldwi_v4sf:
9753 case CODE_FOR_vsx_xxsldwi_v2di:
9754 case CODE_FOR_vsx_xxsldwi_v2df:
9755 /* Only allow 2-bit unsigned literals. */
9757 if (TREE_CODE (arg2) != INTEGER_CST
9758 || TREE_INT_CST_LOW (arg2) & ~0x3)
9760 error ("argument 3 must be a 2-bit unsigned literal");
9765 case CODE_FOR_vsx_set_v2df:
9766 case CODE_FOR_vsx_set_v2di:
9767 /* Only allow 1-bit unsigned literals. */
9769 if (TREE_CODE (arg2) != INTEGER_CST
9770 || TREE_INT_CST_LOW (arg2) & ~0x1)
9772 error ("argument 3 must be a 1-bit unsigned literal");
9782 || GET_MODE (target) != tmode
9783 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9784 target = gen_reg_rtx (tmode);
9786 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9787 op0 = copy_to_mode_reg (mode0, op0);
9788 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9789 op1 = copy_to_mode_reg (mode1, op1);
9790 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
9791 op2 = copy_to_mode_reg (mode2, op2);
9793 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
9794 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
9796 pat = GEN_FCN (icode) (target, op0, op1, op2);
9804 /* Expand the lvx builtins. */
9806 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
9808 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9809 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9811 enum machine_mode tmode, mode0;
9813 enum insn_code icode;
9817 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
9818 icode = CODE_FOR_vector_load_v16qi;
9820 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
9821 icode = CODE_FOR_vector_load_v8hi;
9823 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
9824 icode = CODE_FOR_vector_load_v4si;
9826 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
9827 icode = CODE_FOR_vector_load_v4sf;
9836 arg0 = CALL_EXPR_ARG (exp, 0);
9837 op0 = expand_normal (arg0);
9838 tmode = insn_data[icode].operand[0].mode;
9839 mode0 = insn_data[icode].operand[1].mode;
9842 || GET_MODE (target) != tmode
9843 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9844 target = gen_reg_rtx (tmode);
9846 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9847 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
9849 pat = GEN_FCN (icode) (target, op0);
9856 /* Expand the stvx builtins. */
9858 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
9861 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9862 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9864 enum machine_mode mode0, mode1;
9866 enum insn_code icode;
9870 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
9871 icode = CODE_FOR_vector_store_v16qi;
9873 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
9874 icode = CODE_FOR_vector_store_v8hi;
9876 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
9877 icode = CODE_FOR_vector_store_v4si;
9879 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
9880 icode = CODE_FOR_vector_store_v4sf;
9887 arg0 = CALL_EXPR_ARG (exp, 0);
9888 arg1 = CALL_EXPR_ARG (exp, 1);
9889 op0 = expand_normal (arg0);
9890 op1 = expand_normal (arg1);
9891 mode0 = insn_data[icode].operand[0].mode;
9892 mode1 = insn_data[icode].operand[1].mode;
9894 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
9895 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
9896 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
9897 op1 = copy_to_mode_reg (mode1, op1);
9899 pat = GEN_FCN (icode) (op0, op1);
9907 /* Expand the dst builtins. */
9909 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
9912 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9913 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9914 tree arg0, arg1, arg2;
9915 enum machine_mode mode0, mode1, mode2;
9916 rtx pat, op0, op1, op2;
9917 const struct builtin_description *d;
9922 /* Handle DST variants. */
9924 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
9925 if (d->code == fcode)
9927 arg0 = CALL_EXPR_ARG (exp, 0);
9928 arg1 = CALL_EXPR_ARG (exp, 1);
9929 arg2 = CALL_EXPR_ARG (exp, 2);
9930 op0 = expand_normal (arg0);
9931 op1 = expand_normal (arg1);
9932 op2 = expand_normal (arg2);
9933 mode0 = insn_data[d->icode].operand[0].mode;
9934 mode1 = insn_data[d->icode].operand[1].mode;
9935 mode2 = insn_data[d->icode].operand[2].mode;
9937 /* Invalid arguments, bail out before generating bad rtl. */
9938 if (arg0 == error_mark_node
9939 || arg1 == error_mark_node
9940 || arg2 == error_mark_node)
9945 if (TREE_CODE (arg2) != INTEGER_CST
9946 || TREE_INT_CST_LOW (arg2) & ~0x3)
9948 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
9952 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
9953 op0 = copy_to_mode_reg (Pmode, op0);
9954 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
9955 op1 = copy_to_mode_reg (mode1, op1);
9957 pat = GEN_FCN (d->icode) (op0, op1, op2);
9967 /* Expand vec_init builtin. */
9969 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
9971 enum machine_mode tmode = TYPE_MODE (type);
9972 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
9973 int i, n_elt = GET_MODE_NUNITS (tmode);
9974 rtvec v = rtvec_alloc (n_elt);
9976 gcc_assert (VECTOR_MODE_P (tmode));
9977 gcc_assert (n_elt == call_expr_nargs (exp));
9979 for (i = 0; i < n_elt; ++i)
9981 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
9982 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
9985 if (!target || !register_operand (target, tmode))
9986 target = gen_reg_rtx (tmode);
9988 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
9992 /* Return the integer constant in ARG. Constrain it to be in the range
9993 of the subparts of VEC_TYPE; issue an error if not. */
9996 get_element_number (tree vec_type, tree arg)
9998 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10000 if (!host_integerp (arg, 1)
10001 || (elt = tree_low_cst (arg, 1), elt > max))
10003 error ("selector must be an integer constant in the range 0..%wi", max);
10010 /* Expand vec_set builtin. */
10012 altivec_expand_vec_set_builtin (tree exp)
10014 enum machine_mode tmode, mode1;
10015 tree arg0, arg1, arg2;
10019 arg0 = CALL_EXPR_ARG (exp, 0);
10020 arg1 = CALL_EXPR_ARG (exp, 1);
10021 arg2 = CALL_EXPR_ARG (exp, 2);
10023 tmode = TYPE_MODE (TREE_TYPE (arg0));
10024 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10025 gcc_assert (VECTOR_MODE_P (tmode));
10027 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10028 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10029 elt = get_element_number (TREE_TYPE (arg0), arg2);
10031 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10032 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10034 op0 = force_reg (tmode, op0);
10035 op1 = force_reg (mode1, op1);
10037 rs6000_expand_vector_set (op0, op1, elt);
10042 /* Expand vec_ext builtin. */
10044 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10046 enum machine_mode tmode, mode0;
10051 arg0 = CALL_EXPR_ARG (exp, 0);
10052 arg1 = CALL_EXPR_ARG (exp, 1);
10054 op0 = expand_normal (arg0);
10055 elt = get_element_number (TREE_TYPE (arg0), arg1);
10057 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10058 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10059 gcc_assert (VECTOR_MODE_P (mode0));
10061 op0 = force_reg (mode0, op0);
10063 if (optimize || !target || !register_operand (target, tmode))
10064 target = gen_reg_rtx (tmode);
10066 rs6000_expand_vector_extract (target, op0, elt);
10071 /* Expand the builtin in EXP and store the result in TARGET. Store
10072 true in *EXPANDEDP if we found a builtin to expand. */
10074 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10076 const struct builtin_description *d;
10077 const struct builtin_description_predicates *dp;
10079 enum insn_code icode;
10080 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10083 enum machine_mode tmode, mode0;
10084 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10086 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10087 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10088 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10089 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10092 error ("unresolved overload for Altivec builtin %qF", fndecl);
10096 target = altivec_expand_ld_builtin (exp, target, expandedp);
10100 target = altivec_expand_st_builtin (exp, target, expandedp);
10104 target = altivec_expand_dst_builtin (exp, target, expandedp);
10112 case ALTIVEC_BUILTIN_STVX:
10113 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10114 case ALTIVEC_BUILTIN_STVEBX:
10115 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10116 case ALTIVEC_BUILTIN_STVEHX:
10117 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10118 case ALTIVEC_BUILTIN_STVEWX:
10119 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10120 case ALTIVEC_BUILTIN_STVXL:
10121 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10123 case ALTIVEC_BUILTIN_STVLX:
10124 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10125 case ALTIVEC_BUILTIN_STVLXL:
10126 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10127 case ALTIVEC_BUILTIN_STVRX:
10128 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10129 case ALTIVEC_BUILTIN_STVRXL:
10130 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10132 case ALTIVEC_BUILTIN_MFVSCR:
10133 icode = CODE_FOR_altivec_mfvscr;
10134 tmode = insn_data[icode].operand[0].mode;
10137 || GET_MODE (target) != tmode
10138 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10139 target = gen_reg_rtx (tmode);
10141 pat = GEN_FCN (icode) (target);
10147 case ALTIVEC_BUILTIN_MTVSCR:
10148 icode = CODE_FOR_altivec_mtvscr;
10149 arg0 = CALL_EXPR_ARG (exp, 0);
10150 op0 = expand_normal (arg0);
10151 mode0 = insn_data[icode].operand[0].mode;
10153 /* If we got invalid arguments bail out before generating bad rtl. */
10154 if (arg0 == error_mark_node)
10157 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10158 op0 = copy_to_mode_reg (mode0, op0);
10160 pat = GEN_FCN (icode) (op0);
10165 case ALTIVEC_BUILTIN_DSSALL:
10166 emit_insn (gen_altivec_dssall ());
10169 case ALTIVEC_BUILTIN_DSS:
10170 icode = CODE_FOR_altivec_dss;
10171 arg0 = CALL_EXPR_ARG (exp, 0);
10173 op0 = expand_normal (arg0);
10174 mode0 = insn_data[icode].operand[0].mode;
10176 /* If we got invalid arguments bail out before generating bad rtl. */
10177 if (arg0 == error_mark_node)
10180 if (TREE_CODE (arg0) != INTEGER_CST
10181 || TREE_INT_CST_LOW (arg0) & ~0x3)
10183 error ("argument to dss must be a 2-bit unsigned literal");
10187 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10188 op0 = copy_to_mode_reg (mode0, op0);
10190 emit_insn (gen_altivec_dss (op0));
10193 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10194 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10195 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10196 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10197 case VSX_BUILTIN_VEC_INIT_V2DF:
10198 case VSX_BUILTIN_VEC_INIT_V2DI:
10199 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10201 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10202 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10203 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10204 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10205 case VSX_BUILTIN_VEC_SET_V2DF:
10206 case VSX_BUILTIN_VEC_SET_V2DI:
10207 return altivec_expand_vec_set_builtin (exp);
10209 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10210 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10211 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10212 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10213 case VSX_BUILTIN_VEC_EXT_V2DF:
10214 case VSX_BUILTIN_VEC_EXT_V2DI:
10215 return altivec_expand_vec_ext_builtin (exp, target);
10219 /* Fall through. */
10222 /* Expand abs* operations. */
10224 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10225 if (d->code == fcode)
10226 return altivec_expand_abs_builtin (d->icode, exp, target);
10228 /* Expand the AltiVec predicates. */
10229 dp = bdesc_altivec_preds;
10230 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10231 if (dp->code == fcode)
10232 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10234 /* LV* are funky. We initialized them differently. */
10237 case ALTIVEC_BUILTIN_LVSL:
10238 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10239 exp, target, false);
10240 case ALTIVEC_BUILTIN_LVSR:
10241 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10242 exp, target, false);
10243 case ALTIVEC_BUILTIN_LVEBX:
10244 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10245 exp, target, false);
10246 case ALTIVEC_BUILTIN_LVEHX:
10247 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10248 exp, target, false);
10249 case ALTIVEC_BUILTIN_LVEWX:
10250 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10251 exp, target, false);
10252 case ALTIVEC_BUILTIN_LVXL:
10253 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10254 exp, target, false);
10255 case ALTIVEC_BUILTIN_LVX:
10256 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10257 exp, target, false);
10258 case ALTIVEC_BUILTIN_LVLX:
10259 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10260 exp, target, true);
10261 case ALTIVEC_BUILTIN_LVLXL:
10262 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10263 exp, target, true);
10264 case ALTIVEC_BUILTIN_LVRX:
10265 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10266 exp, target, true);
10267 case ALTIVEC_BUILTIN_LVRXL:
10268 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10269 exp, target, true);
10272 /* Fall through. */
10275 *expandedp = false;
10279 /* Expand the builtin in EXP and store the result in TARGET. Store
10280 true in *EXPANDEDP if we found a builtin to expand. */
10282 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10284 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10285 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10286 const struct builtin_description *d;
10293 case PAIRED_BUILTIN_STX:
10294 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10295 case PAIRED_BUILTIN_LX:
10296 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10299 /* Fall through. */
10302 /* Expand the paired predicates. */
10303 d = bdesc_paired_preds;
10304 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10305 if (d->code == fcode)
10306 return paired_expand_predicate_builtin (d->icode, exp, target);
10308 *expandedp = false;
10312 /* Binops that need to be initialized manually, but can be expanded
10313 automagically by rs6000_expand_binop_builtin. */
10314 static struct builtin_description bdesc_2arg_spe[] =
10316 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10317 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10318 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10319 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10320 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10321 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10322 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10323 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10324 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10325 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10326 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10327 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10328 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10329 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10330 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10331 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10332 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10333 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10334 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10335 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10336 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10337 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10340 /* Expand the builtin in EXP and store the result in TARGET. Store
10341 true in *EXPANDEDP if we found a builtin to expand.
10343 This expands the SPE builtins that are not simple unary and binary
10346 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10348 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10350 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10351 enum insn_code icode;
10352 enum machine_mode tmode, mode0;
10354 struct builtin_description *d;
10359 /* Syntax check for a 5-bit unsigned immediate. */
10362 case SPE_BUILTIN_EVSTDD:
10363 case SPE_BUILTIN_EVSTDH:
10364 case SPE_BUILTIN_EVSTDW:
10365 case SPE_BUILTIN_EVSTWHE:
10366 case SPE_BUILTIN_EVSTWHO:
10367 case SPE_BUILTIN_EVSTWWE:
10368 case SPE_BUILTIN_EVSTWWO:
10369 arg1 = CALL_EXPR_ARG (exp, 2);
10370 if (TREE_CODE (arg1) != INTEGER_CST
10371 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10373 error ("argument 2 must be a 5-bit unsigned literal");
10381 /* The evsplat*i instructions are not quite generic. */
10384 case SPE_BUILTIN_EVSPLATFI:
10385 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
10387 case SPE_BUILTIN_EVSPLATI:
10388 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
10394 d = (struct builtin_description *) bdesc_2arg_spe;
10395 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
10396 if (d->code == fcode)
10397 return rs6000_expand_binop_builtin (d->icode, exp, target);
10399 d = (struct builtin_description *) bdesc_spe_predicates;
10400 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
10401 if (d->code == fcode)
10402 return spe_expand_predicate_builtin (d->icode, exp, target);
10404 d = (struct builtin_description *) bdesc_spe_evsel;
10405 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
10406 if (d->code == fcode)
10407 return spe_expand_evsel_builtin (d->icode, exp, target);
10411 case SPE_BUILTIN_EVSTDDX:
10412 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
10413 case SPE_BUILTIN_EVSTDHX:
10414 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
10415 case SPE_BUILTIN_EVSTDWX:
10416 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
10417 case SPE_BUILTIN_EVSTWHEX:
10418 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
10419 case SPE_BUILTIN_EVSTWHOX:
10420 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
10421 case SPE_BUILTIN_EVSTWWEX:
10422 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
10423 case SPE_BUILTIN_EVSTWWOX:
10424 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
10425 case SPE_BUILTIN_EVSTDD:
10426 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
10427 case SPE_BUILTIN_EVSTDH:
10428 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
10429 case SPE_BUILTIN_EVSTDW:
10430 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
10431 case SPE_BUILTIN_EVSTWHE:
10432 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
10433 case SPE_BUILTIN_EVSTWHO:
10434 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
10435 case SPE_BUILTIN_EVSTWWE:
10436 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
10437 case SPE_BUILTIN_EVSTWWO:
10438 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
10439 case SPE_BUILTIN_MFSPEFSCR:
10440 icode = CODE_FOR_spe_mfspefscr;
10441 tmode = insn_data[icode].operand[0].mode;
10444 || GET_MODE (target) != tmode
10445 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10446 target = gen_reg_rtx (tmode);
10448 pat = GEN_FCN (icode) (target);
10453 case SPE_BUILTIN_MTSPEFSCR:
10454 icode = CODE_FOR_spe_mtspefscr;
10455 arg0 = CALL_EXPR_ARG (exp, 0);
10456 op0 = expand_normal (arg0);
10457 mode0 = insn_data[icode].operand[0].mode;
10459 if (arg0 == error_mark_node)
10462 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10463 op0 = copy_to_mode_reg (mode0, op0);
10465 pat = GEN_FCN (icode) (op0);
10473 *expandedp = false;
10478 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10480 rtx pat, scratch, tmp;
10481 tree form = CALL_EXPR_ARG (exp, 0);
10482 tree arg0 = CALL_EXPR_ARG (exp, 1);
10483 tree arg1 = CALL_EXPR_ARG (exp, 2);
10484 rtx op0 = expand_normal (arg0);
10485 rtx op1 = expand_normal (arg1);
10486 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10487 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10489 enum rtx_code code;
10491 if (TREE_CODE (form) != INTEGER_CST)
10493 error ("argument 1 of __builtin_paired_predicate must be a constant");
10497 form_int = TREE_INT_CST_LOW (form);
10499 gcc_assert (mode0 == mode1);
10501 if (arg0 == error_mark_node || arg1 == error_mark_node)
10505 || GET_MODE (target) != SImode
10506 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
10507 target = gen_reg_rtx (SImode);
10508 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10509 op0 = copy_to_mode_reg (mode0, op0);
10510 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10511 op1 = copy_to_mode_reg (mode1, op1);
10513 scratch = gen_reg_rtx (CCFPmode);
10515 pat = GEN_FCN (icode) (scratch, op0, op1);
10537 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10540 error ("argument 1 of __builtin_paired_predicate is out of range");
10544 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10545 emit_move_insn (target, tmp);
10550 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10552 rtx pat, scratch, tmp;
10553 tree form = CALL_EXPR_ARG (exp, 0);
10554 tree arg0 = CALL_EXPR_ARG (exp, 1);
10555 tree arg1 = CALL_EXPR_ARG (exp, 2);
10556 rtx op0 = expand_normal (arg0);
10557 rtx op1 = expand_normal (arg1);
10558 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10559 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10561 enum rtx_code code;
10563 if (TREE_CODE (form) != INTEGER_CST)
10565 error ("argument 1 of __builtin_spe_predicate must be a constant");
10569 form_int = TREE_INT_CST_LOW (form);
10571 gcc_assert (mode0 == mode1);
10573 if (arg0 == error_mark_node || arg1 == error_mark_node)
10577 || GET_MODE (target) != SImode
10578 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
10579 target = gen_reg_rtx (SImode);
10581 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10582 op0 = copy_to_mode_reg (mode0, op0);
10583 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10584 op1 = copy_to_mode_reg (mode1, op1);
10586 scratch = gen_reg_rtx (CCmode);
10588 pat = GEN_FCN (icode) (scratch, op0, op1);
10593 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
10594 _lower_. We use one compare, but look in different bits of the
10595 CR for each variant.
10597 There are 2 elements in each SPE simd type (upper/lower). The CR
10598 bits are set as follows:
10600 BIT0 | BIT 1 | BIT 2 | BIT 3
10601 U | L | (U | L) | (U & L)
10603 So, for an "all" relationship, BIT 3 would be set.
10604 For an "any" relationship, BIT 2 would be set. Etc.
10606 Following traditional nomenclature, these bits map to:
10608 BIT0 | BIT 1 | BIT 2 | BIT 3
10611 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
10616 /* All variant. OV bit. */
10618 /* We need to get to the OV bit, which is the ORDERED bit. We
10619 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
10620 that's ugly and will make validate_condition_mode die.
10621 So let's just use another pattern. */
10622 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10624 /* Any variant. EQ bit. */
10628 /* Upper variant. LT bit. */
10632 /* Lower variant. GT bit. */
10637 error ("argument 1 of __builtin_spe_predicate is out of range");
10641 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10642 emit_move_insn (target, tmp);
10647 /* The evsel builtins look like this:
10649 e = __builtin_spe_evsel_OP (a, b, c, d);
10651 and work like this:
10653 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
10654 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
10658 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
10661 tree arg0 = CALL_EXPR_ARG (exp, 0);
10662 tree arg1 = CALL_EXPR_ARG (exp, 1);
10663 tree arg2 = CALL_EXPR_ARG (exp, 2);
10664 tree arg3 = CALL_EXPR_ARG (exp, 3);
10665 rtx op0 = expand_normal (arg0);
10666 rtx op1 = expand_normal (arg1);
10667 rtx op2 = expand_normal (arg2);
10668 rtx op3 = expand_normal (arg3);
10669 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10670 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10672 gcc_assert (mode0 == mode1);
10674 if (arg0 == error_mark_node || arg1 == error_mark_node
10675 || arg2 == error_mark_node || arg3 == error_mark_node)
10679 || GET_MODE (target) != mode0
10680 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
10681 target = gen_reg_rtx (mode0);
10683 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10684 op0 = copy_to_mode_reg (mode0, op0);
10685 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10686 op1 = copy_to_mode_reg (mode0, op1);
10687 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10688 op2 = copy_to_mode_reg (mode0, op2);
10689 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
10690 op3 = copy_to_mode_reg (mode0, op3);
10692 /* Generate the compare. */
10693 scratch = gen_reg_rtx (CCmode);
10694 pat = GEN_FCN (icode) (scratch, op0, op1);
10699 if (mode0 == V2SImode)
10700 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
10702 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
10707 /* Expand an expression EXP that calls a built-in function,
10708 with result going to TARGET if that's convenient
10709 (and in mode MODE if that's convenient).
10710 SUBTARGET may be used as the target for computing one of EXP's operands.
10711 IGNORE is nonzero if the value is to be ignored. */
10714 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10715 enum machine_mode mode ATTRIBUTE_UNUSED,
10716 int ignore ATTRIBUTE_UNUSED)
10718 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10719 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10720 const struct builtin_description *d;
10725 if (fcode == RS6000_BUILTIN_RECIP)
10726 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
10728 if (fcode == RS6000_BUILTIN_RECIPF)
10729 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
10731 if (fcode == RS6000_BUILTIN_RSQRTF)
10732 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
10734 if (fcode == RS6000_BUILTIN_BSWAP_HI)
10735 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
10737 if (fcode == POWER7_BUILTIN_BPERMD)
10738 return rs6000_expand_binop_builtin (((TARGET_64BIT)
10739 ? CODE_FOR_bpermd_di
10740 : CODE_FOR_bpermd_si), exp, target);
10742 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
10743 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10745 int icode = (int) CODE_FOR_altivec_lvsr;
10746 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10747 enum machine_mode mode = insn_data[icode].operand[1].mode;
10751 gcc_assert (TARGET_ALTIVEC);
10753 arg = CALL_EXPR_ARG (exp, 0);
10754 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
10755 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
10756 addr = memory_address (mode, op);
10757 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10761 /* For the load case need to negate the address. */
10762 op = gen_reg_rtx (GET_MODE (addr));
10763 emit_insn (gen_rtx_SET (VOIDmode, op,
10764 gen_rtx_NEG (GET_MODE (addr), addr)));
10766 op = gen_rtx_MEM (mode, op);
10769 || GET_MODE (target) != tmode
10770 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10771 target = gen_reg_rtx (tmode);
10773 /*pat = gen_altivec_lvsr (target, op);*/
10774 pat = GEN_FCN (icode) (target, op);
10782 /* FIXME: There's got to be a nicer way to handle this case than
10783 constructing a new CALL_EXPR. */
10784 if (fcode == ALTIVEC_BUILTIN_VCFUX
10785 || fcode == ALTIVEC_BUILTIN_VCFSX
10786 || fcode == ALTIVEC_BUILTIN_VCTUXS
10787 || fcode == ALTIVEC_BUILTIN_VCTSXS)
10789 if (call_expr_nargs (exp) == 1)
10790 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
10791 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
10794 if (TARGET_ALTIVEC)
10796 ret = altivec_expand_builtin (exp, target, &success);
10803 ret = spe_expand_builtin (exp, target, &success);
10808 if (TARGET_PAIRED_FLOAT)
10810 ret = paired_expand_builtin (exp, target, &success);
10816 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
10818 /* Handle simple unary operations. */
10819 d = (struct builtin_description *) bdesc_1arg;
10820 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
10821 if (d->code == fcode)
10822 return rs6000_expand_unop_builtin (d->icode, exp, target);
10824 /* Handle simple binary operations. */
10825 d = (struct builtin_description *) bdesc_2arg;
10826 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
10827 if (d->code == fcode)
10828 return rs6000_expand_binop_builtin (d->icode, exp, target);
10830 /* Handle simple ternary operations. */
10832 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
10833 if (d->code == fcode)
10834 return rs6000_expand_ternop_builtin (d->icode, exp, target);
10836 gcc_unreachable ();
10840 rs6000_init_builtins (void)
10844 V2SI_type_node = build_vector_type (intSI_type_node, 2);
10845 V2SF_type_node = build_vector_type (float_type_node, 2);
10846 V2DI_type_node = build_vector_type (intDI_type_node, 2);
10847 V2DF_type_node = build_vector_type (double_type_node, 2);
10848 V4HI_type_node = build_vector_type (intHI_type_node, 4);
10849 V4SI_type_node = build_vector_type (intSI_type_node, 4);
10850 V4SF_type_node = build_vector_type (float_type_node, 4);
10851 V8HI_type_node = build_vector_type (intHI_type_node, 8);
10852 V16QI_type_node = build_vector_type (intQI_type_node, 16);
10854 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
10855 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
10856 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
10857 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
10859 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
10860 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
10861 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
10862 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
10864 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
10865 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
10866 'vector unsigned short'. */
10868 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
10869 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
10870 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
10871 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
10872 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
10874 long_integer_type_internal_node = long_integer_type_node;
10875 long_unsigned_type_internal_node = long_unsigned_type_node;
10876 intQI_type_internal_node = intQI_type_node;
10877 uintQI_type_internal_node = unsigned_intQI_type_node;
10878 intHI_type_internal_node = intHI_type_node;
10879 uintHI_type_internal_node = unsigned_intHI_type_node;
10880 intSI_type_internal_node = intSI_type_node;
10881 uintSI_type_internal_node = unsigned_intSI_type_node;
10882 intDI_type_internal_node = intDI_type_node;
10883 uintDI_type_internal_node = unsigned_intDI_type_node;
10884 float_type_internal_node = float_type_node;
10885 double_type_internal_node = float_type_node;
10886 void_type_internal_node = void_type_node;
10888 /* Initialize the modes for builtin_function_type, mapping a machine mode to
10890 builtin_mode_to_type[QImode][0] = integer_type_node;
10891 builtin_mode_to_type[HImode][0] = integer_type_node;
10892 builtin_mode_to_type[SImode][0] = intSI_type_node;
10893 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
10894 builtin_mode_to_type[DImode][0] = intDI_type_node;
10895 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
10896 builtin_mode_to_type[SFmode][0] = float_type_node;
10897 builtin_mode_to_type[DFmode][0] = double_type_node;
10898 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
10899 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
10900 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
10901 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
10902 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
10903 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
10904 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
10905 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
10906 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
10907 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
10908 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
10909 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
10910 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
10912 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10913 get_identifier ("__bool char"),
10914 bool_char_type_node);
10915 TYPE_NAME (bool_char_type_node) = tdecl;
10916 (*lang_hooks.decls.pushdecl) (tdecl);
10917 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10918 get_identifier ("__bool short"),
10919 bool_short_type_node);
10920 TYPE_NAME (bool_short_type_node) = tdecl;
10921 (*lang_hooks.decls.pushdecl) (tdecl);
10922 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10923 get_identifier ("__bool int"),
10924 bool_int_type_node);
10925 TYPE_NAME (bool_int_type_node) = tdecl;
10926 (*lang_hooks.decls.pushdecl) (tdecl);
10927 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
10929 TYPE_NAME (pixel_type_node) = tdecl;
10930 (*lang_hooks.decls.pushdecl) (tdecl);
10932 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
10933 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
10934 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
10935 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
10936 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
10938 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10939 get_identifier ("__vector unsigned char"),
10940 unsigned_V16QI_type_node);
10941 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
10942 (*lang_hooks.decls.pushdecl) (tdecl);
10943 tdecl = build_decl (BUILTINS_LOCATION,
10944 TYPE_DECL, get_identifier ("__vector signed char"),
10946 TYPE_NAME (V16QI_type_node) = tdecl;
10947 (*lang_hooks.decls.pushdecl) (tdecl);
10948 tdecl = build_decl (BUILTINS_LOCATION,
10949 TYPE_DECL, get_identifier ("__vector __bool char"),
10950 bool_V16QI_type_node);
10951 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
10952 (*lang_hooks.decls.pushdecl) (tdecl);
10954 tdecl = build_decl (BUILTINS_LOCATION,
10955 TYPE_DECL, get_identifier ("__vector unsigned short"),
10956 unsigned_V8HI_type_node);
10957 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
10958 (*lang_hooks.decls.pushdecl) (tdecl);
10959 tdecl = build_decl (BUILTINS_LOCATION,
10960 TYPE_DECL, get_identifier ("__vector signed short"),
10962 TYPE_NAME (V8HI_type_node) = tdecl;
10963 (*lang_hooks.decls.pushdecl) (tdecl);
10964 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10965 get_identifier ("__vector __bool short"),
10966 bool_V8HI_type_node);
10967 TYPE_NAME (bool_V8HI_type_node) = tdecl;
10968 (*lang_hooks.decls.pushdecl) (tdecl);
10970 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10971 get_identifier ("__vector unsigned int"),
10972 unsigned_V4SI_type_node);
10973 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
10974 (*lang_hooks.decls.pushdecl) (tdecl);
10975 tdecl = build_decl (BUILTINS_LOCATION,
10976 TYPE_DECL, get_identifier ("__vector signed int"),
10978 TYPE_NAME (V4SI_type_node) = tdecl;
10979 (*lang_hooks.decls.pushdecl) (tdecl);
10980 tdecl = build_decl (BUILTINS_LOCATION,
10981 TYPE_DECL, get_identifier ("__vector __bool int"),
10982 bool_V4SI_type_node);
10983 TYPE_NAME (bool_V4SI_type_node) = tdecl;
10984 (*lang_hooks.decls.pushdecl) (tdecl);
10986 tdecl = build_decl (BUILTINS_LOCATION,
10987 TYPE_DECL, get_identifier ("__vector float"),
10989 TYPE_NAME (V4SF_type_node) = tdecl;
10990 (*lang_hooks.decls.pushdecl) (tdecl);
10991 tdecl = build_decl (BUILTINS_LOCATION,
10992 TYPE_DECL, get_identifier ("__vector __pixel"),
10993 pixel_V8HI_type_node);
10994 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
10995 (*lang_hooks.decls.pushdecl) (tdecl);
10999 tdecl = build_decl (BUILTINS_LOCATION,
11000 TYPE_DECL, get_identifier ("__vector double"),
11002 TYPE_NAME (V2DF_type_node) = tdecl;
11003 (*lang_hooks.decls.pushdecl) (tdecl);
11005 tdecl = build_decl (BUILTINS_LOCATION,
11006 TYPE_DECL, get_identifier ("__vector long"),
11008 TYPE_NAME (V2DI_type_node) = tdecl;
11009 (*lang_hooks.decls.pushdecl) (tdecl);
11011 tdecl = build_decl (BUILTINS_LOCATION,
11012 TYPE_DECL, get_identifier ("__vector unsigned long"),
11013 unsigned_V2DI_type_node);
11014 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11015 (*lang_hooks.decls.pushdecl) (tdecl);
11017 tdecl = build_decl (BUILTINS_LOCATION,
11018 TYPE_DECL, get_identifier ("__vector __bool long"),
11019 bool_V2DI_type_node);
11020 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11021 (*lang_hooks.decls.pushdecl) (tdecl);
11024 if (TARGET_PAIRED_FLOAT)
11025 paired_init_builtins ();
11027 spe_init_builtins ();
11028 if (TARGET_ALTIVEC)
11029 altivec_init_builtins ();
11030 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11031 rs6000_common_init_builtins ();
11032 if (TARGET_PPC_GFXOPT)
11034 tree ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11035 RS6000_BUILTIN_RECIPF,
11036 "__builtin_recipdivf");
11037 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11038 RS6000_BUILTIN_RECIPF);
11040 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11041 RS6000_BUILTIN_RSQRTF,
11042 "__builtin_rsqrtf");
11043 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11044 RS6000_BUILTIN_RSQRTF);
11046 if (TARGET_POPCNTB)
11048 tree ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11049 RS6000_BUILTIN_RECIP,
11050 "__builtin_recipdiv");
11051 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11052 RS6000_BUILTIN_RECIP);
11055 if (TARGET_POPCNTD)
11057 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11058 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11059 POWER7_BUILTIN_BPERMD,
11060 "__builtin_bpermd");
11061 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11062 POWER7_BUILTIN_BPERMD);
11064 if (TARGET_POWERPC)
11066 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11067 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11068 unsigned_intHI_type_node,
11070 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11071 RS6000_BUILTIN_BSWAP_HI);
11075 /* AIX libm provides clog as __clog. */
11076 if (built_in_decls [BUILT_IN_CLOG])
11077 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11080 #ifdef SUBTARGET_INIT_BUILTINS
11081 SUBTARGET_INIT_BUILTINS;
11085 /* Search through a set of builtins and enable the mask bits.
11086 DESC is an array of builtins.
11087 SIZE is the total number of builtins.
11088 START is the builtin enum at which to start.
11089 END is the builtin enum at which to end. */
11091 enable_mask_for_builtins (struct builtin_description *desc, int size,
11092 enum rs6000_builtins start,
11093 enum rs6000_builtins end)
11097 for (i = 0; i < size; ++i)
11098 if (desc[i].code == start)
11104 for (; i < size; ++i)
11106 /* Flip all the bits on. */
11107 desc[i].mask = target_flags;
11108 if (desc[i].code == end)
11114 spe_init_builtins (void)
11116 tree endlink = void_list_node;
11117 tree puint_type_node = build_pointer_type (unsigned_type_node);
11118 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11119 struct builtin_description *d;
11122 tree v2si_ftype_4_v2si
11123 = build_function_type
11124 (opaque_V2SI_type_node,
11125 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11126 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11127 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11128 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11131 tree v2sf_ftype_4_v2sf
11132 = build_function_type
11133 (opaque_V2SF_type_node,
11134 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11135 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11136 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11137 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11140 tree int_ftype_int_v2si_v2si
11141 = build_function_type
11142 (integer_type_node,
11143 tree_cons (NULL_TREE, integer_type_node,
11144 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11145 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11148 tree int_ftype_int_v2sf_v2sf
11149 = build_function_type
11150 (integer_type_node,
11151 tree_cons (NULL_TREE, integer_type_node,
11152 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11153 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11156 tree void_ftype_v2si_puint_int
11157 = build_function_type (void_type_node,
11158 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11159 tree_cons (NULL_TREE, puint_type_node,
11160 tree_cons (NULL_TREE,
11164 tree void_ftype_v2si_puint_char
11165 = build_function_type (void_type_node,
11166 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11167 tree_cons (NULL_TREE, puint_type_node,
11168 tree_cons (NULL_TREE,
11172 tree void_ftype_v2si_pv2si_int
11173 = build_function_type (void_type_node,
11174 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11175 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11176 tree_cons (NULL_TREE,
11180 tree void_ftype_v2si_pv2si_char
11181 = build_function_type (void_type_node,
11182 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11183 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11184 tree_cons (NULL_TREE,
11188 tree void_ftype_int
11189 = build_function_type (void_type_node,
11190 tree_cons (NULL_TREE, integer_type_node, endlink));
11192 tree int_ftype_void
11193 = build_function_type (integer_type_node, endlink);
11195 tree v2si_ftype_pv2si_int
11196 = build_function_type (opaque_V2SI_type_node,
11197 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11198 tree_cons (NULL_TREE, integer_type_node,
11201 tree v2si_ftype_puint_int
11202 = build_function_type (opaque_V2SI_type_node,
11203 tree_cons (NULL_TREE, puint_type_node,
11204 tree_cons (NULL_TREE, integer_type_node,
11207 tree v2si_ftype_pushort_int
11208 = build_function_type (opaque_V2SI_type_node,
11209 tree_cons (NULL_TREE, pushort_type_node,
11210 tree_cons (NULL_TREE, integer_type_node,
11213 tree v2si_ftype_signed_char
11214 = build_function_type (opaque_V2SI_type_node,
11215 tree_cons (NULL_TREE, signed_char_type_node,
11218 /* The initialization of the simple binary and unary builtins is
11219 done in rs6000_common_init_builtins, but we have to enable the
11220 mask bits here manually because we have run out of `target_flags'
11221 bits. We really need to redesign this mask business. */
11223 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11224 ARRAY_SIZE (bdesc_2arg),
11225 SPE_BUILTIN_EVADDW,
11226 SPE_BUILTIN_EVXOR);
11227 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11228 ARRAY_SIZE (bdesc_1arg),
11230 SPE_BUILTIN_EVSUBFUSIAAW);
11231 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11232 ARRAY_SIZE (bdesc_spe_predicates),
11233 SPE_BUILTIN_EVCMPEQ,
11234 SPE_BUILTIN_EVFSTSTLT);
11235 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11236 ARRAY_SIZE (bdesc_spe_evsel),
11237 SPE_BUILTIN_EVSEL_CMPGTS,
11238 SPE_BUILTIN_EVSEL_FSTSTEQ);
11240 (*lang_hooks.decls.pushdecl)
11241 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11242 get_identifier ("__ev64_opaque__"),
11243 opaque_V2SI_type_node));
11245 /* Initialize irregular SPE builtins. */
11247 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11248 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11249 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11250 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11251 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11252 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11253 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11254 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11255 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11256 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11257 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11258 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11259 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11260 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11261 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11262 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11263 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11264 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11267 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11268 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11269 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11270 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11271 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11272 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11273 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11274 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11275 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11276 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11277 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11278 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11279 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11280 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11281 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11282 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11283 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11284 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11285 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11286 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11287 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11288 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11291 d = (struct builtin_description *) bdesc_spe_predicates;
11292 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11296 switch (insn_data[d->icode].operand[1].mode)
11299 type = int_ftype_int_v2si_v2si;
11302 type = int_ftype_int_v2sf_v2sf;
11305 gcc_unreachable ();
11308 def_builtin (d->mask, d->name, type, d->code);
11311 /* Evsel predicates. */
11312 d = (struct builtin_description *) bdesc_spe_evsel;
11313 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11317 switch (insn_data[d->icode].operand[1].mode)
11320 type = v2si_ftype_4_v2si;
11323 type = v2sf_ftype_4_v2sf;
11326 gcc_unreachable ();
11329 def_builtin (d->mask, d->name, type, d->code);
11334 paired_init_builtins (void)
11336 const struct builtin_description *d;
11338 tree endlink = void_list_node;
11340 tree int_ftype_int_v2sf_v2sf
11341 = build_function_type
11342 (integer_type_node,
11343 tree_cons (NULL_TREE, integer_type_node,
11344 tree_cons (NULL_TREE, V2SF_type_node,
11345 tree_cons (NULL_TREE, V2SF_type_node,
11347 tree pcfloat_type_node =
11348 build_pointer_type (build_qualified_type
11349 (float_type_node, TYPE_QUAL_CONST));
11351 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
11352 long_integer_type_node,
11355 tree void_ftype_v2sf_long_pcfloat =
11356 build_function_type_list (void_type_node,
11358 long_integer_type_node,
11363 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
11364 PAIRED_BUILTIN_LX);
11367 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
11368 PAIRED_BUILTIN_STX);
11371 d = bdesc_paired_preds;
11372 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
11376 switch (insn_data[d->icode].operand[1].mode)
11379 type = int_ftype_int_v2sf_v2sf;
11382 gcc_unreachable ();
11385 def_builtin (d->mask, d->name, type, d->code);
11390 altivec_init_builtins (void)
11392 const struct builtin_description *d;
11393 const struct builtin_description_predicates *dp;
11397 tree pfloat_type_node = build_pointer_type (float_type_node);
11398 tree pint_type_node = build_pointer_type (integer_type_node);
11399 tree pshort_type_node = build_pointer_type (short_integer_type_node);
11400 tree pchar_type_node = build_pointer_type (char_type_node);
11402 tree pvoid_type_node = build_pointer_type (void_type_node);
11404 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
11405 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
11406 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
11407 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
11409 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
11411 tree int_ftype_opaque
11412 = build_function_type_list (integer_type_node,
11413 opaque_V4SI_type_node, NULL_TREE);
11414 tree opaque_ftype_opaque
11415 = build_function_type (integer_type_node,
11417 tree opaque_ftype_opaque_int
11418 = build_function_type_list (opaque_V4SI_type_node,
11419 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
11420 tree opaque_ftype_opaque_opaque_int
11421 = build_function_type_list (opaque_V4SI_type_node,
11422 opaque_V4SI_type_node, opaque_V4SI_type_node,
11423 integer_type_node, NULL_TREE);
11424 tree int_ftype_int_opaque_opaque
11425 = build_function_type_list (integer_type_node,
11426 integer_type_node, opaque_V4SI_type_node,
11427 opaque_V4SI_type_node, NULL_TREE);
11428 tree int_ftype_int_v4si_v4si
11429 = build_function_type_list (integer_type_node,
11430 integer_type_node, V4SI_type_node,
11431 V4SI_type_node, NULL_TREE);
11432 tree v4sf_ftype_pcfloat
11433 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
11434 tree void_ftype_pfloat_v4sf
11435 = build_function_type_list (void_type_node,
11436 pfloat_type_node, V4SF_type_node, NULL_TREE);
11437 tree v4si_ftype_pcint
11438 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
11439 tree void_ftype_pint_v4si
11440 = build_function_type_list (void_type_node,
11441 pint_type_node, V4SI_type_node, NULL_TREE);
11442 tree v8hi_ftype_pcshort
11443 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
11444 tree void_ftype_pshort_v8hi
11445 = build_function_type_list (void_type_node,
11446 pshort_type_node, V8HI_type_node, NULL_TREE);
11447 tree v16qi_ftype_pcchar
11448 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
11449 tree void_ftype_pchar_v16qi
11450 = build_function_type_list (void_type_node,
11451 pchar_type_node, V16QI_type_node, NULL_TREE);
11452 tree void_ftype_v4si
11453 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
11454 tree v8hi_ftype_void
11455 = build_function_type (V8HI_type_node, void_list_node);
11456 tree void_ftype_void
11457 = build_function_type (void_type_node, void_list_node);
11458 tree void_ftype_int
11459 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
11461 tree opaque_ftype_long_pcvoid
11462 = build_function_type_list (opaque_V4SI_type_node,
11463 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11464 tree v16qi_ftype_long_pcvoid
11465 = build_function_type_list (V16QI_type_node,
11466 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11467 tree v8hi_ftype_long_pcvoid
11468 = build_function_type_list (V8HI_type_node,
11469 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11470 tree v4si_ftype_long_pcvoid
11471 = build_function_type_list (V4SI_type_node,
11472 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11474 tree void_ftype_opaque_long_pvoid
11475 = build_function_type_list (void_type_node,
11476 opaque_V4SI_type_node, long_integer_type_node,
11477 pvoid_type_node, NULL_TREE);
11478 tree void_ftype_v4si_long_pvoid
11479 = build_function_type_list (void_type_node,
11480 V4SI_type_node, long_integer_type_node,
11481 pvoid_type_node, NULL_TREE);
11482 tree void_ftype_v16qi_long_pvoid
11483 = build_function_type_list (void_type_node,
11484 V16QI_type_node, long_integer_type_node,
11485 pvoid_type_node, NULL_TREE);
11486 tree void_ftype_v8hi_long_pvoid
11487 = build_function_type_list (void_type_node,
11488 V8HI_type_node, long_integer_type_node,
11489 pvoid_type_node, NULL_TREE);
11490 tree int_ftype_int_v8hi_v8hi
11491 = build_function_type_list (integer_type_node,
11492 integer_type_node, V8HI_type_node,
11493 V8HI_type_node, NULL_TREE);
11494 tree int_ftype_int_v16qi_v16qi
11495 = build_function_type_list (integer_type_node,
11496 integer_type_node, V16QI_type_node,
11497 V16QI_type_node, NULL_TREE);
11498 tree int_ftype_int_v4sf_v4sf
11499 = build_function_type_list (integer_type_node,
11500 integer_type_node, V4SF_type_node,
11501 V4SF_type_node, NULL_TREE);
11502 tree int_ftype_int_v2df_v2df
11503 = build_function_type_list (integer_type_node,
11504 integer_type_node, V2DF_type_node,
11505 V2DF_type_node, NULL_TREE);
11506 tree v4si_ftype_v4si
11507 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
11508 tree v8hi_ftype_v8hi
11509 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
11510 tree v16qi_ftype_v16qi
11511 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
11512 tree v4sf_ftype_v4sf
11513 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
11514 tree v2df_ftype_v2df
11515 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
11516 tree void_ftype_pcvoid_int_int
11517 = build_function_type_list (void_type_node,
11518 pcvoid_type_node, integer_type_node,
11519 integer_type_node, NULL_TREE);
11521 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
11522 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
11523 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
11524 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
11525 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
11526 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
11527 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
11528 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
11529 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
11530 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
11531 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
11532 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
11533 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
11534 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
11535 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
11536 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
11537 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
11538 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
11539 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
11540 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
11541 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
11542 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
11543 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
11544 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
11545 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
11546 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
11547 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
11548 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
11549 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
11550 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
11551 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
11552 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
11553 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
11554 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
11555 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
11556 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
11557 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
11558 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
11559 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
11560 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
11561 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
11562 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
11563 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
11564 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
11565 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
11566 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
11568 if (rs6000_cpu == PROCESSOR_CELL)
11570 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
11571 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
11572 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
11573 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
11575 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
11576 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
11577 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
11578 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
11580 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
11581 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
11582 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
11583 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
11585 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
11586 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
11587 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
11588 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
11590 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
11591 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
11592 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
11594 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
11595 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
11596 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
11597 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
11598 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
11599 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
11600 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
11601 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
11602 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
11603 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
11604 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
11605 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
11607 /* Add the DST variants. */
11609 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11610 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
11612 /* Initialize the predicates. */
11613 dp = bdesc_altivec_preds;
11614 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11616 enum machine_mode mode1;
11618 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11619 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11620 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
11621 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
11626 mode1 = insn_data[dp->icode].operand[1].mode;
11631 type = int_ftype_int_opaque_opaque;
11634 type = int_ftype_int_v4si_v4si;
11637 type = int_ftype_int_v8hi_v8hi;
11640 type = int_ftype_int_v16qi_v16qi;
11643 type = int_ftype_int_v4sf_v4sf;
11646 type = int_ftype_int_v2df_v2df;
11649 gcc_unreachable ();
11652 def_builtin (dp->mask, dp->name, type, dp->code);
11655 /* Initialize the abs* operators. */
11657 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11659 enum machine_mode mode0;
11662 mode0 = insn_data[d->icode].operand[0].mode;
11667 type = v4si_ftype_v4si;
11670 type = v8hi_ftype_v8hi;
11673 type = v16qi_ftype_v16qi;
11676 type = v4sf_ftype_v4sf;
11679 type = v2df_ftype_v2df;
11682 gcc_unreachable ();
11685 def_builtin (d->mask, d->name, type, d->code);
11688 if (TARGET_ALTIVEC)
11692 /* Initialize target builtin that implements
11693 targetm.vectorize.builtin_mask_for_load. */
11695 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
11696 v16qi_ftype_long_pcvoid,
11697 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
11698 BUILT_IN_MD, NULL, NULL_TREE);
11699 TREE_READONLY (decl) = 1;
11700 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
11701 altivec_builtin_mask_for_load = decl;
11704 /* Access to the vec_init patterns. */
11705 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
11706 integer_type_node, integer_type_node,
11707 integer_type_node, NULL_TREE);
11708 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
11709 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
11711 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
11712 short_integer_type_node,
11713 short_integer_type_node,
11714 short_integer_type_node,
11715 short_integer_type_node,
11716 short_integer_type_node,
11717 short_integer_type_node,
11718 short_integer_type_node, NULL_TREE);
11719 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
11720 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
11722 ftype = build_function_type_list (V16QI_type_node, char_type_node,
11723 char_type_node, char_type_node,
11724 char_type_node, char_type_node,
11725 char_type_node, char_type_node,
11726 char_type_node, char_type_node,
11727 char_type_node, char_type_node,
11728 char_type_node, char_type_node,
11729 char_type_node, char_type_node,
11730 char_type_node, NULL_TREE);
11731 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
11732 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
11734 ftype = build_function_type_list (V4SF_type_node, float_type_node,
11735 float_type_node, float_type_node,
11736 float_type_node, NULL_TREE);
11737 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
11738 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
11742 ftype = build_function_type_list (V2DF_type_node, double_type_node,
11743 double_type_node, NULL_TREE);
11744 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
11745 VSX_BUILTIN_VEC_INIT_V2DF);
11747 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
11748 intDI_type_node, NULL_TREE);
11749 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
11750 VSX_BUILTIN_VEC_INIT_V2DI);
11753 /* Access to the vec_set patterns. */
11754 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
11756 integer_type_node, NULL_TREE);
11757 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
11758 ALTIVEC_BUILTIN_VEC_SET_V4SI);
11760 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
11762 integer_type_node, NULL_TREE);
11763 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
11764 ALTIVEC_BUILTIN_VEC_SET_V8HI);
11766 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
11768 integer_type_node, NULL_TREE);
11769 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
11770 ALTIVEC_BUILTIN_VEC_SET_V16QI);
11772 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
11774 integer_type_node, NULL_TREE);
11775 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
11776 ALTIVEC_BUILTIN_VEC_SET_V4SF);
11780 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
11782 integer_type_node, NULL_TREE);
11783 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
11784 VSX_BUILTIN_VEC_SET_V2DF);
11786 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
11788 integer_type_node, NULL_TREE);
11789 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
11790 VSX_BUILTIN_VEC_SET_V2DI);
11793 /* Access to the vec_extract patterns. */
11794 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
11795 integer_type_node, NULL_TREE);
11796 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
11797 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
11799 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
11800 integer_type_node, NULL_TREE);
11801 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
11802 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
11804 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
11805 integer_type_node, NULL_TREE);
11806 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
11807 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
11809 ftype = build_function_type_list (float_type_node, V4SF_type_node,
11810 integer_type_node, NULL_TREE);
11811 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
11812 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
11816 ftype = build_function_type_list (double_type_node, V2DF_type_node,
11817 integer_type_node, NULL_TREE);
11818 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
11819 VSX_BUILTIN_VEC_EXT_V2DF);
11821 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
11822 integer_type_node, NULL_TREE);
11823 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
11824 VSX_BUILTIN_VEC_EXT_V2DI);
11828 /* Hash function for builtin functions with up to 3 arguments and a return
11831 builtin_hash_function (const void *hash_entry)
11835 const struct builtin_hash_struct *bh =
11836 (const struct builtin_hash_struct *) hash_entry;
11838 for (i = 0; i < 4; i++)
11840 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
11841 ret = (ret * 2) + bh->uns_p[i];
11847 /* Compare builtin hash entries H1 and H2 for equivalence. */
11849 builtin_hash_eq (const void *h1, const void *h2)
11851 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
11852 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
11854 return ((p1->mode[0] == p2->mode[0])
11855 && (p1->mode[1] == p2->mode[1])
11856 && (p1->mode[2] == p2->mode[2])
11857 && (p1->mode[3] == p2->mode[3])
11858 && (p1->uns_p[0] == p2->uns_p[0])
11859 && (p1->uns_p[1] == p2->uns_p[1])
11860 && (p1->uns_p[2] == p2->uns_p[2])
11861 && (p1->uns_p[3] == p2->uns_p[3]));
11864 /* Map types for builtin functions with an explicit return type and up to 3
11865 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
11866 of the argument. */
11868 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
11869 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
11870 enum rs6000_builtins builtin, const char *name)
11872 struct builtin_hash_struct h;
11873 struct builtin_hash_struct *h2;
11877 tree ret_type = NULL_TREE;
11878 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
11881 /* Create builtin_hash_table. */
11882 if (builtin_hash_table == NULL)
11883 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
11884 builtin_hash_eq, NULL);
11886 h.type = NULL_TREE;
11887 h.mode[0] = mode_ret;
11888 h.mode[1] = mode_arg0;
11889 h.mode[2] = mode_arg1;
11890 h.mode[3] = mode_arg2;
11896 /* If the builtin is a type that produces unsigned results or takes unsigned
11897 arguments, and it is returned as a decl for the vectorizer (such as
11898 widening multiplies, permute), make sure the arguments and return value
11899 are type correct. */
11902 /* unsigned 2 argument functions. */
11903 case ALTIVEC_BUILTIN_VMULEUB_UNS:
11904 case ALTIVEC_BUILTIN_VMULEUH_UNS:
11905 case ALTIVEC_BUILTIN_VMULOUB_UNS:
11906 case ALTIVEC_BUILTIN_VMULOUH_UNS:
11912 /* unsigned 3 argument functions. */
11913 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
11914 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
11915 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
11916 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
11917 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
11918 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
11919 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
11920 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
11921 case VSX_BUILTIN_VPERM_16QI_UNS:
11922 case VSX_BUILTIN_VPERM_8HI_UNS:
11923 case VSX_BUILTIN_VPERM_4SI_UNS:
11924 case VSX_BUILTIN_VPERM_2DI_UNS:
11925 case VSX_BUILTIN_XXSEL_16QI_UNS:
11926 case VSX_BUILTIN_XXSEL_8HI_UNS:
11927 case VSX_BUILTIN_XXSEL_4SI_UNS:
11928 case VSX_BUILTIN_XXSEL_2DI_UNS:
11935 /* signed permute functions with unsigned char mask. */
11936 case ALTIVEC_BUILTIN_VPERM_16QI:
11937 case ALTIVEC_BUILTIN_VPERM_8HI:
11938 case ALTIVEC_BUILTIN_VPERM_4SI:
11939 case ALTIVEC_BUILTIN_VPERM_4SF:
11940 case ALTIVEC_BUILTIN_VPERM_2DI:
11941 case ALTIVEC_BUILTIN_VPERM_2DF:
11942 case VSX_BUILTIN_VPERM_16QI:
11943 case VSX_BUILTIN_VPERM_8HI:
11944 case VSX_BUILTIN_VPERM_4SI:
11945 case VSX_BUILTIN_VPERM_4SF:
11946 case VSX_BUILTIN_VPERM_2DI:
11947 case VSX_BUILTIN_VPERM_2DF:
11951 /* unsigned args, signed return. */
11952 case VSX_BUILTIN_XVCVUXDDP_UNS:
11953 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
11957 /* signed args, unsigned return. */
11958 case VSX_BUILTIN_XVCVDPUXDS_UNS:
11959 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
11967 /* Figure out how many args are present. */
11968 while (num_args > 0 && h.mode[num_args] == VOIDmode)
11972 fatal_error ("internal error: builtin function %s had no type", name);
11974 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
11975 if (!ret_type && h.uns_p[0])
11976 ret_type = builtin_mode_to_type[h.mode[0]][0];
11979 fatal_error ("internal error: builtin function %s had an unexpected "
11980 "return type %s", name, GET_MODE_NAME (h.mode[0]));
11982 for (i = 0; i < num_args; i++)
11984 int m = (int) h.mode[i+1];
11985 int uns_p = h.uns_p[i+1];
11987 arg_type[i] = builtin_mode_to_type[m][uns_p];
11988 if (!arg_type[i] && uns_p)
11989 arg_type[i] = builtin_mode_to_type[m][0];
11992 fatal_error ("internal error: builtin function %s, argument %d "
11993 "had unexpected argument type %s", name, i,
11994 GET_MODE_NAME (m));
11997 found = htab_find_slot (builtin_hash_table, &h, INSERT);
11998 if (*found == NULL)
12000 h2 = GGC_NEW (struct builtin_hash_struct);
12002 *found = (void *)h2;
12003 args = void_list_node;
12005 for (i = num_args - 1; i >= 0; i--)
12006 args = tree_cons (NULL_TREE, arg_type[i], args);
12008 h2->type = build_function_type (ret_type, args);
12011 return ((struct builtin_hash_struct *)(*found))->type;
12015 rs6000_common_init_builtins (void)
12017 const struct builtin_description *d;
12020 tree opaque_ftype_opaque = NULL_TREE;
12021 tree opaque_ftype_opaque_opaque = NULL_TREE;
12022 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12023 tree v2si_ftype_qi = NULL_TREE;
12024 tree v2si_ftype_v2si_qi = NULL_TREE;
12025 tree v2si_ftype_int_qi = NULL_TREE;
12027 if (!TARGET_PAIRED_FLOAT)
12029 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12030 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12033 /* Add the ternary operators. */
12035 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12038 int mask = d->mask;
12040 if ((mask != 0 && (mask & target_flags) == 0)
12041 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12044 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12045 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12046 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12047 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12049 if (! (type = opaque_ftype_opaque_opaque_opaque))
12050 type = opaque_ftype_opaque_opaque_opaque
12051 = build_function_type_list (opaque_V4SI_type_node,
12052 opaque_V4SI_type_node,
12053 opaque_V4SI_type_node,
12054 opaque_V4SI_type_node,
12059 enum insn_code icode = d->icode;
12060 if (d->name == 0 || icode == CODE_FOR_nothing)
12063 type = builtin_function_type (insn_data[icode].operand[0].mode,
12064 insn_data[icode].operand[1].mode,
12065 insn_data[icode].operand[2].mode,
12066 insn_data[icode].operand[3].mode,
12070 def_builtin (d->mask, d->name, type, d->code);
12073 /* Add the binary operators. */
12075 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12077 enum machine_mode mode0, mode1, mode2;
12079 int mask = d->mask;
12081 if ((mask != 0 && (mask & target_flags) == 0)
12082 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12085 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12086 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12087 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12088 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12090 if (! (type = opaque_ftype_opaque_opaque))
12091 type = opaque_ftype_opaque_opaque
12092 = build_function_type_list (opaque_V4SI_type_node,
12093 opaque_V4SI_type_node,
12094 opaque_V4SI_type_node,
12099 enum insn_code icode = d->icode;
12100 if (d->name == 0 || icode == CODE_FOR_nothing)
12103 mode0 = insn_data[icode].operand[0].mode;
12104 mode1 = insn_data[icode].operand[1].mode;
12105 mode2 = insn_data[icode].operand[2].mode;
12107 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12109 if (! (type = v2si_ftype_v2si_qi))
12110 type = v2si_ftype_v2si_qi
12111 = build_function_type_list (opaque_V2SI_type_node,
12112 opaque_V2SI_type_node,
12117 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12118 && mode2 == QImode)
12120 if (! (type = v2si_ftype_int_qi))
12121 type = v2si_ftype_int_qi
12122 = build_function_type_list (opaque_V2SI_type_node,
12129 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12133 def_builtin (d->mask, d->name, type, d->code);
12136 /* Add the simple unary operators. */
12137 d = (struct builtin_description *) bdesc_1arg;
12138 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12140 enum machine_mode mode0, mode1;
12142 int mask = d->mask;
12144 if ((mask != 0 && (mask & target_flags) == 0)
12145 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12148 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12149 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12150 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12151 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12153 if (! (type = opaque_ftype_opaque))
12154 type = opaque_ftype_opaque
12155 = build_function_type_list (opaque_V4SI_type_node,
12156 opaque_V4SI_type_node,
12161 enum insn_code icode = d->icode;
12162 if (d->name == 0 || icode == CODE_FOR_nothing)
12165 mode0 = insn_data[icode].operand[0].mode;
12166 mode1 = insn_data[icode].operand[1].mode;
12168 if (mode0 == V2SImode && mode1 == QImode)
12170 if (! (type = v2si_ftype_qi))
12171 type = v2si_ftype_qi
12172 = build_function_type_list (opaque_V2SI_type_node,
12178 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12182 def_builtin (d->mask, d->name, type, d->code);
12187 rs6000_init_libfuncs (void)
12189 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12190 && !TARGET_POWER2 && !TARGET_POWERPC)
12192 /* AIX library routines for float->int conversion. */
12193 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12194 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12195 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12196 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12199 if (!TARGET_IEEEQUAD)
12200 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12201 if (!TARGET_XL_COMPAT)
12203 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12204 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12205 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12206 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12208 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12210 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12211 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12212 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12213 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12214 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12215 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12216 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12218 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12219 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12220 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12221 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12222 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12223 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12224 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12225 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12228 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12229 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12233 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12234 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12235 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12236 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12240 /* 32-bit SVR4 quad floating point routines. */
12242 set_optab_libfunc (add_optab, TFmode, "_q_add");
12243 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12244 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12245 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12246 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12247 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12248 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12250 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12251 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12252 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12253 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12254 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12255 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12257 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12258 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12259 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12260 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12261 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12262 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12263 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12264 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12269 /* Expand a block clear operation, and return 1 if successful. Return 0
12270 if we should let the compiler generate normal code.
12272 operands[0] is the destination
12273 operands[1] is the length
12274 operands[3] is the alignment */
12277 expand_block_clear (rtx operands[])
12279 rtx orig_dest = operands[0];
12280 rtx bytes_rtx = operands[1];
12281 rtx align_rtx = operands[3];
12282 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12283 HOST_WIDE_INT align;
12284 HOST_WIDE_INT bytes;
12289 /* If this is not a fixed size move, just call memcpy */
12293 /* This must be a fixed size alignment */
12294 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12295 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12297 /* Anything to clear? */
12298 bytes = INTVAL (bytes_rtx);
12302 /* Use the builtin memset after a point, to avoid huge code bloat.
12303 When optimize_size, avoid any significant code bloat; calling
12304 memset is about 4 instructions, so allow for one instruction to
12305 load zero and three to do clearing. */
12306 if (TARGET_ALTIVEC && align >= 128)
12308 else if (TARGET_POWERPC64 && align >= 32)
12310 else if (TARGET_SPE && align >= 64)
12315 if (optimize_size && bytes > 3 * clear_step)
12317 if (! optimize_size && bytes > 8 * clear_step)
12320 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12322 enum machine_mode mode = BLKmode;
12325 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
12330 else if (bytes >= 8 && TARGET_SPE && align >= 64)
12335 else if (bytes >= 8 && TARGET_POWERPC64
12336 /* 64-bit loads and stores require word-aligned
12338 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12343 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12344 { /* move 4 bytes */
12348 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12349 { /* move 2 bytes */
12353 else /* move 1 byte at a time */
12359 dest = adjust_address (orig_dest, mode, offset);
12361 emit_move_insn (dest, CONST0_RTX (mode));
12368 /* Expand a block move operation, and return 1 if successful. Return 0
12369 if we should let the compiler generate normal code.
12371 operands[0] is the destination
12372 operands[1] is the source
12373 operands[2] is the length
12374 operands[3] is the alignment */
12376 #define MAX_MOVE_REG 4
12379 expand_block_move (rtx operands[])
12381 rtx orig_dest = operands[0];
12382 rtx orig_src = operands[1];
12383 rtx bytes_rtx = operands[2];
12384 rtx align_rtx = operands[3];
12385 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
12390 rtx stores[MAX_MOVE_REG];
12393 /* If this is not a fixed size move, just call memcpy */
12397 /* This must be a fixed size alignment */
12398 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12399 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12401 /* Anything to move? */
12402 bytes = INTVAL (bytes_rtx);
12406 /* store_one_arg depends on expand_block_move to handle at least the size of
12407 reg_parm_stack_space. */
12408 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
12411 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
12414 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
12415 rtx (*mov) (rtx, rtx);
12417 enum machine_mode mode = BLKmode;
12420 /* Altivec first, since it will be faster than a string move
12421 when it applies, and usually not significantly larger. */
12422 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
12426 gen_func.mov = gen_movv4si;
12428 else if (TARGET_SPE && bytes >= 8 && align >= 64)
12432 gen_func.mov = gen_movv2si;
12434 else if (TARGET_STRING
12435 && bytes > 24 /* move up to 32 bytes at a time */
12441 && ! fixed_regs[10]
12442 && ! fixed_regs[11]
12443 && ! fixed_regs[12])
12445 move_bytes = (bytes > 32) ? 32 : bytes;
12446 gen_func.movmemsi = gen_movmemsi_8reg;
12448 else if (TARGET_STRING
12449 && bytes > 16 /* move up to 24 bytes at a time */
12455 && ! fixed_regs[10])
12457 move_bytes = (bytes > 24) ? 24 : bytes;
12458 gen_func.movmemsi = gen_movmemsi_6reg;
12460 else if (TARGET_STRING
12461 && bytes > 8 /* move up to 16 bytes at a time */
12465 && ! fixed_regs[8])
12467 move_bytes = (bytes > 16) ? 16 : bytes;
12468 gen_func.movmemsi = gen_movmemsi_4reg;
12470 else if (bytes >= 8 && TARGET_POWERPC64
12471 /* 64-bit loads and stores require word-aligned
12473 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12477 gen_func.mov = gen_movdi;
12479 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
12480 { /* move up to 8 bytes at a time */
12481 move_bytes = (bytes > 8) ? 8 : bytes;
12482 gen_func.movmemsi = gen_movmemsi_2reg;
12484 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12485 { /* move 4 bytes */
12488 gen_func.mov = gen_movsi;
12490 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12491 { /* move 2 bytes */
12494 gen_func.mov = gen_movhi;
12496 else if (TARGET_STRING && bytes > 1)
12497 { /* move up to 4 bytes at a time */
12498 move_bytes = (bytes > 4) ? 4 : bytes;
12499 gen_func.movmemsi = gen_movmemsi_1reg;
12501 else /* move 1 byte at a time */
12505 gen_func.mov = gen_movqi;
12508 src = adjust_address (orig_src, mode, offset);
12509 dest = adjust_address (orig_dest, mode, offset);
12511 if (mode != BLKmode)
12513 rtx tmp_reg = gen_reg_rtx (mode);
12515 emit_insn ((*gen_func.mov) (tmp_reg, src));
12516 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
12519 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
12522 for (i = 0; i < num_reg; i++)
12523 emit_insn (stores[i]);
12527 if (mode == BLKmode)
12529 /* Move the address into scratch registers. The movmemsi
12530 patterns require zero offset. */
12531 if (!REG_P (XEXP (src, 0)))
12533 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
12534 src = replace_equiv_address (src, src_reg);
12536 set_mem_size (src, GEN_INT (move_bytes));
12538 if (!REG_P (XEXP (dest, 0)))
12540 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
12541 dest = replace_equiv_address (dest, dest_reg);
12543 set_mem_size (dest, GEN_INT (move_bytes));
12545 emit_insn ((*gen_func.movmemsi) (dest, src,
12546 GEN_INT (move_bytes & 31),
12555 /* Return a string to perform a load_multiple operation.
12556 operands[0] is the vector.
12557 operands[1] is the source address.
12558 operands[2] is the first destination register. */
12561 rs6000_output_load_multiple (rtx operands[3])
12563 /* We have to handle the case where the pseudo used to contain the address
12564 is assigned to one of the output registers. */
12566 int words = XVECLEN (operands[0], 0);
12569 if (XVECLEN (operands[0], 0) == 1)
12570 return "{l|lwz} %2,0(%1)";
12572 for (i = 0; i < words; i++)
12573 if (refers_to_regno_p (REGNO (operands[2]) + i,
12574 REGNO (operands[2]) + i + 1, operands[1], 0))
12578 xop[0] = GEN_INT (4 * (words-1));
12579 xop[1] = operands[1];
12580 xop[2] = operands[2];
12581 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
12586 xop[0] = GEN_INT (4 * (words-1));
12587 xop[1] = operands[1];
12588 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
12589 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);
12594 for (j = 0; j < words; j++)
12597 xop[0] = GEN_INT (j * 4);
12598 xop[1] = operands[1];
12599 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
12600 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
12602 xop[0] = GEN_INT (i * 4);
12603 xop[1] = operands[1];
12604 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
12609 return "{lsi|lswi} %2,%1,%N0";
12613 /* A validation routine: say whether CODE, a condition code, and MODE
12614 match. The other alternatives either don't make sense or should
12615 never be generated. */
12618 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
12620 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
12621 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
12622 && GET_MODE_CLASS (mode) == MODE_CC);
12624 /* These don't make sense. */
12625 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
12626 || mode != CCUNSmode);
12628 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
12629 || mode == CCUNSmode);
12631 gcc_assert (mode == CCFPmode
12632 || (code != ORDERED && code != UNORDERED
12633 && code != UNEQ && code != LTGT
12634 && code != UNGT && code != UNLT
12635 && code != UNGE && code != UNLE));
12637 /* These should never be generated except for
12638 flag_finite_math_only. */
12639 gcc_assert (mode != CCFPmode
12640 || flag_finite_math_only
12641 || (code != LE && code != GE
12642 && code != UNEQ && code != LTGT
12643 && code != UNGT && code != UNLT));
12645 /* These are invalid; the information is not there. */
12646 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
12650 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
12651 mask required to convert the result of a rotate insn into a shift
12652 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
12655 includes_lshift_p (rtx shiftop, rtx andop)
12657 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12659 shift_mask <<= INTVAL (shiftop);
12661 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12664 /* Similar, but for right shift. */
12667 includes_rshift_p (rtx shiftop, rtx andop)
12669 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12671 shift_mask >>= INTVAL (shiftop);
12673 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12676 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
12677 to perform a left shift. It must have exactly SHIFTOP least
12678 significant 0's, then one or more 1's, then zero or more 0's. */
12681 includes_rldic_lshift_p (rtx shiftop, rtx andop)
12683 if (GET_CODE (andop) == CONST_INT)
12685 HOST_WIDE_INT c, lsb, shift_mask;
12687 c = INTVAL (andop);
12688 if (c == 0 || c == ~0)
12692 shift_mask <<= INTVAL (shiftop);
12694 /* Find the least significant one bit. */
12697 /* It must coincide with the LSB of the shift mask. */
12698 if (-lsb != shift_mask)
12701 /* Invert to look for the next transition (if any). */
12704 /* Remove the low group of ones (originally low group of zeros). */
12707 /* Again find the lsb, and check we have all 1's above. */
12711 else if (GET_CODE (andop) == CONST_DOUBLE
12712 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12714 HOST_WIDE_INT low, high, lsb;
12715 HOST_WIDE_INT shift_mask_low, shift_mask_high;
12717 low = CONST_DOUBLE_LOW (andop);
12718 if (HOST_BITS_PER_WIDE_INT < 64)
12719 high = CONST_DOUBLE_HIGH (andop);
12721 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
12722 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
12725 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12727 shift_mask_high = ~0;
12728 if (INTVAL (shiftop) > 32)
12729 shift_mask_high <<= INTVAL (shiftop) - 32;
12731 lsb = high & -high;
12733 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
12739 lsb = high & -high;
12740 return high == -lsb;
12743 shift_mask_low = ~0;
12744 shift_mask_low <<= INTVAL (shiftop);
12748 if (-lsb != shift_mask_low)
12751 if (HOST_BITS_PER_WIDE_INT < 64)
12756 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12758 lsb = high & -high;
12759 return high == -lsb;
12763 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
12769 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
12770 to perform a left shift. It must have SHIFTOP or more least
12771 significant 0's, with the remainder of the word 1's. */
12774 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
12776 if (GET_CODE (andop) == CONST_INT)
12778 HOST_WIDE_INT c, lsb, shift_mask;
12781 shift_mask <<= INTVAL (shiftop);
12782 c = INTVAL (andop);
12784 /* Find the least significant one bit. */
12787 /* It must be covered by the shift mask.
12788 This test also rejects c == 0. */
12789 if ((lsb & shift_mask) == 0)
12792 /* Check we have all 1's above the transition, and reject all 1's. */
12793 return c == -lsb && lsb != 1;
12795 else if (GET_CODE (andop) == CONST_DOUBLE
12796 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12798 HOST_WIDE_INT low, lsb, shift_mask_low;
12800 low = CONST_DOUBLE_LOW (andop);
12802 if (HOST_BITS_PER_WIDE_INT < 64)
12804 HOST_WIDE_INT high, shift_mask_high;
12806 high = CONST_DOUBLE_HIGH (andop);
12810 shift_mask_high = ~0;
12811 if (INTVAL (shiftop) > 32)
12812 shift_mask_high <<= INTVAL (shiftop) - 32;
12814 lsb = high & -high;
12816 if ((lsb & shift_mask_high) == 0)
12819 return high == -lsb;
12825 shift_mask_low = ~0;
12826 shift_mask_low <<= INTVAL (shiftop);
12830 if ((lsb & shift_mask_low) == 0)
12833 return low == -lsb && lsb != 1;
12839 /* Return 1 if operands will generate a valid arguments to rlwimi
12840 instruction for insert with right shift in 64-bit mode. The mask may
12841 not start on the first bit or stop on the last bit because wrap-around
12842 effects of instruction do not correspond to semantics of RTL insn. */
12845 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
12847 if (INTVAL (startop) > 32
12848 && INTVAL (startop) < 64
12849 && INTVAL (sizeop) > 1
12850 && INTVAL (sizeop) + INTVAL (startop) < 64
12851 && INTVAL (shiftop) > 0
12852 && INTVAL (sizeop) + INTVAL (shiftop) < 32
12853 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
12859 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
12860 for lfq and stfq insns iff the registers are hard registers. */
12863 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
12865 /* We might have been passed a SUBREG. */
12866 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
12869 /* We might have been passed non floating point registers. */
12870 if (!FP_REGNO_P (REGNO (reg1))
12871 || !FP_REGNO_P (REGNO (reg2)))
12874 return (REGNO (reg1) == REGNO (reg2) - 1);
12877 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
12878 addr1 and addr2 must be in consecutive memory locations
12879 (addr2 == addr1 + 8). */
12882 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
12885 unsigned int reg1, reg2;
12886 int offset1, offset2;
12888 /* The mems cannot be volatile. */
12889 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
12892 addr1 = XEXP (mem1, 0);
12893 addr2 = XEXP (mem2, 0);
12895 /* Extract an offset (if used) from the first addr. */
12896 if (GET_CODE (addr1) == PLUS)
12898 /* If not a REG, return zero. */
12899 if (GET_CODE (XEXP (addr1, 0)) != REG)
12903 reg1 = REGNO (XEXP (addr1, 0));
12904 /* The offset must be constant! */
12905 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
12907 offset1 = INTVAL (XEXP (addr1, 1));
12910 else if (GET_CODE (addr1) != REG)
12914 reg1 = REGNO (addr1);
12915 /* This was a simple (mem (reg)) expression. Offset is 0. */
12919 /* And now for the second addr. */
12920 if (GET_CODE (addr2) == PLUS)
12922 /* If not a REG, return zero. */
12923 if (GET_CODE (XEXP (addr2, 0)) != REG)
12927 reg2 = REGNO (XEXP (addr2, 0));
12928 /* The offset must be constant. */
12929 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
12931 offset2 = INTVAL (XEXP (addr2, 1));
12934 else if (GET_CODE (addr2) != REG)
12938 reg2 = REGNO (addr2);
12939 /* This was a simple (mem (reg)) expression. Offset is 0. */
12943 /* Both of these must have the same base register. */
12947 /* The offset for the second addr must be 8 more than the first addr. */
12948 if (offset2 != offset1 + 8)
12951 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
12958 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
12960 static bool eliminated = false;
12963 if (mode != SDmode)
12964 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
12967 rtx mem = cfun->machine->sdmode_stack_slot;
12968 gcc_assert (mem != NULL_RTX);
12972 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
12973 cfun->machine->sdmode_stack_slot = mem;
12979 if (TARGET_DEBUG_ADDR)
12981 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
12982 GET_MODE_NAME (mode));
12984 fprintf (stderr, "\tNULL_RTX\n");
12993 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
12995 /* Don't walk into types. */
12996 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
12998 *walk_subtrees = 0;
13002 switch (TREE_CODE (*tp))
13011 case ALIGN_INDIRECT_REF:
13012 case MISALIGNED_INDIRECT_REF:
13013 case VIEW_CONVERT_EXPR:
13014 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13024 enum reload_reg_type {
13026 VECTOR_REGISTER_TYPE,
13027 OTHER_REGISTER_TYPE
13030 static enum reload_reg_type
13031 rs6000_reload_register_type (enum reg_class rclass)
13037 return GPR_REGISTER_TYPE;
13042 return VECTOR_REGISTER_TYPE;
13045 return OTHER_REGISTER_TYPE;
13049 /* Inform reload about cases where moving X with a mode MODE to a register in
13050 RCLASS requires an extra scratch or immediate register. Return the class
13051 needed for the immediate register.
13053 For VSX and Altivec, we may need a register to convert sp+offset into
13056 static enum reg_class
13057 rs6000_secondary_reload (bool in_p,
13059 enum reg_class rclass,
13060 enum machine_mode mode,
13061 secondary_reload_info *sri)
13063 enum reg_class ret = ALL_REGS;
13064 enum insn_code icode;
13065 bool default_p = false;
13067 sri->icode = CODE_FOR_nothing;
13069 /* Convert vector loads and stores into gprs to use an additional base
13071 icode = rs6000_vector_reload[mode][in_p != false];
13072 if (icode != CODE_FOR_nothing)
13075 sri->icode = CODE_FOR_nothing;
13076 sri->extra_cost = 0;
13078 if (GET_CODE (x) == MEM)
13080 rtx addr = XEXP (x, 0);
13082 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13083 an extra register in that case, but it would need an extra
13084 register if the addressing is reg+reg or (reg+reg)&(-16). */
13085 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13087 if (!legitimate_indirect_address_p (addr, false)
13088 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13090 sri->icode = icode;
13091 /* account for splitting the loads, and converting the
13092 address from reg+reg to reg. */
13093 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13094 + ((GET_CODE (addr) == AND) ? 1 : 0));
13097 /* Loads to and stores from vector registers can only do reg+reg
13098 addressing. Altivec registers can also do (reg+reg)&(-16). */
13099 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13100 || rclass == FLOAT_REGS || rclass == NO_REGS)
13102 if (!VECTOR_MEM_ALTIVEC_P (mode)
13103 && GET_CODE (addr) == AND
13104 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13105 && INTVAL (XEXP (addr, 1)) == -16
13106 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13107 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13109 sri->icode = icode;
13110 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13113 else if (!legitimate_indirect_address_p (addr, false)
13114 && (rclass == NO_REGS
13115 || !legitimate_indexed_address_p (addr, false)))
13117 sri->icode = icode;
13118 sri->extra_cost = 1;
13121 icode = CODE_FOR_nothing;
13123 /* Any other loads, including to pseudo registers which haven't been
13124 assigned to a register yet, default to require a scratch
13128 sri->icode = icode;
13129 sri->extra_cost = 2;
13132 else if (REG_P (x))
13134 int regno = true_regnum (x);
13136 icode = CODE_FOR_nothing;
13137 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13141 enum reg_class xclass = REGNO_REG_CLASS (regno);
13142 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13143 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13145 /* If memory is needed, use default_secondary_reload to create the
13147 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13160 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13162 gcc_assert (ret != ALL_REGS);
13164 if (TARGET_DEBUG_ADDR)
13167 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13169 reg_class_names[ret],
13170 in_p ? "true" : "false",
13171 reg_class_names[rclass],
13172 GET_MODE_NAME (mode));
13175 fprintf (stderr, ", default secondary reload");
13177 if (sri->icode != CODE_FOR_nothing)
13178 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13179 insn_data[sri->icode].name, sri->extra_cost);
13181 fprintf (stderr, "\n");
13189 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13190 to SP+reg addressing. */
13193 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13195 int regno = true_regnum (reg);
13196 enum machine_mode mode = GET_MODE (reg);
13197 enum reg_class rclass;
13199 rtx and_op2 = NULL_RTX;
13202 rtx scratch_or_premodify = scratch;
13206 if (TARGET_DEBUG_ADDR)
13208 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13209 store_p ? "store" : "load");
13210 fprintf (stderr, "reg:\n");
13212 fprintf (stderr, "mem:\n");
13214 fprintf (stderr, "scratch:\n");
13215 debug_rtx (scratch);
13218 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13219 gcc_assert (GET_CODE (mem) == MEM);
13220 rclass = REGNO_REG_CLASS (regno);
13221 addr = XEXP (mem, 0);
13225 /* GPRs can handle reg + small constant, all other addresses need to use
13226 the scratch register. */
13229 if (GET_CODE (addr) == AND)
13231 and_op2 = XEXP (addr, 1);
13232 addr = XEXP (addr, 0);
13235 if (GET_CODE (addr) == PRE_MODIFY)
13237 scratch_or_premodify = XEXP (addr, 0);
13238 gcc_assert (REG_P (scratch_or_premodify));
13239 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13240 addr = XEXP (addr, 1);
13243 if (GET_CODE (addr) == PLUS
13244 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13245 || and_op2 != NULL_RTX))
13247 addr_op1 = XEXP (addr, 0);
13248 addr_op2 = XEXP (addr, 1);
13249 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13251 if (!REG_P (addr_op2)
13252 && (GET_CODE (addr_op2) != CONST_INT
13253 || !satisfies_constraint_I (addr_op2)))
13255 if (TARGET_DEBUG_ADDR)
13258 "\nMove plus addr to register %s, mode = %s: ",
13259 rs6000_reg_names[REGNO (scratch)],
13260 GET_MODE_NAME (mode));
13261 debug_rtx (addr_op2);
13263 rs6000_emit_move (scratch, addr_op2, Pmode);
13264 addr_op2 = scratch;
13267 emit_insn (gen_rtx_SET (VOIDmode,
13268 scratch_or_premodify,
13269 gen_rtx_PLUS (Pmode,
13273 addr = scratch_or_premodify;
13274 scratch_or_premodify = scratch;
13276 else if (!legitimate_indirect_address_p (addr, false)
13277 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13279 if (TARGET_DEBUG_ADDR)
13281 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13282 rs6000_reg_names[REGNO (scratch_or_premodify)],
13283 GET_MODE_NAME (mode));
13286 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13287 addr = scratch_or_premodify;
13288 scratch_or_premodify = scratch;
13292 /* Float/Altivec registers can only handle reg+reg addressing. Move
13293 other addresses into a scratch register. */
13298 /* With float regs, we need to handle the AND ourselves, since we can't
13299 use the Altivec instruction with an implicit AND -16. Allow scalar
13300 loads to float registers to use reg+offset even if VSX. */
13301 if (GET_CODE (addr) == AND
13302 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13303 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13304 || INTVAL (XEXP (addr, 1)) != -16
13305 || !VECTOR_MEM_ALTIVEC_P (mode)))
13307 and_op2 = XEXP (addr, 1);
13308 addr = XEXP (addr, 0);
13311 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13312 as the address later. */
13313 if (GET_CODE (addr) == PRE_MODIFY
13314 && (!VECTOR_MEM_VSX_P (mode)
13315 || and_op2 != NULL_RTX
13316 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13318 scratch_or_premodify = XEXP (addr, 0);
13319 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13321 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13322 addr = XEXP (addr, 1);
13325 if (legitimate_indirect_address_p (addr, false) /* reg */
13326 || legitimate_indexed_address_p (addr, false) /* reg+reg */
13327 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
13328 || (GET_CODE (addr) == AND /* Altivec memory */
13329 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13330 && INTVAL (XEXP (addr, 1)) == -16
13331 && VECTOR_MEM_ALTIVEC_P (mode))
13332 || (rclass == FLOAT_REGS /* legacy float mem */
13333 && GET_MODE_SIZE (mode) == 8
13334 && and_op2 == NULL_RTX
13335 && scratch_or_premodify == scratch
13336 && rs6000_legitimate_offset_address_p (mode, addr, false)))
13339 else if (GET_CODE (addr) == PLUS)
13341 addr_op1 = XEXP (addr, 0);
13342 addr_op2 = XEXP (addr, 1);
13343 gcc_assert (REG_P (addr_op1));
13345 if (TARGET_DEBUG_ADDR)
13347 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
13348 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13349 debug_rtx (addr_op2);
13351 rs6000_emit_move (scratch, addr_op2, Pmode);
13352 emit_insn (gen_rtx_SET (VOIDmode,
13353 scratch_or_premodify,
13354 gen_rtx_PLUS (Pmode,
13357 addr = scratch_or_premodify;
13358 scratch_or_premodify = scratch;
13361 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
13362 || GET_CODE (addr) == CONST_INT || REG_P (addr))
13364 if (TARGET_DEBUG_ADDR)
13366 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13367 rs6000_reg_names[REGNO (scratch_or_premodify)],
13368 GET_MODE_NAME (mode));
13372 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13373 addr = scratch_or_premodify;
13374 scratch_or_premodify = scratch;
13378 gcc_unreachable ();
13383 gcc_unreachable ();
13386 /* If the original address involved a pre-modify that we couldn't use the VSX
13387 memory instruction with update, and we haven't taken care of already,
13388 store the address in the pre-modify register and use that as the
13390 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
13392 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
13393 addr = scratch_or_premodify;
13396 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
13397 memory instruction, recreate the AND now, including the clobber which is
13398 generated by the general ANDSI3/ANDDI3 patterns for the
13399 andi. instruction. */
13400 if (and_op2 != NULL_RTX)
13402 if (! legitimate_indirect_address_p (addr, false))
13404 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
13408 if (TARGET_DEBUG_ADDR)
13410 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
13411 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13412 debug_rtx (and_op2);
13415 and_rtx = gen_rtx_SET (VOIDmode,
13417 gen_rtx_AND (Pmode,
13421 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
13422 emit_insn (gen_rtx_PARALLEL (VOIDmode,
13423 gen_rtvec (2, and_rtx, cc_clobber)));
13427 /* Adjust the address if it changed. */
13428 if (addr != XEXP (mem, 0))
13430 mem = change_address (mem, mode, addr);
13431 if (TARGET_DEBUG_ADDR)
13432 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
13435 /* Now create the move. */
13437 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
13439 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
13444 /* Target hook to return the cover classes for Integrated Register Allocator.
13445 Cover classes is a set of non-intersected register classes covering all hard
13446 registers used for register allocation purpose. Any move between two
13447 registers of a cover class should be cheaper than load or store of the
13448 registers. The value is array of register classes with LIM_REG_CLASSES used
13451 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
13452 account for the Altivec and Floating registers being subsets of the VSX
13453 register set under VSX, but distinct register sets on pre-VSX machines. */
13455 static const enum reg_class *
13456 rs6000_ira_cover_classes (void)
13458 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
13459 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
13461 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
13464 /* Allocate a 64-bit stack slot to be used for copying SDmode
13465 values through if this function has any SDmode references. */
13468 rs6000_alloc_sdmode_stack_slot (void)
13472 gimple_stmt_iterator gsi;
13474 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
13477 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
13479 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
13482 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13483 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13489 /* Check for any SDmode parameters of the function. */
13490 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
13492 if (TREE_TYPE (t) == error_mark_node)
13495 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
13496 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
13498 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13499 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13507 rs6000_instantiate_decls (void)
13509 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
13510 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
13513 /* Given an rtx X being reloaded into a reg required to be
13514 in class CLASS, return the class of reg to actually use.
13515 In general this is just CLASS; but on some machines
13516 in some cases it is preferable to use a more restrictive class.
13518 On the RS/6000, we have to return NO_REGS when we want to reload a
13519 floating-point CONST_DOUBLE to force it to be copied to memory.
13521 We also don't want to reload integer values into floating-point
13522 registers if we can at all help it. In fact, this can
13523 cause reload to die, if it tries to generate a reload of CTR
13524 into a FP register and discovers it doesn't have the memory location
13527 ??? Would it be a good idea to have reload do the converse, that is
13528 try to reload floating modes into FP registers if possible?
13531 static enum reg_class
13532 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
13534 enum machine_mode mode = GET_MODE (x);
13536 if (VECTOR_UNIT_VSX_P (mode)
13537 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
13540 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
13541 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
13542 && easy_vector_constant (x, mode))
13543 return ALTIVEC_REGS;
13545 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
13548 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
13549 return GENERAL_REGS;
13551 /* For VSX, prefer the traditional registers for DF if the address is of the
13552 form reg+offset because we can use the non-VSX loads. Prefer the Altivec
13553 registers if Altivec is handling the vector operations (i.e. V16QI, V8HI,
13555 if (rclass == VSX_REGS && VECTOR_MEM_VSX_P (mode))
13557 if (mode == DFmode && GET_CODE (x) == MEM)
13559 rtx addr = XEXP (x, 0);
13561 if (legitimate_indirect_address_p (addr, false)) /* reg */
13564 if (legitimate_indexed_address_p (addr, false)) /* reg+reg */
13567 if (GET_CODE (addr) == PRE_MODIFY
13568 && legitimate_indexed_address_p (XEXP (addr, 0), false))
13574 if (VECTOR_UNIT_ALTIVEC_P (mode))
13575 return ALTIVEC_REGS;
13583 /* Debug version of rs6000_preferred_reload_class. */
13584 static enum reg_class
13585 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
13587 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
13590 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
13592 reg_class_names[ret], reg_class_names[rclass],
13593 GET_MODE_NAME (GET_MODE (x)));
13599 /* If we are copying between FP or AltiVec registers and anything else, we need
13600 a memory location. The exception is when we are targeting ppc64 and the
13601 move to/from fpr to gpr instructions are available. Also, under VSX, you
13602 can copy vector registers from the FP register set to the Altivec register
13603 set and vice versa. */
13606 rs6000_secondary_memory_needed (enum reg_class class1,
13607 enum reg_class class2,
13608 enum machine_mode mode)
13610 if (class1 == class2)
13613 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
13614 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
13615 between these classes. But we need memory for other things that can go in
13616 FLOAT_REGS like SFmode. */
13618 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
13619 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
13620 || class1 == FLOAT_REGS))
13621 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
13622 && class2 != FLOAT_REGS);
13624 if (class1 == VSX_REGS || class2 == VSX_REGS)
13627 if (class1 == FLOAT_REGS
13628 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13629 || ((mode != DFmode)
13630 && (mode != DDmode)
13631 && (mode != DImode))))
13634 if (class2 == FLOAT_REGS
13635 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13636 || ((mode != DFmode)
13637 && (mode != DDmode)
13638 && (mode != DImode))))
13641 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
13647 /* Debug version of rs6000_secondary_memory_needed. */
13649 rs6000_debug_secondary_memory_needed (enum reg_class class1,
13650 enum reg_class class2,
13651 enum machine_mode mode)
13653 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
13656 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
13657 "class2 = %s, mode = %s\n",
13658 ret ? "true" : "false", reg_class_names[class1],
13659 reg_class_names[class2], GET_MODE_NAME (mode));
13664 /* Return the register class of a scratch register needed to copy IN into
13665 or out of a register in RCLASS in MODE. If it can be done directly,
13666 NO_REGS is returned. */
13668 static enum reg_class
13669 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
13674 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
13676 && MACHOPIC_INDIRECT
13680 /* We cannot copy a symbolic operand directly into anything
13681 other than BASE_REGS for TARGET_ELF. So indicate that a
13682 register from BASE_REGS is needed as an intermediate
13685 On Darwin, pic addresses require a load from memory, which
13686 needs a base register. */
13687 if (rclass != BASE_REGS
13688 && (GET_CODE (in) == SYMBOL_REF
13689 || GET_CODE (in) == HIGH
13690 || GET_CODE (in) == LABEL_REF
13691 || GET_CODE (in) == CONST))
13695 if (GET_CODE (in) == REG)
13697 regno = REGNO (in);
13698 if (regno >= FIRST_PSEUDO_REGISTER)
13700 regno = true_regnum (in);
13701 if (regno >= FIRST_PSEUDO_REGISTER)
13705 else if (GET_CODE (in) == SUBREG)
13707 regno = true_regnum (in);
13708 if (regno >= FIRST_PSEUDO_REGISTER)
13714 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
13716 if (rclass == GENERAL_REGS || rclass == BASE_REGS
13717 || (regno >= 0 && INT_REGNO_P (regno)))
13720 /* Constants, memory, and FP registers can go into FP registers. */
13721 if ((regno == -1 || FP_REGNO_P (regno))
13722 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
13723 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
13725 /* Memory, and FP/altivec registers can go into fp/altivec registers under
13728 && (regno == -1 || VSX_REGNO_P (regno))
13729 && VSX_REG_CLASS_P (rclass))
13732 /* Memory, and AltiVec registers can go into AltiVec registers. */
13733 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
13734 && rclass == ALTIVEC_REGS)
13737 /* We can copy among the CR registers. */
13738 if ((rclass == CR_REGS || rclass == CR0_REGS)
13739 && regno >= 0 && CR_REGNO_P (regno))
13742 /* Otherwise, we need GENERAL_REGS. */
13743 return GENERAL_REGS;
13746 /* Debug version of rs6000_secondary_reload_class. */
13747 static enum reg_class
13748 rs6000_debug_secondary_reload_class (enum reg_class rclass,
13749 enum machine_mode mode, rtx in)
13751 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
13753 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
13754 "mode = %s, input rtx:\n",
13755 reg_class_names[ret], reg_class_names[rclass],
13756 GET_MODE_NAME (mode));
13762 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
13765 rs6000_cannot_change_mode_class (enum machine_mode from,
13766 enum machine_mode to,
13767 enum reg_class rclass)
13769 unsigned from_size = GET_MODE_SIZE (from);
13770 unsigned to_size = GET_MODE_SIZE (to);
13772 if (from_size != to_size)
13774 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
13775 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
13776 && reg_classes_intersect_p (xclass, rclass));
13779 if (TARGET_E500_DOUBLE
13780 && ((((to) == DFmode) + ((from) == DFmode)) == 1
13781 || (((to) == TFmode) + ((from) == TFmode)) == 1
13782 || (((to) == DDmode) + ((from) == DDmode)) == 1
13783 || (((to) == TDmode) + ((from) == TDmode)) == 1
13784 || (((to) == DImode) + ((from) == DImode)) == 1))
13787 /* Since the VSX register set includes traditional floating point registers
13788 and altivec registers, just check for the size being different instead of
13789 trying to check whether the modes are vector modes. Otherwise it won't
13790 allow say DF and DI to change classes. */
13791 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
13792 return (from_size != 8 && from_size != 16);
13794 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
13795 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
13798 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
13799 && reg_classes_intersect_p (GENERAL_REGS, rclass))
13805 /* Debug version of rs6000_cannot_change_mode_class. */
13807 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
13808 enum machine_mode to,
13809 enum reg_class rclass)
13811 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
13814 "rs6000_cannot_change_mode_class, return %s, from = %s, "
13815 "to = %s, rclass = %s\n",
13816 ret ? "true" : "false",
13817 GET_MODE_NAME (from), GET_MODE_NAME (to),
13818 reg_class_names[rclass]);
13823 /* Given a comparison operation, return the bit number in CCR to test. We
13824 know this is a valid comparison.
13826 SCC_P is 1 if this is for an scc. That means that %D will have been
13827 used instead of %C, so the bits will be in different places.
13829 Return -1 if OP isn't a valid comparison for some reason. */
13832 ccr_bit (rtx op, int scc_p)
13834 enum rtx_code code = GET_CODE (op);
13835 enum machine_mode cc_mode;
13840 if (!COMPARISON_P (op))
13843 reg = XEXP (op, 0);
13845 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
13847 cc_mode = GET_MODE (reg);
13848 cc_regnum = REGNO (reg);
13849 base_bit = 4 * (cc_regnum - CR0_REGNO);
13851 validate_condition_mode (code, cc_mode);
13853 /* When generating a sCOND operation, only positive conditions are
13856 || code == EQ || code == GT || code == LT || code == UNORDERED
13857 || code == GTU || code == LTU);
13862 return scc_p ? base_bit + 3 : base_bit + 2;
13864 return base_bit + 2;
13865 case GT: case GTU: case UNLE:
13866 return base_bit + 1;
13867 case LT: case LTU: case UNGE:
13869 case ORDERED: case UNORDERED:
13870 return base_bit + 3;
13873 /* If scc, we will have done a cror to put the bit in the
13874 unordered position. So test that bit. For integer, this is ! LT
13875 unless this is an scc insn. */
13876 return scc_p ? base_bit + 3 : base_bit;
13879 return scc_p ? base_bit + 3 : base_bit + 1;
13882 gcc_unreachable ();
13886 /* Return the GOT register. */
13889 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
13891 /* The second flow pass currently (June 1999) can't update
13892 regs_ever_live without disturbing other parts of the compiler, so
13893 update it here to make the prolog/epilogue code happy. */
13894 if (!can_create_pseudo_p ()
13895 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
13896 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
13898 crtl->uses_pic_offset_table = 1;
13900 return pic_offset_table_rtx;
13903 /* Function to init struct machine_function.
13904 This will be called, via a pointer variable,
13905 from push_function_context. */
13907 static struct machine_function *
13908 rs6000_init_machine_status (void)
13910 return GGC_CNEW (machine_function);
13913 /* These macros test for integers and extract the low-order bits. */
13915 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
13916 && GET_MODE (X) == VOIDmode)
13918 #define INT_LOWPART(X) \
13919 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
13922 extract_MB (rtx op)
13925 unsigned long val = INT_LOWPART (op);
13927 /* If the high bit is zero, the value is the first 1 bit we find
13929 if ((val & 0x80000000) == 0)
13931 gcc_assert (val & 0xffffffff);
13934 while (((val <<= 1) & 0x80000000) == 0)
13939 /* If the high bit is set and the low bit is not, or the mask is all
13940 1's, the value is zero. */
13941 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
13944 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
13947 while (((val >>= 1) & 1) != 0)
13954 extract_ME (rtx op)
13957 unsigned long val = INT_LOWPART (op);
13959 /* If the low bit is zero, the value is the first 1 bit we find from
13961 if ((val & 1) == 0)
13963 gcc_assert (val & 0xffffffff);
13966 while (((val >>= 1) & 1) == 0)
13972 /* If the low bit is set and the high bit is not, or the mask is all
13973 1's, the value is 31. */
13974 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
13977 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
13980 while (((val <<= 1) & 0x80000000) != 0)
13986 /* Locate some local-dynamic symbol still in use by this function
13987 so that we can print its name in some tls_ld pattern. */
13989 static const char *
13990 rs6000_get_some_local_dynamic_name (void)
13994 if (cfun->machine->some_ld_name)
13995 return cfun->machine->some_ld_name;
13997 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
13999 && for_each_rtx (&PATTERN (insn),
14000 rs6000_get_some_local_dynamic_name_1, 0))
14001 return cfun->machine->some_ld_name;
14003 gcc_unreachable ();
14006 /* Helper function for rs6000_get_some_local_dynamic_name. */
14009 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14013 if (GET_CODE (x) == SYMBOL_REF)
14015 const char *str = XSTR (x, 0);
14016 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14018 cfun->machine->some_ld_name = str;
14026 /* Write out a function code label. */
14029 rs6000_output_function_entry (FILE *file, const char *fname)
14031 if (fname[0] != '.')
14033 switch (DEFAULT_ABI)
14036 gcc_unreachable ();
14042 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14051 RS6000_OUTPUT_BASENAME (file, fname);
14053 assemble_name (file, fname);
14056 /* Print an operand. Recognize special options, documented below. */
14059 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14060 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14062 #define SMALL_DATA_RELOC "sda21"
14063 #define SMALL_DATA_REG 0
14067 print_operand (FILE *file, rtx x, int code)
14071 unsigned HOST_WIDE_INT uval;
14076 /* Write out an instruction after the call which may be replaced
14077 with glue code by the loader. This depends on the AIX version. */
14078 asm_fprintf (file, RS6000_CALL_GLUE);
14081 /* %a is output_address. */
14084 /* If X is a constant integer whose low-order 5 bits are zero,
14085 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14086 in the AIX assembler where "sri" with a zero shift count
14087 writes a trash instruction. */
14088 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14095 /* If constant, low-order 16 bits of constant, unsigned.
14096 Otherwise, write normally. */
14098 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14100 print_operand (file, x, 0);
14104 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14105 for 64-bit mask direction. */
14106 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14109 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14113 /* X is a CR register. Print the number of the GT bit of the CR. */
14114 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14115 output_operand_lossage ("invalid %%c value");
14117 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14121 /* Like 'J' but get to the GT bit only. */
14122 gcc_assert (GET_CODE (x) == REG);
14124 /* Bit 1 is GT bit. */
14125 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14127 /* Add one for shift count in rlinm for scc. */
14128 fprintf (file, "%d", i + 1);
14132 /* X is a CR register. Print the number of the EQ bit of the CR */
14133 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14134 output_operand_lossage ("invalid %%E value");
14136 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14140 /* X is a CR register. Print the shift count needed to move it
14141 to the high-order four bits. */
14142 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14143 output_operand_lossage ("invalid %%f value");
14145 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14149 /* Similar, but print the count for the rotate in the opposite
14151 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14152 output_operand_lossage ("invalid %%F value");
14154 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14158 /* X is a constant integer. If it is negative, print "m",
14159 otherwise print "z". This is to make an aze or ame insn. */
14160 if (GET_CODE (x) != CONST_INT)
14161 output_operand_lossage ("invalid %%G value");
14162 else if (INTVAL (x) >= 0)
14169 /* If constant, output low-order five bits. Otherwise, write
14172 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14174 print_operand (file, x, 0);
14178 /* If constant, output low-order six bits. Otherwise, write
14181 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14183 print_operand (file, x, 0);
14187 /* Print `i' if this is a constant, else nothing. */
14193 /* Write the bit number in CCR for jump. */
14194 i = ccr_bit (x, 0);
14196 output_operand_lossage ("invalid %%j code");
14198 fprintf (file, "%d", i);
14202 /* Similar, but add one for shift count in rlinm for scc and pass
14203 scc flag to `ccr_bit'. */
14204 i = ccr_bit (x, 1);
14206 output_operand_lossage ("invalid %%J code");
14208 /* If we want bit 31, write a shift count of zero, not 32. */
14209 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14213 /* X must be a constant. Write the 1's complement of the
14216 output_operand_lossage ("invalid %%k value");
14218 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14222 /* X must be a symbolic constant on ELF. Write an
14223 expression suitable for an 'addi' that adds in the low 16
14224 bits of the MEM. */
14225 if (GET_CODE (x) != CONST)
14227 print_operand_address (file, x);
14228 fputs ("@l", file);
14232 if (GET_CODE (XEXP (x, 0)) != PLUS
14233 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14234 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14235 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14236 output_operand_lossage ("invalid %%K value");
14237 print_operand_address (file, XEXP (XEXP (x, 0), 0));
14238 fputs ("@l", file);
14239 /* For GNU as, there must be a non-alphanumeric character
14240 between 'l' and the number. The '-' is added by
14241 print_operand() already. */
14242 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
14244 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
14248 /* %l is output_asm_label. */
14251 /* Write second word of DImode or DFmode reference. Works on register
14252 or non-indexed memory only. */
14253 if (GET_CODE (x) == REG)
14254 fputs (reg_names[REGNO (x) + 1], file);
14255 else if (GET_CODE (x) == MEM)
14257 /* Handle possible auto-increment. Since it is pre-increment and
14258 we have already done it, we can just use an offset of word. */
14259 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14260 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14261 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14263 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14264 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14267 output_address (XEXP (adjust_address_nv (x, SImode,
14271 if (small_data_operand (x, GET_MODE (x)))
14272 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14273 reg_names[SMALL_DATA_REG]);
14278 /* MB value for a mask operand. */
14279 if (! mask_operand (x, SImode))
14280 output_operand_lossage ("invalid %%m value");
14282 fprintf (file, "%d", extract_MB (x));
14286 /* ME value for a mask operand. */
14287 if (! mask_operand (x, SImode))
14288 output_operand_lossage ("invalid %%M value");
14290 fprintf (file, "%d", extract_ME (x));
14293 /* %n outputs the negative of its operand. */
14296 /* Write the number of elements in the vector times 4. */
14297 if (GET_CODE (x) != PARALLEL)
14298 output_operand_lossage ("invalid %%N value");
14300 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14304 /* Similar, but subtract 1 first. */
14305 if (GET_CODE (x) != PARALLEL)
14306 output_operand_lossage ("invalid %%O value");
14308 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14312 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14314 || INT_LOWPART (x) < 0
14315 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14316 output_operand_lossage ("invalid %%p value");
14318 fprintf (file, "%d", i);
14322 /* The operand must be an indirect memory reference. The result
14323 is the register name. */
14324 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14325 || REGNO (XEXP (x, 0)) >= 32)
14326 output_operand_lossage ("invalid %%P value");
14328 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14332 /* This outputs the logical code corresponding to a boolean
14333 expression. The expression may have one or both operands
14334 negated (if one, only the first one). For condition register
14335 logical operations, it will also treat the negated
14336 CR codes as NOTs, but not handle NOTs of them. */
14338 const char *const *t = 0;
14340 enum rtx_code code = GET_CODE (x);
14341 static const char * const tbl[3][3] = {
14342 { "and", "andc", "nor" },
14343 { "or", "orc", "nand" },
14344 { "xor", "eqv", "xor" } };
14348 else if (code == IOR)
14350 else if (code == XOR)
14353 output_operand_lossage ("invalid %%q value");
14355 if (GET_CODE (XEXP (x, 0)) != NOT)
14359 if (GET_CODE (XEXP (x, 1)) == NOT)
14377 /* X is a CR register. Print the mask for `mtcrf'. */
14378 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14379 output_operand_lossage ("invalid %%R value");
14381 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
14385 /* Low 5 bits of 32 - value */
14387 output_operand_lossage ("invalid %%s value");
14389 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
14393 /* PowerPC64 mask position. All 0's is excluded.
14394 CONST_INT 32-bit mask is considered sign-extended so any
14395 transition must occur within the CONST_INT, not on the boundary. */
14396 if (! mask64_operand (x, DImode))
14397 output_operand_lossage ("invalid %%S value");
14399 uval = INT_LOWPART (x);
14401 if (uval & 1) /* Clear Left */
14403 #if HOST_BITS_PER_WIDE_INT > 64
14404 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14408 else /* Clear Right */
14411 #if HOST_BITS_PER_WIDE_INT > 64
14412 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14418 gcc_assert (i >= 0);
14419 fprintf (file, "%d", i);
14423 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
14424 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
14426 /* Bit 3 is OV bit. */
14427 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
14429 /* If we want bit 31, write a shift count of zero, not 32. */
14430 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14434 /* Print the symbolic name of a branch target register. */
14435 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
14436 && REGNO (x) != CTR_REGNO))
14437 output_operand_lossage ("invalid %%T value");
14438 else if (REGNO (x) == LR_REGNO)
14439 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
14441 fputs ("ctr", file);
14445 /* High-order 16 bits of constant for use in unsigned operand. */
14447 output_operand_lossage ("invalid %%u value");
14449 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14450 (INT_LOWPART (x) >> 16) & 0xffff);
14454 /* High-order 16 bits of constant for use in signed operand. */
14456 output_operand_lossage ("invalid %%v value");
14458 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14459 (INT_LOWPART (x) >> 16) & 0xffff);
14463 /* Print `u' if this has an auto-increment or auto-decrement. */
14464 if (GET_CODE (x) == MEM
14465 && (GET_CODE (XEXP (x, 0)) == PRE_INC
14466 || GET_CODE (XEXP (x, 0)) == PRE_DEC
14467 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
14472 /* Print the trap code for this operand. */
14473 switch (GET_CODE (x))
14476 fputs ("eq", file); /* 4 */
14479 fputs ("ne", file); /* 24 */
14482 fputs ("lt", file); /* 16 */
14485 fputs ("le", file); /* 20 */
14488 fputs ("gt", file); /* 8 */
14491 fputs ("ge", file); /* 12 */
14494 fputs ("llt", file); /* 2 */
14497 fputs ("lle", file); /* 6 */
14500 fputs ("lgt", file); /* 1 */
14503 fputs ("lge", file); /* 5 */
14506 gcc_unreachable ();
14511 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
14514 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
14515 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
14517 print_operand (file, x, 0);
14521 /* MB value for a PowerPC64 rldic operand. */
14522 val = (GET_CODE (x) == CONST_INT
14523 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
14528 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
14529 if ((val <<= 1) < 0)
14532 #if HOST_BITS_PER_WIDE_INT == 32
14533 if (GET_CODE (x) == CONST_INT && i >= 0)
14534 i += 32; /* zero-extend high-part was all 0's */
14535 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
14537 val = CONST_DOUBLE_LOW (x);
14543 for ( ; i < 64; i++)
14544 if ((val <<= 1) < 0)
14549 fprintf (file, "%d", i + 1);
14553 /* X is a FPR or Altivec register used in a VSX context. */
14554 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
14555 output_operand_lossage ("invalid %%x value");
14558 int reg = REGNO (x);
14559 int vsx_reg = (FP_REGNO_P (reg)
14561 : reg - FIRST_ALTIVEC_REGNO + 32);
14563 #ifdef TARGET_REGNAMES
14564 if (TARGET_REGNAMES)
14565 fprintf (file, "%%vs%d", vsx_reg);
14568 fprintf (file, "%d", vsx_reg);
14573 if (GET_CODE (x) == MEM
14574 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
14575 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
14576 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
14581 /* Like 'L', for third word of TImode */
14582 if (GET_CODE (x) == REG)
14583 fputs (reg_names[REGNO (x) + 2], file);
14584 else if (GET_CODE (x) == MEM)
14586 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14587 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14588 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14589 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14590 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14592 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
14593 if (small_data_operand (x, GET_MODE (x)))
14594 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14595 reg_names[SMALL_DATA_REG]);
14600 /* X is a SYMBOL_REF. Write out the name preceded by a
14601 period and without any trailing data in brackets. Used for function
14602 names. If we are configured for System V (or the embedded ABI) on
14603 the PowerPC, do not emit the period, since those systems do not use
14604 TOCs and the like. */
14605 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14607 /* Mark the decl as referenced so that cgraph will output the
14609 if (SYMBOL_REF_DECL (x))
14610 mark_decl_referenced (SYMBOL_REF_DECL (x));
14612 /* For macho, check to see if we need a stub. */
14615 const char *name = XSTR (x, 0);
14617 if (MACHOPIC_INDIRECT
14618 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
14619 name = machopic_indirection_name (x, /*stub_p=*/true);
14621 assemble_name (file, name);
14623 else if (!DOT_SYMBOLS)
14624 assemble_name (file, XSTR (x, 0));
14626 rs6000_output_function_entry (file, XSTR (x, 0));
14630 /* Like 'L', for last word of TImode. */
14631 if (GET_CODE (x) == REG)
14632 fputs (reg_names[REGNO (x) + 3], file);
14633 else if (GET_CODE (x) == MEM)
14635 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14636 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14637 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14638 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14639 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14641 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
14642 if (small_data_operand (x, GET_MODE (x)))
14643 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14644 reg_names[SMALL_DATA_REG]);
14648 /* Print AltiVec or SPE memory operand. */
14653 gcc_assert (GET_CODE (x) == MEM);
14657 /* Ugly hack because %y is overloaded. */
14658 if ((TARGET_SPE || TARGET_E500_DOUBLE)
14659 && (GET_MODE_SIZE (GET_MODE (x)) == 8
14660 || GET_MODE (x) == TFmode
14661 || GET_MODE (x) == TImode))
14663 /* Handle [reg]. */
14664 if (GET_CODE (tmp) == REG)
14666 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
14669 /* Handle [reg+UIMM]. */
14670 else if (GET_CODE (tmp) == PLUS &&
14671 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
14675 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
14677 x = INTVAL (XEXP (tmp, 1));
14678 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
14682 /* Fall through. Must be [reg+reg]. */
14684 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
14685 && GET_CODE (tmp) == AND
14686 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
14687 && INTVAL (XEXP (tmp, 1)) == -16)
14688 tmp = XEXP (tmp, 0);
14689 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
14690 && GET_CODE (tmp) == PRE_MODIFY)
14691 tmp = XEXP (tmp, 1);
14692 if (GET_CODE (tmp) == REG)
14693 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
14696 if (!GET_CODE (tmp) == PLUS
14697 || !REG_P (XEXP (tmp, 0))
14698 || !REG_P (XEXP (tmp, 1)))
14700 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
14704 if (REGNO (XEXP (tmp, 0)) == 0)
14705 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
14706 reg_names[ REGNO (XEXP (tmp, 0)) ]);
14708 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
14709 reg_names[ REGNO (XEXP (tmp, 1)) ]);
14715 if (GET_CODE (x) == REG)
14716 fprintf (file, "%s", reg_names[REGNO (x)]);
14717 else if (GET_CODE (x) == MEM)
14719 /* We need to handle PRE_INC and PRE_DEC here, since we need to
14720 know the width from the mode. */
14721 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
14722 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
14723 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14724 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
14725 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
14726 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14727 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14728 output_address (XEXP (XEXP (x, 0), 1));
14730 output_address (XEXP (x, 0));
14733 output_addr_const (file, x);
14737 assemble_name (file, rs6000_get_some_local_dynamic_name ());
14741 output_operand_lossage ("invalid %%xn code");
14745 /* Print the address of an operand. */
14748 print_operand_address (FILE *file, rtx x)
14750 if (GET_CODE (x) == REG)
14751 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
14752 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
14753 || GET_CODE (x) == LABEL_REF)
14755 output_addr_const (file, x);
14756 if (small_data_operand (x, GET_MODE (x)))
14757 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14758 reg_names[SMALL_DATA_REG]);
14760 gcc_assert (!TARGET_TOC);
14762 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
14764 gcc_assert (REG_P (XEXP (x, 0)));
14765 if (REGNO (XEXP (x, 0)) == 0)
14766 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
14767 reg_names[ REGNO (XEXP (x, 0)) ]);
14769 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
14770 reg_names[ REGNO (XEXP (x, 1)) ]);
14772 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
14773 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
14774 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
14776 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
14777 && CONSTANT_P (XEXP (x, 1)))
14779 output_addr_const (file, XEXP (x, 1));
14780 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
14784 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
14785 && CONSTANT_P (XEXP (x, 1)))
14787 fprintf (file, "lo16(");
14788 output_addr_const (file, XEXP (x, 1));
14789 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
14792 else if (legitimate_constant_pool_address_p (x))
14794 output_addr_const (file, XEXP (x, 1));
14795 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
14798 gcc_unreachable ();
14801 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
14804 rs6000_output_addr_const_extra (FILE *file, rtx x)
14806 if (GET_CODE (x) == UNSPEC)
14807 switch (XINT (x, 1))
14809 case UNSPEC_TOCREL:
14810 x = XVECEXP (x, 0, 0);
14811 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14812 output_addr_const (file, x);
14813 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
14816 assemble_name (file, toc_label_name);
14818 else if (TARGET_ELF)
14819 fputs ("@toc", file);
14823 case UNSPEC_MACHOPIC_OFFSET:
14824 output_addr_const (file, XVECEXP (x, 0, 0));
14826 machopic_output_function_base_name (file);
14833 /* Target hook for assembling integer objects. The PowerPC version has
14834 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
14835 is defined. It also needs to handle DI-mode objects on 64-bit
14839 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
14841 #ifdef RELOCATABLE_NEEDS_FIXUP
14842 /* Special handling for SI values. */
14843 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
14845 static int recurse = 0;
14847 /* For -mrelocatable, we mark all addresses that need to be fixed up
14848 in the .fixup section. */
14849 if (TARGET_RELOCATABLE
14850 && in_section != toc_section
14851 && in_section != text_section
14852 && !unlikely_text_section_p (in_section)
14854 && GET_CODE (x) != CONST_INT
14855 && GET_CODE (x) != CONST_DOUBLE
14861 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
14863 ASM_OUTPUT_LABEL (asm_out_file, buf);
14864 fprintf (asm_out_file, "\t.long\t(");
14865 output_addr_const (asm_out_file, x);
14866 fprintf (asm_out_file, ")@fixup\n");
14867 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
14868 ASM_OUTPUT_ALIGN (asm_out_file, 2);
14869 fprintf (asm_out_file, "\t.long\t");
14870 assemble_name (asm_out_file, buf);
14871 fprintf (asm_out_file, "\n\t.previous\n");
14875 /* Remove initial .'s to turn a -mcall-aixdesc function
14876 address into the address of the descriptor, not the function
14878 else if (GET_CODE (x) == SYMBOL_REF
14879 && XSTR (x, 0)[0] == '.'
14880 && DEFAULT_ABI == ABI_AIX)
14882 const char *name = XSTR (x, 0);
14883 while (*name == '.')
14886 fprintf (asm_out_file, "\t.long\t%s\n", name);
14890 #endif /* RELOCATABLE_NEEDS_FIXUP */
14891 return default_assemble_integer (x, size, aligned_p);
14894 #ifdef HAVE_GAS_HIDDEN
14895 /* Emit an assembler directive to set symbol visibility for DECL to
14896 VISIBILITY_TYPE. */
14899 rs6000_assemble_visibility (tree decl, int vis)
14901 /* Functions need to have their entry point symbol visibility set as
14902 well as their descriptor symbol visibility. */
14903 if (DEFAULT_ABI == ABI_AIX
14905 && TREE_CODE (decl) == FUNCTION_DECL)
14907 static const char * const visibility_types[] = {
14908 NULL, "internal", "hidden", "protected"
14911 const char *name, *type;
14913 name = ((* targetm.strip_name_encoding)
14914 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
14915 type = visibility_types[vis];
14917 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
14918 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
14921 default_assemble_visibility (decl, vis);
14926 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
14928 /* Reversal of FP compares takes care -- an ordered compare
14929 becomes an unordered compare and vice versa. */
14930 if (mode == CCFPmode
14931 && (!flag_finite_math_only
14932 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
14933 || code == UNEQ || code == LTGT))
14934 return reverse_condition_maybe_unordered (code);
14936 return reverse_condition (code);
14939 /* Generate a compare for CODE. Return a brand-new rtx that
14940 represents the result of the compare. */
14943 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
14945 enum machine_mode comp_mode;
14946 rtx compare_result;
14947 enum rtx_code code = GET_CODE (cmp);
14948 rtx op0 = XEXP (cmp, 0);
14949 rtx op1 = XEXP (cmp, 1);
14951 if (FLOAT_MODE_P (mode))
14952 comp_mode = CCFPmode;
14953 else if (code == GTU || code == LTU
14954 || code == GEU || code == LEU)
14955 comp_mode = CCUNSmode;
14956 else if ((code == EQ || code == NE)
14957 && GET_CODE (op0) == SUBREG
14958 && GET_CODE (op1) == SUBREG
14959 && SUBREG_PROMOTED_UNSIGNED_P (op0)
14960 && SUBREG_PROMOTED_UNSIGNED_P (op1))
14961 /* These are unsigned values, perhaps there will be a later
14962 ordering compare that can be shared with this one.
14963 Unfortunately we cannot detect the signedness of the operands
14964 for non-subregs. */
14965 comp_mode = CCUNSmode;
14967 comp_mode = CCmode;
14969 /* First, the compare. */
14970 compare_result = gen_reg_rtx (comp_mode);
14972 /* E500 FP compare instructions on the GPRs. Yuck! */
14973 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
14974 && FLOAT_MODE_P (mode))
14976 rtx cmp, or_result, compare_result2;
14977 enum machine_mode op_mode = GET_MODE (op0);
14979 if (op_mode == VOIDmode)
14980 op_mode = GET_MODE (op1);
14982 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
14983 This explains the following mess. */
14987 case EQ: case UNEQ: case NE: case LTGT:
14991 cmp = (flag_finite_math_only && !flag_trapping_math)
14992 ? gen_tstsfeq_gpr (compare_result, op0, op1)
14993 : gen_cmpsfeq_gpr (compare_result, op0, op1);
14997 cmp = (flag_finite_math_only && !flag_trapping_math)
14998 ? gen_tstdfeq_gpr (compare_result, op0, op1)
14999 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15003 cmp = (flag_finite_math_only && !flag_trapping_math)
15004 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15005 : gen_cmptfeq_gpr (compare_result, op0, op1);
15009 gcc_unreachable ();
15013 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15017 cmp = (flag_finite_math_only && !flag_trapping_math)
15018 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15019 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15023 cmp = (flag_finite_math_only && !flag_trapping_math)
15024 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15025 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15029 cmp = (flag_finite_math_only && !flag_trapping_math)
15030 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15031 : gen_cmptfgt_gpr (compare_result, op0, op1);
15035 gcc_unreachable ();
15039 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15043 cmp = (flag_finite_math_only && !flag_trapping_math)
15044 ? gen_tstsflt_gpr (compare_result, op0, op1)
15045 : gen_cmpsflt_gpr (compare_result, op0, op1);
15049 cmp = (flag_finite_math_only && !flag_trapping_math)
15050 ? gen_tstdflt_gpr (compare_result, op0, op1)
15051 : gen_cmpdflt_gpr (compare_result, op0, op1);
15055 cmp = (flag_finite_math_only && !flag_trapping_math)
15056 ? gen_tsttflt_gpr (compare_result, op0, op1)
15057 : gen_cmptflt_gpr (compare_result, op0, op1);
15061 gcc_unreachable ();
15065 gcc_unreachable ();
15068 /* Synthesize LE and GE from LT/GT || EQ. */
15069 if (code == LE || code == GE || code == LEU || code == GEU)
15075 case LE: code = LT; break;
15076 case GE: code = GT; break;
15077 case LEU: code = LT; break;
15078 case GEU: code = GT; break;
15079 default: gcc_unreachable ();
15082 compare_result2 = gen_reg_rtx (CCFPmode);
15088 cmp = (flag_finite_math_only && !flag_trapping_math)
15089 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15090 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15094 cmp = (flag_finite_math_only && !flag_trapping_math)
15095 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15096 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15100 cmp = (flag_finite_math_only && !flag_trapping_math)
15101 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15102 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15106 gcc_unreachable ();
15110 /* OR them together. */
15111 or_result = gen_reg_rtx (CCFPmode);
15112 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15114 compare_result = or_result;
15119 if (code == NE || code == LTGT)
15129 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15130 CLOBBERs to match cmptf_internal2 pattern. */
15131 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15132 && GET_MODE (op0) == TFmode
15133 && !TARGET_IEEEQUAD
15134 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15135 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15137 gen_rtx_SET (VOIDmode,
15139 gen_rtx_COMPARE (comp_mode, op0, op1)),
15140 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15141 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15142 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15143 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15144 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15145 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15146 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15147 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
15148 else if (GET_CODE (op1) == UNSPEC
15149 && XINT (op1, 1) == UNSPEC_SP_TEST)
15151 rtx op1b = XVECEXP (op1, 0, 0);
15152 comp_mode = CCEQmode;
15153 compare_result = gen_reg_rtx (CCEQmode);
15155 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15157 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15160 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15161 gen_rtx_COMPARE (comp_mode, op0, op1)));
15164 /* Some kinds of FP comparisons need an OR operation;
15165 under flag_finite_math_only we don't bother. */
15166 if (FLOAT_MODE_P (mode)
15167 && !flag_finite_math_only
15168 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15169 && (code == LE || code == GE
15170 || code == UNEQ || code == LTGT
15171 || code == UNGT || code == UNLT))
15173 enum rtx_code or1, or2;
15174 rtx or1_rtx, or2_rtx, compare2_rtx;
15175 rtx or_result = gen_reg_rtx (CCEQmode);
15179 case LE: or1 = LT; or2 = EQ; break;
15180 case GE: or1 = GT; or2 = EQ; break;
15181 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15182 case LTGT: or1 = LT; or2 = GT; break;
15183 case UNGT: or1 = UNORDERED; or2 = GT; break;
15184 case UNLT: or1 = UNORDERED; or2 = LT; break;
15185 default: gcc_unreachable ();
15187 validate_condition_mode (or1, comp_mode);
15188 validate_condition_mode (or2, comp_mode);
15189 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15190 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15191 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15192 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15194 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15196 compare_result = or_result;
15200 validate_condition_mode (code, GET_MODE (compare_result));
15202 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15206 /* Emit the RTL for an sCOND pattern. */
15209 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15212 enum machine_mode op_mode;
15213 enum rtx_code cond_code;
15214 rtx result = operands[0];
15216 condition_rtx = rs6000_generate_compare (operands[1], mode);
15217 cond_code = GET_CODE (condition_rtx);
15219 if (FLOAT_MODE_P (mode)
15220 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15224 PUT_MODE (condition_rtx, SImode);
15225 t = XEXP (condition_rtx, 0);
15227 gcc_assert (cond_code == NE || cond_code == EQ);
15229 if (cond_code == NE)
15230 emit_insn (gen_e500_flip_gt_bit (t, t));
15232 emit_insn (gen_move_from_CR_gt_bit (result, t));
15236 if (cond_code == NE
15237 || cond_code == GE || cond_code == LE
15238 || cond_code == GEU || cond_code == LEU
15239 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15241 rtx not_result = gen_reg_rtx (CCEQmode);
15242 rtx not_op, rev_cond_rtx;
15243 enum machine_mode cc_mode;
15245 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15247 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15248 SImode, XEXP (condition_rtx, 0), const0_rtx);
15249 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15250 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15251 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15254 op_mode = GET_MODE (XEXP (operands[1], 0));
15255 if (op_mode == VOIDmode)
15256 op_mode = GET_MODE (XEXP (operands[1], 1));
15258 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15260 PUT_MODE (condition_rtx, DImode);
15261 convert_move (result, condition_rtx, 0);
15265 PUT_MODE (condition_rtx, SImode);
15266 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15270 /* Emit a branch of kind CODE to location LOC. */
15273 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15275 rtx condition_rtx, loc_ref;
15277 condition_rtx = rs6000_generate_compare (operands[0], mode);
15278 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15279 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15280 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15281 loc_ref, pc_rtx)));
15284 /* Return the string to output a conditional branch to LABEL, which is
15285 the operand number of the label, or -1 if the branch is really a
15286 conditional return.
15288 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15289 condition code register and its mode specifies what kind of
15290 comparison we made.
15292 REVERSED is nonzero if we should reverse the sense of the comparison.
15294 INSN is the insn. */
15297 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
15299 static char string[64];
15300 enum rtx_code code = GET_CODE (op);
15301 rtx cc_reg = XEXP (op, 0);
15302 enum machine_mode mode = GET_MODE (cc_reg);
15303 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
15304 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
15305 int really_reversed = reversed ^ need_longbranch;
15311 validate_condition_mode (code, mode);
15313 /* Work out which way this really branches. We could use
15314 reverse_condition_maybe_unordered here always but this
15315 makes the resulting assembler clearer. */
15316 if (really_reversed)
15318 /* Reversal of FP compares takes care -- an ordered compare
15319 becomes an unordered compare and vice versa. */
15320 if (mode == CCFPmode)
15321 code = reverse_condition_maybe_unordered (code);
15323 code = reverse_condition (code);
15326 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
15328 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
15333 /* Opposite of GT. */
15342 gcc_unreachable ();
15348 /* Not all of these are actually distinct opcodes, but
15349 we distinguish them for clarity of the resulting assembler. */
15350 case NE: case LTGT:
15351 ccode = "ne"; break;
15352 case EQ: case UNEQ:
15353 ccode = "eq"; break;
15355 ccode = "ge"; break;
15356 case GT: case GTU: case UNGT:
15357 ccode = "gt"; break;
15359 ccode = "le"; break;
15360 case LT: case LTU: case UNLT:
15361 ccode = "lt"; break;
15362 case UNORDERED: ccode = "un"; break;
15363 case ORDERED: ccode = "nu"; break;
15364 case UNGE: ccode = "nl"; break;
15365 case UNLE: ccode = "ng"; break;
15367 gcc_unreachable ();
15370 /* Maybe we have a guess as to how likely the branch is.
15371 The old mnemonics don't have a way to specify this information. */
15373 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
15374 if (note != NULL_RTX)
15376 /* PROB is the difference from 50%. */
15377 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
15379 /* Only hint for highly probable/improbable branches on newer
15380 cpus as static prediction overrides processor dynamic
15381 prediction. For older cpus we may as well always hint, but
15382 assume not taken for branches that are very close to 50% as a
15383 mispredicted taken branch is more expensive than a
15384 mispredicted not-taken branch. */
15385 if (rs6000_always_hint
15386 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
15387 && br_prob_note_reliable_p (note)))
15389 if (abs (prob) > REG_BR_PROB_BASE / 20
15390 && ((prob > 0) ^ need_longbranch))
15398 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
15400 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
15402 /* We need to escape any '%' characters in the reg_names string.
15403 Assume they'd only be the first character.... */
15404 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
15406 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
15410 /* If the branch distance was too far, we may have to use an
15411 unconditional branch to go the distance. */
15412 if (need_longbranch)
15413 s += sprintf (s, ",$+8\n\tb %s", label);
15415 s += sprintf (s, ",%s", label);
15421 /* Return the string to flip the GT bit on a CR. */
15423 output_e500_flip_gt_bit (rtx dst, rtx src)
15425 static char string[64];
15428 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
15429 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
15432 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
15433 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
15435 sprintf (string, "crnot %d,%d", a, b);
15439 /* Return insn for VSX or Altivec comparisons. */
15442 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
15445 enum machine_mode mode = GET_MODE (op0);
15453 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
15459 mask = gen_reg_rtx (mode);
15460 emit_insn (gen_rtx_SET (VOIDmode,
15462 gen_rtx_fmt_ee (code, mode, op0, op1)));
15469 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
15470 DMODE is expected destination mode. This is a recursive function. */
15473 rs6000_emit_vector_compare (enum rtx_code rcode,
15475 enum machine_mode dmode)
15478 bool swap_operands = false;
15479 bool try_again = false;
15481 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
15482 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
15484 /* See if the comparison works as is. */
15485 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15493 swap_operands = true;
15498 swap_operands = true;
15506 /* Invert condition and try again.
15507 e.g., A != B becomes ~(A==B). */
15509 enum rtx_code rev_code;
15510 enum insn_code nor_code;
15513 rev_code = reverse_condition_maybe_unordered (rcode);
15514 if (rev_code == UNKNOWN)
15517 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
15518 if (nor_code == CODE_FOR_nothing)
15521 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
15525 mask = gen_reg_rtx (dmode);
15526 emit_insn (GEN_FCN (nor_code) (mask, mask2));
15534 /* Try GT/GTU/LT/LTU OR EQ */
15537 enum insn_code ior_code;
15538 enum rtx_code new_code;
15559 gcc_unreachable ();
15562 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
15563 if (ior_code == CODE_FOR_nothing)
15566 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
15570 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
15574 mask = gen_reg_rtx (dmode);
15575 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
15593 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15598 /* You only get two chances. */
15602 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
15603 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
15604 operands for the relation operation COND. */
15607 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
15608 rtx cond, rtx cc_op0, rtx cc_op1)
15610 enum machine_mode dest_mode = GET_MODE (dest);
15611 enum rtx_code rcode = GET_CODE (cond);
15612 enum machine_mode cc_mode = CCmode;
15616 bool invert_move = false;
15618 if (VECTOR_UNIT_NONE_P (dest_mode))
15623 /* Swap operands if we can, and fall back to doing the operation as
15624 specified, and doing a NOR to invert the test. */
15630 /* Invert condition and try again.
15631 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
15632 invert_move = true;
15633 rcode = reverse_condition_maybe_unordered (rcode);
15634 if (rcode == UNKNOWN)
15638 /* Mark unsigned tests with CCUNSmode. */
15643 cc_mode = CCUNSmode;
15650 /* Get the vector mask for the given relational operations. */
15651 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
15659 op_true = op_false;
15663 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
15664 emit_insn (gen_rtx_SET (VOIDmode,
15666 gen_rtx_IF_THEN_ELSE (dest_mode,
15673 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
15674 operands of the last comparison is nonzero/true, FALSE_COND if it
15675 is zero/false. Return 0 if the hardware has no such operation. */
15678 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15680 enum rtx_code code = GET_CODE (op);
15681 rtx op0 = XEXP (op, 0);
15682 rtx op1 = XEXP (op, 1);
15683 REAL_VALUE_TYPE c1;
15684 enum machine_mode compare_mode = GET_MODE (op0);
15685 enum machine_mode result_mode = GET_MODE (dest);
15687 bool is_against_zero;
15689 /* These modes should always match. */
15690 if (GET_MODE (op1) != compare_mode
15691 /* In the isel case however, we can use a compare immediate, so
15692 op1 may be a small constant. */
15693 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
15695 if (GET_MODE (true_cond) != result_mode)
15697 if (GET_MODE (false_cond) != result_mode)
15700 /* First, work out if the hardware can do this at all, or
15701 if it's too slow.... */
15702 if (!FLOAT_MODE_P (compare_mode))
15705 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
15708 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
15709 && SCALAR_FLOAT_MODE_P (compare_mode))
15712 is_against_zero = op1 == CONST0_RTX (compare_mode);
15714 /* A floating-point subtract might overflow, underflow, or produce
15715 an inexact result, thus changing the floating-point flags, so it
15716 can't be generated if we care about that. It's safe if one side
15717 of the construct is zero, since then no subtract will be
15719 if (SCALAR_FLOAT_MODE_P (compare_mode)
15720 && flag_trapping_math && ! is_against_zero)
15723 /* Eliminate half of the comparisons by switching operands, this
15724 makes the remaining code simpler. */
15725 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
15726 || code == LTGT || code == LT || code == UNLE)
15728 code = reverse_condition_maybe_unordered (code);
15730 true_cond = false_cond;
15734 /* UNEQ and LTGT take four instructions for a comparison with zero,
15735 it'll probably be faster to use a branch here too. */
15736 if (code == UNEQ && HONOR_NANS (compare_mode))
15739 if (GET_CODE (op1) == CONST_DOUBLE)
15740 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
15742 /* We're going to try to implement comparisons by performing
15743 a subtract, then comparing against zero. Unfortunately,
15744 Inf - Inf is NaN which is not zero, and so if we don't
15745 know that the operand is finite and the comparison
15746 would treat EQ different to UNORDERED, we can't do it. */
15747 if (HONOR_INFINITIES (compare_mode)
15748 && code != GT && code != UNGE
15749 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
15750 /* Constructs of the form (a OP b ? a : b) are safe. */
15751 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
15752 || (! rtx_equal_p (op0, true_cond)
15753 && ! rtx_equal_p (op1, true_cond))))
15756 /* At this point we know we can use fsel. */
15758 /* Reduce the comparison to a comparison against zero. */
15759 if (! is_against_zero)
15761 temp = gen_reg_rtx (compare_mode);
15762 emit_insn (gen_rtx_SET (VOIDmode, temp,
15763 gen_rtx_MINUS (compare_mode, op0, op1)));
15765 op1 = CONST0_RTX (compare_mode);
15768 /* If we don't care about NaNs we can reduce some of the comparisons
15769 down to faster ones. */
15770 if (! HONOR_NANS (compare_mode))
15776 true_cond = false_cond;
15789 /* Now, reduce everything down to a GE. */
15796 temp = gen_reg_rtx (compare_mode);
15797 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15802 temp = gen_reg_rtx (compare_mode);
15803 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
15808 temp = gen_reg_rtx (compare_mode);
15809 emit_insn (gen_rtx_SET (VOIDmode, temp,
15810 gen_rtx_NEG (compare_mode,
15811 gen_rtx_ABS (compare_mode, op0))));
15816 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
15817 temp = gen_reg_rtx (result_mode);
15818 emit_insn (gen_rtx_SET (VOIDmode, temp,
15819 gen_rtx_IF_THEN_ELSE (result_mode,
15820 gen_rtx_GE (VOIDmode,
15822 true_cond, false_cond)));
15823 false_cond = true_cond;
15826 temp = gen_reg_rtx (compare_mode);
15827 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15832 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
15833 temp = gen_reg_rtx (result_mode);
15834 emit_insn (gen_rtx_SET (VOIDmode, temp,
15835 gen_rtx_IF_THEN_ELSE (result_mode,
15836 gen_rtx_GE (VOIDmode,
15838 true_cond, false_cond)));
15839 true_cond = false_cond;
15842 temp = gen_reg_rtx (compare_mode);
15843 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15848 gcc_unreachable ();
15851 emit_insn (gen_rtx_SET (VOIDmode, dest,
15852 gen_rtx_IF_THEN_ELSE (result_mode,
15853 gen_rtx_GE (VOIDmode,
15855 true_cond, false_cond)));
15859 /* Same as above, but for ints (isel). */
15862 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15864 rtx condition_rtx, cr;
15865 enum machine_mode mode = GET_MODE (XEXP (op, 0));
15867 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
15870 /* We still have to do the compare, because isel doesn't do a
15871 compare, it just looks at the CRx bits set by a previous compare
15873 condition_rtx = rs6000_generate_compare (op, SImode);
15874 cr = XEXP (condition_rtx, 0);
15876 if (mode == SImode)
15878 if (GET_MODE (cr) == CCmode)
15879 emit_insn (gen_isel_signed_si (dest, condition_rtx,
15880 true_cond, false_cond, cr));
15882 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
15883 true_cond, false_cond, cr));
15887 if (GET_MODE (cr) == CCmode)
15888 emit_insn (gen_isel_signed_di (dest, condition_rtx,
15889 true_cond, false_cond, cr));
15891 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
15892 true_cond, false_cond, cr));
15899 output_isel (rtx *operands)
15901 enum rtx_code code;
15903 code = GET_CODE (operands[1]);
15904 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
15906 PUT_CODE (operands[1], reverse_condition (code));
15907 return "isel %0,%3,%2,%j1";
15910 return "isel %0,%2,%3,%j1";
15914 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
15916 enum machine_mode mode = GET_MODE (op0);
15920 /* VSX/altivec have direct min/max insns. */
15921 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
15923 emit_insn (gen_rtx_SET (VOIDmode,
15925 gen_rtx_fmt_ee (code, mode, op0, op1)));
15929 if (code == SMAX || code == SMIN)
15934 if (code == SMAX || code == UMAX)
15935 target = emit_conditional_move (dest, c, op0, op1, mode,
15936 op0, op1, mode, 0);
15938 target = emit_conditional_move (dest, c, op0, op1, mode,
15939 op1, op0, mode, 0);
15940 gcc_assert (target);
15941 if (target != dest)
15942 emit_move_insn (dest, target);
15945 /* Emit instructions to perform a load-reserved/store-conditional operation.
15946 The operation performed is an atomic
15947 (set M (CODE:MODE M OP))
15948 If not NULL, BEFORE is atomically set to M before the operation, and
15949 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
15950 If SYNC_P then a memory barrier is emitted before the operation.
15951 Either OP or M may be wrapped in a NOT operation. */
15954 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
15955 rtx m, rtx op, rtx before_param, rtx after_param,
15958 enum machine_mode used_mode;
15959 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
15962 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
15963 rtx shift = NULL_RTX;
15966 emit_insn (gen_lwsync ());
15970 /* If this is smaller than SImode, we'll have to use SImode with
15972 if (mode == QImode || mode == HImode)
15976 if (MEM_ALIGN (used_m) >= 32)
15979 if (BYTES_BIG_ENDIAN)
15980 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
15982 shift = GEN_INT (ishift);
15983 used_m = change_address (used_m, SImode, 0);
15987 rtx addrSI, aligned_addr;
15988 int shift_mask = mode == QImode ? 0x18 : 0x10;
15990 addrSI = gen_lowpart_common (SImode,
15991 force_reg (Pmode, XEXP (used_m, 0)));
15992 addrSI = force_reg (SImode, addrSI);
15993 shift = gen_reg_rtx (SImode);
15995 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
15996 GEN_INT (shift_mask)));
15997 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
15999 aligned_addr = expand_binop (Pmode, and_optab,
16001 GEN_INT (-4), NULL_RTX,
16002 1, OPTAB_LIB_WIDEN);
16003 used_m = change_address (used_m, SImode, aligned_addr);
16004 set_mem_align (used_m, 32);
16006 /* It's safe to keep the old alias set of USED_M, because
16007 the operation is atomic and only affects the original
16011 if (GET_CODE (op) == NOT)
16013 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16014 oldop = gen_rtx_NOT (SImode, oldop);
16017 oldop = lowpart_subreg (SImode, op, mode);
16023 newop = expand_binop (SImode, and_optab,
16024 oldop, GEN_INT (imask), NULL_RTX,
16025 1, OPTAB_LIB_WIDEN);
16026 emit_insn (gen_ashlsi3 (newop, newop, shift));
16029 case NOT: /* NAND */
16030 newop = expand_binop (SImode, ior_optab,
16031 oldop, GEN_INT (~imask), NULL_RTX,
16032 1, OPTAB_LIB_WIDEN);
16033 emit_insn (gen_rotlsi3 (newop, newop, shift));
16037 newop = expand_binop (SImode, ior_optab,
16038 oldop, GEN_INT (~imask), NULL_RTX,
16039 1, OPTAB_LIB_WIDEN);
16040 emit_insn (gen_rotlsi3 (newop, newop, shift));
16048 newop = expand_binop (SImode, and_optab,
16049 oldop, GEN_INT (imask), NULL_RTX,
16050 1, OPTAB_LIB_WIDEN);
16051 emit_insn (gen_ashlsi3 (newop, newop, shift));
16053 mask = gen_reg_rtx (SImode);
16054 emit_move_insn (mask, GEN_INT (imask));
16055 emit_insn (gen_ashlsi3 (mask, mask, shift));
16058 newop = gen_rtx_PLUS (SImode, m, newop);
16060 newop = gen_rtx_MINUS (SImode, m, newop);
16061 newop = gen_rtx_AND (SImode, newop, mask);
16062 newop = gen_rtx_IOR (SImode, newop,
16063 gen_rtx_AND (SImode,
16064 gen_rtx_NOT (SImode, mask),
16070 gcc_unreachable ();
16074 used_mode = SImode;
16075 before = gen_reg_rtx (used_mode);
16076 after = gen_reg_rtx (used_mode);
16081 before = before_param;
16082 after = after_param;
16084 if (before == NULL_RTX)
16085 before = gen_reg_rtx (used_mode);
16086 if (after == NULL_RTX)
16087 after = gen_reg_rtx (used_mode);
16090 if ((code == PLUS || code == MINUS)
16091 && used_mode != mode)
16092 the_op = op; /* Computed above. */
16093 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16094 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16095 else if (code == NOT)
16096 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16097 gen_rtx_NOT (used_mode, m),
16098 gen_rtx_NOT (used_mode, op));
16100 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16102 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16103 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16104 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16105 gen_rtx_UNSPEC (used_mode,
16106 gen_rtvec (1, the_op),
16108 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16110 if ((code == PLUS || code == MINUS) && used_mode != mode)
16111 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16112 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16114 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16115 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16117 /* Shift and mask the return values properly. */
16118 if (used_mode != mode && before_param)
16120 emit_insn (gen_lshrsi3 (before, before, shift));
16121 convert_move (before_param, before, 1);
16124 if (used_mode != mode && after_param)
16126 emit_insn (gen_lshrsi3 (after, after, shift));
16127 convert_move (after_param, after, 1);
16130 /* The previous sequence will end with a branch that's dependent on
16131 the conditional store, so placing an isync will ensure that no
16132 other instructions (especially, no load or store instructions)
16133 can start before the atomic operation completes. */
16135 emit_insn (gen_isync ());
16138 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16139 COND is true. Mark the jump as unlikely to be taken. */
16142 emit_unlikely_jump (rtx cond, rtx label)
16144 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16147 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16148 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16149 add_reg_note (x, REG_BR_PROB, very_unlikely);
16152 /* A subroutine of the atomic operation splitters. Emit a load-locked
16153 instruction in MODE. */
16156 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16158 rtx (*fn) (rtx, rtx) = NULL;
16159 if (mode == SImode)
16160 fn = gen_load_locked_si;
16161 else if (mode == DImode)
16162 fn = gen_load_locked_di;
16163 emit_insn (fn (reg, mem));
16166 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16167 instruction in MODE. */
16170 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16172 rtx (*fn) (rtx, rtx, rtx) = NULL;
16173 if (mode == SImode)
16174 fn = gen_store_conditional_si;
16175 else if (mode == DImode)
16176 fn = gen_store_conditional_di;
16178 /* Emit sync before stwcx. to address PPC405 Erratum. */
16179 if (PPC405_ERRATUM77)
16180 emit_insn (gen_memory_barrier ());
16182 emit_insn (fn (res, mem, val));
16185 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16186 to perform. MEM is the memory on which to operate. VAL is the second
16187 operand of the binary operator. BEFORE and AFTER are optional locations to
16188 return the value of MEM either before of after the operation. SCRATCH is
16189 a scratch register. */
16192 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16193 rtx before, rtx after, rtx scratch)
16195 enum machine_mode mode = GET_MODE (mem);
16196 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16198 emit_insn (gen_lwsync ());
16200 label = gen_label_rtx ();
16201 emit_label (label);
16202 label = gen_rtx_LABEL_REF (VOIDmode, label);
16204 if (before == NULL_RTX)
16206 emit_load_locked (mode, before, mem);
16209 x = gen_rtx_IOR (mode,
16210 gen_rtx_NOT (mode, before),
16211 gen_rtx_NOT (mode, val));
16212 else if (code == AND)
16213 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16215 x = gen_rtx_fmt_ee (code, mode, before, val);
16217 if (after != NULL_RTX)
16218 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16219 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16221 emit_store_conditional (mode, cond, mem, scratch);
16223 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16224 emit_unlikely_jump (x, label);
16226 emit_insn (gen_isync ());
16229 /* Expand an atomic compare and swap operation. MEM is the memory on which
16230 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16231 value to be stored. SCRATCH is a scratch GPR. */
16234 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16237 enum machine_mode mode = GET_MODE (mem);
16238 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16240 emit_insn (gen_lwsync ());
16242 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16243 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16244 emit_label (XEXP (label1, 0));
16246 emit_load_locked (mode, retval, mem);
16248 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16249 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16251 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16252 emit_unlikely_jump (x, label2);
16254 emit_move_insn (scratch, newval);
16255 emit_store_conditional (mode, cond, mem, scratch);
16257 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16258 emit_unlikely_jump (x, label1);
16260 emit_insn (gen_isync ());
16261 emit_label (XEXP (label2, 0));
16264 /* Expand an atomic test and set operation. MEM is the memory on which
16265 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16268 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16270 enum machine_mode mode = GET_MODE (mem);
16271 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16273 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16274 emit_label (XEXP (label, 0));
16276 emit_load_locked (mode, retval, mem);
16277 emit_move_insn (scratch, val);
16278 emit_store_conditional (mode, cond, mem, scratch);
16280 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16281 emit_unlikely_jump (x, label);
16283 emit_insn (gen_isync ());
16287 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
16289 enum machine_mode mode = GET_MODE (mem);
16290 rtx addrSI, align, wdst, shift, mask;
16291 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
16292 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16294 /* Shift amount for subword relative to aligned word. */
16295 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
16296 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
16297 shift = gen_reg_rtx (SImode);
16298 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16299 GEN_INT (shift_mask)));
16300 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16302 /* Shift and mask old value into position within word. */
16303 oldval = convert_modes (SImode, mode, oldval, 1);
16304 oldval = expand_binop (SImode, and_optab,
16305 oldval, GEN_INT (imask), NULL_RTX,
16306 1, OPTAB_LIB_WIDEN);
16307 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
16309 /* Shift and mask new value into position within word. */
16310 newval = convert_modes (SImode, mode, newval, 1);
16311 newval = expand_binop (SImode, and_optab,
16312 newval, GEN_INT (imask), NULL_RTX,
16313 1, OPTAB_LIB_WIDEN);
16314 emit_insn (gen_ashlsi3 (newval, newval, shift));
16316 /* Mask for insertion. */
16317 mask = gen_reg_rtx (SImode);
16318 emit_move_insn (mask, GEN_INT (imask));
16319 emit_insn (gen_ashlsi3 (mask, mask, shift));
16321 /* Address of aligned word containing subword. */
16322 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
16323 NULL_RTX, 1, OPTAB_LIB_WIDEN);
16324 mem = change_address (mem, SImode, align);
16325 set_mem_align (mem, 32);
16326 MEM_VOLATILE_P (mem) = 1;
16328 wdst = gen_reg_rtx (SImode);
16329 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
16330 oldval, newval, mem));
16332 /* Shift the result back. */
16333 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
16335 emit_move_insn (dst, gen_lowpart (mode, wdst));
16339 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
16340 rtx oldval, rtx newval, rtx mem,
16343 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16345 emit_insn (gen_lwsync ());
16346 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16347 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16348 emit_label (XEXP (label1, 0));
16350 emit_load_locked (SImode, scratch, mem);
16352 /* Mask subword within loaded value for comparison with oldval.
16353 Use UNSPEC_AND to avoid clobber.*/
16354 emit_insn (gen_rtx_SET (SImode, dest,
16355 gen_rtx_UNSPEC (SImode,
16356 gen_rtvec (2, scratch, mask),
16359 x = gen_rtx_COMPARE (CCmode, dest, oldval);
16360 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16362 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16363 emit_unlikely_jump (x, label2);
16365 /* Clear subword within loaded value for insertion of new value. */
16366 emit_insn (gen_rtx_SET (SImode, scratch,
16367 gen_rtx_AND (SImode,
16368 gen_rtx_NOT (SImode, mask), scratch)));
16369 emit_insn (gen_iorsi3 (scratch, scratch, newval));
16370 emit_store_conditional (SImode, cond, mem, scratch);
16372 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16373 emit_unlikely_jump (x, label1);
16375 emit_insn (gen_isync ());
16376 emit_label (XEXP (label2, 0));
16380 /* Emit instructions to move SRC to DST. Called by splitters for
16381 multi-register moves. It will emit at most one instruction for
16382 each register that is accessed; that is, it won't emit li/lis pairs
16383 (or equivalent for 64-bit code). One of SRC or DST must be a hard
16387 rs6000_split_multireg_move (rtx dst, rtx src)
16389 /* The register number of the first register being moved. */
16391 /* The mode that is to be moved. */
16392 enum machine_mode mode;
16393 /* The mode that the move is being done in, and its size. */
16394 enum machine_mode reg_mode;
16396 /* The number of registers that will be moved. */
16399 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
16400 mode = GET_MODE (dst);
16401 nregs = hard_regno_nregs[reg][mode];
16402 if (FP_REGNO_P (reg))
16403 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
16404 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
16405 else if (ALTIVEC_REGNO_P (reg))
16406 reg_mode = V16QImode;
16407 else if (TARGET_E500_DOUBLE && mode == TFmode)
16410 reg_mode = word_mode;
16411 reg_mode_size = GET_MODE_SIZE (reg_mode);
16413 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
16415 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
16417 /* Move register range backwards, if we might have destructive
16420 for (i = nregs - 1; i >= 0; i--)
16421 emit_insn (gen_rtx_SET (VOIDmode,
16422 simplify_gen_subreg (reg_mode, dst, mode,
16423 i * reg_mode_size),
16424 simplify_gen_subreg (reg_mode, src, mode,
16425 i * reg_mode_size)));
16431 bool used_update = false;
16433 if (MEM_P (src) && INT_REGNO_P (reg))
16437 if (GET_CODE (XEXP (src, 0)) == PRE_INC
16438 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
16441 breg = XEXP (XEXP (src, 0), 0);
16442 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
16443 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
16444 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
16445 emit_insn (TARGET_32BIT
16446 ? gen_addsi3 (breg, breg, delta_rtx)
16447 : gen_adddi3 (breg, breg, delta_rtx));
16448 src = replace_equiv_address (src, breg);
16450 else if (! rs6000_offsettable_memref_p (src))
16453 basereg = gen_rtx_REG (Pmode, reg);
16454 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
16455 src = replace_equiv_address (src, basereg);
16458 breg = XEXP (src, 0);
16459 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
16460 breg = XEXP (breg, 0);
16462 /* If the base register we are using to address memory is
16463 also a destination reg, then change that register last. */
16465 && REGNO (breg) >= REGNO (dst)
16466 && REGNO (breg) < REGNO (dst) + nregs)
16467 j = REGNO (breg) - REGNO (dst);
16470 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
16474 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
16475 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
16478 breg = XEXP (XEXP (dst, 0), 0);
16479 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
16480 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
16481 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
16483 /* We have to update the breg before doing the store.
16484 Use store with update, if available. */
16488 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16489 emit_insn (TARGET_32BIT
16490 ? (TARGET_POWERPC64
16491 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
16492 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
16493 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
16494 used_update = true;
16497 emit_insn (TARGET_32BIT
16498 ? gen_addsi3 (breg, breg, delta_rtx)
16499 : gen_adddi3 (breg, breg, delta_rtx));
16500 dst = replace_equiv_address (dst, breg);
16503 gcc_assert (rs6000_offsettable_memref_p (dst));
16506 for (i = 0; i < nregs; i++)
16508 /* Calculate index to next subword. */
16513 /* If compiler already emitted move of first word by
16514 store with update, no need to do anything. */
16515 if (j == 0 && used_update)
16518 emit_insn (gen_rtx_SET (VOIDmode,
16519 simplify_gen_subreg (reg_mode, dst, mode,
16520 j * reg_mode_size),
16521 simplify_gen_subreg (reg_mode, src, mode,
16522 j * reg_mode_size)));
16528 /* This page contains routines that are used to determine what the
16529 function prologue and epilogue code will do and write them out. */
16531 /* Return the first fixed-point register that is required to be
16532 saved. 32 if none. */
16535 first_reg_to_save (void)
16539 /* Find lowest numbered live register. */
16540 for (first_reg = 13; first_reg <= 31; first_reg++)
16541 if (df_regs_ever_live_p (first_reg)
16542 && (! call_used_regs[first_reg]
16543 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
16544 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
16545 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
16546 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
16551 && crtl->uses_pic_offset_table
16552 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
16553 return RS6000_PIC_OFFSET_TABLE_REGNUM;
16559 /* Similar, for FP regs. */
16562 first_fp_reg_to_save (void)
16566 /* Find lowest numbered live register. */
16567 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
16568 if (df_regs_ever_live_p (first_reg))
16574 /* Similar, for AltiVec regs. */
16577 first_altivec_reg_to_save (void)
16581 /* Stack frame remains as is unless we are in AltiVec ABI. */
16582 if (! TARGET_ALTIVEC_ABI)
16583 return LAST_ALTIVEC_REGNO + 1;
16585 /* On Darwin, the unwind routines are compiled without
16586 TARGET_ALTIVEC, and use save_world to save/restore the
16587 altivec registers when necessary. */
16588 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16589 && ! TARGET_ALTIVEC)
16590 return FIRST_ALTIVEC_REGNO + 20;
16592 /* Find lowest numbered live register. */
16593 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
16594 if (df_regs_ever_live_p (i))
16600 /* Return a 32-bit mask of the AltiVec registers we need to set in
16601 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
16602 the 32-bit word is 0. */
16604 static unsigned int
16605 compute_vrsave_mask (void)
16607 unsigned int i, mask = 0;
16609 /* On Darwin, the unwind routines are compiled without
16610 TARGET_ALTIVEC, and use save_world to save/restore the
16611 call-saved altivec registers when necessary. */
16612 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16613 && ! TARGET_ALTIVEC)
16616 /* First, find out if we use _any_ altivec registers. */
16617 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
16618 if (df_regs_ever_live_p (i))
16619 mask |= ALTIVEC_REG_BIT (i);
16624 /* Next, remove the argument registers from the set. These must
16625 be in the VRSAVE mask set by the caller, so we don't need to add
16626 them in again. More importantly, the mask we compute here is
16627 used to generate CLOBBERs in the set_vrsave insn, and we do not
16628 wish the argument registers to die. */
16629 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
16630 mask &= ~ALTIVEC_REG_BIT (i);
16632 /* Similarly, remove the return value from the set. */
16635 diddle_return_value (is_altivec_return_reg, &yes);
16637 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
16643 /* For a very restricted set of circumstances, we can cut down the
16644 size of prologues/epilogues by calling our own save/restore-the-world
16648 compute_save_world_info (rs6000_stack_t *info_ptr)
16650 info_ptr->world_save_p = 1;
16651 info_ptr->world_save_p
16652 = (WORLD_SAVE_P (info_ptr)
16653 && DEFAULT_ABI == ABI_DARWIN
16654 && ! (cfun->calls_setjmp && flag_exceptions)
16655 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
16656 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
16657 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
16658 && info_ptr->cr_save_p);
16660 /* This will not work in conjunction with sibcalls. Make sure there
16661 are none. (This check is expensive, but seldom executed.) */
16662 if (WORLD_SAVE_P (info_ptr))
16665 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
16666 if ( GET_CODE (insn) == CALL_INSN
16667 && SIBLING_CALL_P (insn))
16669 info_ptr->world_save_p = 0;
16674 if (WORLD_SAVE_P (info_ptr))
16676 /* Even if we're not touching VRsave, make sure there's room on the
16677 stack for it, if it looks like we're calling SAVE_WORLD, which
16678 will attempt to save it. */
16679 info_ptr->vrsave_size = 4;
16681 /* If we are going to save the world, we need to save the link register too. */
16682 info_ptr->lr_save_p = 1;
16684 /* "Save" the VRsave register too if we're saving the world. */
16685 if (info_ptr->vrsave_mask == 0)
16686 info_ptr->vrsave_mask = compute_vrsave_mask ();
16688 /* Because the Darwin register save/restore routines only handle
16689 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
16691 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
16692 && (info_ptr->first_altivec_reg_save
16693 >= FIRST_SAVED_ALTIVEC_REGNO));
16700 is_altivec_return_reg (rtx reg, void *xyes)
16702 bool *yes = (bool *) xyes;
16703 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
16708 /* Calculate the stack information for the current function. This is
16709 complicated by having two separate calling sequences, the AIX calling
16710 sequence and the V.4 calling sequence.
16712 AIX (and Darwin/Mac OS X) stack frames look like:
16714 SP----> +---------------------------------------+
16715 | back chain to caller | 0 0
16716 +---------------------------------------+
16717 | saved CR | 4 8 (8-11)
16718 +---------------------------------------+
16720 +---------------------------------------+
16721 | reserved for compilers | 12 24
16722 +---------------------------------------+
16723 | reserved for binders | 16 32
16724 +---------------------------------------+
16725 | saved TOC pointer | 20 40
16726 +---------------------------------------+
16727 | Parameter save area (P) | 24 48
16728 +---------------------------------------+
16729 | Alloca space (A) | 24+P etc.
16730 +---------------------------------------+
16731 | Local variable space (L) | 24+P+A
16732 +---------------------------------------+
16733 | Float/int conversion temporary (X) | 24+P+A+L
16734 +---------------------------------------+
16735 | Save area for AltiVec registers (W) | 24+P+A+L+X
16736 +---------------------------------------+
16737 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
16738 +---------------------------------------+
16739 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
16740 +---------------------------------------+
16741 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
16742 +---------------------------------------+
16743 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
16744 +---------------------------------------+
16745 old SP->| back chain to caller's caller |
16746 +---------------------------------------+
16748 The required alignment for AIX configurations is two words (i.e., 8
16752 V.4 stack frames look like:
16754 SP----> +---------------------------------------+
16755 | back chain to caller | 0
16756 +---------------------------------------+
16757 | caller's saved LR | 4
16758 +---------------------------------------+
16759 | Parameter save area (P) | 8
16760 +---------------------------------------+
16761 | Alloca space (A) | 8+P
16762 +---------------------------------------+
16763 | Varargs save area (V) | 8+P+A
16764 +---------------------------------------+
16765 | Local variable space (L) | 8+P+A+V
16766 +---------------------------------------+
16767 | Float/int conversion temporary (X) | 8+P+A+V+L
16768 +---------------------------------------+
16769 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
16770 +---------------------------------------+
16771 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
16772 +---------------------------------------+
16773 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
16774 +---------------------------------------+
16775 | SPE: area for 64-bit GP registers |
16776 +---------------------------------------+
16777 | SPE alignment padding |
16778 +---------------------------------------+
16779 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
16780 +---------------------------------------+
16781 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
16782 +---------------------------------------+
16783 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
16784 +---------------------------------------+
16785 old SP->| back chain to caller's caller |
16786 +---------------------------------------+
16788 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
16789 given. (But note below and in sysv4.h that we require only 8 and
16790 may round up the size of our stack frame anyways. The historical
16791 reason is early versions of powerpc-linux which didn't properly
16792 align the stack at program startup. A happy side-effect is that
16793 -mno-eabi libraries can be used with -meabi programs.)
16795 The EABI configuration defaults to the V.4 layout. However,
16796 the stack alignment requirements may differ. If -mno-eabi is not
16797 given, the required stack alignment is 8 bytes; if -mno-eabi is
16798 given, the required alignment is 16 bytes. (But see V.4 comment
16801 #ifndef ABI_STACK_BOUNDARY
16802 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
16805 static rs6000_stack_t *
16806 rs6000_stack_info (void)
16808 static rs6000_stack_t info;
16809 rs6000_stack_t *info_ptr = &info;
16810 int reg_size = TARGET_32BIT ? 4 : 8;
16814 HOST_WIDE_INT non_fixed_size;
16816 memset (&info, 0, sizeof (info));
16820 /* Cache value so we don't rescan instruction chain over and over. */
16821 if (cfun->machine->insn_chain_scanned_p == 0)
16822 cfun->machine->insn_chain_scanned_p
16823 = spe_func_has_64bit_regs_p () + 1;
16824 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
16827 /* Select which calling sequence. */
16828 info_ptr->abi = DEFAULT_ABI;
16830 /* Calculate which registers need to be saved & save area size. */
16831 info_ptr->first_gp_reg_save = first_reg_to_save ();
16832 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
16833 even if it currently looks like we won't. Reload may need it to
16834 get at a constant; if so, it will have already created a constant
16835 pool entry for it. */
16836 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
16837 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
16838 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
16839 && crtl->uses_const_pool
16840 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
16841 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
16843 first_gp = info_ptr->first_gp_reg_save;
16845 info_ptr->gp_size = reg_size * (32 - first_gp);
16847 /* For the SPE, we have an additional upper 32-bits on each GPR.
16848 Ideally we should save the entire 64-bits only when the upper
16849 half is used in SIMD instructions. Since we only record
16850 registers live (not the size they are used in), this proves
16851 difficult because we'd have to traverse the instruction chain at
16852 the right time, taking reload into account. This is a real pain,
16853 so we opt to save the GPRs in 64-bits always if but one register
16854 gets used in 64-bits. Otherwise, all the registers in the frame
16855 get saved in 32-bits.
16857 So... since when we save all GPRs (except the SP) in 64-bits, the
16858 traditional GP save area will be empty. */
16859 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
16860 info_ptr->gp_size = 0;
16862 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
16863 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
16865 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
16866 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
16867 - info_ptr->first_altivec_reg_save);
16869 /* Does this function call anything? */
16870 info_ptr->calls_p = (! current_function_is_leaf
16871 || cfun->machine->ra_needs_full_frame);
16873 /* Determine if we need to save the link register. */
16874 if ((DEFAULT_ABI == ABI_AIX
16876 && !TARGET_PROFILE_KERNEL)
16877 #ifdef TARGET_RELOCATABLE
16878 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
16880 || (info_ptr->first_fp_reg_save != 64
16881 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
16882 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
16883 || info_ptr->calls_p
16884 || rs6000_ra_ever_killed ())
16886 info_ptr->lr_save_p = 1;
16887 df_set_regs_ever_live (LR_REGNO, true);
16890 /* Determine if we need to save the condition code registers. */
16891 if (df_regs_ever_live_p (CR2_REGNO)
16892 || df_regs_ever_live_p (CR3_REGNO)
16893 || df_regs_ever_live_p (CR4_REGNO))
16895 info_ptr->cr_save_p = 1;
16896 if (DEFAULT_ABI == ABI_V4)
16897 info_ptr->cr_size = reg_size;
16900 /* If the current function calls __builtin_eh_return, then we need
16901 to allocate stack space for registers that will hold data for
16902 the exception handler. */
16903 if (crtl->calls_eh_return)
16906 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
16909 /* SPE saves EH registers in 64-bits. */
16910 ehrd_size = i * (TARGET_SPE_ABI
16911 && info_ptr->spe_64bit_regs_used != 0
16912 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
16917 /* Determine various sizes. */
16918 info_ptr->reg_size = reg_size;
16919 info_ptr->fixed_size = RS6000_SAVE_AREA;
16920 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
16921 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
16922 TARGET_ALTIVEC ? 16 : 8);
16923 if (FRAME_GROWS_DOWNWARD)
16924 info_ptr->vars_size
16925 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
16926 + info_ptr->parm_size,
16927 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
16928 - (info_ptr->fixed_size + info_ptr->vars_size
16929 + info_ptr->parm_size);
16931 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
16932 info_ptr->spe_gp_size = 8 * (32 - first_gp);
16934 info_ptr->spe_gp_size = 0;
16936 if (TARGET_ALTIVEC_ABI)
16937 info_ptr->vrsave_mask = compute_vrsave_mask ();
16939 info_ptr->vrsave_mask = 0;
16941 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
16942 info_ptr->vrsave_size = 4;
16944 info_ptr->vrsave_size = 0;
16946 compute_save_world_info (info_ptr);
16948 /* Calculate the offsets. */
16949 switch (DEFAULT_ABI)
16953 gcc_unreachable ();
16957 info_ptr->fp_save_offset = - info_ptr->fp_size;
16958 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
16960 if (TARGET_ALTIVEC_ABI)
16962 info_ptr->vrsave_save_offset
16963 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
16965 /* Align stack so vector save area is on a quadword boundary.
16966 The padding goes above the vectors. */
16967 if (info_ptr->altivec_size != 0)
16968 info_ptr->altivec_padding_size
16969 = info_ptr->vrsave_save_offset & 0xF;
16971 info_ptr->altivec_padding_size = 0;
16973 info_ptr->altivec_save_offset
16974 = info_ptr->vrsave_save_offset
16975 - info_ptr->altivec_padding_size
16976 - info_ptr->altivec_size;
16977 gcc_assert (info_ptr->altivec_size == 0
16978 || info_ptr->altivec_save_offset % 16 == 0);
16980 /* Adjust for AltiVec case. */
16981 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
16984 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
16985 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
16986 info_ptr->lr_save_offset = 2*reg_size;
16990 info_ptr->fp_save_offset = - info_ptr->fp_size;
16991 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
16992 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
16994 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
16996 /* Align stack so SPE GPR save area is aligned on a
16997 double-word boundary. */
16998 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
16999 info_ptr->spe_padding_size
17000 = 8 - (-info_ptr->cr_save_offset % 8);
17002 info_ptr->spe_padding_size = 0;
17004 info_ptr->spe_gp_save_offset
17005 = info_ptr->cr_save_offset
17006 - info_ptr->spe_padding_size
17007 - info_ptr->spe_gp_size;
17009 /* Adjust for SPE case. */
17010 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17012 else if (TARGET_ALTIVEC_ABI)
17014 info_ptr->vrsave_save_offset
17015 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17017 /* Align stack so vector save area is on a quadword boundary. */
17018 if (info_ptr->altivec_size != 0)
17019 info_ptr->altivec_padding_size
17020 = 16 - (-info_ptr->vrsave_save_offset % 16);
17022 info_ptr->altivec_padding_size = 0;
17024 info_ptr->altivec_save_offset
17025 = info_ptr->vrsave_save_offset
17026 - info_ptr->altivec_padding_size
17027 - info_ptr->altivec_size;
17029 /* Adjust for AltiVec case. */
17030 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17033 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17034 info_ptr->ehrd_offset -= ehrd_size;
17035 info_ptr->lr_save_offset = reg_size;
17039 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17040 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17041 + info_ptr->gp_size
17042 + info_ptr->altivec_size
17043 + info_ptr->altivec_padding_size
17044 + info_ptr->spe_gp_size
17045 + info_ptr->spe_padding_size
17047 + info_ptr->cr_size
17048 + info_ptr->vrsave_size,
17051 non_fixed_size = (info_ptr->vars_size
17052 + info_ptr->parm_size
17053 + info_ptr->save_size);
17055 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17056 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17058 /* Determine if we need to allocate any stack frame:
17060 For AIX we need to push the stack if a frame pointer is needed
17061 (because the stack might be dynamically adjusted), if we are
17062 debugging, if we make calls, or if the sum of fp_save, gp_save,
17063 and local variables are more than the space needed to save all
17064 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17065 + 18*8 = 288 (GPR13 reserved).
17067 For V.4 we don't have the stack cushion that AIX uses, but assume
17068 that the debugger can handle stackless frames. */
17070 if (info_ptr->calls_p)
17071 info_ptr->push_p = 1;
17073 else if (DEFAULT_ABI == ABI_V4)
17074 info_ptr->push_p = non_fixed_size != 0;
17076 else if (frame_pointer_needed)
17077 info_ptr->push_p = 1;
17079 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17080 info_ptr->push_p = 1;
17083 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17085 /* Zero offsets if we're not saving those registers. */
17086 if (info_ptr->fp_size == 0)
17087 info_ptr->fp_save_offset = 0;
17089 if (info_ptr->gp_size == 0)
17090 info_ptr->gp_save_offset = 0;
17092 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17093 info_ptr->altivec_save_offset = 0;
17095 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17096 info_ptr->vrsave_save_offset = 0;
17098 if (! TARGET_SPE_ABI
17099 || info_ptr->spe_64bit_regs_used == 0
17100 || info_ptr->spe_gp_size == 0)
17101 info_ptr->spe_gp_save_offset = 0;
17103 if (! info_ptr->lr_save_p)
17104 info_ptr->lr_save_offset = 0;
17106 if (! info_ptr->cr_save_p)
17107 info_ptr->cr_save_offset = 0;
17112 /* Return true if the current function uses any GPRs in 64-bit SIMD
17116 spe_func_has_64bit_regs_p (void)
17120 /* Functions that save and restore all the call-saved registers will
17121 need to save/restore the registers in 64-bits. */
17122 if (crtl->calls_eh_return
17123 || cfun->calls_setjmp
17124 || crtl->has_nonlocal_goto)
17127 insns = get_insns ();
17129 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17135 /* FIXME: This should be implemented with attributes...
17137 (set_attr "spe64" "true")....then,
17138 if (get_spe64(insn)) return true;
17140 It's the only reliable way to do the stuff below. */
17142 i = PATTERN (insn);
17143 if (GET_CODE (i) == SET)
17145 enum machine_mode mode = GET_MODE (SET_SRC (i));
17147 if (SPE_VECTOR_MODE (mode))
17149 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17159 debug_stack_info (rs6000_stack_t *info)
17161 const char *abi_string;
17164 info = rs6000_stack_info ();
17166 fprintf (stderr, "\nStack information for function %s:\n",
17167 ((current_function_decl && DECL_NAME (current_function_decl))
17168 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17173 default: abi_string = "Unknown"; break;
17174 case ABI_NONE: abi_string = "NONE"; break;
17175 case ABI_AIX: abi_string = "AIX"; break;
17176 case ABI_DARWIN: abi_string = "Darwin"; break;
17177 case ABI_V4: abi_string = "V.4"; break;
17180 fprintf (stderr, "\tABI = %5s\n", abi_string);
17182 if (TARGET_ALTIVEC_ABI)
17183 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17185 if (TARGET_SPE_ABI)
17186 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17188 if (info->first_gp_reg_save != 32)
17189 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17191 if (info->first_fp_reg_save != 64)
17192 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17194 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17195 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17196 info->first_altivec_reg_save);
17198 if (info->lr_save_p)
17199 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17201 if (info->cr_save_p)
17202 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17204 if (info->vrsave_mask)
17205 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17208 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17211 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17213 if (info->gp_save_offset)
17214 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17216 if (info->fp_save_offset)
17217 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17219 if (info->altivec_save_offset)
17220 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17221 info->altivec_save_offset);
17223 if (info->spe_gp_save_offset)
17224 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17225 info->spe_gp_save_offset);
17227 if (info->vrsave_save_offset)
17228 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17229 info->vrsave_save_offset);
17231 if (info->lr_save_offset)
17232 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
17234 if (info->cr_save_offset)
17235 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
17237 if (info->varargs_save_offset)
17238 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
17240 if (info->total_size)
17241 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17244 if (info->vars_size)
17245 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17248 if (info->parm_size)
17249 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
17251 if (info->fixed_size)
17252 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
17255 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
17257 if (info->spe_gp_size)
17258 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
17261 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
17263 if (info->altivec_size)
17264 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
17266 if (info->vrsave_size)
17267 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
17269 if (info->altivec_padding_size)
17270 fprintf (stderr, "\taltivec_padding_size= %5d\n",
17271 info->altivec_padding_size);
17273 if (info->spe_padding_size)
17274 fprintf (stderr, "\tspe_padding_size = %5d\n",
17275 info->spe_padding_size);
17278 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
17280 if (info->save_size)
17281 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
17283 if (info->reg_size != 4)
17284 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
17286 fprintf (stderr, "\n");
17290 rs6000_return_addr (int count, rtx frame)
17292 /* Currently we don't optimize very well between prolog and body
17293 code and for PIC code the code can be actually quite bad, so
17294 don't try to be too clever here. */
17295 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
17297 cfun->machine->ra_needs_full_frame = 1;
17304 plus_constant (copy_to_reg
17305 (gen_rtx_MEM (Pmode,
17306 memory_address (Pmode, frame))),
17307 RETURN_ADDRESS_OFFSET)));
17310 cfun->machine->ra_need_lr = 1;
17311 return get_hard_reg_initial_val (Pmode, LR_REGNO);
17314 /* Say whether a function is a candidate for sibcall handling or not.
17315 We do not allow indirect calls to be optimized into sibling calls.
17316 Also, we can't do it if there are any vector parameters; there's
17317 nowhere to put the VRsave code so it works; note that functions with
17318 vector parameters are required to have a prototype, so the argument
17319 type info must be available here. (The tail recursion case can work
17320 with vector parameters, but there's no way to distinguish here.) */
17322 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
17327 if (TARGET_ALTIVEC_VRSAVE)
17329 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
17330 type; type = TREE_CHAIN (type))
17332 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
17336 if (DEFAULT_ABI == ABI_DARWIN
17337 || ((*targetm.binds_local_p) (decl)
17338 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
17340 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
17342 if (!lookup_attribute ("longcall", attr_list)
17343 || lookup_attribute ("shortcall", attr_list))
17350 /* NULL if INSN insn is valid within a low-overhead loop.
17351 Otherwise return why doloop cannot be applied.
17352 PowerPC uses the COUNT register for branch on table instructions. */
17354 static const char *
17355 rs6000_invalid_within_doloop (const_rtx insn)
17358 return "Function call in the loop.";
17361 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
17362 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
17363 return "Computed branch in the loop.";
17369 rs6000_ra_ever_killed (void)
17375 if (cfun->is_thunk)
17378 /* regs_ever_live has LR marked as used if any sibcalls are present,
17379 but this should not force saving and restoring in the
17380 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
17381 clobbers LR, so that is inappropriate. */
17383 /* Also, the prologue can generate a store into LR that
17384 doesn't really count, like this:
17387 bcl to set PIC register
17391 When we're called from the epilogue, we need to avoid counting
17392 this as a store. */
17394 push_topmost_sequence ();
17395 top = get_insns ();
17396 pop_topmost_sequence ();
17397 reg = gen_rtx_REG (Pmode, LR_REGNO);
17399 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
17405 if (!SIBLING_CALL_P (insn))
17408 else if (find_regno_note (insn, REG_INC, LR_REGNO))
17410 else if (set_of (reg, insn) != NULL_RTX
17411 && !prologue_epilogue_contains (insn))
17418 /* Emit instructions needed to load the TOC register.
17419 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
17420 a constant pool; or for SVR4 -fpic. */
17423 rs6000_emit_load_toc_table (int fromprolog)
17426 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
17428 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
17431 rtx lab, tmp1, tmp2, got;
17433 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17434 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17436 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17438 got = rs6000_got_sym ();
17439 tmp1 = tmp2 = dest;
17442 tmp1 = gen_reg_rtx (Pmode);
17443 tmp2 = gen_reg_rtx (Pmode);
17445 emit_insn (gen_load_toc_v4_PIC_1 (lab));
17446 emit_move_insn (tmp1,
17447 gen_rtx_REG (Pmode, LR_REGNO));
17448 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
17449 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
17451 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
17453 emit_insn (gen_load_toc_v4_pic_si ());
17454 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
17456 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
17459 rtx temp0 = (fromprolog
17460 ? gen_rtx_REG (Pmode, 0)
17461 : gen_reg_rtx (Pmode));
17467 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17468 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17470 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
17471 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17473 emit_insn (gen_load_toc_v4_PIC_1 (symF));
17474 emit_move_insn (dest,
17475 gen_rtx_REG (Pmode, LR_REGNO));
17476 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
17482 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17483 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
17484 emit_move_insn (dest,
17485 gen_rtx_REG (Pmode, LR_REGNO));
17486 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
17488 emit_insn (gen_addsi3 (dest, temp0, dest));
17490 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
17492 /* This is for AIX code running in non-PIC ELF32. */
17495 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
17496 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17498 emit_insn (gen_elf_high (dest, realsym));
17499 emit_insn (gen_elf_low (dest, dest, realsym));
17503 gcc_assert (DEFAULT_ABI == ABI_AIX);
17506 emit_insn (gen_load_toc_aix_si (dest));
17508 emit_insn (gen_load_toc_aix_di (dest));
17512 /* Emit instructions to restore the link register after determining where
17513 its value has been stored. */
17516 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
17518 rs6000_stack_t *info = rs6000_stack_info ();
17521 operands[0] = source;
17522 operands[1] = scratch;
17524 if (info->lr_save_p)
17526 rtx frame_rtx = stack_pointer_rtx;
17527 HOST_WIDE_INT sp_offset = 0;
17530 if (frame_pointer_needed
17531 || cfun->calls_alloca
17532 || info->total_size > 32767)
17534 tmp = gen_frame_mem (Pmode, frame_rtx);
17535 emit_move_insn (operands[1], tmp);
17536 frame_rtx = operands[1];
17538 else if (info->push_p)
17539 sp_offset = info->total_size;
17541 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
17542 tmp = gen_frame_mem (Pmode, tmp);
17543 emit_move_insn (tmp, operands[0]);
17546 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
17549 static GTY(()) alias_set_type set = -1;
17552 get_TOC_alias_set (void)
17555 set = new_alias_set ();
17559 /* This returns nonzero if the current function uses the TOC. This is
17560 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
17561 is generated by the ABI_V4 load_toc_* patterns. */
17568 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
17571 rtx pat = PATTERN (insn);
17574 if (GET_CODE (pat) == PARALLEL)
17575 for (i = 0; i < XVECLEN (pat, 0); i++)
17577 rtx sub = XVECEXP (pat, 0, i);
17578 if (GET_CODE (sub) == USE)
17580 sub = XEXP (sub, 0);
17581 if (GET_CODE (sub) == UNSPEC
17582 && XINT (sub, 1) == UNSPEC_TOC)
17592 create_TOC_reference (rtx symbol)
17594 if (TARGET_DEBUG_ADDR)
17596 if (GET_CODE (symbol) == SYMBOL_REF)
17597 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
17601 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
17602 GET_RTX_NAME (GET_CODE (symbol)));
17603 debug_rtx (symbol);
17607 if (!can_create_pseudo_p ())
17608 df_set_regs_ever_live (TOC_REGISTER, true);
17609 return gen_rtx_PLUS (Pmode,
17610 gen_rtx_REG (Pmode, TOC_REGISTER),
17611 gen_rtx_CONST (Pmode,
17612 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL)));
17615 /* Issue assembly directives that create a reference to the given DWARF
17616 FRAME_TABLE_LABEL from the current function section. */
17618 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
17620 fprintf (asm_out_file, "\t.ref %s\n",
17621 TARGET_STRIP_NAME_ENCODING (frame_table_label));
17624 /* If _Unwind_* has been called from within the same module,
17625 toc register is not guaranteed to be saved to 40(1) on function
17626 entry. Save it there in that case. */
17629 rs6000_aix_emit_builtin_unwind_init (void)
17632 rtx stack_top = gen_reg_rtx (Pmode);
17633 rtx opcode_addr = gen_reg_rtx (Pmode);
17634 rtx opcode = gen_reg_rtx (SImode);
17635 rtx tocompare = gen_reg_rtx (SImode);
17636 rtx no_toc_save_needed = gen_label_rtx ();
17638 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
17639 emit_move_insn (stack_top, mem);
17641 mem = gen_frame_mem (Pmode,
17642 gen_rtx_PLUS (Pmode, stack_top,
17643 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
17644 emit_move_insn (opcode_addr, mem);
17645 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
17646 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
17647 : 0xE8410028, SImode));
17649 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
17650 SImode, NULL_RTX, NULL_RTX,
17651 no_toc_save_needed);
17653 mem = gen_frame_mem (Pmode,
17654 gen_rtx_PLUS (Pmode, stack_top,
17655 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
17656 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
17657 emit_label (no_toc_save_needed);
17660 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
17661 and the change to the stack pointer. */
17664 rs6000_emit_stack_tie (void)
17666 rtx mem = gen_frame_mem (BLKmode,
17667 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
17669 emit_insn (gen_stack_tie (mem));
17672 /* Emit the correct code for allocating stack space, as insns.
17673 If COPY_R12, make sure a copy of the old frame is left in r12.
17674 If COPY_R11, make sure a copy of the old frame is left in r11,
17675 in preference to r12 if COPY_R12.
17676 The generated code may use hard register 0 as a temporary. */
17679 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
17682 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
17683 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
17684 rtx todec = gen_int_mode (-size, Pmode);
17687 if (INTVAL (todec) != -size)
17689 warning (0, "stack frame too large");
17690 emit_insn (gen_trap ());
17694 if (crtl->limit_stack)
17696 if (REG_P (stack_limit_rtx)
17697 && REGNO (stack_limit_rtx) > 1
17698 && REGNO (stack_limit_rtx) <= 31)
17700 emit_insn (TARGET_32BIT
17701 ? gen_addsi3 (tmp_reg,
17704 : gen_adddi3 (tmp_reg,
17708 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
17711 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
17713 && DEFAULT_ABI == ABI_V4)
17715 rtx toload = gen_rtx_CONST (VOIDmode,
17716 gen_rtx_PLUS (Pmode,
17720 emit_insn (gen_elf_high (tmp_reg, toload));
17721 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
17722 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
17726 warning (0, "stack limit expression is not supported");
17729 if (copy_r12 || copy_r11)
17730 emit_move_insn (copy_r11
17731 ? gen_rtx_REG (Pmode, 11)
17732 : gen_rtx_REG (Pmode, 12),
17737 /* Need a note here so that try_split doesn't get confused. */
17738 if (get_last_insn () == NULL_RTX)
17739 emit_note (NOTE_INSN_DELETED);
17740 insn = emit_move_insn (tmp_reg, todec);
17741 try_split (PATTERN (insn), insn, 0);
17745 insn = emit_insn (TARGET_32BIT
17746 ? gen_movsi_update_stack (stack_reg, stack_reg,
17748 : gen_movdi_di_update_stack (stack_reg, stack_reg,
17749 todec, stack_reg));
17750 /* Since we didn't use gen_frame_mem to generate the MEM, grab
17751 it now and set the alias set/attributes. The above gen_*_update
17752 calls will generate a PARALLEL with the MEM set being the first
17754 par = PATTERN (insn);
17755 gcc_assert (GET_CODE (par) == PARALLEL);
17756 set = XVECEXP (par, 0, 0);
17757 gcc_assert (GET_CODE (set) == SET);
17758 mem = SET_DEST (set);
17759 gcc_assert (MEM_P (mem));
17760 MEM_NOTRAP_P (mem) = 1;
17761 set_mem_alias_set (mem, get_frame_alias_set ());
17763 RTX_FRAME_RELATED_P (insn) = 1;
17764 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
17765 gen_rtx_SET (VOIDmode, stack_reg,
17766 gen_rtx_PLUS (Pmode, stack_reg,
17767 GEN_INT (-size))));
17770 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
17771 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
17772 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
17773 deduce these equivalences by itself so it wasn't necessary to hold
17774 its hand so much. */
17777 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
17778 rtx reg2, rtx rreg)
17782 /* copy_rtx will not make unique copies of registers, so we need to
17783 ensure we don't have unwanted sharing here. */
17785 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
17788 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
17790 real = copy_rtx (PATTERN (insn));
17792 if (reg2 != NULL_RTX)
17793 real = replace_rtx (real, reg2, rreg);
17795 real = replace_rtx (real, reg,
17796 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
17797 STACK_POINTER_REGNUM),
17800 /* We expect that 'real' is either a SET or a PARALLEL containing
17801 SETs (and possibly other stuff). In a PARALLEL, all the SETs
17802 are important so they all have to be marked RTX_FRAME_RELATED_P. */
17804 if (GET_CODE (real) == SET)
17808 temp = simplify_rtx (SET_SRC (set));
17810 SET_SRC (set) = temp;
17811 temp = simplify_rtx (SET_DEST (set));
17813 SET_DEST (set) = temp;
17814 if (GET_CODE (SET_DEST (set)) == MEM)
17816 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
17818 XEXP (SET_DEST (set), 0) = temp;
17825 gcc_assert (GET_CODE (real) == PARALLEL);
17826 for (i = 0; i < XVECLEN (real, 0); i++)
17827 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
17829 rtx set = XVECEXP (real, 0, i);
17831 temp = simplify_rtx (SET_SRC (set));
17833 SET_SRC (set) = temp;
17834 temp = simplify_rtx (SET_DEST (set));
17836 SET_DEST (set) = temp;
17837 if (GET_CODE (SET_DEST (set)) == MEM)
17839 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
17841 XEXP (SET_DEST (set), 0) = temp;
17843 RTX_FRAME_RELATED_P (set) = 1;
17847 RTX_FRAME_RELATED_P (insn) = 1;
17848 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
17851 /* Returns an insn that has a vrsave set operation with the
17852 appropriate CLOBBERs. */
17855 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
17858 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
17859 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
17862 = gen_rtx_SET (VOIDmode,
17864 gen_rtx_UNSPEC_VOLATILE (SImode,
17865 gen_rtvec (2, reg, vrsave),
17866 UNSPECV_SET_VRSAVE));
17870 /* We need to clobber the registers in the mask so the scheduler
17871 does not move sets to VRSAVE before sets of AltiVec registers.
17873 However, if the function receives nonlocal gotos, reload will set
17874 all call saved registers live. We will end up with:
17876 (set (reg 999) (mem))
17877 (parallel [ (set (reg vrsave) (unspec blah))
17878 (clobber (reg 999))])
17880 The clobber will cause the store into reg 999 to be dead, and
17881 flow will attempt to delete an epilogue insn. In this case, we
17882 need an unspec use/set of the register. */
17884 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17885 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
17887 if (!epiloguep || call_used_regs [i])
17888 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
17889 gen_rtx_REG (V4SImode, i));
17892 rtx reg = gen_rtx_REG (V4SImode, i);
17895 = gen_rtx_SET (VOIDmode,
17897 gen_rtx_UNSPEC (V4SImode,
17898 gen_rtvec (1, reg), 27));
17902 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
17904 for (i = 0; i < nclobs; ++i)
17905 XVECEXP (insn, 0, i) = clobs[i];
17910 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
17911 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
17914 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
17915 unsigned int regno, int offset, HOST_WIDE_INT total_size)
17917 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
17918 rtx replacea, replaceb;
17920 int_rtx = GEN_INT (offset);
17922 /* Some cases that need register indexed addressing. */
17923 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
17924 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
17925 || (TARGET_E500_DOUBLE && mode == DFmode)
17927 && SPE_VECTOR_MODE (mode)
17928 && !SPE_CONST_OFFSET_OK (offset)))
17930 /* Whomever calls us must make sure r11 is available in the
17931 flow path of instructions in the prologue. */
17932 offset_rtx = gen_rtx_REG (Pmode, 11);
17933 emit_move_insn (offset_rtx, int_rtx);
17935 replacea = offset_rtx;
17936 replaceb = int_rtx;
17940 offset_rtx = int_rtx;
17941 replacea = NULL_RTX;
17942 replaceb = NULL_RTX;
17945 reg = gen_rtx_REG (mode, regno);
17946 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
17947 mem = gen_frame_mem (mode, addr);
17949 insn = emit_move_insn (mem, reg);
17951 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
17954 /* Emit an offset memory reference suitable for a frame store, while
17955 converting to a valid addressing mode. */
17958 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
17960 rtx int_rtx, offset_rtx;
17962 int_rtx = GEN_INT (offset);
17964 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
17965 || (TARGET_E500_DOUBLE && mode == DFmode))
17967 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
17968 emit_move_insn (offset_rtx, int_rtx);
17971 offset_rtx = int_rtx;
17973 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
17976 /* Look for user-defined global regs. We should not save and restore these,
17977 and cannot use stmw/lmw if there are any in its range. */
17980 no_global_regs_above (int first, bool gpr)
17983 for (i = first; i < gpr ? 32 : 64 ; i++)
17984 if (global_regs[i])
17989 #ifndef TARGET_FIX_AND_CONTINUE
17990 #define TARGET_FIX_AND_CONTINUE 0
17993 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
17994 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
17995 #define LAST_SAVRES_REGISTER 31
17996 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
17998 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18000 /* Return the symbol for an out-of-line register save/restore routine.
18001 We are saving/restoring GPRs if GPR is true. */
18004 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep, bool gpr, bool exitp)
18006 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18008 int select = ((savep ? 1 : 0) << 2
18010 /* On the SPE, we never have any FPRs, but we do have
18011 32/64-bit versions of the routines. */
18012 ? (TARGET_SPE_ABI && info->spe_64bit_regs_used ? 1 : 0)
18016 /* Don't generate bogus routine names. */
18017 gcc_assert (FIRST_SAVRES_REGISTER <= regno && regno <= LAST_SAVRES_REGISTER);
18019 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18024 const char *action;
18025 const char *regkind;
18026 const char *exit_suffix;
18028 action = savep ? "save" : "rest";
18030 /* SPE has slightly different names for its routines depending on
18031 whether we are saving 32-bit or 64-bit registers. */
18032 if (TARGET_SPE_ABI)
18034 /* No floating point saves on the SPE. */
18037 regkind = info->spe_64bit_regs_used ? "64gpr" : "32gpr";
18040 regkind = gpr ? "gpr" : "fpr";
18042 exit_suffix = exitp ? "_x" : "";
18044 sprintf (name, "_%s%s_%d%s", action, regkind, regno, exit_suffix);
18046 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18047 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18053 /* Emit a sequence of insns, including a stack tie if needed, for
18054 resetting the stack pointer. If SAVRES is true, then don't reset the
18055 stack pointer, but move the base of the frame into r11 for use by
18056 out-of-line register restore routines. */
18059 rs6000_emit_stack_reset (rs6000_stack_t *info,
18060 rtx sp_reg_rtx, rtx frame_reg_rtx,
18061 int sp_offset, bool savres)
18063 /* This blockage is needed so that sched doesn't decide to move
18064 the sp change before the register restores. */
18065 if (frame_reg_rtx != sp_reg_rtx
18067 && info->spe_64bit_regs_used != 0
18068 && info->first_gp_reg_save != 32))
18069 rs6000_emit_stack_tie ();
18071 if (frame_reg_rtx != sp_reg_rtx)
18073 if (sp_offset != 0)
18074 return emit_insn (gen_addsi3 (sp_reg_rtx, frame_reg_rtx,
18075 GEN_INT (sp_offset)));
18077 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18079 else if (sp_offset != 0)
18081 /* If we are restoring registers out-of-line, we will be using the
18082 "exit" variants of the restore routines, which will reset the
18083 stack for us. But we do need to point r11 into the right place
18084 for those routines. */
18085 rtx dest_reg = (savres
18086 ? gen_rtx_REG (Pmode, 11)
18089 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18090 GEN_INT (sp_offset)));
18097 /* Construct a parallel rtx describing the effect of a call to an
18098 out-of-line register save/restore routine. */
18101 rs6000_make_savres_rtx (rs6000_stack_t *info,
18102 rtx frame_reg_rtx, int save_area_offset,
18103 enum machine_mode reg_mode,
18104 bool savep, bool gpr, bool exitp)
18107 int offset, start_reg, end_reg, n_regs;
18108 int reg_size = GET_MODE_SIZE (reg_mode);
18114 ? info->first_gp_reg_save
18115 : info->first_fp_reg_save);
18116 end_reg = gpr ? 32 : 64;
18117 n_regs = end_reg - start_reg;
18118 p = rtvec_alloc ((exitp ? 4 : 3) + n_regs);
18120 /* If we're saving registers, then we should never say we're exiting. */
18121 gcc_assert ((savep && !exitp) || !savep);
18124 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18126 RTVEC_ELT (p, offset++)
18127 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18129 sym = rs6000_savres_routine_sym (info, savep, gpr, exitp);
18130 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18131 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 11));
18133 for (i = 0; i < end_reg - start_reg; i++)
18135 rtx addr, reg, mem;
18136 reg = gen_rtx_REG (reg_mode, start_reg + i);
18137 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18138 GEN_INT (save_area_offset + reg_size*i));
18139 mem = gen_frame_mem (reg_mode, addr);
18141 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
18143 savep ? reg : mem);
18146 return gen_rtx_PARALLEL (VOIDmode, p);
18149 /* Determine whether the gp REG is really used. */
18152 rs6000_reg_live_or_pic_offset_p (int reg)
18154 return ((df_regs_ever_live_p (reg)
18155 && (!call_used_regs[reg]
18156 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18157 && TARGET_TOC && TARGET_MINIMAL_TOC)))
18158 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18159 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18160 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
18164 SAVRES_MULTIPLE = 0x1,
18165 SAVRES_INLINE_FPRS = 0x2,
18166 SAVRES_INLINE_GPRS = 0x4
18169 /* Determine the strategy for savings/restoring registers. */
18172 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
18173 int using_static_chain_p, int sibcall)
18175 bool using_multiple_p;
18177 bool savres_fprs_inline;
18178 bool savres_gprs_inline;
18179 bool noclobber_global_gprs
18180 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
18182 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
18183 && (!TARGET_SPE_ABI
18184 || info->spe_64bit_regs_used == 0)
18185 && info->first_gp_reg_save < 31
18186 && noclobber_global_gprs);
18187 /* Don't bother to try to save things out-of-line if r11 is occupied
18188 by the static chain. It would require too much fiddling and the
18189 static chain is rarely used anyway. */
18190 common = (using_static_chain_p
18192 || crtl->calls_eh_return
18193 || !info->lr_save_p
18194 || cfun->machine->ra_need_lr
18195 || info->total_size > 32767);
18196 savres_fprs_inline = (common
18197 || info->first_fp_reg_save == 64
18198 || !no_global_regs_above (info->first_fp_reg_save,
18200 || FP_SAVE_INLINE (info->first_fp_reg_save));
18201 savres_gprs_inline = (common
18202 /* Saving CR interferes with the exit routines
18203 used on the SPE, so just punt here. */
18206 && info->spe_64bit_regs_used != 0
18207 && info->cr_save_p != 0)
18208 || info->first_gp_reg_save == 32
18209 || !noclobber_global_gprs
18210 || GP_SAVE_INLINE (info->first_gp_reg_save));
18213 /* If we are going to use store multiple, then don't even bother
18214 with the out-of-line routines, since the store-multiple instruction
18215 will always be smaller. */
18216 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18219 /* The situation is more complicated with load multiple. We'd
18220 prefer to use the out-of-line routines for restores, since the
18221 "exit" out-of-line routines can handle the restore of LR and
18222 the frame teardown. But we can only use the out-of-line
18223 routines if we know that we've used store multiple or
18224 out-of-line routines in the prologue, i.e. if we've saved all
18225 the registers from first_gp_reg_save. Otherwise, we risk
18226 loading garbage from the stack. Furthermore, we can only use
18227 the "exit" out-of-line gpr restore if we haven't saved any
18229 bool saved_all = !savres_gprs_inline || using_multiple_p;
18231 if (saved_all && info->first_fp_reg_save != 64)
18232 /* We can't use the exit routine; use load multiple if it's
18234 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18237 return (using_multiple_p
18238 | (savres_fprs_inline << 1)
18239 | (savres_gprs_inline << 2));
18242 /* Emit function prologue as insns. */
18245 rs6000_emit_prologue (void)
18247 rs6000_stack_t *info = rs6000_stack_info ();
18248 enum machine_mode reg_mode = Pmode;
18249 int reg_size = TARGET_32BIT ? 4 : 8;
18250 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18251 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
18252 rtx frame_reg_rtx = sp_reg_rtx;
18253 rtx cr_save_rtx = NULL_RTX;
18256 int saving_FPRs_inline;
18257 int saving_GPRs_inline;
18258 int using_store_multiple;
18259 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18260 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18261 && !call_used_regs[STATIC_CHAIN_REGNUM]);
18262 HOST_WIDE_INT sp_offset = 0;
18264 if (TARGET_FIX_AND_CONTINUE)
18266 /* gdb on darwin arranges to forward a function from the old
18267 address by modifying the first 5 instructions of the function
18268 to branch to the overriding function. This is necessary to
18269 permit function pointers that point to the old function to
18270 actually forward to the new function. */
18271 emit_insn (gen_nop ());
18272 emit_insn (gen_nop ());
18273 emit_insn (gen_nop ());
18274 emit_insn (gen_nop ());
18275 emit_insn (gen_nop ());
18278 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
18280 reg_mode = V2SImode;
18284 strategy = rs6000_savres_strategy (info, /*savep=*/true,
18285 /*static_chain_p=*/using_static_chain_p,
18287 using_store_multiple = strategy & SAVRES_MULTIPLE;
18288 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
18289 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
18291 /* For V.4, update stack before we do any saving and set back pointer. */
18292 if (! WORLD_SAVE_P (info)
18294 && (DEFAULT_ABI == ABI_V4
18295 || crtl->calls_eh_return))
18297 bool need_r11 = (TARGET_SPE
18298 ? (!saving_GPRs_inline
18299 && info->spe_64bit_regs_used == 0)
18300 : (!saving_FPRs_inline || !saving_GPRs_inline));
18301 if (info->total_size < 32767)
18302 sp_offset = info->total_size;
18304 frame_reg_rtx = (need_r11
18305 ? gen_rtx_REG (Pmode, 11)
18307 rs6000_emit_allocate_stack (info->total_size,
18308 (frame_reg_rtx != sp_reg_rtx
18309 && (info->cr_save_p
18311 || info->first_fp_reg_save < 64
18312 || info->first_gp_reg_save < 32
18315 if (frame_reg_rtx != sp_reg_rtx)
18316 rs6000_emit_stack_tie ();
18319 /* Handle world saves specially here. */
18320 if (WORLD_SAVE_P (info))
18327 /* save_world expects lr in r0. */
18328 reg0 = gen_rtx_REG (Pmode, 0);
18329 if (info->lr_save_p)
18331 insn = emit_move_insn (reg0,
18332 gen_rtx_REG (Pmode, LR_REGNO));
18333 RTX_FRAME_RELATED_P (insn) = 1;
18336 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
18337 assumptions about the offsets of various bits of the stack
18339 gcc_assert (info->gp_save_offset == -220
18340 && info->fp_save_offset == -144
18341 && info->lr_save_offset == 8
18342 && info->cr_save_offset == 4
18345 && (!crtl->calls_eh_return
18346 || info->ehrd_offset == -432)
18347 && info->vrsave_save_offset == -224
18348 && info->altivec_save_offset == -416);
18350 treg = gen_rtx_REG (SImode, 11);
18351 emit_move_insn (treg, GEN_INT (-info->total_size));
18353 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
18354 in R11. It also clobbers R12, so beware! */
18356 /* Preserve CR2 for save_world prologues */
18358 sz += 32 - info->first_gp_reg_save;
18359 sz += 64 - info->first_fp_reg_save;
18360 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
18361 p = rtvec_alloc (sz);
18363 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
18364 gen_rtx_REG (SImode,
18366 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
18367 gen_rtx_SYMBOL_REF (Pmode,
18369 /* We do floats first so that the instruction pattern matches
18371 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18373 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18374 ? DFmode : SFmode),
18375 info->first_fp_reg_save + i);
18376 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18377 GEN_INT (info->fp_save_offset
18378 + sp_offset + 8 * i));
18379 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18380 ? DFmode : SFmode), addr);
18382 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18384 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
18386 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
18387 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18388 GEN_INT (info->altivec_save_offset
18389 + sp_offset + 16 * i));
18390 rtx mem = gen_frame_mem (V4SImode, addr);
18392 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18394 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18396 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18397 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18398 GEN_INT (info->gp_save_offset
18399 + sp_offset + reg_size * i));
18400 rtx mem = gen_frame_mem (reg_mode, addr);
18402 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18406 /* CR register traditionally saved as CR2. */
18407 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
18408 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18409 GEN_INT (info->cr_save_offset
18411 rtx mem = gen_frame_mem (reg_mode, addr);
18413 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18415 /* Explain about use of R0. */
18416 if (info->lr_save_p)
18418 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18419 GEN_INT (info->lr_save_offset
18421 rtx mem = gen_frame_mem (reg_mode, addr);
18423 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
18425 /* Explain what happens to the stack pointer. */
18427 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
18428 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
18431 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18432 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18433 treg, GEN_INT (-info->total_size));
18434 sp_offset = info->total_size;
18437 /* If we use the link register, get it into r0. */
18438 if (!WORLD_SAVE_P (info) && info->lr_save_p)
18440 rtx addr, reg, mem;
18442 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
18443 gen_rtx_REG (Pmode, LR_REGNO));
18444 RTX_FRAME_RELATED_P (insn) = 1;
18446 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18447 GEN_INT (info->lr_save_offset + sp_offset));
18448 reg = gen_rtx_REG (Pmode, 0);
18449 mem = gen_rtx_MEM (Pmode, addr);
18450 /* This should not be of rs6000_sr_alias_set, because of
18451 __builtin_return_address. */
18453 insn = emit_move_insn (mem, reg);
18454 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18455 NULL_RTX, NULL_RTX);
18458 /* If we need to save CR, put it into r12. */
18459 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
18463 cr_save_rtx = gen_rtx_REG (SImode, 12);
18464 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18465 RTX_FRAME_RELATED_P (insn) = 1;
18466 /* Now, there's no way that dwarf2out_frame_debug_expr is going
18467 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
18468 But that's OK. All we have to do is specify that _one_ condition
18469 code register is saved in this stack slot. The thrower's epilogue
18470 will then restore all the call-saved registers.
18471 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
18472 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
18473 gen_rtx_REG (SImode, CR2_REGNO));
18474 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18477 /* Do any required saving of fpr's. If only one or two to save, do
18478 it ourselves. Otherwise, call function. */
18479 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
18482 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18483 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
18484 && ! call_used_regs[info->first_fp_reg_save+i]))
18485 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
18486 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18488 info->first_fp_reg_save + i,
18489 info->fp_save_offset + sp_offset + 8 * i,
18492 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
18496 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18497 info->fp_save_offset + sp_offset,
18499 /*savep=*/true, /*gpr=*/false,
18501 insn = emit_insn (par);
18502 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18503 NULL_RTX, NULL_RTX);
18506 /* Save GPRs. This is done as a PARALLEL if we are using
18507 the store-multiple instructions. */
18508 if (!WORLD_SAVE_P (info)
18510 && info->spe_64bit_regs_used != 0
18511 && info->first_gp_reg_save != 32)
18514 rtx spe_save_area_ptr;
18516 /* Determine whether we can address all of the registers that need
18517 to be saved with an offset from the stack pointer that fits in
18518 the small const field for SPE memory instructions. */
18519 int spe_regs_addressable_via_sp
18520 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
18521 + (32 - info->first_gp_reg_save - 1) * reg_size)
18522 && saving_GPRs_inline);
18525 if (spe_regs_addressable_via_sp)
18527 spe_save_area_ptr = frame_reg_rtx;
18528 spe_offset = info->spe_gp_save_offset + sp_offset;
18532 /* Make r11 point to the start of the SPE save area. We need
18533 to be careful here if r11 is holding the static chain. If
18534 it is, then temporarily save it in r0. We would use r0 as
18535 our base register here, but using r0 as a base register in
18536 loads and stores means something different from what we
18538 int ool_adjust = (saving_GPRs_inline
18540 : (info->first_gp_reg_save
18541 - (FIRST_SAVRES_REGISTER+1))*8);
18542 HOST_WIDE_INT offset = (info->spe_gp_save_offset
18543 + sp_offset - ool_adjust);
18545 if (using_static_chain_p)
18547 rtx r0 = gen_rtx_REG (Pmode, 0);
18548 gcc_assert (info->first_gp_reg_save > 11);
18550 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
18553 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
18554 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
18556 GEN_INT (offset)));
18557 /* We need to make sure the move to r11 gets noted for
18558 properly outputting unwind information. */
18559 if (!saving_GPRs_inline)
18560 rs6000_frame_related (insn, frame_reg_rtx, offset,
18561 NULL_RTX, NULL_RTX);
18565 if (saving_GPRs_inline)
18567 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18568 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
18570 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18571 rtx offset, addr, mem;
18573 /* We're doing all this to ensure that the offset fits into
18574 the immediate offset of 'evstdd'. */
18575 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
18577 offset = GEN_INT (reg_size * i + spe_offset);
18578 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
18579 mem = gen_rtx_MEM (V2SImode, addr);
18581 insn = emit_move_insn (mem, reg);
18583 rs6000_frame_related (insn, spe_save_area_ptr,
18584 info->spe_gp_save_offset
18585 + sp_offset + reg_size * i,
18586 offset, const0_rtx);
18593 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
18595 /*savep=*/true, /*gpr=*/true,
18597 insn = emit_insn (par);
18598 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18599 NULL_RTX, NULL_RTX);
18603 /* Move the static chain pointer back. */
18604 if (using_static_chain_p && !spe_regs_addressable_via_sp)
18605 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
18607 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
18611 /* Need to adjust r11 if we saved any FPRs. */
18612 if (info->first_fp_reg_save != 64)
18614 rtx r11 = gen_rtx_REG (reg_mode, 11);
18615 rtx offset = GEN_INT (info->total_size
18616 + (-8 * (64-info->first_fp_reg_save)));
18617 rtx ptr_reg = (sp_reg_rtx == frame_reg_rtx
18618 ? sp_reg_rtx : r11);
18620 emit_insn (TARGET_32BIT
18621 ? gen_addsi3 (r11, ptr_reg, offset)
18622 : gen_adddi3 (r11, ptr_reg, offset));
18625 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18626 info->gp_save_offset + sp_offset,
18628 /*savep=*/true, /*gpr=*/true,
18630 insn = emit_insn (par);
18631 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18632 NULL_RTX, NULL_RTX);
18634 else if (!WORLD_SAVE_P (info) && using_store_multiple)
18638 p = rtvec_alloc (32 - info->first_gp_reg_save);
18639 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18641 rtx addr, reg, mem;
18642 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18643 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18644 GEN_INT (info->gp_save_offset
18647 mem = gen_frame_mem (reg_mode, addr);
18649 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
18651 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18652 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18653 NULL_RTX, NULL_RTX);
18655 else if (!WORLD_SAVE_P (info))
18658 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18659 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
18661 rtx addr, reg, mem;
18662 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18664 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18665 GEN_INT (info->gp_save_offset
18668 mem = gen_frame_mem (reg_mode, addr);
18670 insn = emit_move_insn (mem, reg);
18671 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18672 NULL_RTX, NULL_RTX);
18676 /* ??? There's no need to emit actual instructions here, but it's the
18677 easiest way to get the frame unwind information emitted. */
18678 if (crtl->calls_eh_return)
18680 unsigned int i, regno;
18682 /* In AIX ABI we need to pretend we save r2 here. */
18685 rtx addr, reg, mem;
18687 reg = gen_rtx_REG (reg_mode, 2);
18688 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18689 GEN_INT (sp_offset + 5 * reg_size));
18690 mem = gen_frame_mem (reg_mode, addr);
18692 insn = emit_move_insn (mem, reg);
18693 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18694 NULL_RTX, NULL_RTX);
18695 PATTERN (insn) = gen_blockage ();
18700 regno = EH_RETURN_DATA_REGNO (i);
18701 if (regno == INVALID_REGNUM)
18704 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
18705 info->ehrd_offset + sp_offset
18706 + reg_size * (int) i,
18711 /* Save CR if we use any that must be preserved. */
18712 if (!WORLD_SAVE_P (info) && info->cr_save_p)
18714 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18715 GEN_INT (info->cr_save_offset + sp_offset));
18716 rtx mem = gen_frame_mem (SImode, addr);
18717 /* See the large comment above about why CR2_REGNO is used. */
18718 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
18720 /* If r12 was used to hold the original sp, copy cr into r0 now
18722 if (REGNO (frame_reg_rtx) == 12)
18726 cr_save_rtx = gen_rtx_REG (SImode, 0);
18727 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18728 RTX_FRAME_RELATED_P (insn) = 1;
18729 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
18730 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18732 insn = emit_move_insn (mem, cr_save_rtx);
18734 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18735 NULL_RTX, NULL_RTX);
18738 /* Update stack and set back pointer unless this is V.4,
18739 for which it was done previously. */
18740 if (!WORLD_SAVE_P (info) && info->push_p
18741 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
18743 if (info->total_size < 32767)
18744 sp_offset = info->total_size;
18746 frame_reg_rtx = frame_ptr_rtx;
18747 rs6000_emit_allocate_stack (info->total_size,
18748 (frame_reg_rtx != sp_reg_rtx
18749 && ((info->altivec_size != 0)
18750 || (info->vrsave_mask != 0)
18753 if (frame_reg_rtx != sp_reg_rtx)
18754 rs6000_emit_stack_tie ();
18757 /* Set frame pointer, if needed. */
18758 if (frame_pointer_needed)
18760 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
18762 RTX_FRAME_RELATED_P (insn) = 1;
18765 /* Save AltiVec registers if needed. Save here because the red zone does
18766 not include AltiVec registers. */
18767 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
18771 /* There should be a non inline version of this, for when we
18772 are saving lots of vector registers. */
18773 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
18774 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18776 rtx areg, savereg, mem;
18779 offset = info->altivec_save_offset + sp_offset
18780 + 16 * (i - info->first_altivec_reg_save);
18782 savereg = gen_rtx_REG (V4SImode, i);
18784 areg = gen_rtx_REG (Pmode, 0);
18785 emit_move_insn (areg, GEN_INT (offset));
18787 /* AltiVec addressing mode is [reg+reg]. */
18788 mem = gen_frame_mem (V4SImode,
18789 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
18791 insn = emit_move_insn (mem, savereg);
18793 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18794 areg, GEN_INT (offset));
18798 /* VRSAVE is a bit vector representing which AltiVec registers
18799 are used. The OS uses this to determine which vector
18800 registers to save on a context switch. We need to save
18801 VRSAVE on the stack frame, add whatever AltiVec registers we
18802 used in this function, and do the corresponding magic in the
18805 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
18806 && info->vrsave_mask != 0)
18808 rtx reg, mem, vrsave;
18811 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
18812 as frame_reg_rtx and r11 as the static chain pointer for
18813 nested functions. */
18814 reg = gen_rtx_REG (SImode, 0);
18815 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18817 emit_insn (gen_get_vrsave_internal (reg));
18819 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
18821 if (!WORLD_SAVE_P (info))
18824 offset = info->vrsave_save_offset + sp_offset;
18825 mem = gen_frame_mem (SImode,
18826 gen_rtx_PLUS (Pmode, frame_reg_rtx,
18827 GEN_INT (offset)));
18828 insn = emit_move_insn (mem, reg);
18831 /* Include the registers in the mask. */
18832 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
18834 insn = emit_insn (generate_set_vrsave (reg, info, 0));
18837 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
18838 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
18839 || (DEFAULT_ABI == ABI_V4
18840 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
18841 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
18843 /* If emit_load_toc_table will use the link register, we need to save
18844 it. We use R12 for this purpose because emit_load_toc_table
18845 can use register 0. This allows us to use a plain 'blr' to return
18846 from the procedure more often. */
18847 int save_LR_around_toc_setup = (TARGET_ELF
18848 && DEFAULT_ABI != ABI_AIX
18850 && ! info->lr_save_p
18851 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
18852 if (save_LR_around_toc_setup)
18854 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
18856 insn = emit_move_insn (frame_ptr_rtx, lr);
18857 RTX_FRAME_RELATED_P (insn) = 1;
18859 rs6000_emit_load_toc_table (TRUE);
18861 insn = emit_move_insn (lr, frame_ptr_rtx);
18862 RTX_FRAME_RELATED_P (insn) = 1;
18865 rs6000_emit_load_toc_table (TRUE);
18869 if (DEFAULT_ABI == ABI_DARWIN
18870 && flag_pic && crtl->uses_pic_offset_table)
18872 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
18873 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
18875 /* Save and restore LR locally around this call (in R0). */
18876 if (!info->lr_save_p)
18877 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
18879 emit_insn (gen_load_macho_picbase (src));
18881 emit_move_insn (gen_rtx_REG (Pmode,
18882 RS6000_PIC_OFFSET_TABLE_REGNUM),
18885 if (!info->lr_save_p)
18886 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
18891 /* Write function prologue. */
18894 rs6000_output_function_prologue (FILE *file,
18895 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
18897 rs6000_stack_t *info = rs6000_stack_info ();
18899 if (TARGET_DEBUG_STACK)
18900 debug_stack_info (info);
18902 /* Write .extern for any function we will call to save and restore
18904 if (info->first_fp_reg_save < 64
18905 && !FP_SAVE_INLINE (info->first_fp_reg_save))
18906 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
18907 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
18908 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
18910 /* Write .extern for AIX common mode routines, if needed. */
18911 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
18913 fputs ("\t.extern __mulh\n", file);
18914 fputs ("\t.extern __mull\n", file);
18915 fputs ("\t.extern __divss\n", file);
18916 fputs ("\t.extern __divus\n", file);
18917 fputs ("\t.extern __quoss\n", file);
18918 fputs ("\t.extern __quous\n", file);
18919 common_mode_defined = 1;
18922 if (! HAVE_prologue)
18926 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
18927 the "toplevel" insn chain. */
18928 emit_note (NOTE_INSN_DELETED);
18929 rs6000_emit_prologue ();
18930 emit_note (NOTE_INSN_DELETED);
18932 /* Expand INSN_ADDRESSES so final() doesn't crash. */
18936 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
18938 INSN_ADDRESSES_NEW (insn, addr);
18943 if (TARGET_DEBUG_STACK)
18944 debug_rtx_list (get_insns (), 100);
18945 final (get_insns (), file, FALSE);
18949 rs6000_pic_labelno++;
18952 /* Non-zero if vmx regs are restored before the frame pop, zero if
18953 we restore after the pop when possible. */
18954 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
18956 /* Reload CR from REG. */
18959 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
18964 if (using_mfcr_multiple)
18966 for (i = 0; i < 8; i++)
18967 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
18969 gcc_assert (count);
18972 if (using_mfcr_multiple && count > 1)
18977 p = rtvec_alloc (count);
18980 for (i = 0; i < 8; i++)
18981 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
18983 rtvec r = rtvec_alloc (2);
18984 RTVEC_ELT (r, 0) = reg;
18985 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
18986 RTVEC_ELT (p, ndx) =
18987 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
18988 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
18991 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18992 gcc_assert (ndx == count);
18995 for (i = 0; i < 8; i++)
18996 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
18998 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19004 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19005 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19006 below stack pointer not cloberred by signals. */
19009 offset_below_red_zone_p (HOST_WIDE_INT offset)
19011 return offset < (DEFAULT_ABI == ABI_V4
19013 : TARGET_32BIT ? -220 : -288);
19016 /* Emit function epilogue as insns. */
19019 rs6000_emit_epilogue (int sibcall)
19021 rs6000_stack_t *info;
19022 int restoring_GPRs_inline;
19023 int restoring_FPRs_inline;
19024 int using_load_multiple;
19025 int using_mtcr_multiple;
19026 int use_backchain_to_restore_sp;
19030 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19031 rtx frame_reg_rtx = sp_reg_rtx;
19032 rtx cfa_restores = NULL_RTX;
19034 enum machine_mode reg_mode = Pmode;
19035 int reg_size = TARGET_32BIT ? 4 : 8;
19038 info = rs6000_stack_info ();
19040 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19042 reg_mode = V2SImode;
19046 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19047 /*static_chain_p=*/0, sibcall);
19048 using_load_multiple = strategy & SAVRES_MULTIPLE;
19049 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19050 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19051 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19052 || rs6000_cpu == PROCESSOR_PPC603
19053 || rs6000_cpu == PROCESSOR_PPC750
19055 /* Restore via the backchain when we have a large frame, since this
19056 is more efficient than an addis, addi pair. The second condition
19057 here will not trigger at the moment; We don't actually need a
19058 frame pointer for alloca, but the generic parts of the compiler
19059 give us one anyway. */
19060 use_backchain_to_restore_sp = (info->total_size > 32767
19061 || info->total_size
19062 + (info->lr_save_p ? info->lr_save_offset : 0)
19064 || (cfun->calls_alloca
19065 && !frame_pointer_needed));
19066 restore_lr = (info->lr_save_p
19067 && restoring_GPRs_inline
19068 && restoring_FPRs_inline);
19070 if (WORLD_SAVE_P (info))
19074 const char *alloc_rname;
19077 /* eh_rest_world_r10 will return to the location saved in the LR
19078 stack slot (which is not likely to be our caller.)
19079 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19080 rest_world is similar, except any R10 parameter is ignored.
19081 The exception-handling stuff that was here in 2.95 is no
19082 longer necessary. */
19086 + 32 - info->first_gp_reg_save
19087 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
19088 + 63 + 1 - info->first_fp_reg_save);
19090 strcpy (rname, ((crtl->calls_eh_return) ?
19091 "*eh_rest_world_r10" : "*rest_world"));
19092 alloc_rname = ggc_strdup (rname);
19095 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
19096 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19097 gen_rtx_REG (Pmode,
19100 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
19101 /* The instruction pattern requires a clobber here;
19102 it is shared with the restVEC helper. */
19104 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
19107 /* CR register traditionally saved as CR2. */
19108 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19109 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19110 GEN_INT (info->cr_save_offset));
19111 rtx mem = gen_frame_mem (reg_mode, addr);
19113 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19116 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19118 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19119 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19120 GEN_INT (info->gp_save_offset
19122 rtx mem = gen_frame_mem (reg_mode, addr);
19124 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19126 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19128 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19129 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19130 GEN_INT (info->altivec_save_offset
19132 rtx mem = gen_frame_mem (V4SImode, addr);
19134 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19136 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
19138 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19139 ? DFmode : SFmode),
19140 info->first_fp_reg_save + i);
19141 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19142 GEN_INT (info->fp_save_offset
19144 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19145 ? DFmode : SFmode), addr);
19147 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19150 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
19152 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
19154 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
19156 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
19158 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
19159 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19164 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
19166 sp_offset = info->total_size;
19168 /* Restore AltiVec registers if we must do so before adjusting the
19170 if (TARGET_ALTIVEC_ABI
19171 && info->altivec_size != 0
19172 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19173 || (DEFAULT_ABI != ABI_V4
19174 && offset_below_red_zone_p (info->altivec_save_offset))))
19178 if (use_backchain_to_restore_sp)
19180 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19181 emit_move_insn (frame_reg_rtx,
19182 gen_rtx_MEM (Pmode, sp_reg_rtx));
19185 else if (frame_pointer_needed)
19186 frame_reg_rtx = hard_frame_pointer_rtx;
19188 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19189 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19191 rtx addr, areg, mem, reg;
19193 areg = gen_rtx_REG (Pmode, 0);
19195 (areg, GEN_INT (info->altivec_save_offset
19197 + 16 * (i - info->first_altivec_reg_save)));
19199 /* AltiVec addressing mode is [reg+reg]. */
19200 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19201 mem = gen_frame_mem (V4SImode, addr);
19203 reg = gen_rtx_REG (V4SImode, i);
19204 emit_move_insn (reg, mem);
19205 if (offset_below_red_zone_p (info->altivec_save_offset
19206 + (i - info->first_altivec_reg_save)
19208 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19213 /* Restore VRSAVE if we must do so before adjusting the stack. */
19215 && TARGET_ALTIVEC_VRSAVE
19216 && info->vrsave_mask != 0
19217 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19218 || (DEFAULT_ABI != ABI_V4
19219 && offset_below_red_zone_p (info->vrsave_save_offset))))
19221 rtx addr, mem, reg;
19223 if (frame_reg_rtx == sp_reg_rtx)
19225 if (use_backchain_to_restore_sp)
19227 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19228 emit_move_insn (frame_reg_rtx,
19229 gen_rtx_MEM (Pmode, sp_reg_rtx));
19232 else if (frame_pointer_needed)
19233 frame_reg_rtx = hard_frame_pointer_rtx;
19236 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19237 GEN_INT (info->vrsave_save_offset + sp_offset));
19238 mem = gen_frame_mem (SImode, addr);
19239 reg = gen_rtx_REG (SImode, 12);
19240 emit_move_insn (reg, mem);
19242 emit_insn (generate_set_vrsave (reg, info, 1));
19246 /* If we have a large stack frame, restore the old stack pointer
19247 using the backchain. */
19248 if (use_backchain_to_restore_sp)
19250 if (frame_reg_rtx == sp_reg_rtx)
19252 /* Under V.4, don't reset the stack pointer until after we're done
19253 loading the saved registers. */
19254 if (DEFAULT_ABI == ABI_V4)
19255 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19257 insn = emit_move_insn (frame_reg_rtx,
19258 gen_rtx_MEM (Pmode, sp_reg_rtx));
19261 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19262 && DEFAULT_ABI == ABI_V4)
19263 /* frame_reg_rtx has been set up by the altivec restore. */
19267 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19268 frame_reg_rtx = sp_reg_rtx;
19271 /* If we have a frame pointer, we can restore the old stack pointer
19273 else if (frame_pointer_needed)
19275 frame_reg_rtx = sp_reg_rtx;
19276 if (DEFAULT_ABI == ABI_V4)
19277 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19279 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
19280 GEN_INT (info->total_size)));
19283 else if (info->push_p
19284 && DEFAULT_ABI != ABI_V4
19285 && !crtl->calls_eh_return)
19287 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
19288 GEN_INT (info->total_size)));
19291 if (insn && frame_reg_rtx == sp_reg_rtx)
19295 REG_NOTES (insn) = cfa_restores;
19296 cfa_restores = NULL_RTX;
19298 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19299 RTX_FRAME_RELATED_P (insn) = 1;
19302 /* Restore AltiVec registers if we have not done so already. */
19303 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19304 && TARGET_ALTIVEC_ABI
19305 && info->altivec_size != 0
19306 && (DEFAULT_ABI == ABI_V4
19307 || !offset_below_red_zone_p (info->altivec_save_offset)))
19311 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19312 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19314 rtx addr, areg, mem, reg;
19316 areg = gen_rtx_REG (Pmode, 0);
19318 (areg, GEN_INT (info->altivec_save_offset
19320 + 16 * (i - info->first_altivec_reg_save)));
19322 /* AltiVec addressing mode is [reg+reg]. */
19323 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19324 mem = gen_frame_mem (V4SImode, addr);
19326 reg = gen_rtx_REG (V4SImode, i);
19327 emit_move_insn (reg, mem);
19328 if (DEFAULT_ABI == ABI_V4)
19329 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19334 /* Restore VRSAVE if we have not done so already. */
19335 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19337 && TARGET_ALTIVEC_VRSAVE
19338 && info->vrsave_mask != 0
19339 && (DEFAULT_ABI == ABI_V4
19340 || !offset_below_red_zone_p (info->vrsave_save_offset)))
19342 rtx addr, mem, reg;
19344 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19345 GEN_INT (info->vrsave_save_offset + sp_offset));
19346 mem = gen_frame_mem (SImode, addr);
19347 reg = gen_rtx_REG (SImode, 12);
19348 emit_move_insn (reg, mem);
19350 emit_insn (generate_set_vrsave (reg, info, 1));
19353 /* Get the old lr if we saved it. If we are restoring registers
19354 out-of-line, then the out-of-line routines can do this for us. */
19357 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19358 info->lr_save_offset + sp_offset);
19360 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19363 /* Get the old cr if we saved it. */
19364 if (info->cr_save_p)
19366 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19367 GEN_INT (info->cr_save_offset + sp_offset));
19368 rtx mem = gen_frame_mem (SImode, addr);
19370 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
19373 /* Set LR here to try to overlap restores below. LR is always saved
19374 above incoming stack, so it never needs REG_CFA_RESTORE. */
19376 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19377 gen_rtx_REG (Pmode, 0));
19379 /* Load exception handler data registers, if needed. */
19380 if (crtl->calls_eh_return)
19382 unsigned int i, regno;
19386 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19387 GEN_INT (sp_offset + 5 * reg_size));
19388 rtx mem = gen_frame_mem (reg_mode, addr);
19390 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
19397 regno = EH_RETURN_DATA_REGNO (i);
19398 if (regno == INVALID_REGNUM)
19401 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
19402 info->ehrd_offset + sp_offset
19403 + reg_size * (int) i);
19405 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
19409 /* Restore GPRs. This is done as a PARALLEL if we are using
19410 the load-multiple instructions. */
19412 && info->spe_64bit_regs_used != 0
19413 && info->first_gp_reg_save != 32)
19415 /* Determine whether we can address all of the registers that need
19416 to be saved with an offset from the stack pointer that fits in
19417 the small const field for SPE memory instructions. */
19418 int spe_regs_addressable_via_sp
19419 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19420 + (32 - info->first_gp_reg_save - 1) * reg_size)
19421 && restoring_GPRs_inline);
19424 if (spe_regs_addressable_via_sp)
19425 spe_offset = info->spe_gp_save_offset + sp_offset;
19428 rtx old_frame_reg_rtx = frame_reg_rtx;
19429 /* Make r11 point to the start of the SPE save area. We worried about
19430 not clobbering it when we were saving registers in the prologue.
19431 There's no need to worry here because the static chain is passed
19432 anew to every function. */
19433 int ool_adjust = (restoring_GPRs_inline
19435 : (info->first_gp_reg_save
19436 - (FIRST_SAVRES_REGISTER+1))*8);
19438 if (frame_reg_rtx == sp_reg_rtx)
19439 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19440 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
19441 GEN_INT (info->spe_gp_save_offset
19444 /* Keep the invariant that frame_reg_rtx + sp_offset points
19445 at the top of the stack frame. */
19446 sp_offset = -info->spe_gp_save_offset;
19451 if (restoring_GPRs_inline)
19453 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19454 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19456 rtx offset, addr, mem, reg;
19458 /* We're doing all this to ensure that the immediate offset
19459 fits into the immediate field of 'evldd'. */
19460 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
19462 offset = GEN_INT (spe_offset + reg_size * i);
19463 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
19464 mem = gen_rtx_MEM (V2SImode, addr);
19465 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19467 insn = emit_move_insn (reg, mem);
19468 if (DEFAULT_ABI == ABI_V4)
19470 if (frame_pointer_needed
19471 && info->first_gp_reg_save + i
19472 == HARD_FRAME_POINTER_REGNUM)
19474 add_reg_note (insn, REG_CFA_DEF_CFA,
19475 plus_constant (frame_reg_rtx,
19477 RTX_FRAME_RELATED_P (insn) = 1;
19480 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19489 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19491 /*savep=*/false, /*gpr=*/true,
19493 emit_jump_insn (par);
19494 /* We don't want anybody else emitting things after we jumped
19499 else if (!restoring_GPRs_inline)
19501 /* We are jumping to an out-of-line function. */
19502 bool can_use_exit = info->first_fp_reg_save == 64;
19505 /* Emit stack reset code if we need it. */
19507 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19508 sp_offset, can_use_exit);
19510 emit_insn (gen_addsi3 (gen_rtx_REG (Pmode, 11),
19512 GEN_INT (sp_offset - info->fp_size)));
19514 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19515 info->gp_save_offset, reg_mode,
19516 /*savep=*/false, /*gpr=*/true,
19517 /*exitp=*/can_use_exit);
19521 if (info->cr_save_p)
19523 rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12),
19524 using_mtcr_multiple);
19525 if (DEFAULT_ABI == ABI_V4)
19527 = alloc_reg_note (REG_CFA_RESTORE,
19528 gen_rtx_REG (SImode, CR2_REGNO),
19532 emit_jump_insn (par);
19534 /* We don't want anybody else emitting things after we jumped
19539 insn = emit_insn (par);
19540 if (DEFAULT_ABI == ABI_V4)
19542 if (frame_pointer_needed)
19544 add_reg_note (insn, REG_CFA_DEF_CFA,
19545 plus_constant (frame_reg_rtx, sp_offset));
19546 RTX_FRAME_RELATED_P (insn) = 1;
19549 for (i = info->first_gp_reg_save; i < 32; i++)
19551 = alloc_reg_note (REG_CFA_RESTORE,
19552 gen_rtx_REG (reg_mode, i), cfa_restores);
19555 else if (using_load_multiple)
19558 p = rtvec_alloc (32 - info->first_gp_reg_save);
19559 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19561 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19562 GEN_INT (info->gp_save_offset
19565 rtx mem = gen_frame_mem (reg_mode, addr);
19566 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19568 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
19569 if (DEFAULT_ABI == ABI_V4)
19570 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19573 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19574 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
19576 add_reg_note (insn, REG_CFA_DEF_CFA,
19577 plus_constant (frame_reg_rtx, sp_offset));
19578 RTX_FRAME_RELATED_P (insn) = 1;
19583 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19584 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19586 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19587 GEN_INT (info->gp_save_offset
19590 rtx mem = gen_frame_mem (reg_mode, addr);
19591 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19593 insn = emit_move_insn (reg, mem);
19594 if (DEFAULT_ABI == ABI_V4)
19596 if (frame_pointer_needed
19597 && info->first_gp_reg_save + i
19598 == HARD_FRAME_POINTER_REGNUM)
19600 add_reg_note (insn, REG_CFA_DEF_CFA,
19601 plus_constant (frame_reg_rtx, sp_offset));
19602 RTX_FRAME_RELATED_P (insn) = 1;
19605 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19611 /* Restore fpr's if we need to do it without calling a function. */
19612 if (restoring_FPRs_inline)
19613 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19614 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
19615 && ! call_used_regs[info->first_fp_reg_save+i]))
19617 rtx addr, mem, reg;
19618 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19619 GEN_INT (info->fp_save_offset
19622 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19623 ? DFmode : SFmode), addr);
19624 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19625 ? DFmode : SFmode),
19626 info->first_fp_reg_save + i);
19628 emit_move_insn (reg, mem);
19629 if (DEFAULT_ABI == ABI_V4)
19630 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19634 /* If we saved cr, restore it here. Just those that were used. */
19635 if (info->cr_save_p)
19637 rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12), using_mtcr_multiple);
19638 if (DEFAULT_ABI == ABI_V4)
19640 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
19644 /* If this is V.4, unwind the stack pointer after all of the loads
19646 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19647 sp_offset, !restoring_FPRs_inline);
19652 REG_NOTES (insn) = cfa_restores;
19653 cfa_restores = NULL_RTX;
19655 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19656 RTX_FRAME_RELATED_P (insn) = 1;
19659 if (crtl->calls_eh_return)
19661 rtx sa = EH_RETURN_STACKADJ_RTX;
19662 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
19668 if (! restoring_FPRs_inline)
19669 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
19671 p = rtvec_alloc (2);
19673 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
19674 RTVEC_ELT (p, 1) = (restoring_FPRs_inline
19675 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
19676 : gen_rtx_CLOBBER (VOIDmode,
19677 gen_rtx_REG (Pmode, 65)));
19679 /* If we have to restore more than two FP registers, branch to the
19680 restore function. It will return to our caller. */
19681 if (! restoring_FPRs_inline)
19686 sym = rs6000_savres_routine_sym (info,
19690 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
19691 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
19692 gen_rtx_REG (Pmode, 11));
19693 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19696 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
19697 GEN_INT (info->fp_save_offset + 8*i));
19698 mem = gen_frame_mem (DFmode, addr);
19700 RTVEC_ELT (p, i+4) =
19701 gen_rtx_SET (VOIDmode,
19702 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
19707 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19711 /* Write function epilogue. */
19714 rs6000_output_function_epilogue (FILE *file,
19715 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19717 if (! HAVE_epilogue)
19719 rtx insn = get_last_insn ();
19720 /* If the last insn was a BARRIER, we don't have to write anything except
19721 the trace table. */
19722 if (GET_CODE (insn) == NOTE)
19723 insn = prev_nonnote_insn (insn);
19724 if (insn == 0 || GET_CODE (insn) != BARRIER)
19726 /* This is slightly ugly, but at least we don't have two
19727 copies of the epilogue-emitting code. */
19730 /* A NOTE_INSN_DELETED is supposed to be at the start
19731 and end of the "toplevel" insn chain. */
19732 emit_note (NOTE_INSN_DELETED);
19733 rs6000_emit_epilogue (FALSE);
19734 emit_note (NOTE_INSN_DELETED);
19736 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19740 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19742 INSN_ADDRESSES_NEW (insn, addr);
19747 if (TARGET_DEBUG_STACK)
19748 debug_rtx_list (get_insns (), 100);
19749 final (get_insns (), file, FALSE);
19755 macho_branch_islands ();
19756 /* Mach-O doesn't support labels at the end of objects, so if
19757 it looks like we might want one, insert a NOP. */
19759 rtx insn = get_last_insn ();
19762 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
19763 insn = PREV_INSN (insn);
19767 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
19768 fputs ("\tnop\n", file);
19772 /* Output a traceback table here. See /usr/include/sys/debug.h for info
19775 We don't output a traceback table if -finhibit-size-directive was
19776 used. The documentation for -finhibit-size-directive reads
19777 ``don't output a @code{.size} assembler directive, or anything
19778 else that would cause trouble if the function is split in the
19779 middle, and the two halves are placed at locations far apart in
19780 memory.'' The traceback table has this property, since it
19781 includes the offset from the start of the function to the
19782 traceback table itself.
19784 System V.4 Powerpc's (and the embedded ABI derived from it) use a
19785 different traceback table. */
19786 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
19787 && rs6000_traceback != traceback_none && !cfun->is_thunk)
19789 const char *fname = NULL;
19790 const char *language_string = lang_hooks.name;
19791 int fixed_parms = 0, float_parms = 0, parm_info = 0;
19793 int optional_tbtab;
19794 rs6000_stack_t *info = rs6000_stack_info ();
19796 if (rs6000_traceback == traceback_full)
19797 optional_tbtab = 1;
19798 else if (rs6000_traceback == traceback_part)
19799 optional_tbtab = 0;
19801 optional_tbtab = !optimize_size && !TARGET_ELF;
19803 if (optional_tbtab)
19805 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
19806 while (*fname == '.') /* V.4 encodes . in the name */
19809 /* Need label immediately before tbtab, so we can compute
19810 its offset from the function start. */
19811 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
19812 ASM_OUTPUT_LABEL (file, fname);
19815 /* The .tbtab pseudo-op can only be used for the first eight
19816 expressions, since it can't handle the possibly variable
19817 length fields that follow. However, if you omit the optional
19818 fields, the assembler outputs zeros for all optional fields
19819 anyways, giving each variable length field is minimum length
19820 (as defined in sys/debug.h). Thus we can not use the .tbtab
19821 pseudo-op at all. */
19823 /* An all-zero word flags the start of the tbtab, for debuggers
19824 that have to find it by searching forward from the entry
19825 point or from the current pc. */
19826 fputs ("\t.long 0\n", file);
19828 /* Tbtab format type. Use format type 0. */
19829 fputs ("\t.byte 0,", file);
19831 /* Language type. Unfortunately, there does not seem to be any
19832 official way to discover the language being compiled, so we
19833 use language_string.
19834 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
19835 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
19836 a number, so for now use 9. */
19837 if (! strcmp (language_string, "GNU C"))
19839 else if (! strcmp (language_string, "GNU F77")
19840 || ! strcmp (language_string, "GNU Fortran"))
19842 else if (! strcmp (language_string, "GNU Pascal"))
19844 else if (! strcmp (language_string, "GNU Ada"))
19846 else if (! strcmp (language_string, "GNU C++")
19847 || ! strcmp (language_string, "GNU Objective-C++"))
19849 else if (! strcmp (language_string, "GNU Java"))
19851 else if (! strcmp (language_string, "GNU Objective-C"))
19854 gcc_unreachable ();
19855 fprintf (file, "%d,", i);
19857 /* 8 single bit fields: global linkage (not set for C extern linkage,
19858 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
19859 from start of procedure stored in tbtab, internal function, function
19860 has controlled storage, function has no toc, function uses fp,
19861 function logs/aborts fp operations. */
19862 /* Assume that fp operations are used if any fp reg must be saved. */
19863 fprintf (file, "%d,",
19864 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
19866 /* 6 bitfields: function is interrupt handler, name present in
19867 proc table, function calls alloca, on condition directives
19868 (controls stack walks, 3 bits), saves condition reg, saves
19870 /* The `function calls alloca' bit seems to be set whenever reg 31 is
19871 set up as a frame pointer, even when there is no alloca call. */
19872 fprintf (file, "%d,",
19873 ((optional_tbtab << 6)
19874 | ((optional_tbtab & frame_pointer_needed) << 5)
19875 | (info->cr_save_p << 1)
19876 | (info->lr_save_p)));
19878 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
19880 fprintf (file, "%d,",
19881 (info->push_p << 7) | (64 - info->first_fp_reg_save));
19883 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
19884 fprintf (file, "%d,", (32 - first_reg_to_save ()));
19886 if (optional_tbtab)
19888 /* Compute the parameter info from the function decl argument
19891 int next_parm_info_bit = 31;
19893 for (decl = DECL_ARGUMENTS (current_function_decl);
19894 decl; decl = TREE_CHAIN (decl))
19896 rtx parameter = DECL_INCOMING_RTL (decl);
19897 enum machine_mode mode = GET_MODE (parameter);
19899 if (GET_CODE (parameter) == REG)
19901 if (SCALAR_FLOAT_MODE_P (mode))
19922 gcc_unreachable ();
19925 /* If only one bit will fit, don't or in this entry. */
19926 if (next_parm_info_bit > 0)
19927 parm_info |= (bits << (next_parm_info_bit - 1));
19928 next_parm_info_bit -= 2;
19932 fixed_parms += ((GET_MODE_SIZE (mode)
19933 + (UNITS_PER_WORD - 1))
19935 next_parm_info_bit -= 1;
19941 /* Number of fixed point parameters. */
19942 /* This is actually the number of words of fixed point parameters; thus
19943 an 8 byte struct counts as 2; and thus the maximum value is 8. */
19944 fprintf (file, "%d,", fixed_parms);
19946 /* 2 bitfields: number of floating point parameters (7 bits), parameters
19948 /* This is actually the number of fp registers that hold parameters;
19949 and thus the maximum value is 13. */
19950 /* Set parameters on stack bit if parameters are not in their original
19951 registers, regardless of whether they are on the stack? Xlc
19952 seems to set the bit when not optimizing. */
19953 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
19955 if (! optional_tbtab)
19958 /* Optional fields follow. Some are variable length. */
19960 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
19961 11 double float. */
19962 /* There is an entry for each parameter in a register, in the order that
19963 they occur in the parameter list. Any intervening arguments on the
19964 stack are ignored. If the list overflows a long (max possible length
19965 34 bits) then completely leave off all elements that don't fit. */
19966 /* Only emit this long if there was at least one parameter. */
19967 if (fixed_parms || float_parms)
19968 fprintf (file, "\t.long %d\n", parm_info);
19970 /* Offset from start of code to tb table. */
19971 fputs ("\t.long ", file);
19972 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
19974 RS6000_OUTPUT_BASENAME (file, fname);
19976 assemble_name (file, fname);
19978 rs6000_output_function_entry (file, fname);
19981 /* Interrupt handler mask. */
19982 /* Omit this long, since we never set the interrupt handler bit
19985 /* Number of CTL (controlled storage) anchors. */
19986 /* Omit this long, since the has_ctl bit is never set above. */
19988 /* Displacement into stack of each CTL anchor. */
19989 /* Omit this list of longs, because there are no CTL anchors. */
19991 /* Length of function name. */
19994 fprintf (file, "\t.short %d\n", (int) strlen (fname));
19996 /* Function name. */
19997 assemble_string (fname, strlen (fname));
19999 /* Register for alloca automatic storage; this is always reg 31.
20000 Only emit this if the alloca bit was set above. */
20001 if (frame_pointer_needed)
20002 fputs ("\t.byte 31\n", file);
20004 fputs ("\t.align 2\n", file);
20008 /* A C compound statement that outputs the assembler code for a thunk
20009 function, used to implement C++ virtual function calls with
20010 multiple inheritance. The thunk acts as a wrapper around a virtual
20011 function, adjusting the implicit object parameter before handing
20012 control off to the real function.
20014 First, emit code to add the integer DELTA to the location that
20015 contains the incoming first argument. Assume that this argument
20016 contains a pointer, and is the one used to pass the `this' pointer
20017 in C++. This is the incoming argument *before* the function
20018 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20019 values of all other incoming arguments.
20021 After the addition, emit code to jump to FUNCTION, which is a
20022 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20023 not touch the return address. Hence returning from FUNCTION will
20024 return to whoever called the current `thunk'.
20026 The effect must be as if FUNCTION had been called directly with the
20027 adjusted first argument. This macro is responsible for emitting
20028 all of the code for a thunk function; output_function_prologue()
20029 and output_function_epilogue() are not invoked.
20031 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20032 been extracted from it.) It might possibly be useful on some
20033 targets, but probably not.
20035 If you do not define this macro, the target-independent code in the
20036 C++ frontend will generate a less efficient heavyweight thunk that
20037 calls FUNCTION instead of jumping to it. The generic approach does
20038 not support varargs. */
20041 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
20042 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
20045 rtx this_rtx, insn, funexp;
20047 reload_completed = 1;
20048 epilogue_completed = 1;
20050 /* Mark the end of the (empty) prologue. */
20051 emit_note (NOTE_INSN_PROLOGUE_END);
20053 /* Find the "this" pointer. If the function returns a structure,
20054 the structure return pointer is in r3. */
20055 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
20056 this_rtx = gen_rtx_REG (Pmode, 4);
20058 this_rtx = gen_rtx_REG (Pmode, 3);
20060 /* Apply the constant offset, if required. */
20063 rtx delta_rtx = GEN_INT (delta);
20064 emit_insn (TARGET_32BIT
20065 ? gen_addsi3 (this_rtx, this_rtx, delta_rtx)
20066 : gen_adddi3 (this_rtx, this_rtx, delta_rtx));
20069 /* Apply the offset from the vtable, if required. */
20072 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
20073 rtx tmp = gen_rtx_REG (Pmode, 12);
20075 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
20076 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
20078 emit_insn (TARGET_32BIT
20079 ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
20080 : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
20081 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
20085 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
20087 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
20089 emit_insn (TARGET_32BIT
20090 ? gen_addsi3 (this_rtx, this_rtx, tmp)
20091 : gen_adddi3 (this_rtx, this_rtx, tmp));
20094 /* Generate a tail call to the target function. */
20095 if (!TREE_USED (function))
20097 assemble_external (function);
20098 TREE_USED (function) = 1;
20100 funexp = XEXP (DECL_RTL (function), 0);
20101 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
20104 if (MACHOPIC_INDIRECT)
20105 funexp = machopic_indirect_call_target (funexp);
20108 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
20109 generate sibcall RTL explicitly. */
20110 insn = emit_call_insn (
20111 gen_rtx_PARALLEL (VOIDmode,
20113 gen_rtx_CALL (VOIDmode,
20114 funexp, const0_rtx),
20115 gen_rtx_USE (VOIDmode, const0_rtx),
20116 gen_rtx_USE (VOIDmode,
20117 gen_rtx_REG (SImode,
20119 gen_rtx_RETURN (VOIDmode))));
20120 SIBLING_CALL_P (insn) = 1;
20123 /* Run just enough of rest_of_compilation to get the insns emitted.
20124 There's not really enough bulk here to make other passes such as
20125 instruction scheduling worth while. Note that use_thunk calls
20126 assemble_start_function and assemble_end_function. */
20127 insn = get_insns ();
20128 insn_locators_alloc ();
20129 shorten_branches (insn);
20130 final_start_function (insn, file, 1);
20131 final (insn, file, 1);
20132 final_end_function ();
20134 reload_completed = 0;
20135 epilogue_completed = 0;
20138 /* A quick summary of the various types of 'constant-pool tables'
20141 Target Flags Name One table per
20142 AIX (none) AIX TOC object file
20143 AIX -mfull-toc AIX TOC object file
20144 AIX -mminimal-toc AIX minimal TOC translation unit
20145 SVR4/EABI (none) SVR4 SDATA object file
20146 SVR4/EABI -fpic SVR4 pic object file
20147 SVR4/EABI -fPIC SVR4 PIC translation unit
20148 SVR4/EABI -mrelocatable EABI TOC function
20149 SVR4/EABI -maix AIX TOC object file
20150 SVR4/EABI -maix -mminimal-toc
20151 AIX minimal TOC translation unit
20153 Name Reg. Set by entries contains:
20154 made by addrs? fp? sum?
20156 AIX TOC 2 crt0 as Y option option
20157 AIX minimal TOC 30 prolog gcc Y Y option
20158 SVR4 SDATA 13 crt0 gcc N Y N
20159 SVR4 pic 30 prolog ld Y not yet N
20160 SVR4 PIC 30 prolog gcc Y option option
20161 EABI TOC 30 prolog gcc Y option option
20165 /* Hash functions for the hash table. */
20168 rs6000_hash_constant (rtx k)
20170 enum rtx_code code = GET_CODE (k);
20171 enum machine_mode mode = GET_MODE (k);
20172 unsigned result = (code << 3) ^ mode;
20173 const char *format;
20176 format = GET_RTX_FORMAT (code);
20177 flen = strlen (format);
20183 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
20186 if (mode != VOIDmode)
20187 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
20199 for (; fidx < flen; fidx++)
20200 switch (format[fidx])
20205 const char *str = XSTR (k, fidx);
20206 len = strlen (str);
20207 result = result * 613 + len;
20208 for (i = 0; i < len; i++)
20209 result = result * 613 + (unsigned) str[i];
20214 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
20218 result = result * 613 + (unsigned) XINT (k, fidx);
20221 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
20222 result = result * 613 + (unsigned) XWINT (k, fidx);
20226 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
20227 result = result * 613 + (unsigned) (XWINT (k, fidx)
20234 gcc_unreachable ();
20241 toc_hash_function (const void *hash_entry)
20243 const struct toc_hash_struct *thc =
20244 (const struct toc_hash_struct *) hash_entry;
20245 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
20248 /* Compare H1 and H2 for equivalence. */
20251 toc_hash_eq (const void *h1, const void *h2)
20253 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
20254 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
20256 if (((const struct toc_hash_struct *) h1)->key_mode
20257 != ((const struct toc_hash_struct *) h2)->key_mode)
20260 return rtx_equal_p (r1, r2);
20263 /* These are the names given by the C++ front-end to vtables, and
20264 vtable-like objects. Ideally, this logic should not be here;
20265 instead, there should be some programmatic way of inquiring as
20266 to whether or not an object is a vtable. */
20268 #define VTABLE_NAME_P(NAME) \
20269 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
20270 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
20271 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
20272 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
20273 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
20275 #ifdef NO_DOLLAR_IN_LABEL
20276 /* Return a GGC-allocated character string translating dollar signs in
20277 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
20280 rs6000_xcoff_strip_dollar (const char *name)
20285 p = strchr (name, '$');
20287 if (p == 0 || p == name)
20290 len = strlen (name);
20291 strip = (char *) alloca (len + 1);
20292 strcpy (strip, name);
20293 p = strchr (strip, '$');
20297 p = strchr (p + 1, '$');
20300 return ggc_alloc_string (strip, len);
20305 rs6000_output_symbol_ref (FILE *file, rtx x)
20307 /* Currently C++ toc references to vtables can be emitted before it
20308 is decided whether the vtable is public or private. If this is
20309 the case, then the linker will eventually complain that there is
20310 a reference to an unknown section. Thus, for vtables only,
20311 we emit the TOC reference to reference the symbol and not the
20313 const char *name = XSTR (x, 0);
20315 if (VTABLE_NAME_P (name))
20317 RS6000_OUTPUT_BASENAME (file, name);
20320 assemble_name (file, name);
20323 /* Output a TOC entry. We derive the entry name from what is being
20327 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
20330 const char *name = buf;
20332 HOST_WIDE_INT offset = 0;
20334 gcc_assert (!TARGET_NO_TOC);
20336 /* When the linker won't eliminate them, don't output duplicate
20337 TOC entries (this happens on AIX if there is any kind of TOC,
20338 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
20340 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
20342 struct toc_hash_struct *h;
20345 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
20346 time because GGC is not initialized at that point. */
20347 if (toc_hash_table == NULL)
20348 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
20349 toc_hash_eq, NULL);
20351 h = GGC_NEW (struct toc_hash_struct);
20353 h->key_mode = mode;
20354 h->labelno = labelno;
20356 found = htab_find_slot (toc_hash_table, h, INSERT);
20357 if (*found == NULL)
20359 else /* This is indeed a duplicate.
20360 Set this label equal to that label. */
20362 fputs ("\t.set ", file);
20363 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20364 fprintf (file, "%d,", labelno);
20365 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20366 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
20372 /* If we're going to put a double constant in the TOC, make sure it's
20373 aligned properly when strict alignment is on. */
20374 if (GET_CODE (x) == CONST_DOUBLE
20375 && STRICT_ALIGNMENT
20376 && GET_MODE_BITSIZE (mode) >= 64
20377 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
20378 ASM_OUTPUT_ALIGN (file, 3);
20381 (*targetm.asm_out.internal_label) (file, "LC", labelno);
20383 /* Handle FP constants specially. Note that if we have a minimal
20384 TOC, things we put here aren't actually in the TOC, so we can allow
20386 if (GET_CODE (x) == CONST_DOUBLE &&
20387 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
20389 REAL_VALUE_TYPE rv;
20392 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20393 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20394 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
20396 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
20400 if (TARGET_MINIMAL_TOC)
20401 fputs (DOUBLE_INT_ASM_OP, file);
20403 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20404 k[0] & 0xffffffff, k[1] & 0xffffffff,
20405 k[2] & 0xffffffff, k[3] & 0xffffffff);
20406 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
20407 k[0] & 0xffffffff, k[1] & 0xffffffff,
20408 k[2] & 0xffffffff, k[3] & 0xffffffff);
20413 if (TARGET_MINIMAL_TOC)
20414 fputs ("\t.long ", file);
20416 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20417 k[0] & 0xffffffff, k[1] & 0xffffffff,
20418 k[2] & 0xffffffff, k[3] & 0xffffffff);
20419 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
20420 k[0] & 0xffffffff, k[1] & 0xffffffff,
20421 k[2] & 0xffffffff, k[3] & 0xffffffff);
20425 else if (GET_CODE (x) == CONST_DOUBLE &&
20426 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
20428 REAL_VALUE_TYPE rv;
20431 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20433 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20434 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
20436 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
20440 if (TARGET_MINIMAL_TOC)
20441 fputs (DOUBLE_INT_ASM_OP, file);
20443 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20444 k[0] & 0xffffffff, k[1] & 0xffffffff);
20445 fprintf (file, "0x%lx%08lx\n",
20446 k[0] & 0xffffffff, k[1] & 0xffffffff);
20451 if (TARGET_MINIMAL_TOC)
20452 fputs ("\t.long ", file);
20454 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20455 k[0] & 0xffffffff, k[1] & 0xffffffff);
20456 fprintf (file, "0x%lx,0x%lx\n",
20457 k[0] & 0xffffffff, k[1] & 0xffffffff);
20461 else if (GET_CODE (x) == CONST_DOUBLE &&
20462 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
20464 REAL_VALUE_TYPE rv;
20467 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20468 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20469 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
20471 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
20475 if (TARGET_MINIMAL_TOC)
20476 fputs (DOUBLE_INT_ASM_OP, file);
20478 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20479 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
20484 if (TARGET_MINIMAL_TOC)
20485 fputs ("\t.long ", file);
20487 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20488 fprintf (file, "0x%lx\n", l & 0xffffffff);
20492 else if (GET_MODE (x) == VOIDmode
20493 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
20495 unsigned HOST_WIDE_INT low;
20496 HOST_WIDE_INT high;
20498 if (GET_CODE (x) == CONST_DOUBLE)
20500 low = CONST_DOUBLE_LOW (x);
20501 high = CONST_DOUBLE_HIGH (x);
20504 #if HOST_BITS_PER_WIDE_INT == 32
20507 high = (low & 0x80000000) ? ~0 : 0;
20511 low = INTVAL (x) & 0xffffffff;
20512 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
20516 /* TOC entries are always Pmode-sized, but since this
20517 is a bigendian machine then if we're putting smaller
20518 integer constants in the TOC we have to pad them.
20519 (This is still a win over putting the constants in
20520 a separate constant pool, because then we'd have
20521 to have both a TOC entry _and_ the actual constant.)
20523 For a 32-bit target, CONST_INT values are loaded and shifted
20524 entirely within `low' and can be stored in one TOC entry. */
20526 /* It would be easy to make this work, but it doesn't now. */
20527 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
20529 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
20531 #if HOST_BITS_PER_WIDE_INT == 32
20532 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
20533 POINTER_SIZE, &low, &high, 0);
20536 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
20537 high = (HOST_WIDE_INT) low >> 32;
20544 if (TARGET_MINIMAL_TOC)
20545 fputs (DOUBLE_INT_ASM_OP, file);
20547 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
20548 (long) high & 0xffffffff, (long) low & 0xffffffff);
20549 fprintf (file, "0x%lx%08lx\n",
20550 (long) high & 0xffffffff, (long) low & 0xffffffff);
20555 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
20557 if (TARGET_MINIMAL_TOC)
20558 fputs ("\t.long ", file);
20560 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
20561 (long) high & 0xffffffff, (long) low & 0xffffffff);
20562 fprintf (file, "0x%lx,0x%lx\n",
20563 (long) high & 0xffffffff, (long) low & 0xffffffff);
20567 if (TARGET_MINIMAL_TOC)
20568 fputs ("\t.long ", file);
20570 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
20571 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
20577 if (GET_CODE (x) == CONST)
20579 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
20580 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
20582 base = XEXP (XEXP (x, 0), 0);
20583 offset = INTVAL (XEXP (XEXP (x, 0), 1));
20586 switch (GET_CODE (base))
20589 name = XSTR (base, 0);
20593 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
20594 CODE_LABEL_NUMBER (XEXP (base, 0)));
20598 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
20602 gcc_unreachable ();
20605 if (TARGET_MINIMAL_TOC)
20606 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
20609 fputs ("\t.tc ", file);
20610 RS6000_OUTPUT_BASENAME (file, name);
20613 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
20615 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
20617 fputs ("[TC],", file);
20620 /* Currently C++ toc references to vtables can be emitted before it
20621 is decided whether the vtable is public or private. If this is
20622 the case, then the linker will eventually complain that there is
20623 a TOC reference to an unknown section. Thus, for vtables only,
20624 we emit the TOC reference to reference the symbol and not the
20626 if (VTABLE_NAME_P (name))
20628 RS6000_OUTPUT_BASENAME (file, name);
20630 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
20631 else if (offset > 0)
20632 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
20635 output_addr_const (file, x);
20639 /* Output an assembler pseudo-op to write an ASCII string of N characters
20640 starting at P to FILE.
20642 On the RS/6000, we have to do this using the .byte operation and
20643 write out special characters outside the quoted string.
20644 Also, the assembler is broken; very long strings are truncated,
20645 so we must artificially break them up early. */
20648 output_ascii (FILE *file, const char *p, int n)
20651 int i, count_string;
20652 const char *for_string = "\t.byte \"";
20653 const char *for_decimal = "\t.byte ";
20654 const char *to_close = NULL;
20657 for (i = 0; i < n; i++)
20660 if (c >= ' ' && c < 0177)
20663 fputs (for_string, file);
20666 /* Write two quotes to get one. */
20674 for_decimal = "\"\n\t.byte ";
20678 if (count_string >= 512)
20680 fputs (to_close, file);
20682 for_string = "\t.byte \"";
20683 for_decimal = "\t.byte ";
20691 fputs (for_decimal, file);
20692 fprintf (file, "%d", c);
20694 for_string = "\n\t.byte \"";
20695 for_decimal = ", ";
20701 /* Now close the string if we have written one. Then end the line. */
20703 fputs (to_close, file);
20706 /* Generate a unique section name for FILENAME for a section type
20707 represented by SECTION_DESC. Output goes into BUF.
20709 SECTION_DESC can be any string, as long as it is different for each
20710 possible section type.
20712 We name the section in the same manner as xlc. The name begins with an
20713 underscore followed by the filename (after stripping any leading directory
20714 names) with the last period replaced by the string SECTION_DESC. If
20715 FILENAME does not contain a period, SECTION_DESC is appended to the end of
20719 rs6000_gen_section_name (char **buf, const char *filename,
20720 const char *section_desc)
20722 const char *q, *after_last_slash, *last_period = 0;
20726 after_last_slash = filename;
20727 for (q = filename; *q; q++)
20730 after_last_slash = q + 1;
20731 else if (*q == '.')
20735 len = strlen (after_last_slash) + strlen (section_desc) + 2;
20736 *buf = (char *) xmalloc (len);
20741 for (q = after_last_slash; *q; q++)
20743 if (q == last_period)
20745 strcpy (p, section_desc);
20746 p += strlen (section_desc);
20750 else if (ISALNUM (*q))
20754 if (last_period == 0)
20755 strcpy (p, section_desc);
20760 /* Emit profile function. */
20763 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
20765 /* Non-standard profiling for kernels, which just saves LR then calls
20766 _mcount without worrying about arg saves. The idea is to change
20767 the function prologue as little as possible as it isn't easy to
20768 account for arg save/restore code added just for _mcount. */
20769 if (TARGET_PROFILE_KERNEL)
20772 if (DEFAULT_ABI == ABI_AIX)
20774 #ifndef NO_PROFILE_COUNTERS
20775 # define NO_PROFILE_COUNTERS 0
20777 if (NO_PROFILE_COUNTERS)
20778 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
20779 LCT_NORMAL, VOIDmode, 0);
20783 const char *label_name;
20786 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
20787 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
20788 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
20790 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
20791 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
20794 else if (DEFAULT_ABI == ABI_DARWIN)
20796 const char *mcount_name = RS6000_MCOUNT;
20797 int caller_addr_regno = LR_REGNO;
20799 /* Be conservative and always set this, at least for now. */
20800 crtl->uses_pic_offset_table = 1;
20803 /* For PIC code, set up a stub and collect the caller's address
20804 from r0, which is where the prologue puts it. */
20805 if (MACHOPIC_INDIRECT
20806 && crtl->uses_pic_offset_table)
20807 caller_addr_regno = 0;
20809 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
20810 LCT_NORMAL, VOIDmode, 1,
20811 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
20815 /* Write function profiler code. */
20818 output_function_profiler (FILE *file, int labelno)
20822 switch (DEFAULT_ABI)
20825 gcc_unreachable ();
20830 warning (0, "no profiling of 64-bit code for this ABI");
20833 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
20834 fprintf (file, "\tmflr %s\n", reg_names[0]);
20835 if (NO_PROFILE_COUNTERS)
20837 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
20838 reg_names[0], reg_names[1]);
20840 else if (TARGET_SECURE_PLT && flag_pic)
20842 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
20843 reg_names[0], reg_names[1]);
20844 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
20845 asm_fprintf (file, "\t{cau|addis} %s,%s,",
20846 reg_names[12], reg_names[12]);
20847 assemble_name (file, buf);
20848 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
20849 assemble_name (file, buf);
20850 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
20852 else if (flag_pic == 1)
20854 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
20855 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
20856 reg_names[0], reg_names[1]);
20857 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
20858 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
20859 assemble_name (file, buf);
20860 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
20862 else if (flag_pic > 1)
20864 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
20865 reg_names[0], reg_names[1]);
20866 /* Now, we need to get the address of the label. */
20867 fputs ("\tbcl 20,31,1f\n\t.long ", file);
20868 assemble_name (file, buf);
20869 fputs ("-.\n1:", file);
20870 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
20871 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
20872 reg_names[0], reg_names[11]);
20873 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
20874 reg_names[0], reg_names[0], reg_names[11]);
20878 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
20879 assemble_name (file, buf);
20880 fputs ("@ha\n", file);
20881 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
20882 reg_names[0], reg_names[1]);
20883 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
20884 assemble_name (file, buf);
20885 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
20888 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
20889 fprintf (file, "\tbl %s%s\n",
20890 RS6000_MCOUNT, flag_pic ? "@plt" : "");
20895 if (!TARGET_PROFILE_KERNEL)
20897 /* Don't do anything, done in output_profile_hook (). */
20901 gcc_assert (!TARGET_32BIT);
20903 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
20904 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
20906 if (cfun->static_chain_decl != NULL)
20908 asm_fprintf (file, "\tstd %s,24(%s)\n",
20909 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
20910 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
20911 asm_fprintf (file, "\tld %s,24(%s)\n",
20912 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
20915 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
20923 /* The following variable value is the last issued insn. */
20925 static rtx last_scheduled_insn;
20927 /* The following variable helps to balance issuing of load and
20928 store instructions */
20930 static int load_store_pendulum;
20932 /* Power4 load update and store update instructions are cracked into a
20933 load or store and an integer insn which are executed in the same cycle.
20934 Branches have their own dispatch slot which does not count against the
20935 GCC issue rate, but it changes the program flow so there are no other
20936 instructions to issue in this cycle. */
20939 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
20940 int verbose ATTRIBUTE_UNUSED,
20941 rtx insn, int more)
20943 last_scheduled_insn = insn;
20944 if (GET_CODE (PATTERN (insn)) == USE
20945 || GET_CODE (PATTERN (insn)) == CLOBBER)
20947 cached_can_issue_more = more;
20948 return cached_can_issue_more;
20951 if (insn_terminates_group_p (insn, current_group))
20953 cached_can_issue_more = 0;
20954 return cached_can_issue_more;
20957 /* If no reservation, but reach here */
20958 if (recog_memoized (insn) < 0)
20961 if (rs6000_sched_groups)
20963 if (is_microcoded_insn (insn))
20964 cached_can_issue_more = 0;
20965 else if (is_cracked_insn (insn))
20966 cached_can_issue_more = more > 2 ? more - 2 : 0;
20968 cached_can_issue_more = more - 1;
20970 return cached_can_issue_more;
20973 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
20976 cached_can_issue_more = more - 1;
20977 return cached_can_issue_more;
20980 /* Adjust the cost of a scheduling dependency. Return the new cost of
20981 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
20984 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
20986 enum attr_type attr_type;
20988 if (! recog_memoized (insn))
20991 switch (REG_NOTE_KIND (link))
20995 /* Data dependency; DEP_INSN writes a register that INSN reads
20996 some cycles later. */
20998 /* Separate a load from a narrower, dependent store. */
20999 if (rs6000_sched_groups
21000 && GET_CODE (PATTERN (insn)) == SET
21001 && GET_CODE (PATTERN (dep_insn)) == SET
21002 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21003 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21004 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21005 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21008 attr_type = get_attr_type (insn);
21013 /* Tell the first scheduling pass about the latency between
21014 a mtctr and bctr (and mtlr and br/blr). The first
21015 scheduling pass will not know about this latency since
21016 the mtctr instruction, which has the latency associated
21017 to it, will be generated by reload. */
21018 return TARGET_POWER ? 5 : 4;
21020 /* Leave some extra cycles between a compare and its
21021 dependent branch, to inhibit expensive mispredicts. */
21022 if ((rs6000_cpu_attr == CPU_PPC603
21023 || rs6000_cpu_attr == CPU_PPC604
21024 || rs6000_cpu_attr == CPU_PPC604E
21025 || rs6000_cpu_attr == CPU_PPC620
21026 || rs6000_cpu_attr == CPU_PPC630
21027 || rs6000_cpu_attr == CPU_PPC750
21028 || rs6000_cpu_attr == CPU_PPC7400
21029 || rs6000_cpu_attr == CPU_PPC7450
21030 || rs6000_cpu_attr == CPU_POWER4
21031 || rs6000_cpu_attr == CPU_POWER5
21032 || rs6000_cpu_attr == CPU_POWER7
21033 || rs6000_cpu_attr == CPU_CELL)
21034 && recog_memoized (dep_insn)
21035 && (INSN_CODE (dep_insn) >= 0))
21037 switch (get_attr_type (dep_insn))
21041 case TYPE_DELAYED_COMPARE:
21042 case TYPE_IMUL_COMPARE:
21043 case TYPE_LMUL_COMPARE:
21044 case TYPE_FPCOMPARE:
21045 case TYPE_CR_LOGICAL:
21046 case TYPE_DELAYED_CR:
21055 case TYPE_STORE_UX:
21057 case TYPE_FPSTORE_U:
21058 case TYPE_FPSTORE_UX:
21059 if ((rs6000_cpu == PROCESSOR_POWER6)
21060 && recog_memoized (dep_insn)
21061 && (INSN_CODE (dep_insn) >= 0))
21064 if (GET_CODE (PATTERN (insn)) != SET)
21065 /* If this happens, we have to extend this to schedule
21066 optimally. Return default for now. */
21069 /* Adjust the cost for the case where the value written
21070 by a fixed point operation is used as the address
21071 gen value on a store. */
21072 switch (get_attr_type (dep_insn))
21079 if (! store_data_bypass_p (dep_insn, insn))
21083 case TYPE_LOAD_EXT:
21084 case TYPE_LOAD_EXT_U:
21085 case TYPE_LOAD_EXT_UX:
21086 case TYPE_VAR_SHIFT_ROTATE:
21087 case TYPE_VAR_DELAYED_COMPARE:
21089 if (! store_data_bypass_p (dep_insn, insn))
21095 case TYPE_FAST_COMPARE:
21098 case TYPE_INSERT_WORD:
21099 case TYPE_INSERT_DWORD:
21100 case TYPE_FPLOAD_U:
21101 case TYPE_FPLOAD_UX:
21103 case TYPE_STORE_UX:
21104 case TYPE_FPSTORE_U:
21105 case TYPE_FPSTORE_UX:
21107 if (! store_data_bypass_p (dep_insn, insn))
21115 case TYPE_IMUL_COMPARE:
21116 case TYPE_LMUL_COMPARE:
21118 if (! store_data_bypass_p (dep_insn, insn))
21124 if (! store_data_bypass_p (dep_insn, insn))
21130 if (! store_data_bypass_p (dep_insn, insn))
21143 case TYPE_LOAD_EXT:
21144 case TYPE_LOAD_EXT_U:
21145 case TYPE_LOAD_EXT_UX:
21146 if ((rs6000_cpu == PROCESSOR_POWER6)
21147 && recog_memoized (dep_insn)
21148 && (INSN_CODE (dep_insn) >= 0))
21151 /* Adjust the cost for the case where the value written
21152 by a fixed point instruction is used within the address
21153 gen portion of a subsequent load(u)(x) */
21154 switch (get_attr_type (dep_insn))
21161 if (set_to_load_agen (dep_insn, insn))
21165 case TYPE_LOAD_EXT:
21166 case TYPE_LOAD_EXT_U:
21167 case TYPE_LOAD_EXT_UX:
21168 case TYPE_VAR_SHIFT_ROTATE:
21169 case TYPE_VAR_DELAYED_COMPARE:
21171 if (set_to_load_agen (dep_insn, insn))
21177 case TYPE_FAST_COMPARE:
21180 case TYPE_INSERT_WORD:
21181 case TYPE_INSERT_DWORD:
21182 case TYPE_FPLOAD_U:
21183 case TYPE_FPLOAD_UX:
21185 case TYPE_STORE_UX:
21186 case TYPE_FPSTORE_U:
21187 case TYPE_FPSTORE_UX:
21189 if (set_to_load_agen (dep_insn, insn))
21197 case TYPE_IMUL_COMPARE:
21198 case TYPE_LMUL_COMPARE:
21200 if (set_to_load_agen (dep_insn, insn))
21206 if (set_to_load_agen (dep_insn, insn))
21212 if (set_to_load_agen (dep_insn, insn))
21223 if ((rs6000_cpu == PROCESSOR_POWER6)
21224 && recog_memoized (dep_insn)
21225 && (INSN_CODE (dep_insn) >= 0)
21226 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
21233 /* Fall out to return default cost. */
21237 case REG_DEP_OUTPUT:
21238 /* Output dependency; DEP_INSN writes a register that INSN writes some
21240 if ((rs6000_cpu == PROCESSOR_POWER6)
21241 && recog_memoized (dep_insn)
21242 && (INSN_CODE (dep_insn) >= 0))
21244 attr_type = get_attr_type (insn);
21249 if (get_attr_type (dep_insn) == TYPE_FP)
21253 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
21261 /* Anti dependency; DEP_INSN reads a register that INSN writes some
21266 gcc_unreachable ();
21272 /* Debug version of rs6000_adjust_cost. */
21275 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21277 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
21283 switch (REG_NOTE_KIND (link))
21285 default: dep = "unknown depencency"; break;
21286 case REG_DEP_TRUE: dep = "data dependency"; break;
21287 case REG_DEP_OUTPUT: dep = "output dependency"; break;
21288 case REG_DEP_ANTI: dep = "anti depencency"; break;
21292 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
21293 "%s, insn:\n", ret, cost, dep);
21301 /* The function returns a true if INSN is microcoded.
21302 Return false otherwise. */
21305 is_microcoded_insn (rtx insn)
21307 if (!insn || !INSN_P (insn)
21308 || GET_CODE (PATTERN (insn)) == USE
21309 || GET_CODE (PATTERN (insn)) == CLOBBER)
21312 if (rs6000_cpu_attr == CPU_CELL)
21313 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
21315 if (rs6000_sched_groups)
21317 enum attr_type type = get_attr_type (insn);
21318 if (type == TYPE_LOAD_EXT_U
21319 || type == TYPE_LOAD_EXT_UX
21320 || type == TYPE_LOAD_UX
21321 || type == TYPE_STORE_UX
21322 || type == TYPE_MFCR)
21329 /* The function returns true if INSN is cracked into 2 instructions
21330 by the processor (and therefore occupies 2 issue slots). */
21333 is_cracked_insn (rtx insn)
21335 if (!insn || !INSN_P (insn)
21336 || GET_CODE (PATTERN (insn)) == USE
21337 || GET_CODE (PATTERN (insn)) == CLOBBER)
21340 if (rs6000_sched_groups)
21342 enum attr_type type = get_attr_type (insn);
21343 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
21344 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
21345 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
21346 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
21347 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
21348 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
21349 || type == TYPE_IDIV || type == TYPE_LDIV
21350 || type == TYPE_INSERT_WORD)
21357 /* The function returns true if INSN can be issued only from
21358 the branch slot. */
21361 is_branch_slot_insn (rtx insn)
21363 if (!insn || !INSN_P (insn)
21364 || GET_CODE (PATTERN (insn)) == USE
21365 || GET_CODE (PATTERN (insn)) == CLOBBER)
21368 if (rs6000_sched_groups)
21370 enum attr_type type = get_attr_type (insn);
21371 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
21379 /* The function returns true if out_inst sets a value that is
21380 used in the address generation computation of in_insn */
21382 set_to_load_agen (rtx out_insn, rtx in_insn)
21384 rtx out_set, in_set;
21386 /* For performance reasons, only handle the simple case where
21387 both loads are a single_set. */
21388 out_set = single_set (out_insn);
21391 in_set = single_set (in_insn);
21393 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
21399 /* The function returns true if the target storage location of
21400 out_insn is adjacent to the target storage location of in_insn */
21401 /* Return 1 if memory locations are adjacent. */
21404 adjacent_mem_locations (rtx insn1, rtx insn2)
21407 rtx a = get_store_dest (PATTERN (insn1));
21408 rtx b = get_store_dest (PATTERN (insn2));
21410 if ((GET_CODE (XEXP (a, 0)) == REG
21411 || (GET_CODE (XEXP (a, 0)) == PLUS
21412 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
21413 && (GET_CODE (XEXP (b, 0)) == REG
21414 || (GET_CODE (XEXP (b, 0)) == PLUS
21415 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
21417 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
21420 if (GET_CODE (XEXP (a, 0)) == PLUS)
21422 reg0 = XEXP (XEXP (a, 0), 0);
21423 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
21426 reg0 = XEXP (a, 0);
21428 if (GET_CODE (XEXP (b, 0)) == PLUS)
21430 reg1 = XEXP (XEXP (b, 0), 0);
21431 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
21434 reg1 = XEXP (b, 0);
21436 val_diff = val1 - val0;
21438 return ((REGNO (reg0) == REGNO (reg1))
21439 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
21440 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
21446 /* A C statement (sans semicolon) to update the integer scheduling
21447 priority INSN_PRIORITY (INSN). Increase the priority to execute the
21448 INSN earlier, reduce the priority to execute INSN later. Do not
21449 define this macro if you do not need to adjust the scheduling
21450 priorities of insns. */
21453 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
21455 /* On machines (like the 750) which have asymmetric integer units,
21456 where one integer unit can do multiply and divides and the other
21457 can't, reduce the priority of multiply/divide so it is scheduled
21458 before other integer operations. */
21461 if (! INSN_P (insn))
21464 if (GET_CODE (PATTERN (insn)) == USE)
21467 switch (rs6000_cpu_attr) {
21469 switch (get_attr_type (insn))
21476 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
21477 priority, priority);
21478 if (priority >= 0 && priority < 0x01000000)
21485 if (insn_must_be_first_in_group (insn)
21486 && reload_completed
21487 && current_sched_info->sched_max_insns_priority
21488 && rs6000_sched_restricted_insns_priority)
21491 /* Prioritize insns that can be dispatched only in the first
21493 if (rs6000_sched_restricted_insns_priority == 1)
21494 /* Attach highest priority to insn. This means that in
21495 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
21496 precede 'priority' (critical path) considerations. */
21497 return current_sched_info->sched_max_insns_priority;
21498 else if (rs6000_sched_restricted_insns_priority == 2)
21499 /* Increase priority of insn by a minimal amount. This means that in
21500 haifa-sched.c:ready_sort(), only 'priority' (critical path)
21501 considerations precede dispatch-slot restriction considerations. */
21502 return (priority + 1);
21505 if (rs6000_cpu == PROCESSOR_POWER6
21506 && ((load_store_pendulum == -2 && is_load_insn (insn))
21507 || (load_store_pendulum == 2 && is_store_insn (insn))))
21508 /* Attach highest priority to insn if the scheduler has just issued two
21509 stores and this instruction is a load, or two loads and this instruction
21510 is a store. Power6 wants loads and stores scheduled alternately
21512 return current_sched_info->sched_max_insns_priority;
21517 /* Return true if the instruction is nonpipelined on the Cell. */
21519 is_nonpipeline_insn (rtx insn)
21521 enum attr_type type;
21522 if (!insn || !INSN_P (insn)
21523 || GET_CODE (PATTERN (insn)) == USE
21524 || GET_CODE (PATTERN (insn)) == CLOBBER)
21527 type = get_attr_type (insn);
21528 if (type == TYPE_IMUL
21529 || type == TYPE_IMUL2
21530 || type == TYPE_IMUL3
21531 || type == TYPE_LMUL
21532 || type == TYPE_IDIV
21533 || type == TYPE_LDIV
21534 || type == TYPE_SDIV
21535 || type == TYPE_DDIV
21536 || type == TYPE_SSQRT
21537 || type == TYPE_DSQRT
21538 || type == TYPE_MFCR
21539 || type == TYPE_MFCRF
21540 || type == TYPE_MFJMPR)
21548 /* Return how many instructions the machine can issue per cycle. */
21551 rs6000_issue_rate (void)
21553 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
21554 if (!reload_completed)
21557 switch (rs6000_cpu_attr) {
21558 case CPU_RIOS1: /* ? */
21560 case CPU_PPC601: /* ? */
21569 case CPU_PPCE300C2:
21570 case CPU_PPCE300C3:
21571 case CPU_PPCE500MC:
21589 /* Return how many instructions to look ahead for better insn
21593 rs6000_use_sched_lookahead (void)
21595 if (rs6000_cpu_attr == CPU_PPC8540)
21597 if (rs6000_cpu_attr == CPU_CELL)
21598 return (reload_completed ? 8 : 0);
21602 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
21604 rs6000_use_sched_lookahead_guard (rtx insn)
21606 if (rs6000_cpu_attr != CPU_CELL)
21609 if (insn == NULL_RTX || !INSN_P (insn))
21612 if (!reload_completed
21613 || is_nonpipeline_insn (insn)
21614 || is_microcoded_insn (insn))
21620 /* Determine is PAT refers to memory. */
21623 is_mem_ref (rtx pat)
21629 /* stack_tie does not produce any real memory traffic. */
21630 if (GET_CODE (pat) == UNSPEC
21631 && XINT (pat, 1) == UNSPEC_TIE)
21634 if (GET_CODE (pat) == MEM)
21637 /* Recursively process the pattern. */
21638 fmt = GET_RTX_FORMAT (GET_CODE (pat));
21640 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
21643 ret |= is_mem_ref (XEXP (pat, i));
21644 else if (fmt[i] == 'E')
21645 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
21646 ret |= is_mem_ref (XVECEXP (pat, i, j));
21652 /* Determine if PAT is a PATTERN of a load insn. */
21655 is_load_insn1 (rtx pat)
21657 if (!pat || pat == NULL_RTX)
21660 if (GET_CODE (pat) == SET)
21661 return is_mem_ref (SET_SRC (pat));
21663 if (GET_CODE (pat) == PARALLEL)
21667 for (i = 0; i < XVECLEN (pat, 0); i++)
21668 if (is_load_insn1 (XVECEXP (pat, 0, i)))
21675 /* Determine if INSN loads from memory. */
21678 is_load_insn (rtx insn)
21680 if (!insn || !INSN_P (insn))
21683 if (GET_CODE (insn) == CALL_INSN)
21686 return is_load_insn1 (PATTERN (insn));
21689 /* Determine if PAT is a PATTERN of a store insn. */
21692 is_store_insn1 (rtx pat)
21694 if (!pat || pat == NULL_RTX)
21697 if (GET_CODE (pat) == SET)
21698 return is_mem_ref (SET_DEST (pat));
21700 if (GET_CODE (pat) == PARALLEL)
21704 for (i = 0; i < XVECLEN (pat, 0); i++)
21705 if (is_store_insn1 (XVECEXP (pat, 0, i)))
21712 /* Determine if INSN stores to memory. */
21715 is_store_insn (rtx insn)
21717 if (!insn || !INSN_P (insn))
21720 return is_store_insn1 (PATTERN (insn));
21723 /* Return the dest of a store insn. */
21726 get_store_dest (rtx pat)
21728 gcc_assert (is_store_insn1 (pat));
21730 if (GET_CODE (pat) == SET)
21731 return SET_DEST (pat);
21732 else if (GET_CODE (pat) == PARALLEL)
21736 for (i = 0; i < XVECLEN (pat, 0); i++)
21738 rtx inner_pat = XVECEXP (pat, 0, i);
21739 if (GET_CODE (inner_pat) == SET
21740 && is_mem_ref (SET_DEST (inner_pat)))
21744 /* We shouldn't get here, because we should have either a simple
21745 store insn or a store with update which are covered above. */
21749 /* Returns whether the dependence between INSN and NEXT is considered
21750 costly by the given target. */
21753 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
21758 /* If the flag is not enabled - no dependence is considered costly;
21759 allow all dependent insns in the same group.
21760 This is the most aggressive option. */
21761 if (rs6000_sched_costly_dep == no_dep_costly)
21764 /* If the flag is set to 1 - a dependence is always considered costly;
21765 do not allow dependent instructions in the same group.
21766 This is the most conservative option. */
21767 if (rs6000_sched_costly_dep == all_deps_costly)
21770 insn = DEP_PRO (dep);
21771 next = DEP_CON (dep);
21773 if (rs6000_sched_costly_dep == store_to_load_dep_costly
21774 && is_load_insn (next)
21775 && is_store_insn (insn))
21776 /* Prevent load after store in the same group. */
21779 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
21780 && is_load_insn (next)
21781 && is_store_insn (insn)
21782 && DEP_TYPE (dep) == REG_DEP_TRUE)
21783 /* Prevent load after store in the same group if it is a true
21787 /* The flag is set to X; dependences with latency >= X are considered costly,
21788 and will not be scheduled in the same group. */
21789 if (rs6000_sched_costly_dep <= max_dep_latency
21790 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
21796 /* Return the next insn after INSN that is found before TAIL is reached,
21797 skipping any "non-active" insns - insns that will not actually occupy
21798 an issue slot. Return NULL_RTX if such an insn is not found. */
21801 get_next_active_insn (rtx insn, rtx tail)
21803 if (insn == NULL_RTX || insn == tail)
21808 insn = NEXT_INSN (insn);
21809 if (insn == NULL_RTX || insn == tail)
21814 || (NONJUMP_INSN_P (insn)
21815 && GET_CODE (PATTERN (insn)) != USE
21816 && GET_CODE (PATTERN (insn)) != CLOBBER
21817 && INSN_CODE (insn) != CODE_FOR_stack_tie))
21823 /* We are about to begin issuing insns for this clock cycle. */
21826 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
21827 rtx *ready ATTRIBUTE_UNUSED,
21828 int *pn_ready ATTRIBUTE_UNUSED,
21829 int clock_var ATTRIBUTE_UNUSED)
21831 int n_ready = *pn_ready;
21834 fprintf (dump, "// rs6000_sched_reorder :\n");
21836 /* Reorder the ready list, if the second to last ready insn
21837 is a nonepipeline insn. */
21838 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
21840 if (is_nonpipeline_insn (ready[n_ready - 1])
21841 && (recog_memoized (ready[n_ready - 2]) > 0))
21842 /* Simply swap first two insns. */
21844 rtx tmp = ready[n_ready - 1];
21845 ready[n_ready - 1] = ready[n_ready - 2];
21846 ready[n_ready - 2] = tmp;
21850 if (rs6000_cpu == PROCESSOR_POWER6)
21851 load_store_pendulum = 0;
21853 return rs6000_issue_rate ();
21856 /* Like rs6000_sched_reorder, but called after issuing each insn. */
21859 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
21860 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
21863 fprintf (dump, "// rs6000_sched_reorder2 :\n");
21865 /* For Power6, we need to handle some special cases to try and keep the
21866 store queue from overflowing and triggering expensive flushes.
21868 This code monitors how load and store instructions are being issued
21869 and skews the ready list one way or the other to increase the likelihood
21870 that a desired instruction is issued at the proper time.
21872 A couple of things are done. First, we maintain a "load_store_pendulum"
21873 to track the current state of load/store issue.
21875 - If the pendulum is at zero, then no loads or stores have been
21876 issued in the current cycle so we do nothing.
21878 - If the pendulum is 1, then a single load has been issued in this
21879 cycle and we attempt to locate another load in the ready list to
21882 - If the pendulum is -2, then two stores have already been
21883 issued in this cycle, so we increase the priority of the first load
21884 in the ready list to increase it's likelihood of being chosen first
21887 - If the pendulum is -1, then a single store has been issued in this
21888 cycle and we attempt to locate another store in the ready list to
21889 issue with it, preferring a store to an adjacent memory location to
21890 facilitate store pairing in the store queue.
21892 - If the pendulum is 2, then two loads have already been
21893 issued in this cycle, so we increase the priority of the first store
21894 in the ready list to increase it's likelihood of being chosen first
21897 - If the pendulum < -2 or > 2, then do nothing.
21899 Note: This code covers the most common scenarios. There exist non
21900 load/store instructions which make use of the LSU and which
21901 would need to be accounted for to strictly model the behavior
21902 of the machine. Those instructions are currently unaccounted
21903 for to help minimize compile time overhead of this code.
21905 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
21911 if (is_store_insn (last_scheduled_insn))
21912 /* Issuing a store, swing the load_store_pendulum to the left */
21913 load_store_pendulum--;
21914 else if (is_load_insn (last_scheduled_insn))
21915 /* Issuing a load, swing the load_store_pendulum to the right */
21916 load_store_pendulum++;
21918 return cached_can_issue_more;
21920 /* If the pendulum is balanced, or there is only one instruction on
21921 the ready list, then all is well, so return. */
21922 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
21923 return cached_can_issue_more;
21925 if (load_store_pendulum == 1)
21927 /* A load has been issued in this cycle. Scan the ready list
21928 for another load to issue with it */
21933 if (is_load_insn (ready[pos]))
21935 /* Found a load. Move it to the head of the ready list,
21936 and adjust it's priority so that it is more likely to
21939 for (i=pos; i<*pn_ready-1; i++)
21940 ready[i] = ready[i + 1];
21941 ready[*pn_ready-1] = tmp;
21943 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
21944 INSN_PRIORITY (tmp)++;
21950 else if (load_store_pendulum == -2)
21952 /* Two stores have been issued in this cycle. Increase the
21953 priority of the first load in the ready list to favor it for
21954 issuing in the next cycle. */
21959 if (is_load_insn (ready[pos])
21961 && INSN_PRIORITY_KNOWN (ready[pos]))
21963 INSN_PRIORITY (ready[pos])++;
21965 /* Adjust the pendulum to account for the fact that a load
21966 was found and increased in priority. This is to prevent
21967 increasing the priority of multiple loads */
21968 load_store_pendulum--;
21975 else if (load_store_pendulum == -1)
21977 /* A store has been issued in this cycle. Scan the ready list for
21978 another store to issue with it, preferring a store to an adjacent
21980 int first_store_pos = -1;
21986 if (is_store_insn (ready[pos]))
21988 /* Maintain the index of the first store found on the
21990 if (first_store_pos == -1)
21991 first_store_pos = pos;
21993 if (is_store_insn (last_scheduled_insn)
21994 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
21996 /* Found an adjacent store. Move it to the head of the
21997 ready list, and adjust it's priority so that it is
21998 more likely to stay there */
22000 for (i=pos; i<*pn_ready-1; i++)
22001 ready[i] = ready[i + 1];
22002 ready[*pn_ready-1] = tmp;
22004 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22005 INSN_PRIORITY (tmp)++;
22007 first_store_pos = -1;
22015 if (first_store_pos >= 0)
22017 /* An adjacent store wasn't found, but a non-adjacent store was,
22018 so move the non-adjacent store to the front of the ready
22019 list, and adjust its priority so that it is more likely to
22021 tmp = ready[first_store_pos];
22022 for (i=first_store_pos; i<*pn_ready-1; i++)
22023 ready[i] = ready[i + 1];
22024 ready[*pn_ready-1] = tmp;
22025 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22026 INSN_PRIORITY (tmp)++;
22029 else if (load_store_pendulum == 2)
22031 /* Two loads have been issued in this cycle. Increase the priority
22032 of the first store in the ready list to favor it for issuing in
22038 if (is_store_insn (ready[pos])
22040 && INSN_PRIORITY_KNOWN (ready[pos]))
22042 INSN_PRIORITY (ready[pos])++;
22044 /* Adjust the pendulum to account for the fact that a store
22045 was found and increased in priority. This is to prevent
22046 increasing the priority of multiple stores */
22047 load_store_pendulum++;
22056 return cached_can_issue_more;
22059 /* Return whether the presence of INSN causes a dispatch group termination
22060 of group WHICH_GROUP.
22062 If WHICH_GROUP == current_group, this function will return true if INSN
22063 causes the termination of the current group (i.e, the dispatch group to
22064 which INSN belongs). This means that INSN will be the last insn in the
22065 group it belongs to.
22067 If WHICH_GROUP == previous_group, this function will return true if INSN
22068 causes the termination of the previous group (i.e, the dispatch group that
22069 precedes the group to which INSN belongs). This means that INSN will be
22070 the first insn in the group it belongs to). */
22073 insn_terminates_group_p (rtx insn, enum group_termination which_group)
22080 first = insn_must_be_first_in_group (insn);
22081 last = insn_must_be_last_in_group (insn);
22086 if (which_group == current_group)
22088 else if (which_group == previous_group)
22096 insn_must_be_first_in_group (rtx insn)
22098 enum attr_type type;
22101 || insn == NULL_RTX
22102 || GET_CODE (insn) == NOTE
22103 || GET_CODE (PATTERN (insn)) == USE
22104 || GET_CODE (PATTERN (insn)) == CLOBBER)
22107 switch (rs6000_cpu)
22109 case PROCESSOR_POWER5:
22110 if (is_cracked_insn (insn))
22112 case PROCESSOR_POWER4:
22113 if (is_microcoded_insn (insn))
22116 if (!rs6000_sched_groups)
22119 type = get_attr_type (insn);
22126 case TYPE_DELAYED_CR:
22127 case TYPE_CR_LOGICAL:
22141 case PROCESSOR_POWER6:
22142 type = get_attr_type (insn);
22146 case TYPE_INSERT_DWORD:
22150 case TYPE_VAR_SHIFT_ROTATE:
22157 case TYPE_INSERT_WORD:
22158 case TYPE_DELAYED_COMPARE:
22159 case TYPE_IMUL_COMPARE:
22160 case TYPE_LMUL_COMPARE:
22161 case TYPE_FPCOMPARE:
22172 case TYPE_LOAD_EXT_UX:
22174 case TYPE_STORE_UX:
22175 case TYPE_FPLOAD_U:
22176 case TYPE_FPLOAD_UX:
22177 case TYPE_FPSTORE_U:
22178 case TYPE_FPSTORE_UX:
22184 case PROCESSOR_POWER7:
22185 type = get_attr_type (insn);
22189 case TYPE_CR_LOGICAL:
22196 case TYPE_DELAYED_COMPARE:
22197 case TYPE_VAR_DELAYED_COMPARE:
22203 case TYPE_LOAD_EXT:
22204 case TYPE_LOAD_EXT_U:
22205 case TYPE_LOAD_EXT_UX:
22207 case TYPE_STORE_UX:
22208 case TYPE_FPLOAD_U:
22209 case TYPE_FPLOAD_UX:
22210 case TYPE_FPSTORE_U:
22211 case TYPE_FPSTORE_UX:
22227 insn_must_be_last_in_group (rtx insn)
22229 enum attr_type type;
22232 || insn == NULL_RTX
22233 || GET_CODE (insn) == NOTE
22234 || GET_CODE (PATTERN (insn)) == USE
22235 || GET_CODE (PATTERN (insn)) == CLOBBER)
22238 switch (rs6000_cpu) {
22239 case PROCESSOR_POWER4:
22240 case PROCESSOR_POWER5:
22241 if (is_microcoded_insn (insn))
22244 if (is_branch_slot_insn (insn))
22248 case PROCESSOR_POWER6:
22249 type = get_attr_type (insn);
22256 case TYPE_VAR_SHIFT_ROTATE:
22263 case TYPE_DELAYED_COMPARE:
22264 case TYPE_IMUL_COMPARE:
22265 case TYPE_LMUL_COMPARE:
22266 case TYPE_FPCOMPARE:
22280 case PROCESSOR_POWER7:
22281 type = get_attr_type (insn);
22289 case TYPE_LOAD_EXT_U:
22290 case TYPE_LOAD_EXT_UX:
22291 case TYPE_STORE_UX:
22304 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
22305 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
22308 is_costly_group (rtx *group_insns, rtx next_insn)
22311 int issue_rate = rs6000_issue_rate ();
22313 for (i = 0; i < issue_rate; i++)
22315 sd_iterator_def sd_it;
22317 rtx insn = group_insns[i];
22322 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
22324 rtx next = DEP_CON (dep);
22326 if (next == next_insn
22327 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
22335 /* Utility of the function redefine_groups.
22336 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
22337 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
22338 to keep it "far" (in a separate group) from GROUP_INSNS, following
22339 one of the following schemes, depending on the value of the flag
22340 -minsert_sched_nops = X:
22341 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
22342 in order to force NEXT_INSN into a separate group.
22343 (2) X < sched_finish_regroup_exact: insert exactly X nops.
22344 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
22345 insertion (has a group just ended, how many vacant issue slots remain in the
22346 last group, and how many dispatch groups were encountered so far). */
22349 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
22350 rtx next_insn, bool *group_end, int can_issue_more,
22355 int issue_rate = rs6000_issue_rate ();
22356 bool end = *group_end;
22359 if (next_insn == NULL_RTX)
22360 return can_issue_more;
22362 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
22363 return can_issue_more;
22365 force = is_costly_group (group_insns, next_insn);
22367 return can_issue_more;
22369 if (sched_verbose > 6)
22370 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
22371 *group_count ,can_issue_more);
22373 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
22376 can_issue_more = 0;
22378 /* Since only a branch can be issued in the last issue_slot, it is
22379 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
22380 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
22381 in this case the last nop will start a new group and the branch
22382 will be forced to the new group. */
22383 if (can_issue_more && !is_branch_slot_insn (next_insn))
22386 while (can_issue_more > 0)
22389 emit_insn_before (nop, next_insn);
22397 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
22399 int n_nops = rs6000_sched_insert_nops;
22401 /* Nops can't be issued from the branch slot, so the effective
22402 issue_rate for nops is 'issue_rate - 1'. */
22403 if (can_issue_more == 0)
22404 can_issue_more = issue_rate;
22406 if (can_issue_more == 0)
22408 can_issue_more = issue_rate - 1;
22411 for (i = 0; i < issue_rate; i++)
22413 group_insns[i] = 0;
22420 emit_insn_before (nop, next_insn);
22421 if (can_issue_more == issue_rate - 1) /* new group begins */
22424 if (can_issue_more == 0)
22426 can_issue_more = issue_rate - 1;
22429 for (i = 0; i < issue_rate; i++)
22431 group_insns[i] = 0;
22437 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
22440 /* Is next_insn going to start a new group? */
22443 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22444 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22445 || (can_issue_more < issue_rate &&
22446 insn_terminates_group_p (next_insn, previous_group)));
22447 if (*group_end && end)
22450 if (sched_verbose > 6)
22451 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
22452 *group_count, can_issue_more);
22453 return can_issue_more;
22456 return can_issue_more;
22459 /* This function tries to synch the dispatch groups that the compiler "sees"
22460 with the dispatch groups that the processor dispatcher is expected to
22461 form in practice. It tries to achieve this synchronization by forcing the
22462 estimated processor grouping on the compiler (as opposed to the function
22463 'pad_goups' which tries to force the scheduler's grouping on the processor).
22465 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
22466 examines the (estimated) dispatch groups that will be formed by the processor
22467 dispatcher. It marks these group boundaries to reflect the estimated
22468 processor grouping, overriding the grouping that the scheduler had marked.
22469 Depending on the value of the flag '-minsert-sched-nops' this function can
22470 force certain insns into separate groups or force a certain distance between
22471 them by inserting nops, for example, if there exists a "costly dependence"
22474 The function estimates the group boundaries that the processor will form as
22475 follows: It keeps track of how many vacant issue slots are available after
22476 each insn. A subsequent insn will start a new group if one of the following
22478 - no more vacant issue slots remain in the current dispatch group.
22479 - only the last issue slot, which is the branch slot, is vacant, but the next
22480 insn is not a branch.
22481 - only the last 2 or less issue slots, including the branch slot, are vacant,
22482 which means that a cracked insn (which occupies two issue slots) can't be
22483 issued in this group.
22484 - less than 'issue_rate' slots are vacant, and the next insn always needs to
22485 start a new group. */
22488 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22490 rtx insn, next_insn;
22492 int can_issue_more;
22495 int group_count = 0;
22499 issue_rate = rs6000_issue_rate ();
22500 group_insns = XALLOCAVEC (rtx, issue_rate);
22501 for (i = 0; i < issue_rate; i++)
22503 group_insns[i] = 0;
22505 can_issue_more = issue_rate;
22507 insn = get_next_active_insn (prev_head_insn, tail);
22510 while (insn != NULL_RTX)
22512 slot = (issue_rate - can_issue_more);
22513 group_insns[slot] = insn;
22515 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
22516 if (insn_terminates_group_p (insn, current_group))
22517 can_issue_more = 0;
22519 next_insn = get_next_active_insn (insn, tail);
22520 if (next_insn == NULL_RTX)
22521 return group_count + 1;
22523 /* Is next_insn going to start a new group? */
22525 = (can_issue_more == 0
22526 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22527 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22528 || (can_issue_more < issue_rate &&
22529 insn_terminates_group_p (next_insn, previous_group)));
22531 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
22532 next_insn, &group_end, can_issue_more,
22538 can_issue_more = 0;
22539 for (i = 0; i < issue_rate; i++)
22541 group_insns[i] = 0;
22545 if (GET_MODE (next_insn) == TImode && can_issue_more)
22546 PUT_MODE (next_insn, VOIDmode);
22547 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
22548 PUT_MODE (next_insn, TImode);
22551 if (can_issue_more == 0)
22552 can_issue_more = issue_rate;
22555 return group_count;
22558 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
22559 dispatch group boundaries that the scheduler had marked. Pad with nops
22560 any dispatch groups which have vacant issue slots, in order to force the
22561 scheduler's grouping on the processor dispatcher. The function
22562 returns the number of dispatch groups found. */
22565 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22567 rtx insn, next_insn;
22570 int can_issue_more;
22572 int group_count = 0;
22574 /* Initialize issue_rate. */
22575 issue_rate = rs6000_issue_rate ();
22576 can_issue_more = issue_rate;
22578 insn = get_next_active_insn (prev_head_insn, tail);
22579 next_insn = get_next_active_insn (insn, tail);
22581 while (insn != NULL_RTX)
22584 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
22586 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
22588 if (next_insn == NULL_RTX)
22593 /* If the scheduler had marked group termination at this location
22594 (between insn and next_insn), and neither insn nor next_insn will
22595 force group termination, pad the group with nops to force group
22598 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
22599 && !insn_terminates_group_p (insn, current_group)
22600 && !insn_terminates_group_p (next_insn, previous_group))
22602 if (!is_branch_slot_insn (next_insn))
22605 while (can_issue_more)
22608 emit_insn_before (nop, next_insn);
22613 can_issue_more = issue_rate;
22618 next_insn = get_next_active_insn (insn, tail);
22621 return group_count;
22624 /* We're beginning a new block. Initialize data structures as necessary. */
22627 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
22628 int sched_verbose ATTRIBUTE_UNUSED,
22629 int max_ready ATTRIBUTE_UNUSED)
22631 last_scheduled_insn = NULL_RTX;
22632 load_store_pendulum = 0;
22635 /* The following function is called at the end of scheduling BB.
22636 After reload, it inserts nops at insn group bundling. */
22639 rs6000_sched_finish (FILE *dump, int sched_verbose)
22644 fprintf (dump, "=== Finishing schedule.\n");
22646 if (reload_completed && rs6000_sched_groups)
22648 /* Do not run sched_finish hook when selective scheduling enabled. */
22649 if (sel_sched_p ())
22652 if (rs6000_sched_insert_nops == sched_finish_none)
22655 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
22656 n_groups = pad_groups (dump, sched_verbose,
22657 current_sched_info->prev_head,
22658 current_sched_info->next_tail);
22660 n_groups = redefine_groups (dump, sched_verbose,
22661 current_sched_info->prev_head,
22662 current_sched_info->next_tail);
22664 if (sched_verbose >= 6)
22666 fprintf (dump, "ngroups = %d\n", n_groups);
22667 print_rtl (dump, current_sched_info->prev_head);
22668 fprintf (dump, "Done finish_sched\n");
22673 struct _rs6000_sched_context
22675 short cached_can_issue_more;
22676 rtx last_scheduled_insn;
22677 int load_store_pendulum;
22680 typedef struct _rs6000_sched_context rs6000_sched_context_def;
22681 typedef rs6000_sched_context_def *rs6000_sched_context_t;
22683 /* Allocate store for new scheduling context. */
22685 rs6000_alloc_sched_context (void)
22687 return xmalloc (sizeof (rs6000_sched_context_def));
22690 /* If CLEAN_P is true then initializes _SC with clean data,
22691 and from the global context otherwise. */
22693 rs6000_init_sched_context (void *_sc, bool clean_p)
22695 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
22699 sc->cached_can_issue_more = 0;
22700 sc->last_scheduled_insn = NULL_RTX;
22701 sc->load_store_pendulum = 0;
22705 sc->cached_can_issue_more = cached_can_issue_more;
22706 sc->last_scheduled_insn = last_scheduled_insn;
22707 sc->load_store_pendulum = load_store_pendulum;
22711 /* Sets the global scheduling context to the one pointed to by _SC. */
22713 rs6000_set_sched_context (void *_sc)
22715 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
22717 gcc_assert (sc != NULL);
22719 cached_can_issue_more = sc->cached_can_issue_more;
22720 last_scheduled_insn = sc->last_scheduled_insn;
22721 load_store_pendulum = sc->load_store_pendulum;
22726 rs6000_free_sched_context (void *_sc)
22728 gcc_assert (_sc != NULL);
22734 /* Length in units of the trampoline for entering a nested function. */
22737 rs6000_trampoline_size (void)
22741 switch (DEFAULT_ABI)
22744 gcc_unreachable ();
22747 ret = (TARGET_32BIT) ? 12 : 24;
22752 ret = (TARGET_32BIT) ? 40 : 48;
22759 /* Emit RTL insns to initialize the variable parts of a trampoline.
22760 FNADDR is an RTX for the address of the function's pure code.
22761 CXT is an RTX for the static chain value for the function. */
22764 rs6000_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
22766 int regsize = (TARGET_32BIT) ? 4 : 8;
22767 rtx ctx_reg = force_reg (Pmode, cxt);
22769 switch (DEFAULT_ABI)
22772 gcc_unreachable ();
22774 /* Macros to shorten the code expansions below. */
22775 #define MEM_DEREF(addr) gen_rtx_MEM (Pmode, memory_address (Pmode, addr))
22776 #define MEM_PLUS(addr,offset) \
22777 gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (addr, offset)))
22779 /* Under AIX, just build the 3 word function descriptor */
22782 rtx fn_reg = gen_reg_rtx (Pmode);
22783 rtx toc_reg = gen_reg_rtx (Pmode);
22784 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
22785 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
22786 emit_move_insn (MEM_DEREF (addr), fn_reg);
22787 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
22788 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
22792 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
22795 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
22796 LCT_NORMAL, VOIDmode, 4,
22798 GEN_INT (rs6000_trampoline_size ()), SImode,
22808 /* Handle the "altivec" attribute. The attribute may have
22809 arguments as follows:
22811 __attribute__((altivec(vector__)))
22812 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
22813 __attribute__((altivec(bool__))) (always followed by 'unsigned')
22815 and may appear more than once (e.g., 'vector bool char') in a
22816 given declaration. */
22819 rs6000_handle_altivec_attribute (tree *node,
22820 tree name ATTRIBUTE_UNUSED,
22822 int flags ATTRIBUTE_UNUSED,
22823 bool *no_add_attrs)
22825 tree type = *node, result = NULL_TREE;
22826 enum machine_mode mode;
22829 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
22830 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
22831 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
22834 while (POINTER_TYPE_P (type)
22835 || TREE_CODE (type) == FUNCTION_TYPE
22836 || TREE_CODE (type) == METHOD_TYPE
22837 || TREE_CODE (type) == ARRAY_TYPE)
22838 type = TREE_TYPE (type);
22840 mode = TYPE_MODE (type);
22842 /* Check for invalid AltiVec type qualifiers. */
22843 if (type == long_double_type_node)
22844 error ("use of %<long double%> in AltiVec types is invalid");
22845 else if (type == boolean_type_node)
22846 error ("use of boolean types in AltiVec types is invalid");
22847 else if (TREE_CODE (type) == COMPLEX_TYPE)
22848 error ("use of %<complex%> in AltiVec types is invalid");
22849 else if (DECIMAL_FLOAT_MODE_P (mode))
22850 error ("use of decimal floating point types in AltiVec types is invalid");
22851 else if (!TARGET_VSX)
22853 if (type == long_unsigned_type_node || type == long_integer_type_node)
22856 error ("use of %<long%> in AltiVec types is invalid for "
22857 "64-bit code without -mvsx");
22858 else if (rs6000_warn_altivec_long)
22859 warning (0, "use of %<long%> in AltiVec types is deprecated; "
22862 else if (type == long_long_unsigned_type_node
22863 || type == long_long_integer_type_node)
22864 error ("use of %<long long%> in AltiVec types is invalid without "
22866 else if (type == double_type_node)
22867 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
22870 switch (altivec_type)
22873 unsigned_p = TYPE_UNSIGNED (type);
22877 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
22880 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
22883 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
22886 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
22888 case SFmode: result = V4SF_type_node; break;
22889 case DFmode: result = V2DF_type_node; break;
22890 /* If the user says 'vector int bool', we may be handed the 'bool'
22891 attribute _before_ the 'vector' attribute, and so select the
22892 proper type in the 'b' case below. */
22893 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
22894 case V2DImode: case V2DFmode:
22902 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
22903 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
22904 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
22905 case QImode: case V16QImode: result = bool_V16QI_type_node;
22912 case V8HImode: result = pixel_V8HI_type_node;
22918 /* Propagate qualifiers attached to the element type
22919 onto the vector type. */
22920 if (result && result != type && TYPE_QUALS (type))
22921 result = build_qualified_type (result, TYPE_QUALS (type));
22923 *no_add_attrs = true; /* No need to hang on to the attribute. */
22926 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
22931 /* AltiVec defines four built-in scalar types that serve as vector
22932 elements; we must teach the compiler how to mangle them. */
22934 static const char *
22935 rs6000_mangle_type (const_tree type)
22937 type = TYPE_MAIN_VARIANT (type);
22939 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
22940 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
22943 if (type == bool_char_type_node) return "U6__boolc";
22944 if (type == bool_short_type_node) return "U6__bools";
22945 if (type == pixel_type_node) return "u7__pixel";
22946 if (type == bool_int_type_node) return "U6__booli";
22947 if (type == bool_long_type_node) return "U6__booll";
22949 /* Mangle IBM extended float long double as `g' (__float128) on
22950 powerpc*-linux where long-double-64 previously was the default. */
22951 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
22953 && TARGET_LONG_DOUBLE_128
22954 && !TARGET_IEEEQUAD)
22957 /* For all other types, use normal C++ mangling. */
22961 /* Handle a "longcall" or "shortcall" attribute; arguments as in
22962 struct attribute_spec.handler. */
22965 rs6000_handle_longcall_attribute (tree *node, tree name,
22966 tree args ATTRIBUTE_UNUSED,
22967 int flags ATTRIBUTE_UNUSED,
22968 bool *no_add_attrs)
22970 if (TREE_CODE (*node) != FUNCTION_TYPE
22971 && TREE_CODE (*node) != FIELD_DECL
22972 && TREE_CODE (*node) != TYPE_DECL)
22974 warning (OPT_Wattributes, "%qE attribute only applies to functions",
22976 *no_add_attrs = true;
22982 /* Set longcall attributes on all functions declared when
22983 rs6000_default_long_calls is true. */
22985 rs6000_set_default_type_attributes (tree type)
22987 if (rs6000_default_long_calls
22988 && (TREE_CODE (type) == FUNCTION_TYPE
22989 || TREE_CODE (type) == METHOD_TYPE))
22990 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
22992 TYPE_ATTRIBUTES (type));
22995 darwin_set_default_type_attributes (type);
22999 /* Return a reference suitable for calling a function with the
23000 longcall attribute. */
23003 rs6000_longcall_ref (rtx call_ref)
23005 const char *call_name;
23008 if (GET_CODE (call_ref) != SYMBOL_REF)
23011 /* System V adds '.' to the internal name, so skip them. */
23012 call_name = XSTR (call_ref, 0);
23013 if (*call_name == '.')
23015 while (*call_name == '.')
23018 node = get_identifier (call_name);
23019 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
23022 return force_reg (Pmode, call_ref);
23025 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23026 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23029 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23030 struct attribute_spec.handler. */
23032 rs6000_handle_struct_attribute (tree *node, tree name,
23033 tree args ATTRIBUTE_UNUSED,
23034 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
23037 if (DECL_P (*node))
23039 if (TREE_CODE (*node) == TYPE_DECL)
23040 type = &TREE_TYPE (*node);
23045 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
23046 || TREE_CODE (*type) == UNION_TYPE)))
23048 warning (OPT_Wattributes, "%qE attribute ignored", name);
23049 *no_add_attrs = true;
23052 else if ((is_attribute_p ("ms_struct", name)
23053 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
23054 || ((is_attribute_p ("gcc_struct", name)
23055 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
23057 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
23059 *no_add_attrs = true;
23066 rs6000_ms_bitfield_layout_p (const_tree record_type)
23068 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
23069 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
23070 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
23073 #ifdef USING_ELFOS_H
23075 /* A get_unnamed_section callback, used for switching to toc_section. */
23078 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23080 if (DEFAULT_ABI == ABI_AIX
23081 && TARGET_MINIMAL_TOC
23082 && !TARGET_RELOCATABLE)
23084 if (!toc_initialized)
23086 toc_initialized = 1;
23087 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23088 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
23089 fprintf (asm_out_file, "\t.tc ");
23090 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
23091 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23092 fprintf (asm_out_file, "\n");
23094 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23095 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23096 fprintf (asm_out_file, " = .+32768\n");
23099 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23101 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
23102 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23105 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23106 if (!toc_initialized)
23108 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23109 fprintf (asm_out_file, " = .+32768\n");
23110 toc_initialized = 1;
23115 /* Implement TARGET_ASM_INIT_SECTIONS. */
23118 rs6000_elf_asm_init_sections (void)
23121 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
23124 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
23125 SDATA2_SECTION_ASM_OP);
23128 /* Implement TARGET_SELECT_RTX_SECTION. */
23131 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
23132 unsigned HOST_WIDE_INT align)
23134 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23135 return toc_section;
23137 return default_elf_select_rtx_section (mode, x, align);
23140 /* For a SYMBOL_REF, set generic flags and then perform some
23141 target-specific processing.
23143 When the AIX ABI is requested on a non-AIX system, replace the
23144 function name with the real name (with a leading .) rather than the
23145 function descriptor name. This saves a lot of overriding code to
23146 read the prefixes. */
23149 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
23151 default_encode_section_info (decl, rtl, first);
23154 && TREE_CODE (decl) == FUNCTION_DECL
23156 && DEFAULT_ABI == ABI_AIX)
23158 rtx sym_ref = XEXP (rtl, 0);
23159 size_t len = strlen (XSTR (sym_ref, 0));
23160 char *str = XALLOCAVEC (char, len + 2);
23162 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
23163 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
23168 compare_section_name (const char *section, const char *templ)
23172 len = strlen (templ);
23173 return (strncmp (section, templ, len) == 0
23174 && (section[len] == 0 || section[len] == '.'));
23178 rs6000_elf_in_small_data_p (const_tree decl)
23180 if (rs6000_sdata == SDATA_NONE)
23183 /* We want to merge strings, so we never consider them small data. */
23184 if (TREE_CODE (decl) == STRING_CST)
23187 /* Functions are never in the small data area. */
23188 if (TREE_CODE (decl) == FUNCTION_DECL)
23191 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
23193 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
23194 if (compare_section_name (section, ".sdata")
23195 || compare_section_name (section, ".sdata2")
23196 || compare_section_name (section, ".gnu.linkonce.s")
23197 || compare_section_name (section, ".sbss")
23198 || compare_section_name (section, ".sbss2")
23199 || compare_section_name (section, ".gnu.linkonce.sb")
23200 || strcmp (section, ".PPC.EMB.sdata0") == 0
23201 || strcmp (section, ".PPC.EMB.sbss0") == 0)
23206 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
23209 && (unsigned HOST_WIDE_INT) size <= g_switch_value
23210 /* If it's not public, and we're not going to reference it there,
23211 there's no need to put it in the small data section. */
23212 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
23219 #endif /* USING_ELFOS_H */
23221 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
23224 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
23226 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
23229 /* Return a REG that occurs in ADDR with coefficient 1.
23230 ADDR can be effectively incremented by incrementing REG.
23232 r0 is special and we must not select it as an address
23233 register by this routine since our caller will try to
23234 increment the returned register via an "la" instruction. */
23237 find_addr_reg (rtx addr)
23239 while (GET_CODE (addr) == PLUS)
23241 if (GET_CODE (XEXP (addr, 0)) == REG
23242 && REGNO (XEXP (addr, 0)) != 0)
23243 addr = XEXP (addr, 0);
23244 else if (GET_CODE (XEXP (addr, 1)) == REG
23245 && REGNO (XEXP (addr, 1)) != 0)
23246 addr = XEXP (addr, 1);
23247 else if (CONSTANT_P (XEXP (addr, 0)))
23248 addr = XEXP (addr, 1);
23249 else if (CONSTANT_P (XEXP (addr, 1)))
23250 addr = XEXP (addr, 0);
23252 gcc_unreachable ();
23254 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
23259 rs6000_fatal_bad_address (rtx op)
23261 fatal_insn ("bad address", op);
23266 static tree branch_island_list = 0;
23268 /* Remember to generate a branch island for far calls to the given
23272 add_compiler_branch_island (tree label_name, tree function_name,
23275 tree branch_island = build_tree_list (function_name, label_name);
23276 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
23277 TREE_CHAIN (branch_island) = branch_island_list;
23278 branch_island_list = branch_island;
23281 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
23282 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
23283 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
23284 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
23286 /* Generate far-jump branch islands for everything on the
23287 branch_island_list. Invoked immediately after the last instruction
23288 of the epilogue has been emitted; the branch-islands must be
23289 appended to, and contiguous with, the function body. Mach-O stubs
23290 are generated in machopic_output_stub(). */
23293 macho_branch_islands (void)
23296 tree branch_island;
23298 for (branch_island = branch_island_list;
23300 branch_island = TREE_CHAIN (branch_island))
23302 const char *label =
23303 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
23305 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
23306 char name_buf[512];
23307 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
23308 if (name[0] == '*' || name[0] == '&')
23309 strcpy (name_buf, name+1);
23313 strcpy (name_buf+1, name);
23315 strcpy (tmp_buf, "\n");
23316 strcat (tmp_buf, label);
23317 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23318 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23319 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23320 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23323 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
23324 strcat (tmp_buf, label);
23325 strcat (tmp_buf, "_pic\n");
23326 strcat (tmp_buf, label);
23327 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
23329 strcat (tmp_buf, "\taddis r11,r11,ha16(");
23330 strcat (tmp_buf, name_buf);
23331 strcat (tmp_buf, " - ");
23332 strcat (tmp_buf, label);
23333 strcat (tmp_buf, "_pic)\n");
23335 strcat (tmp_buf, "\tmtlr r0\n");
23337 strcat (tmp_buf, "\taddi r12,r11,lo16(");
23338 strcat (tmp_buf, name_buf);
23339 strcat (tmp_buf, " - ");
23340 strcat (tmp_buf, label);
23341 strcat (tmp_buf, "_pic)\n");
23343 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
23347 strcat (tmp_buf, ":\nlis r12,hi16(");
23348 strcat (tmp_buf, name_buf);
23349 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
23350 strcat (tmp_buf, name_buf);
23351 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
23353 output_asm_insn (tmp_buf, 0);
23354 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23355 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23356 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23357 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23360 branch_island_list = 0;
23363 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
23364 already there or not. */
23367 no_previous_def (tree function_name)
23369 tree branch_island;
23370 for (branch_island = branch_island_list;
23372 branch_island = TREE_CHAIN (branch_island))
23373 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23378 /* GET_PREV_LABEL gets the label name from the previous definition of
23382 get_prev_label (tree function_name)
23384 tree branch_island;
23385 for (branch_island = branch_island_list;
23387 branch_island = TREE_CHAIN (branch_island))
23388 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23389 return BRANCH_ISLAND_LABEL_NAME (branch_island);
23393 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
23394 #define DARWIN_LINKER_GENERATES_ISLANDS 0
23397 /* KEXTs still need branch islands. */
23398 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
23399 || flag_mkernel || flag_apple_kext)
23401 /* INSN is either a function call or a millicode call. It may have an
23402 unconditional jump in its delay slot.
23404 CALL_DEST is the routine we are calling. */
23407 output_call (rtx insn, rtx *operands, int dest_operand_number,
23408 int cookie_operand_number)
23410 static char buf[256];
23411 if (DARWIN_GENERATE_ISLANDS
23412 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
23413 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
23416 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
23418 if (no_previous_def (funname))
23420 rtx label_rtx = gen_label_rtx ();
23421 char *label_buf, temp_buf[256];
23422 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
23423 CODE_LABEL_NUMBER (label_rtx));
23424 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
23425 labelname = get_identifier (label_buf);
23426 add_compiler_branch_island (labelname, funname, insn_line (insn));
23429 labelname = get_prev_label (funname);
23431 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
23432 instruction will reach 'foo', otherwise link as 'bl L42'".
23433 "L42" should be a 'branch island', that will do a far jump to
23434 'foo'. Branch islands are generated in
23435 macho_branch_islands(). */
23436 sprintf (buf, "jbsr %%z%d,%.246s",
23437 dest_operand_number, IDENTIFIER_POINTER (labelname));
23440 sprintf (buf, "bl %%z%d", dest_operand_number);
23444 /* Generate PIC and indirect symbol stubs. */
23447 machopic_output_stub (FILE *file, const char *symb, const char *stub)
23449 unsigned int length;
23450 char *symbol_name, *lazy_ptr_name;
23451 char *local_label_0;
23452 static int label = 0;
23454 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
23455 symb = (*targetm.strip_name_encoding) (symb);
23458 length = strlen (symb);
23459 symbol_name = XALLOCAVEC (char, length + 32);
23460 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
23462 lazy_ptr_name = XALLOCAVEC (char, length + 32);
23463 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
23466 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
23468 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
23472 fprintf (file, "\t.align 5\n");
23474 fprintf (file, "%s:\n", stub);
23475 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23478 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
23479 sprintf (local_label_0, "\"L%011d$spb\"", label);
23481 fprintf (file, "\tmflr r0\n");
23482 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
23483 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
23484 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
23485 lazy_ptr_name, local_label_0);
23486 fprintf (file, "\tmtlr r0\n");
23487 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
23488 (TARGET_64BIT ? "ldu" : "lwzu"),
23489 lazy_ptr_name, local_label_0);
23490 fprintf (file, "\tmtctr r12\n");
23491 fprintf (file, "\tbctr\n");
23495 fprintf (file, "\t.align 4\n");
23497 fprintf (file, "%s:\n", stub);
23498 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23500 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
23501 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
23502 (TARGET_64BIT ? "ldu" : "lwzu"),
23504 fprintf (file, "\tmtctr r12\n");
23505 fprintf (file, "\tbctr\n");
23508 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
23509 fprintf (file, "%s:\n", lazy_ptr_name);
23510 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23511 fprintf (file, "%sdyld_stub_binding_helper\n",
23512 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
23515 /* Legitimize PIC addresses. If the address is already
23516 position-independent, we return ORIG. Newly generated
23517 position-independent addresses go into a reg. This is REG if non
23518 zero, otherwise we allocate register(s) as necessary. */
23520 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
23523 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
23528 if (reg == NULL && ! reload_in_progress && ! reload_completed)
23529 reg = gen_reg_rtx (Pmode);
23531 if (GET_CODE (orig) == CONST)
23535 if (GET_CODE (XEXP (orig, 0)) == PLUS
23536 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
23539 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
23541 /* Use a different reg for the intermediate value, as
23542 it will be marked UNCHANGING. */
23543 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
23544 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
23547 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
23550 if (GET_CODE (offset) == CONST_INT)
23552 if (SMALL_INT (offset))
23553 return plus_constant (base, INTVAL (offset));
23554 else if (! reload_in_progress && ! reload_completed)
23555 offset = force_reg (Pmode, offset);
23558 rtx mem = force_const_mem (Pmode, orig);
23559 return machopic_legitimize_pic_address (mem, Pmode, reg);
23562 return gen_rtx_PLUS (Pmode, base, offset);
23565 /* Fall back on generic machopic code. */
23566 return machopic_legitimize_pic_address (orig, mode, reg);
23569 /* Output a .machine directive for the Darwin assembler, and call
23570 the generic start_file routine. */
23573 rs6000_darwin_file_start (void)
23575 static const struct
23581 { "ppc64", "ppc64", MASK_64BIT },
23582 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
23583 { "power4", "ppc970", 0 },
23584 { "G5", "ppc970", 0 },
23585 { "7450", "ppc7450", 0 },
23586 { "7400", "ppc7400", MASK_ALTIVEC },
23587 { "G4", "ppc7400", 0 },
23588 { "750", "ppc750", 0 },
23589 { "740", "ppc750", 0 },
23590 { "G3", "ppc750", 0 },
23591 { "604e", "ppc604e", 0 },
23592 { "604", "ppc604", 0 },
23593 { "603e", "ppc603", 0 },
23594 { "603", "ppc603", 0 },
23595 { "601", "ppc601", 0 },
23596 { NULL, "ppc", 0 } };
23597 const char *cpu_id = "";
23600 rs6000_file_start ();
23601 darwin_file_start ();
23603 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
23604 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
23605 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
23606 && rs6000_select[i].string[0] != '\0')
23607 cpu_id = rs6000_select[i].string;
23609 /* Look through the mapping array. Pick the first name that either
23610 matches the argument, has a bit set in IF_SET that is also set
23611 in the target flags, or has a NULL name. */
23614 while (mapping[i].arg != NULL
23615 && strcmp (mapping[i].arg, cpu_id) != 0
23616 && (mapping[i].if_set & target_flags) == 0)
23619 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
23622 #endif /* TARGET_MACHO */
23626 rs6000_elf_reloc_rw_mask (void)
23630 else if (DEFAULT_ABI == ABI_AIX)
23636 /* Record an element in the table of global constructors. SYMBOL is
23637 a SYMBOL_REF of the function to be called; PRIORITY is a number
23638 between 0 and MAX_INIT_PRIORITY.
23640 This differs from default_named_section_asm_out_constructor in
23641 that we have special handling for -mrelocatable. */
23644 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
23646 const char *section = ".ctors";
23649 if (priority != DEFAULT_INIT_PRIORITY)
23651 sprintf (buf, ".ctors.%.5u",
23652 /* Invert the numbering so the linker puts us in the proper
23653 order; constructors are run from right to left, and the
23654 linker sorts in increasing order. */
23655 MAX_INIT_PRIORITY - priority);
23659 switch_to_section (get_section (section, SECTION_WRITE, NULL));
23660 assemble_align (POINTER_SIZE);
23662 if (TARGET_RELOCATABLE)
23664 fputs ("\t.long (", asm_out_file);
23665 output_addr_const (asm_out_file, symbol);
23666 fputs (")@fixup\n", asm_out_file);
23669 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
23673 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
23675 const char *section = ".dtors";
23678 if (priority != DEFAULT_INIT_PRIORITY)
23680 sprintf (buf, ".dtors.%.5u",
23681 /* Invert the numbering so the linker puts us in the proper
23682 order; constructors are run from right to left, and the
23683 linker sorts in increasing order. */
23684 MAX_INIT_PRIORITY - priority);
23688 switch_to_section (get_section (section, SECTION_WRITE, NULL));
23689 assemble_align (POINTER_SIZE);
23691 if (TARGET_RELOCATABLE)
23693 fputs ("\t.long (", asm_out_file);
23694 output_addr_const (asm_out_file, symbol);
23695 fputs (")@fixup\n", asm_out_file);
23698 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
23702 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
23706 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
23707 ASM_OUTPUT_LABEL (file, name);
23708 fputs (DOUBLE_INT_ASM_OP, file);
23709 rs6000_output_function_entry (file, name);
23710 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
23713 fputs ("\t.size\t", file);
23714 assemble_name (file, name);
23715 fputs (",24\n\t.type\t.", file);
23716 assemble_name (file, name);
23717 fputs (",@function\n", file);
23718 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
23720 fputs ("\t.globl\t.", file);
23721 assemble_name (file, name);
23726 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
23727 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
23728 rs6000_output_function_entry (file, name);
23729 fputs (":\n", file);
23733 if (TARGET_RELOCATABLE
23734 && !TARGET_SECURE_PLT
23735 && (get_pool_size () != 0 || crtl->profile)
23740 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
23742 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
23743 fprintf (file, "\t.long ");
23744 assemble_name (file, buf);
23746 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
23747 assemble_name (file, buf);
23751 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
23752 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
23754 if (DEFAULT_ABI == ABI_AIX)
23756 const char *desc_name, *orig_name;
23758 orig_name = (*targetm.strip_name_encoding) (name);
23759 desc_name = orig_name;
23760 while (*desc_name == '.')
23763 if (TREE_PUBLIC (decl))
23764 fprintf (file, "\t.globl %s\n", desc_name);
23766 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23767 fprintf (file, "%s:\n", desc_name);
23768 fprintf (file, "\t.long %s\n", orig_name);
23769 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
23770 if (DEFAULT_ABI == ABI_AIX)
23771 fputs ("\t.long 0\n", file);
23772 fprintf (file, "\t.previous\n");
23774 ASM_OUTPUT_LABEL (file, name);
23778 rs6000_elf_end_indicate_exec_stack (void)
23781 file_end_indicate_exec_stack ();
23787 rs6000_xcoff_asm_output_anchor (rtx symbol)
23791 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
23792 SYMBOL_REF_BLOCK_OFFSET (symbol));
23793 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
23797 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
23799 fputs (GLOBAL_ASM_OP, stream);
23800 RS6000_OUTPUT_BASENAME (stream, name);
23801 putc ('\n', stream);
23804 /* A get_unnamed_decl callback, used for read-only sections. PTR
23805 points to the section string variable. */
23808 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
23810 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
23811 *(const char *const *) directive,
23812 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
23815 /* Likewise for read-write sections. */
23818 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
23820 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
23821 *(const char *const *) directive,
23822 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
23825 /* A get_unnamed_section callback, used for switching to toc_section. */
23828 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23830 if (TARGET_MINIMAL_TOC)
23832 /* toc_section is always selected at least once from
23833 rs6000_xcoff_file_start, so this is guaranteed to
23834 always be defined once and only once in each file. */
23835 if (!toc_initialized)
23837 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
23838 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
23839 toc_initialized = 1;
23841 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
23842 (TARGET_32BIT ? "" : ",3"));
23845 fputs ("\t.toc\n", asm_out_file);
23848 /* Implement TARGET_ASM_INIT_SECTIONS. */
23851 rs6000_xcoff_asm_init_sections (void)
23853 read_only_data_section
23854 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
23855 &xcoff_read_only_section_name);
23857 private_data_section
23858 = get_unnamed_section (SECTION_WRITE,
23859 rs6000_xcoff_output_readwrite_section_asm_op,
23860 &xcoff_private_data_section_name);
23862 read_only_private_data_section
23863 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
23864 &xcoff_private_data_section_name);
23867 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
23869 readonly_data_section = read_only_data_section;
23870 exception_section = data_section;
23874 rs6000_xcoff_reloc_rw_mask (void)
23880 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
23881 tree decl ATTRIBUTE_UNUSED)
23884 static const char * const suffix[3] = { "PR", "RO", "RW" };
23886 if (flags & SECTION_CODE)
23888 else if (flags & SECTION_WRITE)
23893 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
23894 (flags & SECTION_CODE) ? "." : "",
23895 name, suffix[smclass], flags & SECTION_ENTSIZE);
23899 rs6000_xcoff_select_section (tree decl, int reloc,
23900 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
23902 if (decl_readonly_section (decl, reloc))
23904 if (TREE_PUBLIC (decl))
23905 return read_only_data_section;
23907 return read_only_private_data_section;
23911 if (TREE_PUBLIC (decl))
23912 return data_section;
23914 return private_data_section;
23919 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
23923 /* Use select_section for private and uninitialized data. */
23924 if (!TREE_PUBLIC (decl)
23925 || DECL_COMMON (decl)
23926 || DECL_INITIAL (decl) == NULL_TREE
23927 || DECL_INITIAL (decl) == error_mark_node
23928 || (flag_zero_initialized_in_bss
23929 && initializer_zerop (DECL_INITIAL (decl))))
23932 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
23933 name = (*targetm.strip_name_encoding) (name);
23934 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
23937 /* Select section for constant in constant pool.
23939 On RS/6000, all constants are in the private read-only data area.
23940 However, if this is being placed in the TOC it must be output as a
23944 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
23945 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
23947 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23948 return toc_section;
23950 return read_only_private_data_section;
23953 /* Remove any trailing [DS] or the like from the symbol name. */
23955 static const char *
23956 rs6000_xcoff_strip_name_encoding (const char *name)
23961 len = strlen (name);
23962 if (name[len - 1] == ']')
23963 return ggc_alloc_string (name, len - 4);
23968 /* Section attributes. AIX is always PIC. */
23970 static unsigned int
23971 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
23973 unsigned int align;
23974 unsigned int flags = default_section_type_flags (decl, name, reloc);
23976 /* Align to at least UNIT size. */
23977 if (flags & SECTION_CODE)
23978 align = MIN_UNITS_PER_WORD;
23980 /* Increase alignment of large objects if not already stricter. */
23981 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
23982 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
23983 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
23985 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
23988 /* Output at beginning of assembler file.
23990 Initialize the section names for the RS/6000 at this point.
23992 Specify filename, including full path, to assembler.
23994 We want to go into the TOC section so at least one .toc will be emitted.
23995 Also, in order to output proper .bs/.es pairs, we need at least one static
23996 [RW] section emitted.
23998 Finally, declare mcount when profiling to make the assembler happy. */
24001 rs6000_xcoff_file_start (void)
24003 rs6000_gen_section_name (&xcoff_bss_section_name,
24004 main_input_filename, ".bss_");
24005 rs6000_gen_section_name (&xcoff_private_data_section_name,
24006 main_input_filename, ".rw_");
24007 rs6000_gen_section_name (&xcoff_read_only_section_name,
24008 main_input_filename, ".ro_");
24010 fputs ("\t.file\t", asm_out_file);
24011 output_quoted_string (asm_out_file, main_input_filename);
24012 fputc ('\n', asm_out_file);
24013 if (write_symbols != NO_DEBUG)
24014 switch_to_section (private_data_section);
24015 switch_to_section (text_section);
24017 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
24018 rs6000_file_start ();
24021 /* Output at end of assembler file.
24022 On the RS/6000, referencing data should automatically pull in text. */
24025 rs6000_xcoff_file_end (void)
24027 switch_to_section (text_section);
24028 fputs ("_section_.text:\n", asm_out_file);
24029 switch_to_section (data_section);
24030 fputs (TARGET_32BIT
24031 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24034 #endif /* TARGET_XCOFF */
24036 /* Compute a (partial) cost for rtx X. Return true if the complete
24037 cost has been computed, and false if subexpressions should be
24038 scanned. In either case, *TOTAL contains the cost result. */
24041 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
24044 enum machine_mode mode = GET_MODE (x);
24048 /* On the RS/6000, if it is valid in the insn, it is free. */
24050 if (((outer_code == SET
24051 || outer_code == PLUS
24052 || outer_code == MINUS)
24053 && (satisfies_constraint_I (x)
24054 || satisfies_constraint_L (x)))
24055 || (outer_code == AND
24056 && (satisfies_constraint_K (x)
24058 ? satisfies_constraint_L (x)
24059 : satisfies_constraint_J (x))
24060 || mask_operand (x, mode)
24062 && mask64_operand (x, DImode))))
24063 || ((outer_code == IOR || outer_code == XOR)
24064 && (satisfies_constraint_K (x)
24066 ? satisfies_constraint_L (x)
24067 : satisfies_constraint_J (x))))
24068 || outer_code == ASHIFT
24069 || outer_code == ASHIFTRT
24070 || outer_code == LSHIFTRT
24071 || outer_code == ROTATE
24072 || outer_code == ROTATERT
24073 || outer_code == ZERO_EXTRACT
24074 || (outer_code == MULT
24075 && satisfies_constraint_I (x))
24076 || ((outer_code == DIV || outer_code == UDIV
24077 || outer_code == MOD || outer_code == UMOD)
24078 && exact_log2 (INTVAL (x)) >= 0)
24079 || (outer_code == COMPARE
24080 && (satisfies_constraint_I (x)
24081 || satisfies_constraint_K (x)))
24082 || (outer_code == EQ
24083 && (satisfies_constraint_I (x)
24084 || satisfies_constraint_K (x)
24086 ? satisfies_constraint_L (x)
24087 : satisfies_constraint_J (x))))
24088 || (outer_code == GTU
24089 && satisfies_constraint_I (x))
24090 || (outer_code == LTU
24091 && satisfies_constraint_P (x)))
24096 else if ((outer_code == PLUS
24097 && reg_or_add_cint_operand (x, VOIDmode))
24098 || (outer_code == MINUS
24099 && reg_or_sub_cint_operand (x, VOIDmode))
24100 || ((outer_code == SET
24101 || outer_code == IOR
24102 || outer_code == XOR)
24104 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
24106 *total = COSTS_N_INSNS (1);
24112 if (mode == DImode && code == CONST_DOUBLE)
24114 if ((outer_code == IOR || outer_code == XOR)
24115 && CONST_DOUBLE_HIGH (x) == 0
24116 && (CONST_DOUBLE_LOW (x)
24117 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
24122 else if ((outer_code == AND && and64_2_operand (x, DImode))
24123 || ((outer_code == SET
24124 || outer_code == IOR
24125 || outer_code == XOR)
24126 && CONST_DOUBLE_HIGH (x) == 0))
24128 *total = COSTS_N_INSNS (1);
24138 /* When optimizing for size, MEM should be slightly more expensive
24139 than generating address, e.g., (plus (reg) (const)).
24140 L1 cache latency is about two instructions. */
24141 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
24149 if (mode == DFmode)
24151 if (GET_CODE (XEXP (x, 0)) == MULT)
24153 /* FNMA accounted in outer NEG. */
24154 if (outer_code == NEG)
24155 *total = rs6000_cost->dmul - rs6000_cost->fp;
24157 *total = rs6000_cost->dmul;
24160 *total = rs6000_cost->fp;
24162 else if (mode == SFmode)
24164 /* FNMA accounted in outer NEG. */
24165 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24168 *total = rs6000_cost->fp;
24171 *total = COSTS_N_INSNS (1);
24175 if (mode == DFmode)
24177 if (GET_CODE (XEXP (x, 0)) == MULT
24178 || GET_CODE (XEXP (x, 1)) == MULT)
24180 /* FNMA accounted in outer NEG. */
24181 if (outer_code == NEG)
24182 *total = rs6000_cost->dmul - rs6000_cost->fp;
24184 *total = rs6000_cost->dmul;
24187 *total = rs6000_cost->fp;
24189 else if (mode == SFmode)
24191 /* FNMA accounted in outer NEG. */
24192 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24195 *total = rs6000_cost->fp;
24198 *total = COSTS_N_INSNS (1);
24202 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24203 && satisfies_constraint_I (XEXP (x, 1)))
24205 if (INTVAL (XEXP (x, 1)) >= -256
24206 && INTVAL (XEXP (x, 1)) <= 255)
24207 *total = rs6000_cost->mulsi_const9;
24209 *total = rs6000_cost->mulsi_const;
24211 /* FMA accounted in outer PLUS/MINUS. */
24212 else if ((mode == DFmode || mode == SFmode)
24213 && (outer_code == PLUS || outer_code == MINUS))
24215 else if (mode == DFmode)
24216 *total = rs6000_cost->dmul;
24217 else if (mode == SFmode)
24218 *total = rs6000_cost->fp;
24219 else if (mode == DImode)
24220 *total = rs6000_cost->muldi;
24222 *total = rs6000_cost->mulsi;
24227 if (FLOAT_MODE_P (mode))
24229 *total = mode == DFmode ? rs6000_cost->ddiv
24230 : rs6000_cost->sdiv;
24237 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24238 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
24240 if (code == DIV || code == MOD)
24242 *total = COSTS_N_INSNS (2);
24245 *total = COSTS_N_INSNS (1);
24249 if (GET_MODE (XEXP (x, 1)) == DImode)
24250 *total = rs6000_cost->divdi;
24252 *total = rs6000_cost->divsi;
24254 /* Add in shift and subtract for MOD. */
24255 if (code == MOD || code == UMOD)
24256 *total += COSTS_N_INSNS (2);
24261 *total = COSTS_N_INSNS (4);
24265 *total = COSTS_N_INSNS (6);
24269 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
24281 *total = COSTS_N_INSNS (1);
24289 /* Handle mul_highpart. */
24290 if (outer_code == TRUNCATE
24291 && GET_CODE (XEXP (x, 0)) == MULT)
24293 if (mode == DImode)
24294 *total = rs6000_cost->muldi;
24296 *total = rs6000_cost->mulsi;
24299 else if (outer_code == AND)
24302 *total = COSTS_N_INSNS (1);
24307 if (GET_CODE (XEXP (x, 0)) == MEM)
24310 *total = COSTS_N_INSNS (1);
24316 if (!FLOAT_MODE_P (mode))
24318 *total = COSTS_N_INSNS (1);
24324 case UNSIGNED_FLOAT:
24327 case FLOAT_TRUNCATE:
24328 *total = rs6000_cost->fp;
24332 if (mode == DFmode)
24335 *total = rs6000_cost->fp;
24339 switch (XINT (x, 1))
24342 *total = rs6000_cost->fp;
24354 *total = COSTS_N_INSNS (1);
24357 else if (FLOAT_MODE_P (mode)
24358 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
24360 *total = rs6000_cost->fp;
24368 /* Carry bit requires mode == Pmode.
24369 NEG or PLUS already counted so only add one. */
24371 && (outer_code == NEG || outer_code == PLUS))
24373 *total = COSTS_N_INSNS (1);
24376 if (outer_code == SET)
24378 if (XEXP (x, 1) == const0_rtx)
24380 *total = COSTS_N_INSNS (2);
24383 else if (mode == Pmode)
24385 *total = COSTS_N_INSNS (3);
24394 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
24396 *total = COSTS_N_INSNS (2);
24400 if (outer_code == COMPARE)
24414 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
24417 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
24420 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
24423 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
24424 "total = %d, speed = %s, x:\n",
24425 ret ? "complete" : "scan inner",
24426 GET_RTX_NAME (code),
24427 GET_RTX_NAME (outer_code),
24429 speed ? "true" : "false");
24436 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
24439 rs6000_debug_address_cost (rtx x, bool speed)
24441 int ret = TARGET_ADDRESS_COST (x, speed);
24443 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
24444 ret, speed ? "true" : "false");
24451 /* A C expression returning the cost of moving data from a register of class
24452 CLASS1 to one of CLASS2. */
24455 rs6000_register_move_cost (enum machine_mode mode,
24456 enum reg_class from, enum reg_class to)
24460 /* Moves from/to GENERAL_REGS. */
24461 if (reg_classes_intersect_p (to, GENERAL_REGS)
24462 || reg_classes_intersect_p (from, GENERAL_REGS))
24464 if (! reg_classes_intersect_p (to, GENERAL_REGS))
24467 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
24468 ret = (rs6000_memory_move_cost (mode, from, 0)
24469 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
24471 /* It's more expensive to move CR_REGS than CR0_REGS because of the
24473 else if (from == CR_REGS)
24476 /* Power6 has slower LR/CTR moves so make them more expensive than
24477 memory in order to bias spills to memory .*/
24478 else if (rs6000_cpu == PROCESSOR_POWER6
24479 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
24480 ret = 6 * hard_regno_nregs[0][mode];
24483 /* A move will cost one instruction per GPR moved. */
24484 ret = 2 * hard_regno_nregs[0][mode];
24487 /* If we have VSX, we can easily move between FPR or Altivec registers. */
24488 else if (VECTOR_UNIT_VSX_P (mode)
24489 && reg_classes_intersect_p (to, VSX_REGS)
24490 && reg_classes_intersect_p (from, VSX_REGS))
24491 ret = 2 * hard_regno_nregs[32][mode];
24493 /* Moving between two similar registers is just one instruction. */
24494 else if (reg_classes_intersect_p (to, from))
24495 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
24497 /* Everything else has to go through GENERAL_REGS. */
24499 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
24500 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
24502 if (TARGET_DEBUG_COST)
24504 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
24505 ret, GET_MODE_NAME (mode), reg_class_names[from],
24506 reg_class_names[to]);
24511 /* A C expressions returning the cost of moving data of MODE from a register to
24515 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
24516 int in ATTRIBUTE_UNUSED)
24520 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
24521 ret = 4 * hard_regno_nregs[0][mode];
24522 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
24523 ret = 4 * hard_regno_nregs[32][mode];
24524 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
24525 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
24527 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
24529 if (TARGET_DEBUG_COST)
24531 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
24532 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
24537 /* Returns a code for a target-specific builtin that implements
24538 reciprocal of the function, or NULL_TREE if not available. */
24541 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
24542 bool sqrt ATTRIBUTE_UNUSED)
24544 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
24545 && flag_finite_math_only && !flag_trapping_math
24546 && flag_unsafe_math_optimizations))
24554 case BUILT_IN_SQRTF:
24555 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
24562 /* Newton-Raphson approximation of single-precision floating point divide n/d.
24563 Assumes no trapping math and finite arguments. */
24566 rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
24568 rtx x0, e0, e1, y1, u0, v0, one;
24570 x0 = gen_reg_rtx (SFmode);
24571 e0 = gen_reg_rtx (SFmode);
24572 e1 = gen_reg_rtx (SFmode);
24573 y1 = gen_reg_rtx (SFmode);
24574 u0 = gen_reg_rtx (SFmode);
24575 v0 = gen_reg_rtx (SFmode);
24576 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
24578 /* x0 = 1./d estimate */
24579 emit_insn (gen_rtx_SET (VOIDmode, x0,
24580 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
24582 /* e0 = 1. - d * x0 */
24583 emit_insn (gen_rtx_SET (VOIDmode, e0,
24584 gen_rtx_MINUS (SFmode, one,
24585 gen_rtx_MULT (SFmode, d, x0))));
24586 /* e1 = e0 + e0 * e0 */
24587 emit_insn (gen_rtx_SET (VOIDmode, e1,
24588 gen_rtx_PLUS (SFmode,
24589 gen_rtx_MULT (SFmode, e0, e0), e0)));
24590 /* y1 = x0 + e1 * x0 */
24591 emit_insn (gen_rtx_SET (VOIDmode, y1,
24592 gen_rtx_PLUS (SFmode,
24593 gen_rtx_MULT (SFmode, e1, x0), x0)));
24595 emit_insn (gen_rtx_SET (VOIDmode, u0,
24596 gen_rtx_MULT (SFmode, n, y1)));
24597 /* v0 = n - d * u0 */
24598 emit_insn (gen_rtx_SET (VOIDmode, v0,
24599 gen_rtx_MINUS (SFmode, n,
24600 gen_rtx_MULT (SFmode, d, u0))));
24601 /* dst = u0 + v0 * y1 */
24602 emit_insn (gen_rtx_SET (VOIDmode, dst,
24603 gen_rtx_PLUS (SFmode,
24604 gen_rtx_MULT (SFmode, v0, y1), u0)));
24607 /* Newton-Raphson approximation of double-precision floating point divide n/d.
24608 Assumes no trapping math and finite arguments. */
24611 rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
24613 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
24615 x0 = gen_reg_rtx (DFmode);
24616 e0 = gen_reg_rtx (DFmode);
24617 e1 = gen_reg_rtx (DFmode);
24618 e2 = gen_reg_rtx (DFmode);
24619 y1 = gen_reg_rtx (DFmode);
24620 y2 = gen_reg_rtx (DFmode);
24621 y3 = gen_reg_rtx (DFmode);
24622 u0 = gen_reg_rtx (DFmode);
24623 v0 = gen_reg_rtx (DFmode);
24624 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
24626 /* x0 = 1./d estimate */
24627 emit_insn (gen_rtx_SET (VOIDmode, x0,
24628 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
24630 /* e0 = 1. - d * x0 */
24631 emit_insn (gen_rtx_SET (VOIDmode, e0,
24632 gen_rtx_MINUS (DFmode, one,
24633 gen_rtx_MULT (SFmode, d, x0))));
24634 /* y1 = x0 + e0 * x0 */
24635 emit_insn (gen_rtx_SET (VOIDmode, y1,
24636 gen_rtx_PLUS (DFmode,
24637 gen_rtx_MULT (DFmode, e0, x0), x0)));
24639 emit_insn (gen_rtx_SET (VOIDmode, e1,
24640 gen_rtx_MULT (DFmode, e0, e0)));
24641 /* y2 = y1 + e1 * y1 */
24642 emit_insn (gen_rtx_SET (VOIDmode, y2,
24643 gen_rtx_PLUS (DFmode,
24644 gen_rtx_MULT (DFmode, e1, y1), y1)));
24646 emit_insn (gen_rtx_SET (VOIDmode, e2,
24647 gen_rtx_MULT (DFmode, e1, e1)));
24648 /* y3 = y2 + e2 * y2 */
24649 emit_insn (gen_rtx_SET (VOIDmode, y3,
24650 gen_rtx_PLUS (DFmode,
24651 gen_rtx_MULT (DFmode, e2, y2), y2)));
24653 emit_insn (gen_rtx_SET (VOIDmode, u0,
24654 gen_rtx_MULT (DFmode, n, y3)));
24655 /* v0 = n - d * u0 */
24656 emit_insn (gen_rtx_SET (VOIDmode, v0,
24657 gen_rtx_MINUS (DFmode, n,
24658 gen_rtx_MULT (DFmode, d, u0))));
24659 /* dst = u0 + v0 * y3 */
24660 emit_insn (gen_rtx_SET (VOIDmode, dst,
24661 gen_rtx_PLUS (DFmode,
24662 gen_rtx_MULT (DFmode, v0, y3), u0)));
24666 /* Newton-Raphson approximation of single-precision floating point rsqrt.
24667 Assumes no trapping math and finite arguments. */
24670 rs6000_emit_swrsqrtsf (rtx dst, rtx src)
24672 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
24673 half, one, halfthree, c1, cond, label;
24675 x0 = gen_reg_rtx (SFmode);
24676 x1 = gen_reg_rtx (SFmode);
24677 x2 = gen_reg_rtx (SFmode);
24678 y1 = gen_reg_rtx (SFmode);
24679 u0 = gen_reg_rtx (SFmode);
24680 u1 = gen_reg_rtx (SFmode);
24681 u2 = gen_reg_rtx (SFmode);
24682 v0 = gen_reg_rtx (SFmode);
24683 v1 = gen_reg_rtx (SFmode);
24684 v2 = gen_reg_rtx (SFmode);
24685 t0 = gen_reg_rtx (SFmode);
24686 halfthree = gen_reg_rtx (SFmode);
24687 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
24688 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
24690 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
24691 emit_insn (gen_rtx_SET (VOIDmode, t0,
24692 gen_rtx_MULT (SFmode, src, src)));
24694 emit_insn (gen_rtx_SET (VOIDmode, cond,
24695 gen_rtx_COMPARE (CCFPmode, t0, src)));
24696 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
24697 emit_unlikely_jump (c1, label);
24699 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
24700 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
24702 /* halfthree = 1.5 = 1.0 + 0.5 */
24703 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
24704 gen_rtx_PLUS (SFmode, one, half)));
24706 /* x0 = rsqrt estimate */
24707 emit_insn (gen_rtx_SET (VOIDmode, x0,
24708 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
24711 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
24712 emit_insn (gen_rtx_SET (VOIDmode, y1,
24713 gen_rtx_MINUS (SFmode,
24714 gen_rtx_MULT (SFmode, src, halfthree),
24717 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
24718 emit_insn (gen_rtx_SET (VOIDmode, u0,
24719 gen_rtx_MULT (SFmode, x0, x0)));
24720 emit_insn (gen_rtx_SET (VOIDmode, v0,
24721 gen_rtx_MINUS (SFmode,
24723 gen_rtx_MULT (SFmode, y1, u0))));
24724 emit_insn (gen_rtx_SET (VOIDmode, x1,
24725 gen_rtx_MULT (SFmode, x0, v0)));
24727 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
24728 emit_insn (gen_rtx_SET (VOIDmode, u1,
24729 gen_rtx_MULT (SFmode, x1, x1)));
24730 emit_insn (gen_rtx_SET (VOIDmode, v1,
24731 gen_rtx_MINUS (SFmode,
24733 gen_rtx_MULT (SFmode, y1, u1))));
24734 emit_insn (gen_rtx_SET (VOIDmode, x2,
24735 gen_rtx_MULT (SFmode, x1, v1)));
24737 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
24738 emit_insn (gen_rtx_SET (VOIDmode, u2,
24739 gen_rtx_MULT (SFmode, x2, x2)));
24740 emit_insn (gen_rtx_SET (VOIDmode, v2,
24741 gen_rtx_MINUS (SFmode,
24743 gen_rtx_MULT (SFmode, y1, u2))));
24744 emit_insn (gen_rtx_SET (VOIDmode, dst,
24745 gen_rtx_MULT (SFmode, x2, v2)));
24747 emit_label (XEXP (label, 0));
24750 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
24751 (Power7) targets. DST is the target, and SRC is the argument operand. */
24754 rs6000_emit_popcount (rtx dst, rtx src)
24756 enum machine_mode mode = GET_MODE (dst);
24759 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
24760 if (TARGET_POPCNTD)
24762 if (mode == SImode)
24763 emit_insn (gen_popcntwsi2 (dst, src));
24765 emit_insn (gen_popcntddi2 (dst, src));
24769 tmp1 = gen_reg_rtx (mode);
24771 if (mode == SImode)
24773 emit_insn (gen_popcntbsi2 (tmp1, src));
24774 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
24776 tmp2 = force_reg (SImode, tmp2);
24777 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
24781 emit_insn (gen_popcntbdi2 (tmp1, src));
24782 tmp2 = expand_mult (DImode, tmp1,
24783 GEN_INT ((HOST_WIDE_INT)
24784 0x01010101 << 32 | 0x01010101),
24786 tmp2 = force_reg (DImode, tmp2);
24787 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
24792 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
24793 target, and SRC is the argument operand. */
24796 rs6000_emit_parity (rtx dst, rtx src)
24798 enum machine_mode mode = GET_MODE (dst);
24801 tmp = gen_reg_rtx (mode);
24802 if (mode == SImode)
24804 /* Is mult+shift >= shift+xor+shift+xor? */
24805 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
24807 rtx tmp1, tmp2, tmp3, tmp4;
24809 tmp1 = gen_reg_rtx (SImode);
24810 emit_insn (gen_popcntbsi2 (tmp1, src));
24812 tmp2 = gen_reg_rtx (SImode);
24813 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
24814 tmp3 = gen_reg_rtx (SImode);
24815 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
24817 tmp4 = gen_reg_rtx (SImode);
24818 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
24819 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
24822 rs6000_emit_popcount (tmp, src);
24823 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
24827 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
24828 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
24830 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
24832 tmp1 = gen_reg_rtx (DImode);
24833 emit_insn (gen_popcntbdi2 (tmp1, src));
24835 tmp2 = gen_reg_rtx (DImode);
24836 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
24837 tmp3 = gen_reg_rtx (DImode);
24838 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
24840 tmp4 = gen_reg_rtx (DImode);
24841 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
24842 tmp5 = gen_reg_rtx (DImode);
24843 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
24845 tmp6 = gen_reg_rtx (DImode);
24846 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
24847 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
24850 rs6000_emit_popcount (tmp, src);
24851 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
24855 /* Return an RTX representing where to find the function value of a
24856 function returning MODE. */
24858 rs6000_complex_function_value (enum machine_mode mode)
24860 unsigned int regno;
24862 enum machine_mode inner = GET_MODE_INNER (mode);
24863 unsigned int inner_bytes = GET_MODE_SIZE (inner);
24865 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
24866 regno = FP_ARG_RETURN;
24869 regno = GP_ARG_RETURN;
24871 /* 32-bit is OK since it'll go in r3/r4. */
24872 if (TARGET_32BIT && inner_bytes >= 4)
24873 return gen_rtx_REG (mode, regno);
24876 if (inner_bytes >= 8)
24877 return gen_rtx_REG (mode, regno);
24879 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
24881 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
24882 GEN_INT (inner_bytes));
24883 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
24886 /* Define how to find the value returned by a function.
24887 VALTYPE is the data type of the value (as a tree).
24888 If the precise function being called is known, FUNC is its FUNCTION_DECL;
24889 otherwise, FUNC is 0.
24891 On the SPE, both FPs and vectors are returned in r3.
24893 On RS/6000 an integer value is in r3 and a floating-point value is in
24894 fp1, unless -msoft-float. */
24897 rs6000_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
24899 enum machine_mode mode;
24900 unsigned int regno;
24902 /* Special handling for structs in darwin64. */
24903 if (rs6000_darwin64_abi
24904 && TYPE_MODE (valtype) == BLKmode
24905 && TREE_CODE (valtype) == RECORD_TYPE
24906 && int_size_in_bytes (valtype) > 0)
24908 CUMULATIVE_ARGS valcum;
24912 valcum.fregno = FP_ARG_MIN_REG;
24913 valcum.vregno = ALTIVEC_ARG_MIN_REG;
24914 /* Do a trial code generation as if this were going to be passed as
24915 an argument; if any part goes in memory, we return NULL. */
24916 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
24919 /* Otherwise fall through to standard ABI rules. */
24922 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
24924 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
24925 return gen_rtx_PARALLEL (DImode,
24927 gen_rtx_EXPR_LIST (VOIDmode,
24928 gen_rtx_REG (SImode, GP_ARG_RETURN),
24930 gen_rtx_EXPR_LIST (VOIDmode,
24931 gen_rtx_REG (SImode,
24932 GP_ARG_RETURN + 1),
24935 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
24937 return gen_rtx_PARALLEL (DCmode,
24939 gen_rtx_EXPR_LIST (VOIDmode,
24940 gen_rtx_REG (SImode, GP_ARG_RETURN),
24942 gen_rtx_EXPR_LIST (VOIDmode,
24943 gen_rtx_REG (SImode,
24944 GP_ARG_RETURN + 1),
24946 gen_rtx_EXPR_LIST (VOIDmode,
24947 gen_rtx_REG (SImode,
24948 GP_ARG_RETURN + 2),
24950 gen_rtx_EXPR_LIST (VOIDmode,
24951 gen_rtx_REG (SImode,
24952 GP_ARG_RETURN + 3),
24956 mode = TYPE_MODE (valtype);
24957 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
24958 || POINTER_TYPE_P (valtype))
24959 mode = TARGET_32BIT ? SImode : DImode;
24961 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
24962 /* _Decimal128 must use an even/odd register pair. */
24963 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
24964 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
24965 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
24966 regno = FP_ARG_RETURN;
24967 else if (TREE_CODE (valtype) == COMPLEX_TYPE
24968 && targetm.calls.split_complex_arg)
24969 return rs6000_complex_function_value (mode);
24970 else if (TREE_CODE (valtype) == VECTOR_TYPE
24971 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
24972 && ALTIVEC_VECTOR_MODE (mode))
24973 regno = ALTIVEC_ARG_RETURN;
24974 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
24975 && (mode == DFmode || mode == DCmode
24976 || mode == TFmode || mode == TCmode))
24977 return spe_build_register_parallel (mode, GP_ARG_RETURN);
24979 regno = GP_ARG_RETURN;
24981 return gen_rtx_REG (mode, regno);
24984 /* Define how to find the value returned by a library function
24985 assuming the value has mode MODE. */
24987 rs6000_libcall_value (enum machine_mode mode)
24989 unsigned int regno;
24991 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
24993 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
24994 return gen_rtx_PARALLEL (DImode,
24996 gen_rtx_EXPR_LIST (VOIDmode,
24997 gen_rtx_REG (SImode, GP_ARG_RETURN),
24999 gen_rtx_EXPR_LIST (VOIDmode,
25000 gen_rtx_REG (SImode,
25001 GP_ARG_RETURN + 1),
25005 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25006 /* _Decimal128 must use an even/odd register pair. */
25007 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25008 else if (SCALAR_FLOAT_MODE_P (mode)
25009 && TARGET_HARD_FLOAT && TARGET_FPRS
25010 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
25011 regno = FP_ARG_RETURN;
25012 else if (ALTIVEC_VECTOR_MODE (mode)
25013 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
25014 regno = ALTIVEC_ARG_RETURN;
25015 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
25016 return rs6000_complex_function_value (mode);
25017 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25018 && (mode == DFmode || mode == DCmode
25019 || mode == TFmode || mode == TCmode))
25020 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25022 regno = GP_ARG_RETURN;
25024 return gen_rtx_REG (mode, regno);
25028 /* Given FROM and TO register numbers, say whether this elimination is allowed.
25029 Frame pointer elimination is automatically handled.
25031 For the RS/6000, if frame pointer elimination is being done, we would like
25032 to convert ap into fp, not sp.
25034 We need r30 if -mminimal-toc was specified, and there are constant pool
25038 rs6000_can_eliminate (const int from, const int to)
25040 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
25041 ? ! frame_pointer_needed
25042 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
25043 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
25047 /* Define the offset between two registers, FROM to be eliminated and its
25048 replacement TO, at the start of a routine. */
25050 rs6000_initial_elimination_offset (int from, int to)
25052 rs6000_stack_t *info = rs6000_stack_info ();
25053 HOST_WIDE_INT offset;
25055 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25056 offset = info->push_p ? 0 : -info->total_size;
25057 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25059 offset = info->push_p ? 0 : -info->total_size;
25060 if (FRAME_GROWS_DOWNWARD)
25061 offset += info->fixed_size + info->vars_size + info->parm_size;
25063 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25064 offset = FRAME_GROWS_DOWNWARD
25065 ? info->fixed_size + info->vars_size + info->parm_size
25067 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25068 offset = info->total_size;
25069 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25070 offset = info->push_p ? info->total_size : 0;
25071 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
25074 gcc_unreachable ();
25080 rs6000_dwarf_register_span (rtx reg)
25084 unsigned regno = REGNO (reg);
25085 enum machine_mode mode = GET_MODE (reg);
25089 && (SPE_VECTOR_MODE (GET_MODE (reg))
25090 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
25091 && mode != SFmode && mode != SDmode && mode != SCmode)))
25096 regno = REGNO (reg);
25098 /* The duality of the SPE register size wreaks all kinds of havoc.
25099 This is a way of distinguishing r0 in 32-bits from r0 in
25101 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
25102 gcc_assert (words <= 4);
25103 for (i = 0; i < words; i++, regno++)
25105 if (BYTES_BIG_ENDIAN)
25107 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
25108 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
25112 parts[2 * i] = gen_rtx_REG (SImode, regno);
25113 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
25117 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
25120 /* Fill in sizes for SPE register high parts in table used by unwinder. */
25123 rs6000_init_dwarf_reg_sizes_extra (tree address)
25128 enum machine_mode mode = TYPE_MODE (char_type_node);
25129 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
25130 rtx mem = gen_rtx_MEM (BLKmode, addr);
25131 rtx value = gen_int_mode (4, mode);
25133 for (i = 1201; i < 1232; i++)
25135 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
25136 HOST_WIDE_INT offset
25137 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
25139 emit_move_insn (adjust_address (mem, mode, offset), value);
25144 /* Map internal gcc register numbers to DWARF2 register numbers. */
25147 rs6000_dbx_register_number (unsigned int regno)
25149 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
25151 if (regno == MQ_REGNO)
25153 if (regno == LR_REGNO)
25155 if (regno == CTR_REGNO)
25157 if (CR_REGNO_P (regno))
25158 return regno - CR0_REGNO + 86;
25159 if (regno == XER_REGNO)
25161 if (ALTIVEC_REGNO_P (regno))
25162 return regno - FIRST_ALTIVEC_REGNO + 1124;
25163 if (regno == VRSAVE_REGNO)
25165 if (regno == VSCR_REGNO)
25167 if (regno == SPE_ACC_REGNO)
25169 if (regno == SPEFSCR_REGNO)
25171 /* SPE high reg number. We get these values of regno from
25172 rs6000_dwarf_register_span. */
25173 gcc_assert (regno >= 1200 && regno < 1232);
25177 /* target hook eh_return_filter_mode */
25178 static enum machine_mode
25179 rs6000_eh_return_filter_mode (void)
25181 return TARGET_32BIT ? SImode : word_mode;
25184 /* Target hook for scalar_mode_supported_p. */
25186 rs6000_scalar_mode_supported_p (enum machine_mode mode)
25188 if (DECIMAL_FLOAT_MODE_P (mode))
25191 return default_scalar_mode_supported_p (mode);
25194 /* Target hook for vector_mode_supported_p. */
25196 rs6000_vector_mode_supported_p (enum machine_mode mode)
25199 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
25202 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
25205 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
25212 /* Target hook for invalid_arg_for_unprototyped_fn. */
25213 static const char *
25214 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
25216 return (!rs6000_darwin64_abi
25218 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
25219 && (funcdecl == NULL_TREE
25220 || (TREE_CODE (funcdecl) == FUNCTION_DECL
25221 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
25222 ? N_("AltiVec argument passed to unprototyped function")
25226 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
25227 setup by using __stack_chk_fail_local hidden function instead of
25228 calling __stack_chk_fail directly. Otherwise it is better to call
25229 __stack_chk_fail directly. */
25232 rs6000_stack_protect_fail (void)
25234 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
25235 ? default_hidden_stack_protect_fail ()
25236 : default_external_stack_protect_fail ();
25240 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
25241 int num_operands ATTRIBUTE_UNUSED)
25243 if (rs6000_warn_cell_microcode)
25246 int insn_code_number = recog_memoized (insn);
25247 location_t location = locator_location (INSN_LOCATOR (insn));
25249 /* Punt on insns we cannot recognize. */
25250 if (insn_code_number < 0)
25253 temp = get_insn_template (insn_code_number, insn);
25255 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
25256 warning_at (location, OPT_mwarn_cell_microcode,
25257 "emitting microcode insn %s\t[%s] #%d",
25258 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25259 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
25260 warning_at (location, OPT_mwarn_cell_microcode,
25261 "emitting conditional microcode insn %s\t[%s] #%d",
25262 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25266 #include "gt-rs6000.h"