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 rtx rs6000_delegitimize_address (rtx);
983 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
984 static rtx rs6000_tls_get_addr (void);
985 static rtx rs6000_got_sym (void);
986 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
987 static const char *rs6000_get_some_local_dynamic_name (void);
988 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
989 static rtx rs6000_complex_function_value (enum machine_mode);
990 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
991 enum machine_mode, tree);
992 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
994 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
995 tree, HOST_WIDE_INT);
996 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
999 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1000 const_tree, HOST_WIDE_INT,
1002 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
1003 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
1004 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1005 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1006 enum machine_mode, tree,
1008 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1010 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1012 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1014 static void macho_branch_islands (void);
1015 static int no_previous_def (tree function_name);
1016 static tree get_prev_label (tree function_name);
1017 static void rs6000_darwin_file_start (void);
1020 static tree rs6000_build_builtin_va_list (void);
1021 static void rs6000_va_start (tree, rtx);
1022 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1023 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1024 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1025 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1026 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1027 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1029 static tree rs6000_stack_protect_fail (void);
1031 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1034 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1037 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1039 = rs6000_legitimize_reload_address;
1041 static bool rs6000_mode_dependent_address (rtx);
1042 static bool rs6000_debug_mode_dependent_address (rtx);
1043 bool (*rs6000_mode_dependent_address_ptr) (rtx)
1044 = rs6000_mode_dependent_address;
1046 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1047 enum machine_mode, rtx);
1048 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1051 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1052 enum machine_mode, rtx)
1053 = rs6000_secondary_reload_class;
1055 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1056 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1058 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1059 = rs6000_preferred_reload_class;
1061 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1064 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1068 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1070 = rs6000_secondary_memory_needed;
1072 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1075 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1079 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1082 = rs6000_cannot_change_mode_class;
1084 static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class,
1086 struct secondary_reload_info *);
1088 static const enum reg_class *rs6000_ira_cover_classes (void);
1090 const int INSN_NOT_AVAILABLE = -1;
1091 static enum machine_mode rs6000_eh_return_filter_mode (void);
1092 static bool rs6000_can_eliminate (const int, const int);
1094 /* Hash table stuff for keeping track of TOC entries. */
1096 struct GTY(()) toc_hash_struct
1098 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1099 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1101 enum machine_mode key_mode;
1105 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1107 /* Hash table to keep track of the argument types for builtin functions. */
1109 struct GTY(()) builtin_hash_struct
1112 enum machine_mode mode[4]; /* return value + 3 arguments. */
1113 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1116 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1118 /* Default register names. */
1119 char rs6000_reg_names[][8] =
1121 "0", "1", "2", "3", "4", "5", "6", "7",
1122 "8", "9", "10", "11", "12", "13", "14", "15",
1123 "16", "17", "18", "19", "20", "21", "22", "23",
1124 "24", "25", "26", "27", "28", "29", "30", "31",
1125 "0", "1", "2", "3", "4", "5", "6", "7",
1126 "8", "9", "10", "11", "12", "13", "14", "15",
1127 "16", "17", "18", "19", "20", "21", "22", "23",
1128 "24", "25", "26", "27", "28", "29", "30", "31",
1129 "mq", "lr", "ctr","ap",
1130 "0", "1", "2", "3", "4", "5", "6", "7",
1132 /* AltiVec registers. */
1133 "0", "1", "2", "3", "4", "5", "6", "7",
1134 "8", "9", "10", "11", "12", "13", "14", "15",
1135 "16", "17", "18", "19", "20", "21", "22", "23",
1136 "24", "25", "26", "27", "28", "29", "30", "31",
1138 /* SPE registers. */
1139 "spe_acc", "spefscr",
1140 /* Soft frame pointer. */
1144 #ifdef TARGET_REGNAMES
1145 static const char alt_reg_names[][8] =
1147 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1148 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1149 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1150 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1151 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1152 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1153 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1154 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1155 "mq", "lr", "ctr", "ap",
1156 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1158 /* AltiVec registers. */
1159 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1160 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1161 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1162 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1164 /* SPE registers. */
1165 "spe_acc", "spefscr",
1166 /* Soft frame pointer. */
1171 /* Table of valid machine attributes. */
1173 static const struct attribute_spec rs6000_attribute_table[] =
1175 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1176 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1177 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1178 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1179 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1180 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1181 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1182 SUBTARGET_ATTRIBUTE_TABLE,
1184 { NULL, 0, 0, false, false, false, NULL }
1187 #ifndef MASK_STRICT_ALIGN
1188 #define MASK_STRICT_ALIGN 0
1190 #ifndef TARGET_PROFILE_KERNEL
1191 #define TARGET_PROFILE_KERNEL 0
1192 #define SET_PROFILE_KERNEL(N)
1194 #define SET_PROFILE_KERNEL(N) TARGET_PROFILE_KERNEL = (N)
1197 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1198 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1200 /* Initialize the GCC target structure. */
1201 #undef TARGET_ATTRIBUTE_TABLE
1202 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1203 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1204 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1206 #undef TARGET_ASM_ALIGNED_DI_OP
1207 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1209 /* Default unaligned ops are only provided for ELF. Find the ops needed
1210 for non-ELF systems. */
1211 #ifndef OBJECT_FORMAT_ELF
1213 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1215 #undef TARGET_ASM_UNALIGNED_HI_OP
1216 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1217 #undef TARGET_ASM_UNALIGNED_SI_OP
1218 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1219 #undef TARGET_ASM_UNALIGNED_DI_OP
1220 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1223 #undef TARGET_ASM_UNALIGNED_HI_OP
1224 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1225 #undef TARGET_ASM_UNALIGNED_SI_OP
1226 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1227 #undef TARGET_ASM_UNALIGNED_DI_OP
1228 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1229 #undef TARGET_ASM_ALIGNED_DI_OP
1230 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1234 /* This hook deals with fixups for relocatable code and DI-mode objects
1236 #undef TARGET_ASM_INTEGER
1237 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1239 #ifdef HAVE_GAS_HIDDEN
1240 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1241 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1244 #undef TARGET_HAVE_TLS
1245 #define TARGET_HAVE_TLS HAVE_AS_TLS
1247 #undef TARGET_CANNOT_FORCE_CONST_MEM
1248 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1250 #undef TARGET_ASM_FUNCTION_PROLOGUE
1251 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1252 #undef TARGET_ASM_FUNCTION_EPILOGUE
1253 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1255 #undef TARGET_LEGITIMIZE_ADDRESS
1256 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1258 #undef TARGET_SCHED_VARIABLE_ISSUE
1259 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1261 #undef TARGET_SCHED_ISSUE_RATE
1262 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1263 #undef TARGET_SCHED_ADJUST_COST
1264 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1265 #undef TARGET_SCHED_ADJUST_PRIORITY
1266 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1267 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1268 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1269 #undef TARGET_SCHED_INIT
1270 #define TARGET_SCHED_INIT rs6000_sched_init
1271 #undef TARGET_SCHED_FINISH
1272 #define TARGET_SCHED_FINISH rs6000_sched_finish
1273 #undef TARGET_SCHED_REORDER
1274 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1275 #undef TARGET_SCHED_REORDER2
1276 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1278 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1279 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1281 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1282 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1284 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1285 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1286 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1287 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1288 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1289 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1290 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1291 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1293 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1294 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1295 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1296 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1297 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1298 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1299 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1300 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1301 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1302 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1304 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1305 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1307 #undef TARGET_INIT_BUILTINS
1308 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1310 #undef TARGET_EXPAND_BUILTIN
1311 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1313 #undef TARGET_MANGLE_TYPE
1314 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1316 #undef TARGET_INIT_LIBFUNCS
1317 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1320 #undef TARGET_BINDS_LOCAL_P
1321 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1324 #undef TARGET_MS_BITFIELD_LAYOUT_P
1325 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1327 #undef TARGET_ASM_OUTPUT_MI_THUNK
1328 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1330 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1331 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1333 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1334 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1336 #undef TARGET_INVALID_WITHIN_DOLOOP
1337 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1339 #undef TARGET_RTX_COSTS
1340 #define TARGET_RTX_COSTS rs6000_rtx_costs
1341 #undef TARGET_ADDRESS_COST
1342 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1344 #undef TARGET_DWARF_REGISTER_SPAN
1345 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1347 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1348 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1350 /* On rs6000, function arguments are promoted, as are function return
1352 #undef TARGET_PROMOTE_FUNCTION_MODE
1353 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1355 #undef TARGET_RETURN_IN_MEMORY
1356 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1358 #undef TARGET_SETUP_INCOMING_VARARGS
1359 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1361 /* Always strict argument naming on rs6000. */
1362 #undef TARGET_STRICT_ARGUMENT_NAMING
1363 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1364 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1365 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1366 #undef TARGET_SPLIT_COMPLEX_ARG
1367 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1368 #undef TARGET_MUST_PASS_IN_STACK
1369 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1370 #undef TARGET_PASS_BY_REFERENCE
1371 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1372 #undef TARGET_ARG_PARTIAL_BYTES
1373 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1375 #undef TARGET_BUILD_BUILTIN_VA_LIST
1376 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1378 #undef TARGET_EXPAND_BUILTIN_VA_START
1379 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1381 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1382 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1384 #undef TARGET_EH_RETURN_FILTER_MODE
1385 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1387 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1388 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1390 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1391 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1393 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1394 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1396 #undef TARGET_HANDLE_OPTION
1397 #define TARGET_HANDLE_OPTION rs6000_handle_option
1399 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1400 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1401 rs6000_builtin_vectorized_function
1403 #undef TARGET_DEFAULT_TARGET_FLAGS
1404 #define TARGET_DEFAULT_TARGET_FLAGS \
1407 #undef TARGET_STACK_PROTECT_FAIL
1408 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1410 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1411 The PowerPC architecture requires only weak consistency among
1412 processors--that is, memory accesses between processors need not be
1413 sequentially consistent and memory accesses among processors can occur
1414 in any order. The ability to order memory accesses weakly provides
1415 opportunities for more efficient use of the system bus. Unless a
1416 dependency exists, the 604e allows read operations to precede store
1418 #undef TARGET_RELAXED_ORDERING
1419 #define TARGET_RELAXED_ORDERING true
1422 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1423 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1426 /* Use a 32-bit anchor range. This leads to sequences like:
1428 addis tmp,anchor,high
1431 where tmp itself acts as an anchor, and can be shared between
1432 accesses to the same 64k page. */
1433 #undef TARGET_MIN_ANCHOR_OFFSET
1434 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1435 #undef TARGET_MAX_ANCHOR_OFFSET
1436 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1437 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1438 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1440 #undef TARGET_DELEGITIMIZE_ADDRESS
1441 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1443 #undef TARGET_BUILTIN_RECIPROCAL
1444 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1446 #undef TARGET_EXPAND_TO_RTL_HOOK
1447 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1449 #undef TARGET_INSTANTIATE_DECLS
1450 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1452 #undef TARGET_SECONDARY_RELOAD
1453 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1455 #undef TARGET_IRA_COVER_CLASSES
1456 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1458 #undef TARGET_LEGITIMATE_ADDRESS_P
1459 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1461 #undef TARGET_CAN_ELIMINATE
1462 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1464 struct gcc_target targetm = TARGET_INITIALIZER;
1466 /* Return number of consecutive hard regs needed starting at reg REGNO
1467 to hold something of mode MODE.
1468 This is ordinarily the length in words of a value of mode MODE
1469 but can be less for certain modes in special long registers.
1471 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1472 scalar instructions. The upper 32 bits are only available to the
1475 POWER and PowerPC GPRs hold 32 bits worth;
1476 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1479 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1481 unsigned HOST_WIDE_INT reg_size;
1483 if (FP_REGNO_P (regno))
1484 reg_size = (VECTOR_MEM_VSX_P (mode)
1485 ? UNITS_PER_VSX_WORD
1486 : UNITS_PER_FP_WORD);
1488 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1489 reg_size = UNITS_PER_SPE_WORD;
1491 else if (ALTIVEC_REGNO_P (regno))
1492 reg_size = UNITS_PER_ALTIVEC_WORD;
1494 /* The value returned for SCmode in the E500 double case is 2 for
1495 ABI compatibility; storing an SCmode value in a single register
1496 would require function_arg and rs6000_spe_function_arg to handle
1497 SCmode so as to pass the value correctly in a pair of
1499 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1500 && !DECIMAL_FLOAT_MODE_P (mode))
1501 reg_size = UNITS_PER_FP_WORD;
1504 reg_size = UNITS_PER_WORD;
1506 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1509 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1512 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1514 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1516 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1517 implementations. Don't allow an item to be split between a FP register
1518 and an Altivec register. */
1519 if (VECTOR_MEM_VSX_P (mode))
1521 if (FP_REGNO_P (regno))
1522 return FP_REGNO_P (last_regno);
1524 if (ALTIVEC_REGNO_P (regno))
1525 return ALTIVEC_REGNO_P (last_regno);
1528 /* The GPRs can hold any mode, but values bigger than one register
1529 cannot go past R31. */
1530 if (INT_REGNO_P (regno))
1531 return INT_REGNO_P (last_regno);
1533 /* The float registers (except for VSX vector modes) can only hold floating
1534 modes and DImode. This excludes the 32-bit decimal float mode for
1536 if (FP_REGNO_P (regno))
1538 if (SCALAR_FLOAT_MODE_P (mode)
1539 && (mode != TDmode || (regno % 2) == 0)
1540 && FP_REGNO_P (last_regno))
1543 if (GET_MODE_CLASS (mode) == MODE_INT
1544 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1547 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1548 && PAIRED_VECTOR_MODE (mode))
1554 /* The CR register can only hold CC modes. */
1555 if (CR_REGNO_P (regno))
1556 return GET_MODE_CLASS (mode) == MODE_CC;
1558 if (XER_REGNO_P (regno))
1559 return mode == PSImode;
1561 /* AltiVec only in AldyVec registers. */
1562 if (ALTIVEC_REGNO_P (regno))
1563 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1565 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1566 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1569 /* We cannot put TImode anywhere except general register and it must be able
1570 to fit within the register set. In the future, allow TImode in the
1571 Altivec or VSX registers. */
1573 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1576 /* Print interesting facts about registers. */
1578 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1582 for (r = first_regno; r <= last_regno; ++r)
1584 const char *comma = "";
1587 if (first_regno == last_regno)
1588 fprintf (stderr, "%s:\t", reg_name);
1590 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1593 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1594 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1598 fprintf (stderr, ",\n\t");
1603 if (rs6000_hard_regno_nregs[m][r] > 1)
1604 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1605 rs6000_hard_regno_nregs[m][r]);
1607 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1612 if (call_used_regs[r])
1616 fprintf (stderr, ",\n\t");
1621 len += fprintf (stderr, "%s%s", comma, "call-used");
1629 fprintf (stderr, ",\n\t");
1634 len += fprintf (stderr, "%s%s", comma, "fixed");
1640 fprintf (stderr, ",\n\t");
1644 fprintf (stderr, "%sregno = %d\n", comma, r);
1648 /* Print various interesting information with -mdebug=reg. */
1650 rs6000_debug_reg_global (void)
1652 const char *nl = (const char *)0;
1654 char costly_num[20];
1656 const char *costly_str;
1657 const char *nop_str;
1659 /* Map enum rs6000_vector to string. */
1660 static const char *rs6000_debug_vector_unit[] = {
1669 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1670 LAST_VIRTUAL_REGISTER);
1671 rs6000_debug_reg_print (0, 31, "gr");
1672 rs6000_debug_reg_print (32, 63, "fp");
1673 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1676 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1677 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1678 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1679 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1680 rs6000_debug_reg_print (XER_REGNO, XER_REGNO, "xer");
1681 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1682 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1683 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1684 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1688 "d reg_class = %s\n"
1689 "f reg_class = %s\n"
1690 "v reg_class = %s\n"
1691 "wa reg_class = %s\n"
1692 "wd reg_class = %s\n"
1693 "wf reg_class = %s\n"
1694 "ws reg_class = %s\n\n",
1695 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1696 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1697 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1698 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1699 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1700 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1701 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1703 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1704 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1707 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1709 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1710 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1716 switch (rs6000_sched_costly_dep)
1718 case max_dep_latency:
1719 costly_str = "max_dep_latency";
1723 costly_str = "no_dep_costly";
1726 case all_deps_costly:
1727 costly_str = "all_deps_costly";
1730 case true_store_to_load_dep_costly:
1731 costly_str = "true_store_to_load_dep_costly";
1734 case store_to_load_dep_costly:
1735 costly_str = "store_to_load_dep_costly";
1739 costly_str = costly_num;
1740 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1744 switch (rs6000_sched_insert_nops)
1746 case sched_finish_regroup_exact:
1747 nop_str = "sched_finish_regroup_exact";
1750 case sched_finish_pad_groups:
1751 nop_str = "sched_finish_pad_groups";
1754 case sched_finish_none:
1755 nop_str = "sched_finish_none";
1760 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1765 "always_hint = %s\n"
1766 "align_branch_targets = %s\n"
1767 "sched_restricted_insns_priority = %d\n"
1768 "sched_costly_dep = %s\n"
1769 "sched_insert_nops = %s\n\n",
1770 rs6000_always_hint ? "true" : "false",
1771 rs6000_align_branch_targets ? "true" : "false",
1772 (int)rs6000_sched_restricted_insns_priority,
1773 costly_str, nop_str);
1776 /* Initialize the various global tables that are based on register size. */
1778 rs6000_init_hard_regno_mode_ok (void)
1784 /* Precalculate REGNO_REG_CLASS. */
1785 rs6000_regno_regclass[0] = GENERAL_REGS;
1786 for (r = 1; r < 32; ++r)
1787 rs6000_regno_regclass[r] = BASE_REGS;
1789 for (r = 32; r < 64; ++r)
1790 rs6000_regno_regclass[r] = FLOAT_REGS;
1792 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1793 rs6000_regno_regclass[r] = NO_REGS;
1795 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
1796 rs6000_regno_regclass[r] = ALTIVEC_REGS;
1798 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
1799 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
1800 rs6000_regno_regclass[r] = CR_REGS;
1802 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
1803 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
1804 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
1805 rs6000_regno_regclass[XER_REGNO] = XER_REGS;
1806 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
1807 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
1808 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
1809 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
1810 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
1811 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
1813 /* Precalculate vector information, this must be set up before the
1814 rs6000_hard_regno_nregs_internal below. */
1815 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1817 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
1818 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
1819 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
1822 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
1823 rs6000_constraints[c] = NO_REGS;
1825 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
1826 believes it can use native alignment or still uses 128-bit alignment. */
1827 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
1838 /* V2DF mode, VSX only. */
1841 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
1842 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
1843 rs6000_vector_align[V2DFmode] = align64;
1846 /* V4SF mode, either VSX or Altivec. */
1849 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
1850 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
1851 rs6000_vector_align[V4SFmode] = align32;
1853 else if (TARGET_ALTIVEC)
1855 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
1856 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
1857 rs6000_vector_align[V4SFmode] = align32;
1860 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
1864 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
1865 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
1866 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
1867 rs6000_vector_align[V4SImode] = align32;
1868 rs6000_vector_align[V8HImode] = align32;
1869 rs6000_vector_align[V16QImode] = align32;
1873 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
1874 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
1875 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
1879 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
1880 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
1881 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
1885 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
1886 Altivec doesn't have 64-bit support. */
1889 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
1890 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
1891 rs6000_vector_align[V2DImode] = align64;
1894 /* DFmode, see if we want to use the VSX unit. */
1895 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
1897 rs6000_vector_unit[DFmode] = VECTOR_VSX;
1898 rs6000_vector_mem[DFmode]
1899 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
1900 rs6000_vector_align[DFmode] = align64;
1903 /* TODO add SPE and paired floating point vector support. */
1905 /* Register class constaints for the constraints that depend on compile
1907 if (TARGET_HARD_FLOAT && TARGET_FPRS)
1908 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
1910 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
1911 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
1915 /* At present, we just use VSX_REGS, but we have different constraints
1916 based on the use, in case we want to fine tune the default register
1917 class used. wa = any VSX register, wf = register class to use for
1918 V4SF, wd = register class to use for V2DF, and ws = register classs to
1919 use for DF scalars. */
1920 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
1921 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
1922 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
1923 if (TARGET_VSX_SCALAR_DOUBLE)
1924 rs6000_constraints[RS6000_CONSTRAINT_ws] = VSX_REGS;
1928 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
1930 /* Set up the reload helper functions. */
1931 if (TARGET_VSX || TARGET_ALTIVEC)
1935 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
1936 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
1937 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
1938 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
1939 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
1940 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
1941 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
1942 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
1943 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
1944 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
1945 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
1946 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
1950 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
1951 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
1952 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
1953 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
1954 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
1955 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
1956 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
1957 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
1958 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
1959 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
1960 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
1961 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
1965 /* Precalculate HARD_REGNO_NREGS. */
1966 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
1967 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1968 rs6000_hard_regno_nregs[m][r]
1969 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
1971 /* Precalculate HARD_REGNO_MODE_OK. */
1972 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
1973 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1974 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
1975 rs6000_hard_regno_mode_ok_p[m][r] = true;
1977 /* Precalculate CLASS_MAX_NREGS sizes. */
1978 for (c = 0; c < LIM_REG_CLASSES; ++c)
1982 if (TARGET_VSX && VSX_REG_CLASS_P (c))
1983 reg_size = UNITS_PER_VSX_WORD;
1985 else if (c == ALTIVEC_REGS)
1986 reg_size = UNITS_PER_ALTIVEC_WORD;
1988 else if (c == FLOAT_REGS)
1989 reg_size = UNITS_PER_FP_WORD;
1992 reg_size = UNITS_PER_WORD;
1994 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1995 rs6000_class_max_nregs[m][c]
1996 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
1999 if (TARGET_E500_DOUBLE)
2000 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2002 if (TARGET_DEBUG_REG)
2003 rs6000_debug_reg_global ();
2007 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2010 darwin_rs6000_override_options (void)
2012 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2014 rs6000_altivec_abi = 1;
2015 TARGET_ALTIVEC_VRSAVE = 1;
2016 if (DEFAULT_ABI == ABI_DARWIN)
2018 if (MACHO_DYNAMIC_NO_PIC_P)
2021 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2024 else if (flag_pic == 1)
2029 if (TARGET_64BIT && ! TARGET_POWERPC64)
2031 target_flags |= MASK_POWERPC64;
2032 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2036 rs6000_default_long_calls = 1;
2037 target_flags |= MASK_SOFT_FLOAT;
2040 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2042 if (!flag_mkernel && !flag_apple_kext
2044 && ! (target_flags_explicit & MASK_ALTIVEC))
2045 target_flags |= MASK_ALTIVEC;
2047 /* Unless the user (not the configurer) has explicitly overridden
2048 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2049 G4 unless targetting the kernel. */
2052 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2053 && ! (target_flags_explicit & MASK_ALTIVEC)
2054 && ! rs6000_select[1].string)
2056 target_flags |= MASK_ALTIVEC;
2061 /* If not otherwise specified by a target, make 'long double' equivalent to
2064 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2065 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2068 /* Override command line options. Mostly we process the processor
2069 type and sometimes adjust other TARGET_ options. */
2072 rs6000_override_options (const char *default_cpu)
2075 struct rs6000_cpu_select *ptr;
2078 /* Simplifications for entries below. */
2081 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2082 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2085 /* This table occasionally claims that a processor does not support
2086 a particular feature even though it does, but the feature is slower
2087 than the alternative. Thus, it shouldn't be relied on as a
2088 complete description of the processor's support.
2090 Please keep this list in order, and don't forget to update the
2091 documentation in invoke.texi when adding a new processor or
2095 const char *const name; /* Canonical processor name. */
2096 const enum processor_type processor; /* Processor type enum value. */
2097 const int target_enable; /* Target flags to enable. */
2098 } const processor_target_table[]
2099 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2100 {"403", PROCESSOR_PPC403,
2101 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2102 {"405", PROCESSOR_PPC405,
2103 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2104 {"405fp", PROCESSOR_PPC405,
2105 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2106 {"440", PROCESSOR_PPC440,
2107 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2108 {"440fp", PROCESSOR_PPC440,
2109 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2110 {"464", PROCESSOR_PPC440,
2111 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2112 {"464fp", PROCESSOR_PPC440,
2113 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2114 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2115 {"601", PROCESSOR_PPC601,
2116 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2117 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2118 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2119 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2120 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2121 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2122 {"620", PROCESSOR_PPC620,
2123 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2124 {"630", PROCESSOR_PPC630,
2125 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2126 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2127 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2128 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2129 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2130 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2131 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2132 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2133 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2135 /* 8548 has a dummy entry for now. */
2136 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2138 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2139 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2140 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2142 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2143 {"970", PROCESSOR_POWER4,
2144 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2145 {"cell", PROCESSOR_CELL,
2146 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2147 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2148 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2149 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2150 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2151 {"G5", PROCESSOR_POWER4,
2152 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2153 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2154 {"power2", PROCESSOR_POWER,
2155 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2156 {"power3", PROCESSOR_PPC630,
2157 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2158 {"power4", PROCESSOR_POWER4,
2159 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2161 {"power5", PROCESSOR_POWER5,
2162 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2163 | MASK_MFCRF | MASK_POPCNTB},
2164 {"power5+", PROCESSOR_POWER5,
2165 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2166 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2167 {"power6", PROCESSOR_POWER6,
2168 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2169 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP},
2170 {"power6x", PROCESSOR_POWER6,
2171 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2172 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2174 {"power7", PROCESSOR_POWER7,
2175 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2176 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2177 | MASK_VSX}, /* Don't add MASK_ISEL by default */
2178 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2179 {"powerpc64", PROCESSOR_POWERPC64,
2180 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2181 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2182 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2183 {"rios2", PROCESSOR_RIOS2,
2184 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2185 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2186 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2187 {"rs64", PROCESSOR_RS64A,
2188 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2191 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2193 /* Some OSs don't support saving the high part of 64-bit registers on
2194 context switch. Other OSs don't support saving Altivec registers.
2195 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2196 settings; if the user wants either, the user must explicitly specify
2197 them and we won't interfere with the user's specification. */
2200 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2201 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2202 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2203 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2204 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2205 | MASK_POPCNTD | MASK_VSX | MASK_ISEL)
2208 /* Set the pointer size. */
2211 rs6000_pmode = (int)DImode;
2212 rs6000_pointer_size = 64;
2216 rs6000_pmode = (int)SImode;
2217 rs6000_pointer_size = 32;
2220 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2221 #ifdef OS_MISSING_POWERPC64
2222 if (OS_MISSING_POWERPC64)
2223 set_masks &= ~MASK_POWERPC64;
2225 #ifdef OS_MISSING_ALTIVEC
2226 if (OS_MISSING_ALTIVEC)
2227 set_masks &= ~MASK_ALTIVEC;
2230 /* Don't override by the processor default if given explicitly. */
2231 set_masks &= ~target_flags_explicit;
2233 /* Identify the processor type. */
2234 rs6000_select[0].string = default_cpu;
2235 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2237 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2239 ptr = &rs6000_select[i];
2240 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2242 for (j = 0; j < ptt_size; j++)
2243 if (! strcmp (ptr->string, processor_target_table[j].name))
2245 if (ptr->set_tune_p)
2246 rs6000_cpu = processor_target_table[j].processor;
2248 if (ptr->set_arch_p)
2250 target_flags &= ~set_masks;
2251 target_flags |= (processor_target_table[j].target_enable
2258 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2262 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2263 || rs6000_cpu == PROCESSOR_PPCE500MC)
2266 error ("AltiVec not supported in this target");
2268 error ("Spe not supported in this target");
2271 /* Disable Cell microcode if we are optimizing for the Cell
2272 and not optimizing for size. */
2273 if (rs6000_gen_cell_microcode == -1)
2274 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2277 /* If we are optimizing big endian systems for space, use the load/store
2278 multiple and string instructions unless we are not generating
2280 if (BYTES_BIG_ENDIAN && optimize_size && !rs6000_gen_cell_microcode)
2281 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2283 /* Don't allow -mmultiple or -mstring on little endian systems
2284 unless the cpu is a 750, because the hardware doesn't support the
2285 instructions used in little endian mode, and causes an alignment
2286 trap. The 750 does not cause an alignment trap (except when the
2287 target is unaligned). */
2289 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2291 if (TARGET_MULTIPLE)
2293 target_flags &= ~MASK_MULTIPLE;
2294 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2295 warning (0, "-mmultiple is not supported on little endian systems");
2300 target_flags &= ~MASK_STRING;
2301 if ((target_flags_explicit & MASK_STRING) != 0)
2302 warning (0, "-mstring is not supported on little endian systems");
2306 /* Add some warnings for VSX. Enable -maltivec unless the user explicitly
2307 used -mno-altivec */
2310 const char *msg = NULL;
2311 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2312 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2314 if (target_flags_explicit & MASK_VSX)
2315 msg = N_("-mvsx requires hardware floating point");
2317 target_flags &= ~ MASK_VSX;
2319 else if (TARGET_PAIRED_FLOAT)
2320 msg = N_("-mvsx and -mpaired are incompatible");
2321 /* The hardware will allow VSX and little endian, but until we make sure
2322 things like vector select, etc. work don't allow VSX on little endian
2323 systems at this point. */
2324 else if (!BYTES_BIG_ENDIAN)
2325 msg = N_("-mvsx used with little endian code");
2326 else if (TARGET_AVOID_XFORM > 0)
2327 msg = N_("-mvsx needs indexed addressing");
2332 target_flags &= ~ MASK_VSX;
2334 else if (TARGET_VSX && !TARGET_ALTIVEC
2335 && (target_flags_explicit & MASK_ALTIVEC) == 0)
2336 target_flags |= MASK_ALTIVEC;
2339 /* Set debug flags */
2340 if (rs6000_debug_name)
2342 if (! strcmp (rs6000_debug_name, "all"))
2343 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2344 = rs6000_debug_addr = rs6000_debug_cost = 1;
2345 else if (! strcmp (rs6000_debug_name, "stack"))
2346 rs6000_debug_stack = 1;
2347 else if (! strcmp (rs6000_debug_name, "arg"))
2348 rs6000_debug_arg = 1;
2349 else if (! strcmp (rs6000_debug_name, "reg"))
2350 rs6000_debug_reg = 1;
2351 else if (! strcmp (rs6000_debug_name, "addr"))
2352 rs6000_debug_addr = 1;
2353 else if (! strcmp (rs6000_debug_name, "cost"))
2354 rs6000_debug_cost = 1;
2356 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2358 /* If the appropriate debug option is enabled, replace the target hooks
2359 with debug versions that call the real version and then prints
2360 debugging information. */
2361 if (TARGET_DEBUG_COST)
2363 targetm.rtx_costs = rs6000_debug_rtx_costs;
2364 targetm.address_cost = rs6000_debug_address_cost;
2365 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2368 if (TARGET_DEBUG_ADDR)
2370 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2371 targetm.legitimize_address = rs6000_debug_legitimize_address;
2372 rs6000_secondary_reload_class_ptr
2373 = rs6000_debug_secondary_reload_class;
2374 rs6000_secondary_memory_needed_ptr
2375 = rs6000_debug_secondary_memory_needed;
2376 rs6000_cannot_change_mode_class_ptr
2377 = rs6000_debug_cannot_change_mode_class;
2378 rs6000_preferred_reload_class_ptr
2379 = rs6000_debug_preferred_reload_class;
2380 rs6000_legitimize_reload_address_ptr
2381 = rs6000_debug_legitimize_reload_address;
2382 rs6000_mode_dependent_address_ptr
2383 = rs6000_debug_mode_dependent_address;
2387 if (rs6000_traceback_name)
2389 if (! strncmp (rs6000_traceback_name, "full", 4))
2390 rs6000_traceback = traceback_full;
2391 else if (! strncmp (rs6000_traceback_name, "part", 4))
2392 rs6000_traceback = traceback_part;
2393 else if (! strncmp (rs6000_traceback_name, "no", 2))
2394 rs6000_traceback = traceback_none;
2396 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2397 rs6000_traceback_name);
2400 if (!rs6000_explicit_options.long_double)
2401 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2403 #ifndef POWERPC_LINUX
2404 if (!rs6000_explicit_options.ieee)
2405 rs6000_ieeequad = 1;
2408 /* Enable Altivec ABI for AIX -maltivec. */
2409 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2410 rs6000_altivec_abi = 1;
2412 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2413 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2414 be explicitly overridden in either case. */
2417 if (!rs6000_explicit_options.altivec_abi
2418 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2419 rs6000_altivec_abi = 1;
2421 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2422 if (!rs6000_explicit_options.vrsave)
2423 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2426 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2427 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2429 rs6000_darwin64_abi = 1;
2431 darwin_one_byte_bool = 1;
2433 /* Default to natural alignment, for better performance. */
2434 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2437 /* Place FP constants in the constant pool instead of TOC
2438 if section anchors enabled. */
2439 if (flag_section_anchors)
2440 TARGET_NO_FP_IN_TOC = 1;
2442 /* Handle -mtls-size option. */
2443 rs6000_parse_tls_size_option ();
2445 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2446 SUBTARGET_OVERRIDE_OPTIONS;
2448 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2449 SUBSUBTARGET_OVERRIDE_OPTIONS;
2451 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2452 SUB3TARGET_OVERRIDE_OPTIONS;
2455 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC)
2457 /* The e500 and e500mc do not have string instructions, and we set
2458 MASK_STRING above when optimizing for size. */
2459 if ((target_flags & MASK_STRING) != 0)
2460 target_flags = target_flags & ~MASK_STRING;
2462 else if (rs6000_select[1].string != NULL)
2464 /* For the powerpc-eabispe configuration, we set all these by
2465 default, so let's unset them if we manually set another
2466 CPU that is not the E500. */
2467 if (!rs6000_explicit_options.spe_abi)
2469 if (!rs6000_explicit_options.spe)
2471 if (!rs6000_explicit_options.float_gprs)
2472 rs6000_float_gprs = 0;
2473 if (!(target_flags_explicit & MASK_ISEL))
2474 target_flags &= ~MASK_ISEL;
2477 /* Detect invalid option combinations with E500. */
2480 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2481 && rs6000_cpu != PROCESSOR_POWER5
2482 && rs6000_cpu != PROCESSOR_POWER6
2483 && rs6000_cpu != PROCESSOR_POWER7
2484 && rs6000_cpu != PROCESSOR_CELL);
2485 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2486 || rs6000_cpu == PROCESSOR_POWER5
2487 || rs6000_cpu == PROCESSOR_POWER7);
2488 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2489 || rs6000_cpu == PROCESSOR_POWER5
2490 || rs6000_cpu == PROCESSOR_POWER6
2491 || rs6000_cpu == PROCESSOR_POWER7);
2493 /* Allow debug switches to override the above settings. */
2494 if (TARGET_ALWAYS_HINT > 0)
2495 rs6000_always_hint = TARGET_ALWAYS_HINT;
2497 if (TARGET_SCHED_GROUPS > 0)
2498 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2500 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2501 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2503 rs6000_sched_restricted_insns_priority
2504 = (rs6000_sched_groups ? 1 : 0);
2506 /* Handle -msched-costly-dep option. */
2507 rs6000_sched_costly_dep
2508 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2510 if (rs6000_sched_costly_dep_str)
2512 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2513 rs6000_sched_costly_dep = no_dep_costly;
2514 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2515 rs6000_sched_costly_dep = all_deps_costly;
2516 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2517 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2518 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2519 rs6000_sched_costly_dep = store_to_load_dep_costly;
2521 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2522 atoi (rs6000_sched_costly_dep_str));
2525 /* Handle -minsert-sched-nops option. */
2526 rs6000_sched_insert_nops
2527 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2529 if (rs6000_sched_insert_nops_str)
2531 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2532 rs6000_sched_insert_nops = sched_finish_none;
2533 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2534 rs6000_sched_insert_nops = sched_finish_pad_groups;
2535 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2536 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2538 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2539 atoi (rs6000_sched_insert_nops_str));
2542 #ifdef TARGET_REGNAMES
2543 /* If the user desires alternate register names, copy in the
2544 alternate names now. */
2545 if (TARGET_REGNAMES)
2546 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2549 /* Set aix_struct_return last, after the ABI is determined.
2550 If -maix-struct-return or -msvr4-struct-return was explicitly
2551 used, don't override with the ABI default. */
2552 if (!rs6000_explicit_options.aix_struct_ret)
2553 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2555 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2556 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2559 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2561 /* We can only guarantee the availability of DI pseudo-ops when
2562 assembling for 64-bit targets. */
2565 targetm.asm_out.aligned_op.di = NULL;
2566 targetm.asm_out.unaligned_op.di = NULL;
2569 /* Set branch target alignment, if not optimizing for size. */
2572 /* Cell wants to be aligned 8byte for dual issue. */
2573 if (rs6000_cpu == PROCESSOR_CELL)
2575 if (align_functions <= 0)
2576 align_functions = 8;
2577 if (align_jumps <= 0)
2579 if (align_loops <= 0)
2582 if (rs6000_align_branch_targets)
2584 if (align_functions <= 0)
2585 align_functions = 16;
2586 if (align_jumps <= 0)
2588 if (align_loops <= 0)
2591 if (align_jumps_max_skip <= 0)
2592 align_jumps_max_skip = 15;
2593 if (align_loops_max_skip <= 0)
2594 align_loops_max_skip = 15;
2597 /* Arrange to save and restore machine status around nested functions. */
2598 init_machine_status = rs6000_init_machine_status;
2600 /* We should always be splitting complex arguments, but we can't break
2601 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2602 if (DEFAULT_ABI != ABI_AIX)
2603 targetm.calls.split_complex_arg = NULL;
2605 /* Initialize rs6000_cost with the appropriate target costs. */
2607 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2611 case PROCESSOR_RIOS1:
2612 rs6000_cost = &rios1_cost;
2615 case PROCESSOR_RIOS2:
2616 rs6000_cost = &rios2_cost;
2619 case PROCESSOR_RS64A:
2620 rs6000_cost = &rs64a_cost;
2623 case PROCESSOR_MPCCORE:
2624 rs6000_cost = &mpccore_cost;
2627 case PROCESSOR_PPC403:
2628 rs6000_cost = &ppc403_cost;
2631 case PROCESSOR_PPC405:
2632 rs6000_cost = &ppc405_cost;
2635 case PROCESSOR_PPC440:
2636 rs6000_cost = &ppc440_cost;
2639 case PROCESSOR_PPC601:
2640 rs6000_cost = &ppc601_cost;
2643 case PROCESSOR_PPC603:
2644 rs6000_cost = &ppc603_cost;
2647 case PROCESSOR_PPC604:
2648 rs6000_cost = &ppc604_cost;
2651 case PROCESSOR_PPC604e:
2652 rs6000_cost = &ppc604e_cost;
2655 case PROCESSOR_PPC620:
2656 rs6000_cost = &ppc620_cost;
2659 case PROCESSOR_PPC630:
2660 rs6000_cost = &ppc630_cost;
2663 case PROCESSOR_CELL:
2664 rs6000_cost = &ppccell_cost;
2667 case PROCESSOR_PPC750:
2668 case PROCESSOR_PPC7400:
2669 rs6000_cost = &ppc750_cost;
2672 case PROCESSOR_PPC7450:
2673 rs6000_cost = &ppc7450_cost;
2676 case PROCESSOR_PPC8540:
2677 rs6000_cost = &ppc8540_cost;
2680 case PROCESSOR_PPCE300C2:
2681 case PROCESSOR_PPCE300C3:
2682 rs6000_cost = &ppce300c2c3_cost;
2685 case PROCESSOR_PPCE500MC:
2686 rs6000_cost = &ppce500mc_cost;
2689 case PROCESSOR_POWER4:
2690 case PROCESSOR_POWER5:
2691 rs6000_cost = &power4_cost;
2694 case PROCESSOR_POWER6:
2695 rs6000_cost = &power6_cost;
2698 case PROCESSOR_POWER7:
2699 rs6000_cost = &power7_cost;
2706 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
2707 set_param_value ("simultaneous-prefetches",
2708 rs6000_cost->simultaneous_prefetches);
2709 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
2710 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
2711 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
2712 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
2713 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
2714 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
2716 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
2717 can be optimized to ap = __builtin_next_arg (0). */
2718 if (DEFAULT_ABI != ABI_V4)
2719 targetm.expand_builtin_va_start = NULL;
2721 /* Set up single/double float flags.
2722 If TARGET_HARD_FLOAT is set, but neither single or double is set,
2723 then set both flags. */
2724 if (TARGET_HARD_FLOAT && TARGET_FPRS
2725 && rs6000_single_float == 0 && rs6000_double_float == 0)
2726 rs6000_single_float = rs6000_double_float = 1;
2728 /* Reset single and double FP flags if target is E500. */
2731 rs6000_single_float = rs6000_double_float = 0;
2732 if (TARGET_E500_SINGLE)
2733 rs6000_single_float = 1;
2734 if (TARGET_E500_DOUBLE)
2735 rs6000_single_float = rs6000_double_float = 1;
2738 /* If not explicitly specified via option, decide whether to generate indexed
2739 load/store instructions. */
2740 if (TARGET_AVOID_XFORM == -1)
2741 /* Avoid indexed addressing when targeting Power6 in order to avoid
2742 the DERAT mispredict penalty. */
2743 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
2745 rs6000_init_hard_regno_mode_ok ();
2748 /* Implement targetm.vectorize.builtin_mask_for_load. */
2750 rs6000_builtin_mask_for_load (void)
2752 if (TARGET_ALTIVEC || TARGET_VSX)
2753 return altivec_builtin_mask_for_load;
2758 /* Implement targetm.vectorize.builtin_conversion.
2759 Returns a decl of a function that implements conversion of an integer vector
2760 into a floating-point vector, or vice-versa. TYPE is the type of the integer
2761 side of the conversion.
2762 Return NULL_TREE if it is not available. */
2764 rs6000_builtin_conversion (unsigned int tcode, tree type)
2766 enum tree_code code = (enum tree_code) tcode;
2770 case FIX_TRUNC_EXPR:
2771 switch (TYPE_MODE (type))
2774 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2777 return TYPE_UNSIGNED (type)
2778 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
2779 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
2782 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2785 return TYPE_UNSIGNED (type)
2786 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
2787 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
2794 switch (TYPE_MODE (type))
2797 if (!VECTOR_UNIT_VSX_P (V2DFmode))
2800 return TYPE_UNSIGNED (type)
2801 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
2802 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
2805 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
2808 return TYPE_UNSIGNED (type)
2809 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
2810 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
2821 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2823 rs6000_builtin_mul_widen_even (tree type)
2825 if (!TARGET_ALTIVEC)
2828 switch (TYPE_MODE (type))
2831 return TYPE_UNSIGNED (type)
2832 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
2833 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
2836 return TYPE_UNSIGNED (type)
2837 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
2838 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
2844 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2846 rs6000_builtin_mul_widen_odd (tree type)
2848 if (!TARGET_ALTIVEC)
2851 switch (TYPE_MODE (type))
2854 return TYPE_UNSIGNED (type)
2855 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
2856 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
2859 return TYPE_UNSIGNED (type)
2860 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
2861 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
2868 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2869 after applying N number of iterations. This routine does not determine
2870 how may iterations are required to reach desired alignment. */
2873 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
2880 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
2883 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
2893 /* Assuming that all other types are naturally aligned. CHECKME! */
2898 /* Implement targetm.vectorize.builtin_vec_perm. */
2900 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
2902 tree inner_type = TREE_TYPE (type);
2903 bool uns_p = TYPE_UNSIGNED (inner_type);
2906 *mask_element_type = unsigned_char_type_node;
2908 switch (TYPE_MODE (type))
2912 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
2913 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
2918 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
2919 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
2924 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
2925 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
2929 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
2933 if (!TARGET_ALLOW_DF_PERMUTE)
2936 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
2940 if (!TARGET_ALLOW_DF_PERMUTE)
2944 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
2945 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
2956 /* Handle generic options of the form -mfoo=yes/no.
2957 NAME is the option name.
2958 VALUE is the option value.
2959 FLAG is the pointer to the flag where to store a 1 or 0, depending on
2960 whether the option value is 'yes' or 'no' respectively. */
2962 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
2966 else if (!strcmp (value, "yes"))
2968 else if (!strcmp (value, "no"))
2971 error ("unknown -m%s= option specified: '%s'", name, value);
2974 /* Validate and record the size specified with the -mtls-size option. */
2977 rs6000_parse_tls_size_option (void)
2979 if (rs6000_tls_size_string == 0)
2981 else if (strcmp (rs6000_tls_size_string, "16") == 0)
2982 rs6000_tls_size = 16;
2983 else if (strcmp (rs6000_tls_size_string, "32") == 0)
2984 rs6000_tls_size = 32;
2985 else if (strcmp (rs6000_tls_size_string, "64") == 0)
2986 rs6000_tls_size = 64;
2988 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
2992 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
2994 if (DEFAULT_ABI == ABI_DARWIN)
2995 /* The Darwin libraries never set errno, so we might as well
2996 avoid calling them when that's the only reason we would. */
2997 flag_errno_math = 0;
2999 /* Double growth factor to counter reduced min jump length. */
3000 set_param_value ("max-grow-copy-bb-insns", 16);
3002 /* Enable section anchors by default.
3003 Skip section anchors for Objective C and Objective C++
3004 until front-ends fixed. */
3005 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3006 flag_section_anchors = 2;
3009 static enum fpu_type_t
3010 rs6000_parse_fpu_option (const char *option)
3012 if (!strcmp("none", option)) return FPU_NONE;
3013 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3014 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3015 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3016 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3017 error("unknown value %s for -mfpu", option);
3021 /* Returns a function decl for a vectorized version of the builtin function
3022 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3023 if it is not available. */
3026 rs6000_builtin_vectorized_function (unsigned int fn, tree type_out,
3029 enum machine_mode in_mode, out_mode;
3032 if (TREE_CODE (type_out) != VECTOR_TYPE
3033 || TREE_CODE (type_in) != VECTOR_TYPE
3034 || !TARGET_VECTORIZE_BUILTINS)
3037 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3038 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3039 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3040 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3044 case BUILT_IN_COPYSIGN:
3045 if (VECTOR_UNIT_VSX_P (V2DFmode)
3046 && out_mode == DFmode && out_n == 2
3047 && in_mode == DFmode && in_n == 2)
3048 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3050 case BUILT_IN_COPYSIGNF:
3051 if (out_mode != SFmode || out_n != 4
3052 || in_mode != SFmode || in_n != 4)
3054 if (VECTOR_UNIT_VSX_P (V4SFmode))
3055 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3056 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3057 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3060 if (VECTOR_UNIT_VSX_P (V2DFmode)
3061 && out_mode == DFmode && out_n == 2
3062 && in_mode == DFmode && in_n == 2)
3063 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3065 case BUILT_IN_SQRTF:
3066 if (VECTOR_UNIT_VSX_P (V4SFmode)
3067 && out_mode == SFmode && out_n == 4
3068 && in_mode == SFmode && in_n == 4)
3069 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3072 if (VECTOR_UNIT_VSX_P (V2DFmode)
3073 && out_mode == DFmode && out_n == 2
3074 && in_mode == DFmode && in_n == 2)
3075 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3077 case BUILT_IN_CEILF:
3078 if (out_mode != SFmode || out_n != 4
3079 || in_mode != SFmode || in_n != 4)
3081 if (VECTOR_UNIT_VSX_P (V4SFmode))
3082 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3083 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3084 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3086 case BUILT_IN_FLOOR:
3087 if (VECTOR_UNIT_VSX_P (V2DFmode)
3088 && out_mode == DFmode && out_n == 2
3089 && in_mode == DFmode && in_n == 2)
3090 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3092 case BUILT_IN_FLOORF:
3093 if (out_mode != SFmode || out_n != 4
3094 || in_mode != SFmode || in_n != 4)
3096 if (VECTOR_UNIT_VSX_P (V4SFmode))
3097 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3098 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3099 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3101 case BUILT_IN_TRUNC:
3102 if (VECTOR_UNIT_VSX_P (V2DFmode)
3103 && out_mode == DFmode && out_n == 2
3104 && in_mode == DFmode && in_n == 2)
3105 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3107 case BUILT_IN_TRUNCF:
3108 if (out_mode != SFmode || out_n != 4
3109 || in_mode != SFmode || in_n != 4)
3111 if (VECTOR_UNIT_VSX_P (V4SFmode))
3112 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3113 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3114 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3116 case BUILT_IN_NEARBYINT:
3117 if (VECTOR_UNIT_VSX_P (V2DFmode)
3118 && flag_unsafe_math_optimizations
3119 && out_mode == DFmode && out_n == 2
3120 && in_mode == DFmode && in_n == 2)
3121 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3123 case BUILT_IN_NEARBYINTF:
3124 if (VECTOR_UNIT_VSX_P (V4SFmode)
3125 && flag_unsafe_math_optimizations
3126 && out_mode == SFmode && out_n == 4
3127 && in_mode == SFmode && in_n == 4)
3128 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3131 if (VECTOR_UNIT_VSX_P (V2DFmode)
3132 && !flag_trapping_math
3133 && out_mode == DFmode && out_n == 2
3134 && in_mode == DFmode && in_n == 2)
3135 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3137 case BUILT_IN_RINTF:
3138 if (VECTOR_UNIT_VSX_P (V4SFmode)
3139 && !flag_trapping_math
3140 && out_mode == SFmode && out_n == 4
3141 && in_mode == SFmode && in_n == 4)
3142 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3151 /* Implement TARGET_HANDLE_OPTION. */
3154 rs6000_handle_option (size_t code, const char *arg, int value)
3156 enum fpu_type_t fpu_type = FPU_NONE;
3162 target_flags &= ~(MASK_POWER | MASK_POWER2
3163 | MASK_MULTIPLE | MASK_STRING);
3164 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3165 | MASK_MULTIPLE | MASK_STRING);
3167 case OPT_mno_powerpc:
3168 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3169 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3170 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3171 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3174 target_flags &= ~MASK_MINIMAL_TOC;
3175 TARGET_NO_FP_IN_TOC = 0;
3176 TARGET_NO_SUM_IN_TOC = 0;
3177 target_flags_explicit |= MASK_MINIMAL_TOC;
3178 #ifdef TARGET_USES_SYSV4_OPT
3179 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3180 just the same as -mminimal-toc. */
3181 target_flags |= MASK_MINIMAL_TOC;
3182 target_flags_explicit |= MASK_MINIMAL_TOC;
3186 #ifdef TARGET_USES_SYSV4_OPT
3188 /* Make -mtoc behave like -mminimal-toc. */
3189 target_flags |= MASK_MINIMAL_TOC;
3190 target_flags_explicit |= MASK_MINIMAL_TOC;
3194 #ifdef TARGET_USES_AIX64_OPT
3199 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3200 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3201 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3204 #ifdef TARGET_USES_AIX64_OPT
3209 target_flags &= ~MASK_POWERPC64;
3210 target_flags_explicit |= MASK_POWERPC64;
3213 case OPT_minsert_sched_nops_:
3214 rs6000_sched_insert_nops_str = arg;
3217 case OPT_mminimal_toc:
3220 TARGET_NO_FP_IN_TOC = 0;
3221 TARGET_NO_SUM_IN_TOC = 0;
3228 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3229 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3236 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3237 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3241 case OPT_mpowerpc_gpopt:
3242 case OPT_mpowerpc_gfxopt:
3245 target_flags |= MASK_POWERPC;
3246 target_flags_explicit |= MASK_POWERPC;
3250 case OPT_maix_struct_return:
3251 case OPT_msvr4_struct_return:
3252 rs6000_explicit_options.aix_struct_ret = true;
3256 rs6000_explicit_options.vrsave = true;
3257 TARGET_ALTIVEC_VRSAVE = value;
3261 rs6000_explicit_options.vrsave = true;
3262 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3266 target_flags_explicit |= MASK_ISEL;
3268 rs6000_parse_yes_no_option ("isel", arg, &isel);
3270 target_flags |= MASK_ISEL;
3272 target_flags &= ~MASK_ISEL;
3276 rs6000_explicit_options.spe = true;
3281 rs6000_explicit_options.spe = true;
3282 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3286 rs6000_debug_name = arg;
3289 #ifdef TARGET_USES_SYSV4_OPT
3291 rs6000_abi_name = arg;
3295 rs6000_sdata_name = arg;
3298 case OPT_mtls_size_:
3299 rs6000_tls_size_string = arg;
3302 case OPT_mrelocatable:
3305 target_flags |= MASK_MINIMAL_TOC;
3306 target_flags_explicit |= MASK_MINIMAL_TOC;
3307 TARGET_NO_FP_IN_TOC = 1;
3311 case OPT_mrelocatable_lib:
3314 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3315 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3316 TARGET_NO_FP_IN_TOC = 1;
3320 target_flags &= ~MASK_RELOCATABLE;
3321 target_flags_explicit |= MASK_RELOCATABLE;
3327 if (!strcmp (arg, "altivec"))
3329 rs6000_explicit_options.altivec_abi = true;
3330 rs6000_altivec_abi = 1;
3332 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3335 else if (! strcmp (arg, "no-altivec"))
3337 rs6000_explicit_options.altivec_abi = true;
3338 rs6000_altivec_abi = 0;
3340 else if (! strcmp (arg, "spe"))
3342 rs6000_explicit_options.spe_abi = true;
3344 rs6000_altivec_abi = 0;
3345 if (!TARGET_SPE_ABI)
3346 error ("not configured for ABI: '%s'", arg);
3348 else if (! strcmp (arg, "no-spe"))
3350 rs6000_explicit_options.spe_abi = true;
3354 /* These are here for testing during development only, do not
3355 document in the manual please. */
3356 else if (! strcmp (arg, "d64"))
3358 rs6000_darwin64_abi = 1;
3359 warning (0, "Using darwin64 ABI");
3361 else if (! strcmp (arg, "d32"))
3363 rs6000_darwin64_abi = 0;
3364 warning (0, "Using old darwin ABI");
3367 else if (! strcmp (arg, "ibmlongdouble"))
3369 rs6000_explicit_options.ieee = true;
3370 rs6000_ieeequad = 0;
3371 warning (0, "Using IBM extended precision long double");
3373 else if (! strcmp (arg, "ieeelongdouble"))
3375 rs6000_explicit_options.ieee = true;
3376 rs6000_ieeequad = 1;
3377 warning (0, "Using IEEE extended precision long double");
3382 error ("unknown ABI specified: '%s'", arg);
3388 rs6000_select[1].string = arg;
3392 rs6000_select[2].string = arg;
3395 case OPT_mtraceback_:
3396 rs6000_traceback_name = arg;
3399 case OPT_mfloat_gprs_:
3400 rs6000_explicit_options.float_gprs = true;
3401 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3402 rs6000_float_gprs = 1;
3403 else if (! strcmp (arg, "double"))
3404 rs6000_float_gprs = 2;
3405 else if (! strcmp (arg, "no"))
3406 rs6000_float_gprs = 0;
3409 error ("invalid option for -mfloat-gprs: '%s'", arg);
3414 case OPT_mlong_double_:
3415 rs6000_explicit_options.long_double = true;
3416 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3417 if (value != 64 && value != 128)
3419 error ("Unknown switch -mlong-double-%s", arg);
3420 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3424 rs6000_long_double_type_size = value;
3427 case OPT_msched_costly_dep_:
3428 rs6000_sched_costly_dep_str = arg;
3432 rs6000_explicit_options.alignment = true;
3433 if (! strcmp (arg, "power"))
3435 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3436 some C library functions, so warn about it. The flag may be
3437 useful for performance studies from time to time though, so
3438 don't disable it entirely. */
3439 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3440 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3441 " it is incompatible with the installed C and C++ libraries");
3442 rs6000_alignment_flags = MASK_ALIGN_POWER;
3444 else if (! strcmp (arg, "natural"))
3445 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3448 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3453 case OPT_msingle_float:
3454 if (!TARGET_SINGLE_FPU)
3455 warning (0, "-msingle-float option equivalent to -mhard-float");
3456 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3457 rs6000_double_float = 0;
3458 target_flags &= ~MASK_SOFT_FLOAT;
3459 target_flags_explicit |= MASK_SOFT_FLOAT;
3462 case OPT_mdouble_float:
3463 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3464 rs6000_single_float = 1;
3465 target_flags &= ~MASK_SOFT_FLOAT;
3466 target_flags_explicit |= MASK_SOFT_FLOAT;
3469 case OPT_msimple_fpu:
3470 if (!TARGET_SINGLE_FPU)
3471 warning (0, "-msimple-fpu option ignored");
3474 case OPT_mhard_float:
3475 /* -mhard_float implies -msingle-float and -mdouble-float. */
3476 rs6000_single_float = rs6000_double_float = 1;
3479 case OPT_msoft_float:
3480 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3481 rs6000_single_float = rs6000_double_float = 0;
3485 fpu_type = rs6000_parse_fpu_option(arg);
3486 if (fpu_type != FPU_NONE)
3487 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3489 target_flags &= ~MASK_SOFT_FLOAT;
3490 target_flags_explicit |= MASK_SOFT_FLOAT;
3491 rs6000_xilinx_fpu = 1;
3492 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3493 rs6000_single_float = 1;
3494 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3495 rs6000_single_float = rs6000_double_float = 1;
3496 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3497 rs6000_simple_fpu = 1;
3501 /* -mfpu=none is equivalent to -msoft-float */
3502 target_flags |= MASK_SOFT_FLOAT;
3503 target_flags_explicit |= MASK_SOFT_FLOAT;
3504 rs6000_single_float = rs6000_double_float = 0;
3511 /* Do anything needed at the start of the asm file. */
3514 rs6000_file_start (void)
3518 const char *start = buffer;
3519 struct rs6000_cpu_select *ptr;
3520 const char *default_cpu = TARGET_CPU_DEFAULT;
3521 FILE *file = asm_out_file;
3523 default_file_start ();
3525 #ifdef TARGET_BI_ARCH
3526 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3530 if (flag_verbose_asm)
3532 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3533 rs6000_select[0].string = default_cpu;
3535 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3537 ptr = &rs6000_select[i];
3538 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
3540 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
3545 if (PPC405_ERRATUM77)
3547 fprintf (file, "%s PPC405CR_ERRATUM77", start);
3551 #ifdef USING_ELFOS_H
3552 switch (rs6000_sdata)
3554 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
3555 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
3556 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
3557 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
3560 if (rs6000_sdata && g_switch_value)
3562 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
3572 #ifdef HAVE_AS_GNU_ATTRIBUTE
3573 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
3575 fprintf (file, "\t.gnu_attribute 4, %d\n",
3576 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
3577 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
3579 fprintf (file, "\t.gnu_attribute 8, %d\n",
3580 (TARGET_ALTIVEC_ABI ? 2
3581 : TARGET_SPE_ABI ? 3
3583 fprintf (file, "\t.gnu_attribute 12, %d\n",
3584 aix_struct_return ? 2 : 1);
3589 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
3591 switch_to_section (toc_section);
3592 switch_to_section (text_section);
3597 /* Return nonzero if this function is known to have a null epilogue. */
3600 direct_return (void)
3602 if (reload_completed)
3604 rs6000_stack_t *info = rs6000_stack_info ();
3606 if (info->first_gp_reg_save == 32
3607 && info->first_fp_reg_save == 64
3608 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
3609 && ! info->lr_save_p
3610 && ! info->cr_save_p
3611 && info->vrsave_mask == 0
3619 /* Return the number of instructions it takes to form a constant in an
3620 integer register. */
3623 num_insns_constant_wide (HOST_WIDE_INT value)
3625 /* signed constant loadable with {cal|addi} */
3626 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
3629 /* constant loadable with {cau|addis} */
3630 else if ((value & 0xffff) == 0
3631 && (value >> 31 == -1 || value >> 31 == 0))
3634 #if HOST_BITS_PER_WIDE_INT == 64
3635 else if (TARGET_POWERPC64)
3637 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
3638 HOST_WIDE_INT high = value >> 31;
3640 if (high == 0 || high == -1)
3646 return num_insns_constant_wide (high) + 1;
3648 return (num_insns_constant_wide (high)
3649 + num_insns_constant_wide (low) + 1);
3658 num_insns_constant (rtx op, enum machine_mode mode)
3660 HOST_WIDE_INT low, high;
3662 switch (GET_CODE (op))
3665 #if HOST_BITS_PER_WIDE_INT == 64
3666 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
3667 && mask64_operand (op, mode))
3671 return num_insns_constant_wide (INTVAL (op));
3674 if (mode == SFmode || mode == SDmode)
3679 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3680 if (DECIMAL_FLOAT_MODE_P (mode))
3681 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
3683 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
3684 return num_insns_constant_wide ((HOST_WIDE_INT) l);
3687 if (mode == VOIDmode || mode == DImode)
3689 high = CONST_DOUBLE_HIGH (op);
3690 low = CONST_DOUBLE_LOW (op);
3697 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
3698 if (DECIMAL_FLOAT_MODE_P (mode))
3699 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
3701 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
3702 high = l[WORDS_BIG_ENDIAN == 0];
3703 low = l[WORDS_BIG_ENDIAN != 0];
3707 return (num_insns_constant_wide (low)
3708 + num_insns_constant_wide (high));
3711 if ((high == 0 && low >= 0)
3712 || (high == -1 && low < 0))
3713 return num_insns_constant_wide (low);
3715 else if (mask64_operand (op, mode))
3719 return num_insns_constant_wide (high) + 1;
3722 return (num_insns_constant_wide (high)
3723 + num_insns_constant_wide (low) + 1);
3731 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
3732 If the mode of OP is MODE_VECTOR_INT, this simply returns the
3733 corresponding element of the vector, but for V4SFmode and V2SFmode,
3734 the corresponding "float" is interpreted as an SImode integer. */
3737 const_vector_elt_as_int (rtx op, unsigned int elt)
3739 rtx tmp = CONST_VECTOR_ELT (op, elt);
3740 if (GET_MODE (op) == V4SFmode
3741 || GET_MODE (op) == V2SFmode)
3742 tmp = gen_lowpart (SImode, tmp);
3743 return INTVAL (tmp);
3746 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
3747 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
3748 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
3749 all items are set to the same value and contain COPIES replicas of the
3750 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
3751 operand and the others are set to the value of the operand's msb. */
3754 vspltis_constant (rtx op, unsigned step, unsigned copies)
3756 enum machine_mode mode = GET_MODE (op);
3757 enum machine_mode inner = GET_MODE_INNER (mode);
3760 unsigned nunits = GET_MODE_NUNITS (mode);
3761 unsigned bitsize = GET_MODE_BITSIZE (inner);
3762 unsigned mask = GET_MODE_MASK (inner);
3764 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
3765 HOST_WIDE_INT splat_val = val;
3766 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
3768 /* Construct the value to be splatted, if possible. If not, return 0. */
3769 for (i = 2; i <= copies; i *= 2)
3771 HOST_WIDE_INT small_val;
3773 small_val = splat_val >> bitsize;
3775 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
3777 splat_val = small_val;
3780 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
3781 if (EASY_VECTOR_15 (splat_val))
3784 /* Also check if we can splat, and then add the result to itself. Do so if
3785 the value is positive, of if the splat instruction is using OP's mode;
3786 for splat_val < 0, the splat and the add should use the same mode. */
3787 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
3788 && (splat_val >= 0 || (step == 1 && copies == 1)))
3791 /* Also check if are loading up the most significant bit which can be done by
3792 loading up -1 and shifting the value left by -1. */
3793 else if (EASY_VECTOR_MSB (splat_val, inner))
3799 /* Check if VAL is present in every STEP-th element, and the
3800 other elements are filled with its most significant bit. */
3801 for (i = 0; i < nunits - 1; ++i)
3803 HOST_WIDE_INT desired_val;
3804 if (((i + 1) & (step - 1)) == 0)
3807 desired_val = msb_val;
3809 if (desired_val != const_vector_elt_as_int (op, i))
3817 /* Return true if OP is of the given MODE and can be synthesized
3818 with a vspltisb, vspltish or vspltisw. */
3821 easy_altivec_constant (rtx op, enum machine_mode mode)
3823 unsigned step, copies;
3825 if (mode == VOIDmode)
3826 mode = GET_MODE (op);
3827 else if (mode != GET_MODE (op))
3830 /* Start with a vspltisw. */
3831 step = GET_MODE_NUNITS (mode) / 4;
3834 if (vspltis_constant (op, step, copies))
3837 /* Then try with a vspltish. */
3843 if (vspltis_constant (op, step, copies))
3846 /* And finally a vspltisb. */
3852 if (vspltis_constant (op, step, copies))
3858 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
3859 result is OP. Abort if it is not possible. */
3862 gen_easy_altivec_constant (rtx op)
3864 enum machine_mode mode = GET_MODE (op);
3865 int nunits = GET_MODE_NUNITS (mode);
3866 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
3867 unsigned step = nunits / 4;
3868 unsigned copies = 1;
3870 /* Start with a vspltisw. */
3871 if (vspltis_constant (op, step, copies))
3872 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
3874 /* Then try with a vspltish. */
3880 if (vspltis_constant (op, step, copies))
3881 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
3883 /* And finally a vspltisb. */
3889 if (vspltis_constant (op, step, copies))
3890 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
3896 output_vec_const_move (rtx *operands)
3899 enum machine_mode mode;
3904 mode = GET_MODE (dest);
3906 if (TARGET_VSX && zero_constant (vec, mode))
3907 return "xxlxor %x0,%x0,%x0";
3912 if (zero_constant (vec, mode))
3913 return "vxor %0,%0,%0";
3915 splat_vec = gen_easy_altivec_constant (vec);
3916 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
3917 operands[1] = XEXP (splat_vec, 0);
3918 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
3921 switch (GET_MODE (splat_vec))
3924 return "vspltisw %0,%1";
3927 return "vspltish %0,%1";
3930 return "vspltisb %0,%1";
3937 gcc_assert (TARGET_SPE);
3939 /* Vector constant 0 is handled as a splitter of V2SI, and in the
3940 pattern of V1DI, V4HI, and V2SF.
3942 FIXME: We should probably return # and add post reload
3943 splitters for these, but this way is so easy ;-). */
3944 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
3945 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
3946 operands[1] = CONST_VECTOR_ELT (vec, 0);
3947 operands[2] = CONST_VECTOR_ELT (vec, 1);
3949 return "li %0,%1\n\tevmergelo %0,%0,%0";
3951 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
3954 /* Initialize TARGET of vector PAIRED to VALS. */
3957 paired_expand_vector_init (rtx target, rtx vals)
3959 enum machine_mode mode = GET_MODE (target);
3960 int n_elts = GET_MODE_NUNITS (mode);
3962 rtx x, new_rtx, tmp, constant_op, op1, op2;
3965 for (i = 0; i < n_elts; ++i)
3967 x = XVECEXP (vals, 0, i);
3968 if (!CONSTANT_P (x))
3973 /* Load from constant pool. */
3974 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
3980 /* The vector is initialized only with non-constants. */
3981 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
3982 XVECEXP (vals, 0, 1));
3984 emit_move_insn (target, new_rtx);
3988 /* One field is non-constant and the other one is a constant. Load the
3989 constant from the constant pool and use ps_merge instruction to
3990 construct the whole vector. */
3991 op1 = XVECEXP (vals, 0, 0);
3992 op2 = XVECEXP (vals, 0, 1);
3994 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
3996 tmp = gen_reg_rtx (GET_MODE (constant_op));
3997 emit_move_insn (tmp, constant_op);
3999 if (CONSTANT_P (op1))
4000 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4002 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4004 emit_move_insn (target, new_rtx);
4008 paired_expand_vector_move (rtx operands[])
4010 rtx op0 = operands[0], op1 = operands[1];
4012 emit_move_insn (op0, op1);
4015 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4016 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4017 operands for the relation operation COND. This is a recursive
4021 paired_emit_vector_compare (enum rtx_code rcode,
4022 rtx dest, rtx op0, rtx op1,
4023 rtx cc_op0, rtx cc_op1)
4025 rtx tmp = gen_reg_rtx (V2SFmode);
4026 rtx tmp1, max, min, equal_zero;
4028 gcc_assert (TARGET_PAIRED_FLOAT);
4029 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4035 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4039 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4040 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4044 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4047 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4050 tmp1 = gen_reg_rtx (V2SFmode);
4051 max = gen_reg_rtx (V2SFmode);
4052 min = gen_reg_rtx (V2SFmode);
4053 equal_zero = gen_reg_rtx (V2SFmode);
4055 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4056 emit_insn (gen_selv2sf4
4057 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4058 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4059 emit_insn (gen_selv2sf4
4060 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4061 emit_insn (gen_subv2sf3 (tmp1, min, max));
4062 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4065 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4068 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4071 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4074 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4077 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4086 /* Emit vector conditional expression.
4087 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4088 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4091 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4092 rtx cond, rtx cc_op0, rtx cc_op1)
4094 enum rtx_code rcode = GET_CODE (cond);
4096 if (!TARGET_PAIRED_FLOAT)
4099 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4104 /* Initialize vector TARGET to VALS. */
4107 rs6000_expand_vector_init (rtx target, rtx vals)
4109 enum machine_mode mode = GET_MODE (target);
4110 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4111 int n_elts = GET_MODE_NUNITS (mode);
4112 int n_var = 0, one_var = -1;
4113 bool all_same = true, all_const_zero = true;
4117 for (i = 0; i < n_elts; ++i)
4119 x = XVECEXP (vals, 0, i);
4120 if (!CONSTANT_P (x))
4121 ++n_var, one_var = i;
4122 else if (x != CONST0_RTX (inner_mode))
4123 all_const_zero = false;
4125 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4131 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4132 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4133 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4135 /* Zero register. */
4136 emit_insn (gen_rtx_SET (VOIDmode, target,
4137 gen_rtx_XOR (mode, target, target)));
4140 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4142 /* Splat immediate. */
4143 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4148 /* Load from constant pool. */
4149 emit_move_insn (target, const_vec);
4154 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4155 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4159 rtx element = XVECEXP (vals, 0, 0);
4160 if (mode == V2DFmode)
4161 emit_insn (gen_vsx_splat_v2df (target, element));
4163 emit_insn (gen_vsx_splat_v2di (target, element));
4167 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4168 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4169 if (mode == V2DFmode)
4170 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4172 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4177 /* With single precision floating point on VSX, know that internally single
4178 precision is actually represented as a double, and either make 2 V2DF
4179 vectors, and convert these vectors to single precision, or do one
4180 conversion, and splat the result to the other elements. */
4181 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4185 rtx freg = gen_reg_rtx (V4SFmode);
4186 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4188 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4189 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4193 rtx dbl_even = gen_reg_rtx (V2DFmode);
4194 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4195 rtx flt_even = gen_reg_rtx (V4SFmode);
4196 rtx flt_odd = gen_reg_rtx (V4SFmode);
4198 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4199 copy_to_reg (XVECEXP (vals, 0, 0)),
4200 copy_to_reg (XVECEXP (vals, 0, 1))));
4201 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4202 copy_to_reg (XVECEXP (vals, 0, 2)),
4203 copy_to_reg (XVECEXP (vals, 0, 3))));
4204 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4205 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4206 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4211 /* Store value to stack temp. Load vector element. Splat. However, splat
4212 of 64-bit items is not supported on Altivec. */
4213 if (all_same && GET_MODE_SIZE (mode) <= 4)
4215 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4216 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4217 XVECEXP (vals, 0, 0));
4218 x = gen_rtx_UNSPEC (VOIDmode,
4219 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4220 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4222 gen_rtx_SET (VOIDmode,
4225 x = gen_rtx_VEC_SELECT (inner_mode, target,
4226 gen_rtx_PARALLEL (VOIDmode,
4227 gen_rtvec (1, const0_rtx)));
4228 emit_insn (gen_rtx_SET (VOIDmode, target,
4229 gen_rtx_VEC_DUPLICATE (mode, x)));
4233 /* One field is non-constant. Load constant then overwrite
4237 rtx copy = copy_rtx (vals);
4239 /* Load constant part of vector, substitute neighboring value for
4241 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4242 rs6000_expand_vector_init (target, copy);
4244 /* Insert variable. */
4245 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4249 /* Construct the vector in memory one field at a time
4250 and load the whole vector. */
4251 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4252 for (i = 0; i < n_elts; i++)
4253 emit_move_insn (adjust_address_nv (mem, inner_mode,
4254 i * GET_MODE_SIZE (inner_mode)),
4255 XVECEXP (vals, 0, i));
4256 emit_move_insn (target, mem);
4259 /* Set field ELT of TARGET to VAL. */
4262 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4264 enum machine_mode mode = GET_MODE (target);
4265 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4266 rtx reg = gen_reg_rtx (mode);
4268 int width = GET_MODE_SIZE (inner_mode);
4271 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4273 rtx (*set_func) (rtx, rtx, rtx, rtx)
4274 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4275 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4279 /* Load single variable value. */
4280 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4281 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4282 x = gen_rtx_UNSPEC (VOIDmode,
4283 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4284 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4286 gen_rtx_SET (VOIDmode,
4290 /* Linear sequence. */
4291 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4292 for (i = 0; i < 16; ++i)
4293 XVECEXP (mask, 0, i) = GEN_INT (i);
4295 /* Set permute mask to insert element into target. */
4296 for (i = 0; i < width; ++i)
4297 XVECEXP (mask, 0, elt*width + i)
4298 = GEN_INT (i + 0x10);
4299 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4300 x = gen_rtx_UNSPEC (mode,
4301 gen_rtvec (3, target, reg,
4302 force_reg (V16QImode, x)),
4304 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4307 /* Extract field ELT from VEC into TARGET. */
4310 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4312 enum machine_mode mode = GET_MODE (vec);
4313 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4316 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4318 rtx (*extract_func) (rtx, rtx, rtx)
4319 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4320 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4324 /* Allocate mode-sized buffer. */
4325 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4327 /* Add offset to field within buffer matching vector element. */
4328 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4330 /* Store single field into mode-sized buffer. */
4331 x = gen_rtx_UNSPEC (VOIDmode,
4332 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4333 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4335 gen_rtx_SET (VOIDmode,
4338 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4341 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4342 implement ANDing by the mask IN. */
4344 build_mask64_2_operands (rtx in, rtx *out)
4346 #if HOST_BITS_PER_WIDE_INT >= 64
4347 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4350 gcc_assert (GET_CODE (in) == CONST_INT);
4355 /* Assume c initially something like 0x00fff000000fffff. The idea
4356 is to rotate the word so that the middle ^^^^^^ group of zeros
4357 is at the MS end and can be cleared with an rldicl mask. We then
4358 rotate back and clear off the MS ^^ group of zeros with a
4360 c = ~c; /* c == 0xff000ffffff00000 */
4361 lsb = c & -c; /* lsb == 0x0000000000100000 */
4362 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4363 c = ~c; /* c == 0x00fff000000fffff */
4364 c &= -lsb; /* c == 0x00fff00000000000 */
4365 lsb = c & -c; /* lsb == 0x0000100000000000 */
4366 c = ~c; /* c == 0xff000fffffffffff */
4367 c &= -lsb; /* c == 0xff00000000000000 */
4369 while ((lsb >>= 1) != 0)
4370 shift++; /* shift == 44 on exit from loop */
4371 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4372 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4373 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4377 /* Assume c initially something like 0xff000f0000000000. The idea
4378 is to rotate the word so that the ^^^ middle group of zeros
4379 is at the LS end and can be cleared with an rldicr mask. We then
4380 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4382 lsb = c & -c; /* lsb == 0x0000010000000000 */
4383 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4384 c = ~c; /* c == 0x00fff0ffffffffff */
4385 c &= -lsb; /* c == 0x00fff00000000000 */
4386 lsb = c & -c; /* lsb == 0x0000100000000000 */
4387 c = ~c; /* c == 0xff000fffffffffff */
4388 c &= -lsb; /* c == 0xff00000000000000 */
4390 while ((lsb >>= 1) != 0)
4391 shift++; /* shift == 44 on exit from loop */
4392 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4393 m1 >>= shift; /* m1 == 0x0000000000000fff */
4394 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4397 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4398 masks will be all 1's. We are guaranteed more than one transition. */
4399 out[0] = GEN_INT (64 - shift);
4400 out[1] = GEN_INT (m1);
4401 out[2] = GEN_INT (shift);
4402 out[3] = GEN_INT (m2);
4410 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4413 invalid_e500_subreg (rtx op, enum machine_mode mode)
4415 if (TARGET_E500_DOUBLE)
4417 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4418 subreg:TI and reg:TF. Decimal float modes are like integer
4419 modes (only low part of each register used) for this
4421 if (GET_CODE (op) == SUBREG
4422 && (mode == SImode || mode == DImode || mode == TImode
4423 || mode == DDmode || mode == TDmode)
4424 && REG_P (SUBREG_REG (op))
4425 && (GET_MODE (SUBREG_REG (op)) == DFmode
4426 || GET_MODE (SUBREG_REG (op)) == TFmode))
4429 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4431 if (GET_CODE (op) == SUBREG
4432 && (mode == DFmode || mode == TFmode)
4433 && REG_P (SUBREG_REG (op))
4434 && (GET_MODE (SUBREG_REG (op)) == DImode
4435 || GET_MODE (SUBREG_REG (op)) == TImode
4436 || GET_MODE (SUBREG_REG (op)) == DDmode
4437 || GET_MODE (SUBREG_REG (op)) == TDmode))
4442 && GET_CODE (op) == SUBREG
4444 && REG_P (SUBREG_REG (op))
4445 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4451 /* AIX increases natural record alignment to doubleword if the first
4452 field is an FP double while the FP fields remain word aligned. */
4455 rs6000_special_round_type_align (tree type, unsigned int computed,
4456 unsigned int specified)
4458 unsigned int align = MAX (computed, specified);
4459 tree field = TYPE_FIELDS (type);
4461 /* Skip all non field decls */
4462 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4463 field = TREE_CHAIN (field);
4465 if (field != NULL && field != type)
4467 type = TREE_TYPE (field);
4468 while (TREE_CODE (type) == ARRAY_TYPE)
4469 type = TREE_TYPE (type);
4471 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4472 align = MAX (align, 64);
4478 /* Darwin increases record alignment to the natural alignment of
4482 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4483 unsigned int specified)
4485 unsigned int align = MAX (computed, specified);
4487 if (TYPE_PACKED (type))
4490 /* Find the first field, looking down into aggregates. */
4492 tree field = TYPE_FIELDS (type);
4493 /* Skip all non field decls */
4494 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4495 field = TREE_CHAIN (field);
4498 type = TREE_TYPE (field);
4499 while (TREE_CODE (type) == ARRAY_TYPE)
4500 type = TREE_TYPE (type);
4501 } while (AGGREGATE_TYPE_P (type));
4503 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
4504 align = MAX (align, TYPE_ALIGN (type));
4509 /* Return 1 for an operand in small memory on V.4/eabi. */
4512 small_data_operand (rtx op ATTRIBUTE_UNUSED,
4513 enum machine_mode mode ATTRIBUTE_UNUSED)
4518 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
4521 if (DEFAULT_ABI != ABI_V4)
4524 /* Vector and float memory instructions have a limited offset on the
4525 SPE, so using a vector or float variable directly as an operand is
4528 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
4531 if (GET_CODE (op) == SYMBOL_REF)
4534 else if (GET_CODE (op) != CONST
4535 || GET_CODE (XEXP (op, 0)) != PLUS
4536 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
4537 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
4542 rtx sum = XEXP (op, 0);
4543 HOST_WIDE_INT summand;
4545 /* We have to be careful here, because it is the referenced address
4546 that must be 32k from _SDA_BASE_, not just the symbol. */
4547 summand = INTVAL (XEXP (sum, 1));
4548 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
4551 sym_ref = XEXP (sum, 0);
4554 return SYMBOL_REF_SMALL_P (sym_ref);
4560 /* Return true if either operand is a general purpose register. */
4563 gpr_or_gpr_p (rtx op0, rtx op1)
4565 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
4566 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
4570 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
4573 reg_offset_addressing_ok_p (enum machine_mode mode)
4583 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
4584 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
4592 /* Paired vector modes. Only reg+reg addressing is valid. */
4593 if (TARGET_PAIRED_FLOAT)
4605 virtual_stack_registers_memory_p (rtx op)
4609 if (GET_CODE (op) == REG)
4610 regnum = REGNO (op);
4612 else if (GET_CODE (op) == PLUS
4613 && GET_CODE (XEXP (op, 0)) == REG
4614 && GET_CODE (XEXP (op, 1)) == CONST_INT)
4615 regnum = REGNO (XEXP (op, 0));
4620 return (regnum >= FIRST_VIRTUAL_REGISTER
4621 && regnum <= LAST_VIRTUAL_REGISTER);
4625 constant_pool_expr_p (rtx op)
4629 split_const (op, &base, &offset);
4630 return (GET_CODE (base) == SYMBOL_REF
4631 && CONSTANT_POOL_ADDRESS_P (base)
4632 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
4636 toc_relative_expr_p (rtx op)
4640 if (GET_CODE (op) != CONST)
4643 split_const (op, &base, &offset);
4644 return (GET_CODE (base) == UNSPEC
4645 && XINT (base, 1) == UNSPEC_TOCREL);
4649 legitimate_constant_pool_address_p (rtx x)
4652 && GET_CODE (x) == PLUS
4653 && GET_CODE (XEXP (x, 0)) == REG
4654 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
4655 && toc_relative_expr_p (XEXP (x, 1)));
4659 legitimate_small_data_p (enum machine_mode mode, rtx x)
4661 return (DEFAULT_ABI == ABI_V4
4662 && !flag_pic && !TARGET_TOC
4663 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
4664 && small_data_operand (x, mode));
4667 /* SPE offset addressing is limited to 5-bits worth of double words. */
4668 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
4671 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
4673 unsigned HOST_WIDE_INT offset, extra;
4675 if (GET_CODE (x) != PLUS)
4677 if (GET_CODE (XEXP (x, 0)) != REG)
4679 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4681 if (!reg_offset_addressing_ok_p (mode))
4682 return virtual_stack_registers_memory_p (x);
4683 if (legitimate_constant_pool_address_p (x))
4685 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4688 offset = INTVAL (XEXP (x, 1));
4696 /* SPE vector modes. */
4697 return SPE_CONST_OFFSET_OK (offset);
4700 if (TARGET_E500_DOUBLE)
4701 return SPE_CONST_OFFSET_OK (offset);
4703 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
4705 if (VECTOR_MEM_VSX_P (DFmode))
4710 /* On e500v2, we may have:
4712 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
4714 Which gets addressed with evldd instructions. */
4715 if (TARGET_E500_DOUBLE)
4716 return SPE_CONST_OFFSET_OK (offset);
4718 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
4720 else if (offset & 3)
4725 if (TARGET_E500_DOUBLE)
4726 return (SPE_CONST_OFFSET_OK (offset)
4727 && SPE_CONST_OFFSET_OK (offset + 8));
4731 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
4733 else if (offset & 3)
4744 return (offset < 0x10000) && (offset + extra < 0x10000);
4748 legitimate_indexed_address_p (rtx x, int strict)
4752 if (GET_CODE (x) != PLUS)
4758 /* Recognize the rtl generated by reload which we know will later be
4759 replaced with proper base and index regs. */
4761 && reload_in_progress
4762 && (REG_P (op0) || GET_CODE (op0) == PLUS)
4766 return (REG_P (op0) && REG_P (op1)
4767 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
4768 && INT_REG_OK_FOR_INDEX_P (op1, strict))
4769 || (INT_REG_OK_FOR_BASE_P (op1, strict)
4770 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
4774 avoiding_indexed_address_p (enum machine_mode mode)
4776 /* Avoid indexed addressing for modes that have non-indexed
4777 load/store instruction forms. */
4778 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
4782 legitimate_indirect_address_p (rtx x, int strict)
4784 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
4788 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
4790 if (!TARGET_MACHO || !flag_pic
4791 || mode != SImode || GET_CODE (x) != MEM)
4795 if (GET_CODE (x) != LO_SUM)
4797 if (GET_CODE (XEXP (x, 0)) != REG)
4799 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
4803 return CONSTANT_P (x);
4807 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
4809 if (GET_CODE (x) != LO_SUM)
4811 if (GET_CODE (XEXP (x, 0)) != REG)
4813 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
4815 /* Restrict addressing for DI because of our SUBREG hackery. */
4816 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4817 || mode == DDmode || mode == TDmode
4822 if (TARGET_ELF || TARGET_MACHO)
4824 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
4828 if (GET_MODE_NUNITS (mode) != 1)
4830 if (GET_MODE_BITSIZE (mode) > 64
4831 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
4832 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4833 && (mode == DFmode || mode == DDmode))))
4836 return CONSTANT_P (x);
4843 /* Try machine-dependent ways of modifying an illegitimate address
4844 to be legitimate. If we find one, return the new, valid address.
4845 This is used from only one place: `memory_address' in explow.c.
4847 OLDX is the address as it was before break_out_memory_refs was
4848 called. In some cases it is useful to look at this to decide what
4851 It is always safe for this function to do nothing. It exists to
4852 recognize opportunities to optimize the output.
4854 On RS/6000, first check for the sum of a register with a constant
4855 integer that is out of range. If so, generate code to add the
4856 constant with the low-order 16 bits masked to the register and force
4857 this result into another register (this can be done with `cau').
4858 Then generate an address of REG+(CONST&0xffff), allowing for the
4859 possibility of bit 16 being a one.
4861 Then check for the sum of a register and something not constant, try to
4862 load the other things into a register and return the sum. */
4865 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
4866 enum machine_mode mode)
4868 unsigned int extra = 0;
4870 if (!reg_offset_addressing_ok_p (mode))
4872 if (virtual_stack_registers_memory_p (x))
4875 /* In theory we should not be seeing addresses of the form reg+0,
4876 but just in case it is generated, optimize it away. */
4877 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
4878 return force_reg (Pmode, XEXP (x, 0));
4880 /* Make sure both operands are registers. */
4881 else if (GET_CODE (x) == PLUS)
4882 return gen_rtx_PLUS (Pmode,
4883 force_reg (Pmode, XEXP (x, 0)),
4884 force_reg (Pmode, XEXP (x, 1)));
4886 return force_reg (Pmode, x);
4888 if (GET_CODE (x) == SYMBOL_REF)
4890 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
4892 return rs6000_legitimize_tls_address (x, model);
4902 if (!TARGET_POWERPC64)
4910 extra = TARGET_POWERPC64 ? 8 : 12;
4916 if (GET_CODE (x) == PLUS
4917 && GET_CODE (XEXP (x, 0)) == REG
4918 && GET_CODE (XEXP (x, 1)) == CONST_INT
4919 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
4921 && !((TARGET_POWERPC64
4922 && (mode == DImode || mode == TImode)
4923 && (INTVAL (XEXP (x, 1)) & 3) != 0)
4924 || SPE_VECTOR_MODE (mode)
4925 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4926 || mode == DImode || mode == DDmode
4927 || mode == TDmode))))
4929 HOST_WIDE_INT high_int, low_int;
4931 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
4932 if (low_int >= 0x8000 - extra)
4934 high_int = INTVAL (XEXP (x, 1)) - low_int;
4935 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
4936 GEN_INT (high_int)), 0);
4937 return plus_constant (sum, low_int);
4939 else if (GET_CODE (x) == PLUS
4940 && GET_CODE (XEXP (x, 0)) == REG
4941 && GET_CODE (XEXP (x, 1)) != CONST_INT
4942 && GET_MODE_NUNITS (mode) == 1
4943 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
4945 || ((mode != DImode && mode != DFmode && mode != DDmode)
4946 || (TARGET_E500_DOUBLE && mode != DDmode)))
4947 && (TARGET_POWERPC64 || mode != DImode)
4948 && !avoiding_indexed_address_p (mode)
4953 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
4954 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
4956 else if (SPE_VECTOR_MODE (mode)
4957 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
4958 || mode == DDmode || mode == TDmode
4959 || mode == DImode)))
4963 /* We accept [reg + reg] and [reg + OFFSET]. */
4965 if (GET_CODE (x) == PLUS)
4967 rtx op1 = XEXP (x, 0);
4968 rtx op2 = XEXP (x, 1);
4971 op1 = force_reg (Pmode, op1);
4973 if (GET_CODE (op2) != REG
4974 && (GET_CODE (op2) != CONST_INT
4975 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
4976 || (GET_MODE_SIZE (mode) > 8
4977 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
4978 op2 = force_reg (Pmode, op2);
4980 /* We can't always do [reg + reg] for these, because [reg +
4981 reg + offset] is not a legitimate addressing mode. */
4982 y = gen_rtx_PLUS (Pmode, op1, op2);
4984 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
4985 return force_reg (Pmode, y);
4990 return force_reg (Pmode, x);
4996 && GET_CODE (x) != CONST_INT
4997 && GET_CODE (x) != CONST_DOUBLE
4999 && GET_MODE_NUNITS (mode) == 1
5000 && (GET_MODE_BITSIZE (mode) <= 32
5001 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5002 && (mode == DFmode || mode == DDmode))))
5004 rtx reg = gen_reg_rtx (Pmode);
5005 emit_insn (gen_elf_high (reg, x));
5006 return gen_rtx_LO_SUM (Pmode, reg, x);
5008 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5011 && ! MACHO_DYNAMIC_NO_PIC_P
5013 && GET_CODE (x) != CONST_INT
5014 && GET_CODE (x) != CONST_DOUBLE
5016 && GET_MODE_NUNITS (mode) == 1
5017 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5018 || (mode != DFmode && mode != DDmode))
5022 rtx reg = gen_reg_rtx (Pmode);
5023 emit_insn (gen_macho_high (reg, x));
5024 return gen_rtx_LO_SUM (Pmode, reg, x);
5027 && GET_CODE (x) == SYMBOL_REF
5028 && constant_pool_expr_p (x)
5029 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5031 return create_TOC_reference (x);
5037 /* Debug version of rs6000_legitimize_address. */
5039 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5045 ret = rs6000_legitimize_address (x, oldx, mode);
5046 insns = get_insns ();
5052 "\nrs6000_legitimize_address: mode %s, old code %s, "
5053 "new code %s, modified\n",
5054 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5055 GET_RTX_NAME (GET_CODE (ret)));
5057 fprintf (stderr, "Original address:\n");
5060 fprintf (stderr, "oldx:\n");
5063 fprintf (stderr, "New address:\n");
5068 fprintf (stderr, "Insns added:\n");
5069 debug_rtx_list (insns, 20);
5075 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5076 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5087 /* If ORIG_X is a constant pool reference, return its known value,
5088 otherwise ORIG_X. */
5091 rs6000_delegitimize_address (rtx x)
5093 rtx orig_x = delegitimize_mem_from_attrs (x);
5102 if (legitimate_constant_pool_address_p (x)
5103 && GET_CODE (XEXP (x, 1)) == CONST
5104 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
5105 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
5106 && constant_pool_expr_p (XEXP (XEXP (XEXP (x, 1), 0), 0))
5107 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF
5108 && toc_relative_expr_p (XEXP (XEXP (XEXP (x, 1), 0), 1)))
5109 return get_pool_constant (XEXP (XEXP (XEXP (x, 1), 0), 0));
5114 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5115 We need to emit DTP-relative relocations. */
5118 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5123 fputs ("\t.long\t", file);
5126 fputs (DOUBLE_INT_ASM_OP, file);
5131 output_addr_const (file, x);
5132 fputs ("@dtprel+0x8000", file);
5135 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5137 static GTY(()) rtx rs6000_tls_symbol;
5139 rs6000_tls_get_addr (void)
5141 if (!rs6000_tls_symbol)
5142 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5144 return rs6000_tls_symbol;
5147 /* Construct the SYMBOL_REF for TLS GOT references. */
5149 static GTY(()) rtx rs6000_got_symbol;
5151 rs6000_got_sym (void)
5153 if (!rs6000_got_symbol)
5155 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5156 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5157 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5160 return rs6000_got_symbol;
5163 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5164 this (thread-local) address. */
5167 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5171 dest = gen_reg_rtx (Pmode);
5172 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5178 tlsreg = gen_rtx_REG (Pmode, 13);
5179 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5183 tlsreg = gen_rtx_REG (Pmode, 2);
5184 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5188 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5192 tmp = gen_reg_rtx (Pmode);
5195 tlsreg = gen_rtx_REG (Pmode, 13);
5196 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5200 tlsreg = gen_rtx_REG (Pmode, 2);
5201 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5205 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5207 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5212 rtx r3, got, tga, tmp1, tmp2, eqv;
5214 /* We currently use relocations like @got@tlsgd for tls, which
5215 means the linker will handle allocation of tls entries, placing
5216 them in the .got section. So use a pointer to the .got section,
5217 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5218 or to secondary GOT sections used by 32-bit -fPIC. */
5220 got = gen_rtx_REG (Pmode, 2);
5224 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5227 rtx gsym = rs6000_got_sym ();
5228 got = gen_reg_rtx (Pmode);
5230 rs6000_emit_move (got, gsym, Pmode);
5236 tmp1 = gen_reg_rtx (Pmode);
5237 tmp2 = gen_reg_rtx (Pmode);
5238 tmp3 = gen_reg_rtx (Pmode);
5239 mem = gen_const_mem (Pmode, tmp1);
5241 first = emit_insn (gen_load_toc_v4_PIC_1b (gsym));
5242 emit_move_insn (tmp1,
5243 gen_rtx_REG (Pmode, LR_REGNO));
5244 emit_move_insn (tmp2, mem);
5245 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
5246 last = emit_move_insn (got, tmp3);
5247 set_unique_reg_note (last, REG_EQUAL, gsym);
5252 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5254 r3 = gen_rtx_REG (Pmode, 3);
5255 tga = rs6000_tls_get_addr ();
5257 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5258 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5259 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5260 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5261 else if (DEFAULT_ABI == ABI_V4)
5262 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5267 insn = emit_call_insn (insn);
5268 RTL_CONST_CALL_P (insn) = 1;
5269 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5270 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5271 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5272 insn = get_insns ();
5274 emit_libcall_block (insn, dest, r3, addr);
5276 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5278 r3 = gen_rtx_REG (Pmode, 3);
5279 tga = rs6000_tls_get_addr ();
5281 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5282 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5283 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5284 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5285 else if (DEFAULT_ABI == ABI_V4)
5286 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5291 insn = emit_call_insn (insn);
5292 RTL_CONST_CALL_P (insn) = 1;
5293 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
5294 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5295 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
5296 insn = get_insns ();
5298 tmp1 = gen_reg_rtx (Pmode);
5299 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
5301 emit_libcall_block (insn, tmp1, r3, eqv);
5302 if (rs6000_tls_size == 16)
5305 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5307 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5309 else if (rs6000_tls_size == 32)
5311 tmp2 = gen_reg_rtx (Pmode);
5313 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5315 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5318 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5320 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5324 tmp2 = gen_reg_rtx (Pmode);
5326 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5328 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5330 insn = gen_rtx_SET (Pmode, dest,
5331 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5337 /* IE, or 64-bit offset LE. */
5338 tmp2 = gen_reg_rtx (Pmode);
5340 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5342 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5345 insn = gen_tls_tls_64 (dest, tmp2, addr);
5347 insn = gen_tls_tls_32 (dest, tmp2, addr);
5355 /* Return 1 if X contains a thread-local symbol. */
5358 rs6000_tls_referenced_p (rtx x)
5360 if (! TARGET_HAVE_TLS)
5363 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5366 /* Return 1 if *X is a thread-local symbol. This is the same as
5367 rs6000_tls_symbol_ref except for the type of the unused argument. */
5370 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5372 return RS6000_SYMBOL_REF_TLS_P (*x);
5375 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5376 replace the input X, or the original X if no replacement is called for.
5377 The output parameter *WIN is 1 if the calling macro should goto WIN,
5380 For RS/6000, we wish to handle large displacements off a base
5381 register by splitting the addend across an addiu/addis and the mem insn.
5382 This cuts number of extra insns needed from 3 to 1.
5384 On Darwin, we use this to generate code for floating point constants.
5385 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5386 The Darwin code is inside #if TARGET_MACHO because only then are the
5387 machopic_* functions defined. */
5389 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5390 int opnum, int type,
5391 int ind_levels ATTRIBUTE_UNUSED, int *win)
5393 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5395 /* We must recognize output that we have already generated ourselves. */
5396 if (GET_CODE (x) == PLUS
5397 && GET_CODE (XEXP (x, 0)) == PLUS
5398 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5399 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5400 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5402 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5403 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5404 opnum, (enum reload_type)type);
5410 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5411 && GET_CODE (x) == LO_SUM
5412 && GET_CODE (XEXP (x, 0)) == PLUS
5413 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5414 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5415 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5416 && machopic_operand_p (XEXP (x, 1)))
5418 /* Result of previous invocation of this function on Darwin
5419 floating point constant. */
5420 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5421 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5422 opnum, (enum reload_type)type);
5428 /* Force ld/std non-word aligned offset into base register by wrapping
5430 if (GET_CODE (x) == PLUS
5431 && GET_CODE (XEXP (x, 0)) == REG
5432 && REGNO (XEXP (x, 0)) < 32
5433 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5434 && GET_CODE (XEXP (x, 1)) == CONST_INT
5436 && (INTVAL (XEXP (x, 1)) & 3) != 0
5437 && VECTOR_MEM_NONE_P (mode)
5438 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5439 && TARGET_POWERPC64)
5441 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5442 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5443 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5444 opnum, (enum reload_type) type);
5449 if (GET_CODE (x) == PLUS
5450 && GET_CODE (XEXP (x, 0)) == REG
5451 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5452 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5453 && GET_CODE (XEXP (x, 1)) == CONST_INT
5455 && !SPE_VECTOR_MODE (mode)
5456 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5457 || mode == DDmode || mode == TDmode
5459 && VECTOR_MEM_NONE_P (mode))
5461 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5462 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5464 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5466 /* Check for 32-bit overflow. */
5467 if (high + low != val)
5473 /* Reload the high part into a base reg; leave the low part
5474 in the mem directly. */
5476 x = gen_rtx_PLUS (GET_MODE (x),
5477 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5481 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5482 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5483 opnum, (enum reload_type)type);
5488 if (GET_CODE (x) == SYMBOL_REF
5490 && VECTOR_MEM_NONE_P (mode)
5491 && !SPE_VECTOR_MODE (mode)
5493 && DEFAULT_ABI == ABI_DARWIN
5494 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
5496 && DEFAULT_ABI == ABI_V4
5499 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
5500 The same goes for DImode without 64-bit gprs and DFmode and DDmode
5504 && (mode != DImode || TARGET_POWERPC64)
5505 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
5506 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
5511 rtx offset = machopic_gen_offset (x);
5512 x = gen_rtx_LO_SUM (GET_MODE (x),
5513 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
5514 gen_rtx_HIGH (Pmode, offset)), offset);
5518 x = gen_rtx_LO_SUM (GET_MODE (x),
5519 gen_rtx_HIGH (Pmode, x), x);
5521 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5522 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5523 opnum, (enum reload_type)type);
5528 /* Reload an offset address wrapped by an AND that represents the
5529 masking of the lower bits. Strip the outer AND and let reload
5530 convert the offset address into an indirect address. For VSX,
5531 force reload to create the address with an AND in a separate
5532 register, because we can't guarantee an altivec register will
5534 if (VECTOR_MEM_ALTIVEC_P (mode)
5535 && GET_CODE (x) == AND
5536 && GET_CODE (XEXP (x, 0)) == PLUS
5537 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5538 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5539 && GET_CODE (XEXP (x, 1)) == CONST_INT
5540 && INTVAL (XEXP (x, 1)) == -16)
5549 && GET_CODE (x) == SYMBOL_REF
5550 && constant_pool_expr_p (x)
5551 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
5553 x = create_TOC_reference (x);
5561 /* Debug version of rs6000_legitimize_reload_address. */
5563 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
5564 int opnum, int type,
5565 int ind_levels, int *win)
5567 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
5570 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
5571 "type = %d, ind_levels = %d, win = %d, original addr:\n",
5572 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
5576 fprintf (stderr, "Same address returned\n");
5578 fprintf (stderr, "NULL returned\n");
5581 fprintf (stderr, "New address:\n");
5588 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
5589 that is a valid memory address for an instruction.
5590 The MODE argument is the machine mode for the MEM expression
5591 that wants to use this address.
5593 On the RS/6000, there are four valid address: a SYMBOL_REF that
5594 refers to a constant pool entry of an address (or the sum of it
5595 plus a constant), a short (16-bit signed) constant plus a register,
5596 the sum of two registers, or a register indirect, possibly with an
5597 auto-increment. For DFmode, DDmode and DImode with a constant plus
5598 register, we must ensure that both words are addressable or PowerPC64
5599 with offset word aligned.
5601 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
5602 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
5603 because adjacent memory cells are accessed by adding word-sized offsets
5604 during assembly output. */
5606 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
5608 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5610 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
5611 if (VECTOR_MEM_ALTIVEC_P (mode)
5612 && GET_CODE (x) == AND
5613 && GET_CODE (XEXP (x, 1)) == CONST_INT
5614 && INTVAL (XEXP (x, 1)) == -16)
5617 if (RS6000_SYMBOL_REF_TLS_P (x))
5619 if (legitimate_indirect_address_p (x, reg_ok_strict))
5621 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
5622 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
5623 && !SPE_VECTOR_MODE (mode)
5626 /* Restrict addressing for DI because of our SUBREG hackery. */
5627 && !(TARGET_E500_DOUBLE
5628 && (mode == DFmode || mode == DDmode || mode == DImode))
5630 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
5632 if (virtual_stack_registers_memory_p (x))
5634 if (reg_offset_p && legitimate_small_data_p (mode, x))
5636 if (reg_offset_p && legitimate_constant_pool_address_p (x))
5638 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
5641 && GET_CODE (x) == PLUS
5642 && GET_CODE (XEXP (x, 0)) == REG
5643 && (XEXP (x, 0) == virtual_stack_vars_rtx
5644 || XEXP (x, 0) == arg_pointer_rtx)
5645 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5647 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
5652 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5654 || (mode != DFmode && mode != DDmode)
5655 || (TARGET_E500_DOUBLE && mode != DDmode))
5656 && (TARGET_POWERPC64 || mode != DImode)
5657 && !avoiding_indexed_address_p (mode)
5658 && legitimate_indexed_address_p (x, reg_ok_strict))
5660 if (GET_CODE (x) == PRE_MODIFY
5661 && VECTOR_MEM_VSX_P (mode)
5663 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)
5664 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5666 if (GET_CODE (x) == PRE_MODIFY
5670 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5672 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
5673 && (TARGET_POWERPC64 || mode != DImode)
5674 && !VECTOR_MEM_ALTIVEC_P (mode)
5675 && !SPE_VECTOR_MODE (mode)
5676 /* Restrict addressing for DI because of our SUBREG hackery. */
5677 && !(TARGET_E500_DOUBLE
5678 && (mode == DFmode || mode == DDmode || mode == DImode))
5680 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
5681 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
5682 || (!avoiding_indexed_address_p (mode)
5683 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
5684 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
5686 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
5691 /* Debug version of rs6000_legitimate_address_p. */
5693 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
5696 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
5698 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
5699 "strict = %d, code = %s\n",
5700 ret ? "true" : "false",
5701 GET_MODE_NAME (mode),
5703 GET_RTX_NAME (GET_CODE (x)));
5709 /* Go to LABEL if ADDR (a legitimate address expression)
5710 has an effect that depends on the machine mode it is used for.
5712 On the RS/6000 this is true of all integral offsets (since AltiVec
5713 and VSX modes don't allow them) or is a pre-increment or decrement.
5715 ??? Except that due to conceptual problems in offsettable_address_p
5716 we can't really report the problems of integral offsets. So leave
5717 this assuming that the adjustable offset must be valid for the
5718 sub-words of a TFmode operand, which is what we had before. */
5721 rs6000_mode_dependent_address (rtx addr)
5723 switch (GET_CODE (addr))
5726 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
5727 is considered a legitimate address before reload, so there
5728 are no offset restrictions in that case. Note that this
5729 condition is safe in strict mode because any address involving
5730 virtual_stack_vars_rtx or arg_pointer_rtx would already have
5731 been rejected as illegitimate. */
5732 if (XEXP (addr, 0) != virtual_stack_vars_rtx
5733 && XEXP (addr, 0) != arg_pointer_rtx
5734 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5736 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
5737 return val + 12 + 0x8000 >= 0x10000;
5744 /* Auto-increment cases are now treated generically in recog.c. */
5746 return TARGET_UPDATE;
5748 /* AND is only allowed in Altivec loads. */
5759 /* Debug version of rs6000_mode_dependent_address. */
5761 rs6000_debug_mode_dependent_address (rtx addr)
5763 bool ret = rs6000_mode_dependent_address (addr);
5765 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
5766 ret ? "true" : "false");
5772 /* Implement FIND_BASE_TERM. */
5775 rs6000_find_base_term (rtx op)
5779 split_const (op, &base, &offset);
5780 if (GET_CODE (base) == UNSPEC)
5781 switch (XINT (base, 1))
5784 case UNSPEC_MACHOPIC_OFFSET:
5785 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
5786 for aliasing purposes. */
5787 return XVECEXP (base, 0, 0);
5793 /* More elaborate version of recog's offsettable_memref_p predicate
5794 that works around the ??? note of rs6000_mode_dependent_address.
5795 In particular it accepts
5797 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
5799 in 32-bit mode, that the recog predicate rejects. */
5802 rs6000_offsettable_memref_p (rtx op)
5807 /* First mimic offsettable_memref_p. */
5808 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
5811 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
5812 the latter predicate knows nothing about the mode of the memory
5813 reference and, therefore, assumes that it is the largest supported
5814 mode (TFmode). As a consequence, legitimate offsettable memory
5815 references are rejected. rs6000_legitimate_offset_address_p contains
5816 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
5817 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
5820 /* Change register usage conditional on target flags. */
5822 rs6000_conditional_register_usage (void)
5826 /* Set MQ register fixed (already call_used) if not POWER
5827 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
5832 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
5834 fixed_regs[13] = call_used_regs[13]
5835 = call_really_used_regs[13] = 1;
5837 /* Conditionally disable FPRs. */
5838 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
5839 for (i = 32; i < 64; i++)
5840 fixed_regs[i] = call_used_regs[i]
5841 = call_really_used_regs[i] = 1;
5843 /* The TOC register is not killed across calls in a way that is
5844 visible to the compiler. */
5845 if (DEFAULT_ABI == ABI_AIX)
5846 call_really_used_regs[2] = 0;
5848 if (DEFAULT_ABI == ABI_V4
5849 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
5851 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5853 if (DEFAULT_ABI == ABI_V4
5854 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
5856 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5857 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5858 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5860 if (DEFAULT_ABI == ABI_DARWIN
5861 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
5862 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5863 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5864 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5866 if (TARGET_TOC && TARGET_MINIMAL_TOC)
5867 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
5868 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
5872 global_regs[SPEFSCR_REGNO] = 1;
5873 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
5874 registers in prologues and epilogues. We no longer use r14
5875 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
5876 pool for link-compatibility with older versions of GCC. Once
5877 "old" code has died out, we can return r14 to the allocation
5880 = call_used_regs[14]
5881 = call_really_used_regs[14] = 1;
5884 if (!TARGET_ALTIVEC && !TARGET_VSX)
5886 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
5887 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
5888 call_really_used_regs[VRSAVE_REGNO] = 1;
5891 if (TARGET_ALTIVEC || TARGET_VSX)
5892 global_regs[VSCR_REGNO] = 1;
5894 if (TARGET_ALTIVEC_ABI)
5896 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
5897 call_used_regs[i] = call_really_used_regs[i] = 1;
5899 /* AIX reserves VR20:31 in non-extended ABI mode. */
5901 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
5902 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
5906 /* Try to output insns to set TARGET equal to the constant C if it can
5907 be done in less than N insns. Do all computations in MODE.
5908 Returns the place where the output has been placed if it can be
5909 done and the insns have been emitted. If it would take more than N
5910 insns, zero is returned and no insns and emitted. */
5913 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
5914 rtx source, int n ATTRIBUTE_UNUSED)
5916 rtx result, insn, set;
5917 HOST_WIDE_INT c0, c1;
5924 dest = gen_reg_rtx (mode);
5925 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
5929 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
5931 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
5932 GEN_INT (INTVAL (source)
5933 & (~ (HOST_WIDE_INT) 0xffff))));
5934 emit_insn (gen_rtx_SET (VOIDmode, dest,
5935 gen_rtx_IOR (SImode, copy_rtx (result),
5936 GEN_INT (INTVAL (source) & 0xffff))));
5941 switch (GET_CODE (source))
5944 c0 = INTVAL (source);
5949 #if HOST_BITS_PER_WIDE_INT >= 64
5950 c0 = CONST_DOUBLE_LOW (source);
5953 c0 = CONST_DOUBLE_LOW (source);
5954 c1 = CONST_DOUBLE_HIGH (source);
5962 result = rs6000_emit_set_long_const (dest, c0, c1);
5969 insn = get_last_insn ();
5970 set = single_set (insn);
5971 if (! CONSTANT_P (SET_SRC (set)))
5972 set_unique_reg_note (insn, REG_EQUAL, source);
5977 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
5978 fall back to a straight forward decomposition. We do this to avoid
5979 exponential run times encountered when looking for longer sequences
5980 with rs6000_emit_set_const. */
5982 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
5984 if (!TARGET_POWERPC64)
5986 rtx operand1, operand2;
5988 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
5990 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
5992 emit_move_insn (operand1, GEN_INT (c1));
5993 emit_move_insn (operand2, GEN_INT (c2));
5997 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6000 ud2 = (c1 & 0xffff0000) >> 16;
6001 #if HOST_BITS_PER_WIDE_INT >= 64
6005 ud4 = (c2 & 0xffff0000) >> 16;
6007 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6008 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6011 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6013 emit_move_insn (dest, GEN_INT (ud1));
6016 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6017 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6020 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6023 emit_move_insn (dest, GEN_INT (ud2 << 16));
6025 emit_move_insn (copy_rtx (dest),
6026 gen_rtx_IOR (DImode, copy_rtx (dest),
6029 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6030 || (ud4 == 0 && ! (ud3 & 0x8000)))
6033 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6036 emit_move_insn (dest, GEN_INT (ud3 << 16));
6039 emit_move_insn (copy_rtx (dest),
6040 gen_rtx_IOR (DImode, copy_rtx (dest),
6042 emit_move_insn (copy_rtx (dest),
6043 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6046 emit_move_insn (copy_rtx (dest),
6047 gen_rtx_IOR (DImode, copy_rtx (dest),
6053 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6056 emit_move_insn (dest, GEN_INT (ud4 << 16));
6059 emit_move_insn (copy_rtx (dest),
6060 gen_rtx_IOR (DImode, copy_rtx (dest),
6063 emit_move_insn (copy_rtx (dest),
6064 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6067 emit_move_insn (copy_rtx (dest),
6068 gen_rtx_IOR (DImode, copy_rtx (dest),
6069 GEN_INT (ud2 << 16)));
6071 emit_move_insn (copy_rtx (dest),
6072 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6078 /* Helper for the following. Get rid of [r+r] memory refs
6079 in cases where it won't work (TImode, TFmode, TDmode). */
6082 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6084 if (GET_CODE (operands[0]) == MEM
6085 && GET_CODE (XEXP (operands[0], 0)) != REG
6086 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
6087 && ! reload_in_progress)
6089 = replace_equiv_address (operands[0],
6090 copy_addr_to_reg (XEXP (operands[0], 0)));
6092 if (GET_CODE (operands[1]) == MEM
6093 && GET_CODE (XEXP (operands[1], 0)) != REG
6094 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
6095 && ! reload_in_progress)
6097 = replace_equiv_address (operands[1],
6098 copy_addr_to_reg (XEXP (operands[1], 0)));
6101 /* Emit a move from SOURCE to DEST in mode MODE. */
6103 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6107 operands[1] = source;
6109 if (TARGET_DEBUG_ADDR)
6112 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6113 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6114 GET_MODE_NAME (mode),
6117 can_create_pseudo_p ());
6119 fprintf (stderr, "source:\n");
6123 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6124 if (GET_CODE (operands[1]) == CONST_DOUBLE
6125 && ! FLOAT_MODE_P (mode)
6126 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6128 /* FIXME. This should never happen. */
6129 /* Since it seems that it does, do the safe thing and convert
6131 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6133 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6134 || FLOAT_MODE_P (mode)
6135 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6136 || CONST_DOUBLE_LOW (operands[1]) < 0)
6137 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6138 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6140 /* Check if GCC is setting up a block move that will end up using FP
6141 registers as temporaries. We must make sure this is acceptable. */
6142 if (GET_CODE (operands[0]) == MEM
6143 && GET_CODE (operands[1]) == MEM
6145 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6146 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6147 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6148 ? 32 : MEM_ALIGN (operands[0])))
6149 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6151 : MEM_ALIGN (operands[1]))))
6152 && ! MEM_VOLATILE_P (operands [0])
6153 && ! MEM_VOLATILE_P (operands [1]))
6155 emit_move_insn (adjust_address (operands[0], SImode, 0),
6156 adjust_address (operands[1], SImode, 0));
6157 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6158 adjust_address (copy_rtx (operands[1]), SImode, 4));
6162 /* Fix up invalid (const (plus (symbol_ref) (reg))) that seems to be created
6163 in the secondary_reload phase, which evidently overwrites the CONST_INT
6165 if (GET_CODE (source) == CONST && GET_CODE (XEXP (source, 0)) == PLUS
6168 rtx add_op0 = XEXP (XEXP (source, 0), 0);
6169 rtx add_op1 = XEXP (XEXP (source, 0), 1);
6171 if (GET_CODE (add_op0) == SYMBOL_REF && GET_CODE (add_op1) == REG)
6173 rtx tmp = (can_create_pseudo_p ()) ? gen_reg_rtx (Pmode) : dest;
6175 if (TARGET_DEBUG_ADDR)
6177 fprintf (stderr, "\nrs6000_emit_move: bad source\n");
6181 rs6000_emit_move (tmp, add_op0, Pmode);
6182 emit_insn (gen_rtx_SET (VOIDmode, dest,
6183 gen_rtx_PLUS (Pmode, tmp, add_op1)));
6188 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6189 && !gpc_reg_operand (operands[1], mode))
6190 operands[1] = force_reg (mode, operands[1]);
6192 if (mode == SFmode && ! TARGET_POWERPC
6193 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6194 && GET_CODE (operands[0]) == MEM)
6198 if (reload_in_progress || reload_completed)
6199 regnum = true_regnum (operands[1]);
6200 else if (GET_CODE (operands[1]) == REG)
6201 regnum = REGNO (operands[1]);
6205 /* If operands[1] is a register, on POWER it may have
6206 double-precision data in it, so truncate it to single
6208 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6211 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6212 : gen_reg_rtx (mode));
6213 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6214 operands[1] = newreg;
6218 /* Recognize the case where operand[1] is a reference to thread-local
6219 data and load its address to a register. */
6220 if (rs6000_tls_referenced_p (operands[1]))
6222 enum tls_model model;
6223 rtx tmp = operands[1];
6226 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6228 addend = XEXP (XEXP (tmp, 0), 1);
6229 tmp = XEXP (XEXP (tmp, 0), 0);
6232 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6233 model = SYMBOL_REF_TLS_MODEL (tmp);
6234 gcc_assert (model != 0);
6236 tmp = rs6000_legitimize_tls_address (tmp, model);
6239 tmp = gen_rtx_PLUS (mode, tmp, addend);
6240 tmp = force_operand (tmp, operands[0]);
6245 /* Handle the case where reload calls us with an invalid address. */
6246 if (reload_in_progress && mode == Pmode
6247 && (! general_operand (operands[1], mode)
6248 || ! nonimmediate_operand (operands[0], mode)))
6251 /* 128-bit constant floating-point values on Darwin should really be
6252 loaded as two parts. */
6253 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6254 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6256 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6257 know how to get a DFmode SUBREG of a TFmode. */
6258 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6259 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6260 simplify_gen_subreg (imode, operands[1], mode, 0),
6262 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6263 GET_MODE_SIZE (imode)),
6264 simplify_gen_subreg (imode, operands[1], mode,
6265 GET_MODE_SIZE (imode)),
6270 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6271 cfun->machine->sdmode_stack_slot =
6272 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6274 if (reload_in_progress
6276 && MEM_P (operands[0])
6277 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6278 && REG_P (operands[1]))
6280 if (FP_REGNO_P (REGNO (operands[1])))
6282 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6283 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6284 emit_insn (gen_movsd_store (mem, operands[1]));
6286 else if (INT_REGNO_P (REGNO (operands[1])))
6288 rtx mem = adjust_address_nv (operands[0], mode, 4);
6289 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6290 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6296 if (reload_in_progress
6298 && REG_P (operands[0])
6299 && MEM_P (operands[1])
6300 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6302 if (FP_REGNO_P (REGNO (operands[0])))
6304 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6305 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6306 emit_insn (gen_movsd_load (operands[0], mem));
6308 else if (INT_REGNO_P (REGNO (operands[0])))
6310 rtx mem = adjust_address_nv (operands[1], mode, 4);
6311 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6312 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6319 /* FIXME: In the long term, this switch statement should go away
6320 and be replaced by a sequence of tests based on things like
6326 if (CONSTANT_P (operands[1])
6327 && GET_CODE (operands[1]) != CONST_INT)
6328 operands[1] = force_const_mem (mode, operands[1]);
6333 rs6000_eliminate_indexed_memrefs (operands);
6340 if (CONSTANT_P (operands[1])
6341 && ! easy_fp_constant (operands[1], mode))
6342 operands[1] = force_const_mem (mode, operands[1]);
6355 if (CONSTANT_P (operands[1])
6356 && !easy_vector_constant (operands[1], mode))
6357 operands[1] = force_const_mem (mode, operands[1]);
6362 /* Use default pattern for address of ELF small data */
6365 && DEFAULT_ABI == ABI_V4
6366 && (GET_CODE (operands[1]) == SYMBOL_REF
6367 || GET_CODE (operands[1]) == CONST)
6368 && small_data_operand (operands[1], mode))
6370 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6374 if (DEFAULT_ABI == ABI_V4
6375 && mode == Pmode && mode == SImode
6376 && flag_pic == 1 && got_operand (operands[1], mode))
6378 emit_insn (gen_movsi_got (operands[0], operands[1]));
6382 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6386 && CONSTANT_P (operands[1])
6387 && GET_CODE (operands[1]) != HIGH
6388 && GET_CODE (operands[1]) != CONST_INT)
6390 rtx target = (!can_create_pseudo_p ()
6392 : gen_reg_rtx (mode));
6394 /* If this is a function address on -mcall-aixdesc,
6395 convert it to the address of the descriptor. */
6396 if (DEFAULT_ABI == ABI_AIX
6397 && GET_CODE (operands[1]) == SYMBOL_REF
6398 && XSTR (operands[1], 0)[0] == '.')
6400 const char *name = XSTR (operands[1], 0);
6402 while (*name == '.')
6404 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6405 CONSTANT_POOL_ADDRESS_P (new_ref)
6406 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6407 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6408 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6409 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6410 operands[1] = new_ref;
6413 if (DEFAULT_ABI == ABI_DARWIN)
6416 if (MACHO_DYNAMIC_NO_PIC_P)
6418 /* Take care of any required data indirection. */
6419 operands[1] = rs6000_machopic_legitimize_pic_address (
6420 operands[1], mode, operands[0]);
6421 if (operands[0] != operands[1])
6422 emit_insn (gen_rtx_SET (VOIDmode,
6423 operands[0], operands[1]));
6427 emit_insn (gen_macho_high (target, operands[1]));
6428 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6432 emit_insn (gen_elf_high (target, operands[1]));
6433 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6437 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6438 and we have put it in the TOC, we just need to make a TOC-relative
6441 && GET_CODE (operands[1]) == SYMBOL_REF
6442 && constant_pool_expr_p (operands[1])
6443 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6444 get_pool_mode (operands[1])))
6446 operands[1] = create_TOC_reference (operands[1]);
6448 else if (mode == Pmode
6449 && CONSTANT_P (operands[1])
6450 && ((GET_CODE (operands[1]) != CONST_INT
6451 && ! easy_fp_constant (operands[1], mode))
6452 || (GET_CODE (operands[1]) == CONST_INT
6453 && num_insns_constant (operands[1], mode) > 2)
6454 || (GET_CODE (operands[0]) == REG
6455 && FP_REGNO_P (REGNO (operands[0]))))
6456 && GET_CODE (operands[1]) != HIGH
6457 && ! legitimate_constant_pool_address_p (operands[1])
6458 && ! toc_relative_expr_p (operands[1]))
6462 /* Darwin uses a special PIC legitimizer. */
6463 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
6466 rs6000_machopic_legitimize_pic_address (operands[1], mode,
6468 if (operands[0] != operands[1])
6469 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6474 /* If we are to limit the number of things we put in the TOC and
6475 this is a symbol plus a constant we can add in one insn,
6476 just put the symbol in the TOC and add the constant. Don't do
6477 this if reload is in progress. */
6478 if (GET_CODE (operands[1]) == CONST
6479 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
6480 && GET_CODE (XEXP (operands[1], 0)) == PLUS
6481 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
6482 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
6483 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
6484 && ! side_effects_p (operands[0]))
6487 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
6488 rtx other = XEXP (XEXP (operands[1], 0), 1);
6490 sym = force_reg (mode, sym);
6492 emit_insn (gen_addsi3 (operands[0], sym, other));
6494 emit_insn (gen_adddi3 (operands[0], sym, other));
6498 operands[1] = force_const_mem (mode, operands[1]);
6501 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6502 && constant_pool_expr_p (XEXP (operands[1], 0))
6503 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
6504 get_pool_constant (XEXP (operands[1], 0)),
6505 get_pool_mode (XEXP (operands[1], 0))))
6508 = gen_const_mem (mode,
6509 create_TOC_reference (XEXP (operands[1], 0)));
6510 set_mem_alias_set (operands[1], get_TOC_alias_set ());
6516 rs6000_eliminate_indexed_memrefs (operands);
6520 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6522 gen_rtx_SET (VOIDmode,
6523 operands[0], operands[1]),
6524 gen_rtx_CLOBBER (VOIDmode,
6525 gen_rtx_SCRATCH (SImode)))));
6531 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
6534 /* Above, we may have called force_const_mem which may have returned
6535 an invalid address. If we can, fix this up; otherwise, reload will
6536 have to deal with it. */
6537 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
6538 operands[1] = validize_mem (operands[1]);
6541 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6544 /* Nonzero if we can use a floating-point register to pass this arg. */
6545 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
6546 (SCALAR_FLOAT_MODE_P (MODE) \
6547 && (CUM)->fregno <= FP_ARG_MAX_REG \
6548 && TARGET_HARD_FLOAT && TARGET_FPRS)
6550 /* Nonzero if we can use an AltiVec register to pass this arg. */
6551 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
6552 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
6553 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
6554 && TARGET_ALTIVEC_ABI \
6557 /* Return a nonzero value to say to return the function value in
6558 memory, just as large structures are always returned. TYPE will be
6559 the data type of the value, and FNTYPE will be the type of the
6560 function doing the returning, or @code{NULL} for libcalls.
6562 The AIX ABI for the RS/6000 specifies that all structures are
6563 returned in memory. The Darwin ABI does the same. The SVR4 ABI
6564 specifies that structures <= 8 bytes are returned in r3/r4, but a
6565 draft put them in memory, and GCC used to implement the draft
6566 instead of the final standard. Therefore, aix_struct_return
6567 controls this instead of DEFAULT_ABI; V.4 targets needing backward
6568 compatibility can change DRAFT_V4_STRUCT_RET to override the
6569 default, and -m switches get the final word. See
6570 rs6000_override_options for more details.
6572 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
6573 long double support is enabled. These values are returned in memory.
6575 int_size_in_bytes returns -1 for variable size objects, which go in
6576 memory always. The cast to unsigned makes -1 > 8. */
6579 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6581 /* In the darwin64 abi, try to use registers for larger structs
6583 if (rs6000_darwin64_abi
6584 && TREE_CODE (type) == RECORD_TYPE
6585 && int_size_in_bytes (type) > 0)
6587 CUMULATIVE_ARGS valcum;
6591 valcum.fregno = FP_ARG_MIN_REG;
6592 valcum.vregno = ALTIVEC_ARG_MIN_REG;
6593 /* Do a trial code generation as if this were going to be passed
6594 as an argument; if any part goes in memory, we return NULL. */
6595 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
6598 /* Otherwise fall through to more conventional ABI rules. */
6601 if (AGGREGATE_TYPE_P (type)
6602 && (aix_struct_return
6603 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
6606 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6607 modes only exist for GCC vector types if -maltivec. */
6608 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
6609 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6612 /* Return synthetic vectors in memory. */
6613 if (TREE_CODE (type) == VECTOR_TYPE
6614 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
6616 static bool warned_for_return_big_vectors = false;
6617 if (!warned_for_return_big_vectors)
6619 warning (0, "GCC vector returned by reference: "
6620 "non-standard ABI extension with no compatibility guarantee");
6621 warned_for_return_big_vectors = true;
6626 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
6632 /* Initialize a variable CUM of type CUMULATIVE_ARGS
6633 for a call to a function whose data type is FNTYPE.
6634 For a library call, FNTYPE is 0.
6636 For incoming args we set the number of arguments in the prototype large
6637 so we never return a PARALLEL. */
6640 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
6641 rtx libname ATTRIBUTE_UNUSED, int incoming,
6642 int libcall, int n_named_args)
6644 static CUMULATIVE_ARGS zero_cumulative;
6646 *cum = zero_cumulative;
6648 cum->fregno = FP_ARG_MIN_REG;
6649 cum->vregno = ALTIVEC_ARG_MIN_REG;
6650 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
6651 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
6652 ? CALL_LIBCALL : CALL_NORMAL);
6653 cum->sysv_gregno = GP_ARG_MIN_REG;
6654 cum->stdarg = fntype
6655 && (TYPE_ARG_TYPES (fntype) != 0
6656 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
6657 != void_type_node));
6659 cum->nargs_prototype = 0;
6660 if (incoming || cum->prototype)
6661 cum->nargs_prototype = n_named_args;
6663 /* Check for a longcall attribute. */
6664 if ((!fntype && rs6000_default_long_calls)
6666 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
6667 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
6668 cum->call_cookie |= CALL_LONG;
6670 if (TARGET_DEBUG_ARG)
6672 fprintf (stderr, "\ninit_cumulative_args:");
6675 tree ret_type = TREE_TYPE (fntype);
6676 fprintf (stderr, " ret code = %s,",
6677 tree_code_name[ (int)TREE_CODE (ret_type) ]);
6680 if (cum->call_cookie & CALL_LONG)
6681 fprintf (stderr, " longcall,");
6683 fprintf (stderr, " proto = %d, nargs = %d\n",
6684 cum->prototype, cum->nargs_prototype);
6689 && TARGET_ALTIVEC_ABI
6690 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
6692 error ("cannot return value in vector register because"
6693 " altivec instructions are disabled, use -maltivec"
6698 /* Return true if TYPE must be passed on the stack and not in registers. */
6701 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
6703 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
6704 return must_pass_in_stack_var_size (mode, type);
6706 return must_pass_in_stack_var_size_or_pad (mode, type);
6709 /* If defined, a C expression which determines whether, and in which
6710 direction, to pad out an argument with extra space. The value
6711 should be of type `enum direction': either `upward' to pad above
6712 the argument, `downward' to pad below, or `none' to inhibit
6715 For the AIX ABI structs are always stored left shifted in their
6719 function_arg_padding (enum machine_mode mode, const_tree type)
6721 #ifndef AGGREGATE_PADDING_FIXED
6722 #define AGGREGATE_PADDING_FIXED 0
6724 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
6725 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
6728 if (!AGGREGATE_PADDING_FIXED)
6730 /* GCC used to pass structures of the same size as integer types as
6731 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
6732 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6733 passed padded downward, except that -mstrict-align further
6734 muddied the water in that multi-component structures of 2 and 4
6735 bytes in size were passed padded upward.
6737 The following arranges for best compatibility with previous
6738 versions of gcc, but removes the -mstrict-align dependency. */
6739 if (BYTES_BIG_ENDIAN)
6741 HOST_WIDE_INT size = 0;
6743 if (mode == BLKmode)
6745 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
6746 size = int_size_in_bytes (type);
6749 size = GET_MODE_SIZE (mode);
6751 if (size == 1 || size == 2 || size == 4)
6757 if (AGGREGATES_PAD_UPWARD_ALWAYS)
6759 if (type != 0 && AGGREGATE_TYPE_P (type))
6763 /* Fall back to the default. */
6764 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
6767 /* If defined, a C expression that gives the alignment boundary, in bits,
6768 of an argument with the specified mode and type. If it is not defined,
6769 PARM_BOUNDARY is used for all arguments.
6771 V.4 wants long longs and doubles to be double word aligned. Just
6772 testing the mode size is a boneheaded way to do this as it means
6773 that other types such as complex int are also double word aligned.
6774 However, we're stuck with this because changing the ABI might break
6775 existing library interfaces.
6777 Doubleword align SPE vectors.
6778 Quadword align Altivec vectors.
6779 Quadword align large synthetic vector types. */
6782 function_arg_boundary (enum machine_mode mode, tree type)
6784 if (DEFAULT_ABI == ABI_V4
6785 && (GET_MODE_SIZE (mode) == 8
6786 || (TARGET_HARD_FLOAT
6788 && (mode == TFmode || mode == TDmode))))
6790 else if (SPE_VECTOR_MODE (mode)
6791 || (type && TREE_CODE (type) == VECTOR_TYPE
6792 && int_size_in_bytes (type) >= 8
6793 && int_size_in_bytes (type) < 16))
6795 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
6796 || (type && TREE_CODE (type) == VECTOR_TYPE
6797 && int_size_in_bytes (type) >= 16))
6799 else if (rs6000_darwin64_abi && mode == BLKmode
6800 && type && TYPE_ALIGN (type) > 64)
6803 return PARM_BOUNDARY;
6806 /* For a function parm of MODE and TYPE, return the starting word in
6807 the parameter area. NWORDS of the parameter area are already used. */
6810 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
6813 unsigned int parm_offset;
6815 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
6816 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
6817 return nwords + (-(parm_offset + nwords) & align);
6820 /* Compute the size (in words) of a function argument. */
6822 static unsigned long
6823 rs6000_arg_size (enum machine_mode mode, tree type)
6827 if (mode != BLKmode)
6828 size = GET_MODE_SIZE (mode);
6830 size = int_size_in_bytes (type);
6833 return (size + 3) >> 2;
6835 return (size + 7) >> 3;
6838 /* Use this to flush pending int fields. */
6841 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
6842 HOST_WIDE_INT bitpos)
6844 unsigned int startbit, endbit;
6845 int intregs, intoffset;
6846 enum machine_mode mode;
6848 if (cum->intoffset == -1)
6851 intoffset = cum->intoffset;
6852 cum->intoffset = -1;
6854 if (intoffset % BITS_PER_WORD != 0)
6856 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
6858 if (mode == BLKmode)
6860 /* We couldn't find an appropriate mode, which happens,
6861 e.g., in packed structs when there are 3 bytes to load.
6862 Back intoffset back to the beginning of the word in this
6864 intoffset = intoffset & -BITS_PER_WORD;
6868 startbit = intoffset & -BITS_PER_WORD;
6869 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
6870 intregs = (endbit - startbit) / BITS_PER_WORD;
6871 cum->words += intregs;
6874 /* The darwin64 ABI calls for us to recurse down through structs,
6875 looking for elements passed in registers. Unfortunately, we have
6876 to track int register count here also because of misalignments
6877 in powerpc alignment mode. */
6880 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
6882 HOST_WIDE_INT startbitpos)
6886 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
6887 if (TREE_CODE (f) == FIELD_DECL)
6889 HOST_WIDE_INT bitpos = startbitpos;
6890 tree ftype = TREE_TYPE (f);
6891 enum machine_mode mode;
6892 if (ftype == error_mark_node)
6894 mode = TYPE_MODE (ftype);
6896 if (DECL_SIZE (f) != 0
6897 && host_integerp (bit_position (f), 1))
6898 bitpos += int_bit_position (f);
6900 /* ??? FIXME: else assume zero offset. */
6902 if (TREE_CODE (ftype) == RECORD_TYPE)
6903 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
6904 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
6906 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
6907 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
6908 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
6910 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
6912 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
6916 else if (cum->intoffset == -1)
6917 cum->intoffset = bitpos;
6921 /* Update the data in CUM to advance over an argument
6922 of mode MODE and data type TYPE.
6923 (TYPE is null for libcalls where that information may not be available.)
6925 Note that for args passed by reference, function_arg will be called
6926 with MODE and TYPE set to that of the pointer to the arg, not the arg
6930 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
6931 tree type, int named, int depth)
6935 /* Only tick off an argument if we're not recursing. */
6937 cum->nargs_prototype--;
6939 if (TARGET_ALTIVEC_ABI
6940 && (ALTIVEC_VECTOR_MODE (mode)
6941 || VSX_VECTOR_MODE (mode)
6942 || (type && TREE_CODE (type) == VECTOR_TYPE
6943 && int_size_in_bytes (type) == 16)))
6947 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
6950 if (!TARGET_ALTIVEC)
6951 error ("cannot pass argument in vector register because"
6952 " altivec instructions are disabled, use -maltivec"
6955 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
6956 even if it is going to be passed in a vector register.
6957 Darwin does the same for variable-argument functions. */
6958 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6959 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
6969 /* Vector parameters must be 16-byte aligned. This places
6970 them at 2 mod 4 in terms of words in 32-bit mode, since
6971 the parameter save area starts at offset 24 from the
6972 stack. In 64-bit mode, they just have to start on an
6973 even word, since the parameter save area is 16-byte
6974 aligned. Space for GPRs is reserved even if the argument
6975 will be passed in memory. */
6977 align = (2 - cum->words) & 3;
6979 align = cum->words & 1;
6980 cum->words += align + rs6000_arg_size (mode, type);
6982 if (TARGET_DEBUG_ARG)
6984 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
6986 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
6987 cum->nargs_prototype, cum->prototype,
6988 GET_MODE_NAME (mode));
6992 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
6994 && cum->sysv_gregno <= GP_ARG_MAX_REG)
6997 else if (rs6000_darwin64_abi
6999 && TREE_CODE (type) == RECORD_TYPE
7000 && (size = int_size_in_bytes (type)) > 0)
7002 /* Variable sized types have size == -1 and are
7003 treated as if consisting entirely of ints.
7004 Pad to 16 byte boundary if needed. */
7005 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7006 && (cum->words % 2) != 0)
7008 /* For varargs, we can just go up by the size of the struct. */
7010 cum->words += (size + 7) / 8;
7013 /* It is tempting to say int register count just goes up by
7014 sizeof(type)/8, but this is wrong in a case such as
7015 { int; double; int; } [powerpc alignment]. We have to
7016 grovel through the fields for these too. */
7018 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7019 rs6000_darwin64_record_arg_advance_flush (cum,
7020 size * BITS_PER_UNIT);
7023 else if (DEFAULT_ABI == ABI_V4)
7025 if (TARGET_HARD_FLOAT && TARGET_FPRS
7026 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7027 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7028 || (mode == TFmode && !TARGET_IEEEQUAD)
7029 || mode == SDmode || mode == DDmode || mode == TDmode))
7031 /* _Decimal128 must use an even/odd register pair. This assumes
7032 that the register number is odd when fregno is odd. */
7033 if (mode == TDmode && (cum->fregno % 2) == 1)
7036 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7037 <= FP_ARG_V4_MAX_REG)
7038 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7041 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7042 if (mode == DFmode || mode == TFmode
7043 || mode == DDmode || mode == TDmode)
7044 cum->words += cum->words & 1;
7045 cum->words += rs6000_arg_size (mode, type);
7050 int n_words = rs6000_arg_size (mode, type);
7051 int gregno = cum->sysv_gregno;
7053 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7054 (r7,r8) or (r9,r10). As does any other 2 word item such
7055 as complex int due to a historical mistake. */
7057 gregno += (1 - gregno) & 1;
7059 /* Multi-reg args are not split between registers and stack. */
7060 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7062 /* Long long and SPE vectors are aligned on the stack.
7063 So are other 2 word items such as complex int due to
7064 a historical mistake. */
7066 cum->words += cum->words & 1;
7067 cum->words += n_words;
7070 /* Note: continuing to accumulate gregno past when we've started
7071 spilling to the stack indicates the fact that we've started
7072 spilling to the stack to expand_builtin_saveregs. */
7073 cum->sysv_gregno = gregno + n_words;
7076 if (TARGET_DEBUG_ARG)
7078 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7079 cum->words, cum->fregno);
7080 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7081 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7082 fprintf (stderr, "mode = %4s, named = %d\n",
7083 GET_MODE_NAME (mode), named);
7088 int n_words = rs6000_arg_size (mode, type);
7089 int start_words = cum->words;
7090 int align_words = rs6000_parm_start (mode, type, start_words);
7092 cum->words = align_words + n_words;
7094 if (SCALAR_FLOAT_MODE_P (mode)
7095 && TARGET_HARD_FLOAT && TARGET_FPRS)
7097 /* _Decimal128 must be passed in an even/odd float register pair.
7098 This assumes that the register number is odd when fregno is
7100 if (mode == TDmode && (cum->fregno % 2) == 1)
7102 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7105 if (TARGET_DEBUG_ARG)
7107 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7108 cum->words, cum->fregno);
7109 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7110 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7111 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7112 named, align_words - start_words, depth);
7118 spe_build_register_parallel (enum machine_mode mode, int gregno)
7125 r1 = gen_rtx_REG (DImode, gregno);
7126 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7127 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7131 r1 = gen_rtx_REG (DImode, gregno);
7132 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7133 r3 = gen_rtx_REG (DImode, gregno + 2);
7134 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7135 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7138 r1 = gen_rtx_REG (DImode, gregno);
7139 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7140 r3 = gen_rtx_REG (DImode, gregno + 2);
7141 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7142 r5 = gen_rtx_REG (DImode, gregno + 4);
7143 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7144 r7 = gen_rtx_REG (DImode, gregno + 6);
7145 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7146 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7153 /* Determine where to put a SIMD argument on the SPE. */
7155 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7158 int gregno = cum->sysv_gregno;
7160 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7161 are passed and returned in a pair of GPRs for ABI compatibility. */
7162 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7163 || mode == DCmode || mode == TCmode))
7165 int n_words = rs6000_arg_size (mode, type);
7167 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7169 gregno += (1 - gregno) & 1;
7171 /* Multi-reg args are not split between registers and stack. */
7172 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7175 return spe_build_register_parallel (mode, gregno);
7179 int n_words = rs6000_arg_size (mode, type);
7181 /* SPE vectors are put in odd registers. */
7182 if (n_words == 2 && (gregno & 1) == 0)
7185 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7188 enum machine_mode m = SImode;
7190 r1 = gen_rtx_REG (m, gregno);
7191 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7192 r2 = gen_rtx_REG (m, gregno + 1);
7193 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7194 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7201 if (gregno <= GP_ARG_MAX_REG)
7202 return gen_rtx_REG (mode, gregno);
7208 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7209 structure between cum->intoffset and bitpos to integer registers. */
7212 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7213 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7215 enum machine_mode mode;
7217 unsigned int startbit, endbit;
7218 int this_regno, intregs, intoffset;
7221 if (cum->intoffset == -1)
7224 intoffset = cum->intoffset;
7225 cum->intoffset = -1;
7227 /* If this is the trailing part of a word, try to only load that
7228 much into the register. Otherwise load the whole register. Note
7229 that in the latter case we may pick up unwanted bits. It's not a
7230 problem at the moment but may wish to revisit. */
7232 if (intoffset % BITS_PER_WORD != 0)
7234 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7236 if (mode == BLKmode)
7238 /* We couldn't find an appropriate mode, which happens,
7239 e.g., in packed structs when there are 3 bytes to load.
7240 Back intoffset back to the beginning of the word in this
7242 intoffset = intoffset & -BITS_PER_WORD;
7249 startbit = intoffset & -BITS_PER_WORD;
7250 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7251 intregs = (endbit - startbit) / BITS_PER_WORD;
7252 this_regno = cum->words + intoffset / BITS_PER_WORD;
7254 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7257 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7261 intoffset /= BITS_PER_UNIT;
7264 regno = GP_ARG_MIN_REG + this_regno;
7265 reg = gen_rtx_REG (mode, regno);
7267 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7270 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7274 while (intregs > 0);
7277 /* Recursive workhorse for the following. */
7280 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7281 HOST_WIDE_INT startbitpos, rtx rvec[],
7286 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7287 if (TREE_CODE (f) == FIELD_DECL)
7289 HOST_WIDE_INT bitpos = startbitpos;
7290 tree ftype = TREE_TYPE (f);
7291 enum machine_mode mode;
7292 if (ftype == error_mark_node)
7294 mode = TYPE_MODE (ftype);
7296 if (DECL_SIZE (f) != 0
7297 && host_integerp (bit_position (f), 1))
7298 bitpos += int_bit_position (f);
7300 /* ??? FIXME: else assume zero offset. */
7302 if (TREE_CODE (ftype) == RECORD_TYPE)
7303 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7304 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7309 case SCmode: mode = SFmode; break;
7310 case DCmode: mode = DFmode; break;
7311 case TCmode: mode = TFmode; break;
7315 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7317 = gen_rtx_EXPR_LIST (VOIDmode,
7318 gen_rtx_REG (mode, cum->fregno++),
7319 GEN_INT (bitpos / BITS_PER_UNIT));
7320 if (mode == TFmode || mode == TDmode)
7323 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7325 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7327 = gen_rtx_EXPR_LIST (VOIDmode,
7328 gen_rtx_REG (mode, cum->vregno++),
7329 GEN_INT (bitpos / BITS_PER_UNIT));
7331 else if (cum->intoffset == -1)
7332 cum->intoffset = bitpos;
7336 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7337 the register(s) to be used for each field and subfield of a struct
7338 being passed by value, along with the offset of where the
7339 register's value may be found in the block. FP fields go in FP
7340 register, vector fields go in vector registers, and everything
7341 else goes in int registers, packed as in memory.
7343 This code is also used for function return values. RETVAL indicates
7344 whether this is the case.
7346 Much of this is taken from the SPARC V9 port, which has a similar
7347 calling convention. */
7350 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7351 int named, bool retval)
7353 rtx rvec[FIRST_PSEUDO_REGISTER];
7354 int k = 1, kbase = 1;
7355 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7356 /* This is a copy; modifications are not visible to our caller. */
7357 CUMULATIVE_ARGS copy_cum = *orig_cum;
7358 CUMULATIVE_ARGS *cum = ©_cum;
7360 /* Pad to 16 byte boundary if needed. */
7361 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7362 && (cum->words % 2) != 0)
7369 /* Put entries into rvec[] for individual FP and vector fields, and
7370 for the chunks of memory that go in int regs. Note we start at
7371 element 1; 0 is reserved for an indication of using memory, and
7372 may or may not be filled in below. */
7373 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7374 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7376 /* If any part of the struct went on the stack put all of it there.
7377 This hack is because the generic code for
7378 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7379 parts of the struct are not at the beginning. */
7383 return NULL_RTX; /* doesn't go in registers at all */
7385 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7387 if (k > 1 || cum->use_stack)
7388 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7393 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7396 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7400 rtx rvec[GP_ARG_NUM_REG + 1];
7402 if (align_words >= GP_ARG_NUM_REG)
7405 n_units = rs6000_arg_size (mode, type);
7407 /* Optimize the simple case where the arg fits in one gpr, except in
7408 the case of BLKmode due to assign_parms assuming that registers are
7409 BITS_PER_WORD wide. */
7411 || (n_units == 1 && mode != BLKmode))
7412 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7415 if (align_words + n_units > GP_ARG_NUM_REG)
7416 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7417 using a magic NULL_RTX component.
7418 This is not strictly correct. Only some of the arg belongs in
7419 memory, not all of it. However, the normal scheme using
7420 function_arg_partial_nregs can result in unusual subregs, eg.
7421 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7422 store the whole arg to memory is often more efficient than code
7423 to store pieces, and we know that space is available in the right
7424 place for the whole arg. */
7425 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7430 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7431 rtx off = GEN_INT (i++ * 4);
7432 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7434 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7436 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7439 /* Determine where to put an argument to a function.
7440 Value is zero to push the argument on the stack,
7441 or a hard register in which to store the argument.
7443 MODE is the argument's machine mode.
7444 TYPE is the data type of the argument (as a tree).
7445 This is null for libcalls where that information may
7447 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7448 the preceding args and about the function being called. It is
7449 not modified in this routine.
7450 NAMED is nonzero if this argument is a named parameter
7451 (otherwise it is an extra parameter matching an ellipsis).
7453 On RS/6000 the first eight words of non-FP are normally in registers
7454 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7455 Under V.4, the first 8 FP args are in registers.
7457 If this is floating-point and no prototype is specified, we use
7458 both an FP and integer register (or possibly FP reg and stack). Library
7459 functions (when CALL_LIBCALL is set) always have the proper types for args,
7460 so we can pass the FP value just in one register. emit_library_function
7461 doesn't support PARALLEL anyway.
7463 Note that for args passed by reference, function_arg will be called
7464 with MODE and TYPE set to that of the pointer to the arg, not the arg
7468 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7469 tree type, int named)
7471 enum rs6000_abi abi = DEFAULT_ABI;
7473 /* Return a marker to indicate whether CR1 needs to set or clear the
7474 bit that V.4 uses to say fp args were passed in registers.
7475 Assume that we don't need the marker for software floating point,
7476 or compiler generated library calls. */
7477 if (mode == VOIDmode)
7480 && (cum->call_cookie & CALL_LIBCALL) == 0
7482 || (cum->nargs_prototype < 0
7483 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7485 /* For the SPE, we need to crxor CR6 always. */
7487 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
7488 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
7489 return GEN_INT (cum->call_cookie
7490 | ((cum->fregno == FP_ARG_MIN_REG)
7491 ? CALL_V4_SET_FP_ARGS
7492 : CALL_V4_CLEAR_FP_ARGS));
7495 return GEN_INT (cum->call_cookie);
7498 if (rs6000_darwin64_abi && mode == BLKmode
7499 && TREE_CODE (type) == RECORD_TYPE)
7501 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
7502 if (rslt != NULL_RTX)
7504 /* Else fall through to usual handling. */
7507 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7508 if (TARGET_64BIT && ! cum->prototype)
7510 /* Vector parameters get passed in vector register
7511 and also in GPRs or memory, in absence of prototype. */
7514 align_words = (cum->words + 1) & ~1;
7516 if (align_words >= GP_ARG_NUM_REG)
7522 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7524 return gen_rtx_PARALLEL (mode,
7526 gen_rtx_EXPR_LIST (VOIDmode,
7528 gen_rtx_EXPR_LIST (VOIDmode,
7529 gen_rtx_REG (mode, cum->vregno),
7533 return gen_rtx_REG (mode, cum->vregno);
7534 else if (TARGET_ALTIVEC_ABI
7535 && (ALTIVEC_VECTOR_MODE (mode)
7536 || VSX_VECTOR_MODE (mode)
7537 || (type && TREE_CODE (type) == VECTOR_TYPE
7538 && int_size_in_bytes (type) == 16)))
7540 if (named || abi == ABI_V4)
7544 /* Vector parameters to varargs functions under AIX or Darwin
7545 get passed in memory and possibly also in GPRs. */
7546 int align, align_words, n_words;
7547 enum machine_mode part_mode;
7549 /* Vector parameters must be 16-byte aligned. This places them at
7550 2 mod 4 in terms of words in 32-bit mode, since the parameter
7551 save area starts at offset 24 from the stack. In 64-bit mode,
7552 they just have to start on an even word, since the parameter
7553 save area is 16-byte aligned. */
7555 align = (2 - cum->words) & 3;
7557 align = cum->words & 1;
7558 align_words = cum->words + align;
7560 /* Out of registers? Memory, then. */
7561 if (align_words >= GP_ARG_NUM_REG)
7564 if (TARGET_32BIT && TARGET_POWERPC64)
7565 return rs6000_mixed_function_arg (mode, type, align_words);
7567 /* The vector value goes in GPRs. Only the part of the
7568 value in GPRs is reported here. */
7570 n_words = rs6000_arg_size (mode, type);
7571 if (align_words + n_words > GP_ARG_NUM_REG)
7572 /* Fortunately, there are only two possibilities, the value
7573 is either wholly in GPRs or half in GPRs and half not. */
7576 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
7579 else if (TARGET_SPE_ABI && TARGET_SPE
7580 && (SPE_VECTOR_MODE (mode)
7581 || (TARGET_E500_DOUBLE && (mode == DFmode
7584 || mode == TCmode))))
7585 return rs6000_spe_function_arg (cum, mode, type);
7587 else if (abi == ABI_V4)
7589 if (TARGET_HARD_FLOAT && TARGET_FPRS
7590 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7591 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7592 || (mode == TFmode && !TARGET_IEEEQUAD)
7593 || mode == SDmode || mode == DDmode || mode == TDmode))
7595 /* _Decimal128 must use an even/odd register pair. This assumes
7596 that the register number is odd when fregno is odd. */
7597 if (mode == TDmode && (cum->fregno % 2) == 1)
7600 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7601 <= FP_ARG_V4_MAX_REG)
7602 return gen_rtx_REG (mode, cum->fregno);
7608 int n_words = rs6000_arg_size (mode, type);
7609 int gregno = cum->sysv_gregno;
7611 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7612 (r7,r8) or (r9,r10). As does any other 2 word item such
7613 as complex int due to a historical mistake. */
7615 gregno += (1 - gregno) & 1;
7617 /* Multi-reg args are not split between registers and stack. */
7618 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7621 if (TARGET_32BIT && TARGET_POWERPC64)
7622 return rs6000_mixed_function_arg (mode, type,
7623 gregno - GP_ARG_MIN_REG);
7624 return gen_rtx_REG (mode, gregno);
7629 int align_words = rs6000_parm_start (mode, type, cum->words);
7631 /* _Decimal128 must be passed in an even/odd float register pair.
7632 This assumes that the register number is odd when fregno is odd. */
7633 if (mode == TDmode && (cum->fregno % 2) == 1)
7636 if (USE_FP_FOR_ARG_P (cum, mode, type))
7638 rtx rvec[GP_ARG_NUM_REG + 1];
7642 enum machine_mode fmode = mode;
7643 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
7645 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
7647 /* Currently, we only ever need one reg here because complex
7648 doubles are split. */
7649 gcc_assert (cum->fregno == FP_ARG_MAX_REG
7650 && (fmode == TFmode || fmode == TDmode));
7652 /* Long double or _Decimal128 split over regs and memory. */
7653 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
7656 /* Do we also need to pass this arg in the parameter save
7659 && (cum->nargs_prototype <= 0
7660 || (DEFAULT_ABI == ABI_AIX
7662 && align_words >= GP_ARG_NUM_REG)));
7664 if (!needs_psave && mode == fmode)
7665 return gen_rtx_REG (fmode, cum->fregno);
7670 /* Describe the part that goes in gprs or the stack.
7671 This piece must come first, before the fprs. */
7672 if (align_words < GP_ARG_NUM_REG)
7674 unsigned long n_words = rs6000_arg_size (mode, type);
7676 if (align_words + n_words > GP_ARG_NUM_REG
7677 || (TARGET_32BIT && TARGET_POWERPC64))
7679 /* If this is partially on the stack, then we only
7680 include the portion actually in registers here. */
7681 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
7684 if (align_words + n_words > GP_ARG_NUM_REG)
7685 /* Not all of the arg fits in gprs. Say that it
7686 goes in memory too, using a magic NULL_RTX
7687 component. Also see comment in
7688 rs6000_mixed_function_arg for why the normal
7689 function_arg_partial_nregs scheme doesn't work
7691 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
7695 r = gen_rtx_REG (rmode,
7696 GP_ARG_MIN_REG + align_words);
7697 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
7698 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7700 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
7704 /* The whole arg fits in gprs. */
7705 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7706 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7710 /* It's entirely in memory. */
7711 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7714 /* Describe where this piece goes in the fprs. */
7715 r = gen_rtx_REG (fmode, cum->fregno);
7716 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
7718 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7720 else if (align_words < GP_ARG_NUM_REG)
7722 if (TARGET_32BIT && TARGET_POWERPC64)
7723 return rs6000_mixed_function_arg (mode, type, align_words);
7725 if (mode == BLKmode)
7728 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7735 /* For an arg passed partly in registers and partly in memory, this is
7736 the number of bytes passed in registers. For args passed entirely in
7737 registers or entirely in memory, zero. When an arg is described by a
7738 PARALLEL, perhaps using more than one register type, this function
7739 returns the number of bytes used by the first element of the PARALLEL. */
7742 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7743 tree type, bool named)
7748 if (DEFAULT_ABI == ABI_V4)
7751 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
7752 && cum->nargs_prototype >= 0)
7755 /* In this complicated case we just disable the partial_nregs code. */
7756 if (rs6000_darwin64_abi && mode == BLKmode
7757 && TREE_CODE (type) == RECORD_TYPE
7758 && int_size_in_bytes (type) > 0)
7761 align_words = rs6000_parm_start (mode, type, cum->words);
7763 if (USE_FP_FOR_ARG_P (cum, mode, type))
7765 /* If we are passing this arg in the fixed parameter save area
7766 (gprs or memory) as well as fprs, then this function should
7767 return the number of partial bytes passed in the parameter
7768 save area rather than partial bytes passed in fprs. */
7770 && (cum->nargs_prototype <= 0
7771 || (DEFAULT_ABI == ABI_AIX
7773 && align_words >= GP_ARG_NUM_REG)))
7775 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
7776 > FP_ARG_MAX_REG + 1)
7777 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
7778 else if (cum->nargs_prototype >= 0)
7782 if (align_words < GP_ARG_NUM_REG
7783 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
7784 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
7786 if (ret != 0 && TARGET_DEBUG_ARG)
7787 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
7792 /* A C expression that indicates when an argument must be passed by
7793 reference. If nonzero for an argument, a copy of that argument is
7794 made in memory and a pointer to the argument is passed instead of
7795 the argument itself. The pointer is passed in whatever way is
7796 appropriate for passing a pointer to that type.
7798 Under V.4, aggregates and long double are passed by reference.
7800 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
7801 reference unless the AltiVec vector extension ABI is in force.
7803 As an extension to all ABIs, variable sized types are passed by
7807 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
7808 enum machine_mode mode, const_tree type,
7809 bool named ATTRIBUTE_UNUSED)
7811 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
7813 if (TARGET_DEBUG_ARG)
7814 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
7821 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
7823 if (TARGET_DEBUG_ARG)
7824 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
7828 if (int_size_in_bytes (type) < 0)
7830 if (TARGET_DEBUG_ARG)
7831 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
7835 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7836 modes only exist for GCC vector types if -maltivec. */
7837 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
7839 if (TARGET_DEBUG_ARG)
7840 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
7844 /* Pass synthetic vectors in memory. */
7845 if (TREE_CODE (type) == VECTOR_TYPE
7846 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7848 static bool warned_for_pass_big_vectors = false;
7849 if (TARGET_DEBUG_ARG)
7850 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
7851 if (!warned_for_pass_big_vectors)
7853 warning (0, "GCC vector passed by reference: "
7854 "non-standard ABI extension with no compatibility guarantee");
7855 warned_for_pass_big_vectors = true;
7864 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
7867 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
7872 for (i = 0; i < nregs; i++)
7874 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
7875 if (reload_completed)
7877 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
7880 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
7881 i * GET_MODE_SIZE (reg_mode));
7884 tem = replace_equiv_address (tem, XEXP (tem, 0));
7888 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
7892 /* Perform any needed actions needed for a function that is receiving a
7893 variable number of arguments.
7897 MODE and TYPE are the mode and type of the current parameter.
7899 PRETEND_SIZE is a variable that should be set to the amount of stack
7900 that must be pushed by the prolog to pretend that our caller pushed
7903 Normally, this macro will push all remaining incoming registers on the
7904 stack and set PRETEND_SIZE to the length of the registers pushed. */
7907 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7908 tree type, int *pretend_size ATTRIBUTE_UNUSED,
7911 CUMULATIVE_ARGS next_cum;
7912 int reg_size = TARGET_32BIT ? 4 : 8;
7913 rtx save_area = NULL_RTX, mem;
7914 int first_reg_offset;
7917 /* Skip the last named argument. */
7919 function_arg_advance (&next_cum, mode, type, 1, 0);
7921 if (DEFAULT_ABI == ABI_V4)
7923 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
7927 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
7928 HOST_WIDE_INT offset = 0;
7930 /* Try to optimize the size of the varargs save area.
7931 The ABI requires that ap.reg_save_area is doubleword
7932 aligned, but we don't need to allocate space for all
7933 the bytes, only those to which we actually will save
7935 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
7936 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
7937 if (TARGET_HARD_FLOAT && TARGET_FPRS
7938 && next_cum.fregno <= FP_ARG_V4_MAX_REG
7939 && cfun->va_list_fpr_size)
7942 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
7943 * UNITS_PER_FP_WORD;
7944 if (cfun->va_list_fpr_size
7945 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
7946 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
7948 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
7949 * UNITS_PER_FP_WORD;
7953 offset = -((first_reg_offset * reg_size) & ~7);
7954 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
7956 gpr_reg_num = cfun->va_list_gpr_size;
7957 if (reg_size == 4 && (first_reg_offset & 1))
7960 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
7963 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
7965 - (int) (GP_ARG_NUM_REG * reg_size);
7967 if (gpr_size + fpr_size)
7970 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
7971 gcc_assert (GET_CODE (reg_save_area) == MEM);
7972 reg_save_area = XEXP (reg_save_area, 0);
7973 if (GET_CODE (reg_save_area) == PLUS)
7975 gcc_assert (XEXP (reg_save_area, 0)
7976 == virtual_stack_vars_rtx);
7977 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
7978 offset += INTVAL (XEXP (reg_save_area, 1));
7981 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
7984 cfun->machine->varargs_save_offset = offset;
7985 save_area = plus_constant (virtual_stack_vars_rtx, offset);
7990 first_reg_offset = next_cum.words;
7991 save_area = virtual_incoming_args_rtx;
7993 if (targetm.calls.must_pass_in_stack (mode, type))
7994 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
7997 set = get_varargs_alias_set ();
7998 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
7999 && cfun->va_list_gpr_size)
8001 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8003 if (va_list_gpr_counter_field)
8005 /* V4 va_list_gpr_size counts number of registers needed. */
8006 if (nregs > cfun->va_list_gpr_size)
8007 nregs = cfun->va_list_gpr_size;
8011 /* char * va_list instead counts number of bytes needed. */
8012 if (nregs > cfun->va_list_gpr_size / reg_size)
8013 nregs = cfun->va_list_gpr_size / reg_size;
8016 mem = gen_rtx_MEM (BLKmode,
8017 plus_constant (save_area,
8018 first_reg_offset * reg_size));
8019 MEM_NOTRAP_P (mem) = 1;
8020 set_mem_alias_set (mem, set);
8021 set_mem_align (mem, BITS_PER_WORD);
8023 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8027 /* Save FP registers if needed. */
8028 if (DEFAULT_ABI == ABI_V4
8029 && TARGET_HARD_FLOAT && TARGET_FPRS
8031 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8032 && cfun->va_list_fpr_size)
8034 int fregno = next_cum.fregno, nregs;
8035 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8036 rtx lab = gen_label_rtx ();
8037 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8038 * UNITS_PER_FP_WORD);
8041 (gen_rtx_SET (VOIDmode,
8043 gen_rtx_IF_THEN_ELSE (VOIDmode,
8044 gen_rtx_NE (VOIDmode, cr1,
8046 gen_rtx_LABEL_REF (VOIDmode, lab),
8050 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8051 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8053 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8055 plus_constant (save_area, off));
8056 MEM_NOTRAP_P (mem) = 1;
8057 set_mem_alias_set (mem, set);
8058 set_mem_align (mem, GET_MODE_ALIGNMENT (
8059 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8060 ? DFmode : SFmode));
8061 emit_move_insn (mem, gen_rtx_REG (
8062 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8063 ? DFmode : SFmode, fregno));
8070 /* Create the va_list data type. */
8073 rs6000_build_builtin_va_list (void)
8075 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8077 /* For AIX, prefer 'char *' because that's what the system
8078 header files like. */
8079 if (DEFAULT_ABI != ABI_V4)
8080 return build_pointer_type (char_type_node);
8082 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8083 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8084 get_identifier ("__va_list_tag"), record);
8086 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8087 unsigned_char_type_node);
8088 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8089 unsigned_char_type_node);
8090 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8092 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8093 get_identifier ("reserved"), short_unsigned_type_node);
8094 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8095 get_identifier ("overflow_arg_area"),
8097 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8098 get_identifier ("reg_save_area"),
8101 va_list_gpr_counter_field = f_gpr;
8102 va_list_fpr_counter_field = f_fpr;
8104 DECL_FIELD_CONTEXT (f_gpr) = record;
8105 DECL_FIELD_CONTEXT (f_fpr) = record;
8106 DECL_FIELD_CONTEXT (f_res) = record;
8107 DECL_FIELD_CONTEXT (f_ovf) = record;
8108 DECL_FIELD_CONTEXT (f_sav) = record;
8110 TREE_CHAIN (record) = type_decl;
8111 TYPE_NAME (record) = type_decl;
8112 TYPE_FIELDS (record) = f_gpr;
8113 TREE_CHAIN (f_gpr) = f_fpr;
8114 TREE_CHAIN (f_fpr) = f_res;
8115 TREE_CHAIN (f_res) = f_ovf;
8116 TREE_CHAIN (f_ovf) = f_sav;
8118 layout_type (record);
8120 /* The correct type is an array type of one element. */
8121 return build_array_type (record, build_index_type (size_zero_node));
8124 /* Implement va_start. */
8127 rs6000_va_start (tree valist, rtx nextarg)
8129 HOST_WIDE_INT words, n_gpr, n_fpr;
8130 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8131 tree gpr, fpr, ovf, sav, t;
8133 /* Only SVR4 needs something special. */
8134 if (DEFAULT_ABI != ABI_V4)
8136 std_expand_builtin_va_start (valist, nextarg);
8140 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8141 f_fpr = TREE_CHAIN (f_gpr);
8142 f_res = TREE_CHAIN (f_fpr);
8143 f_ovf = TREE_CHAIN (f_res);
8144 f_sav = TREE_CHAIN (f_ovf);
8146 valist = build_va_arg_indirect_ref (valist);
8147 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8148 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8150 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8152 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8155 /* Count number of gp and fp argument registers used. */
8156 words = crtl->args.info.words;
8157 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8159 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8162 if (TARGET_DEBUG_ARG)
8163 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8164 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8165 words, n_gpr, n_fpr);
8167 if (cfun->va_list_gpr_size)
8169 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8170 build_int_cst (NULL_TREE, n_gpr));
8171 TREE_SIDE_EFFECTS (t) = 1;
8172 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8175 if (cfun->va_list_fpr_size)
8177 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8178 build_int_cst (NULL_TREE, n_fpr));
8179 TREE_SIDE_EFFECTS (t) = 1;
8180 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8183 /* Find the overflow area. */
8184 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8186 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8187 size_int (words * UNITS_PER_WORD));
8188 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8189 TREE_SIDE_EFFECTS (t) = 1;
8190 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8192 /* If there were no va_arg invocations, don't set up the register
8194 if (!cfun->va_list_gpr_size
8195 && !cfun->va_list_fpr_size
8196 && n_gpr < GP_ARG_NUM_REG
8197 && n_fpr < FP_ARG_V4_MAX_REG)
8200 /* Find the register save area. */
8201 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8202 if (cfun->machine->varargs_save_offset)
8203 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8204 size_int (cfun->machine->varargs_save_offset));
8205 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8206 TREE_SIDE_EFFECTS (t) = 1;
8207 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8210 /* Implement va_arg. */
8213 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8216 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8217 tree gpr, fpr, ovf, sav, reg, t, u;
8218 int size, rsize, n_reg, sav_ofs, sav_scale;
8219 tree lab_false, lab_over, addr;
8221 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8225 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8227 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8228 return build_va_arg_indirect_ref (t);
8231 if (DEFAULT_ABI != ABI_V4)
8233 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8235 tree elem_type = TREE_TYPE (type);
8236 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8237 int elem_size = GET_MODE_SIZE (elem_mode);
8239 if (elem_size < UNITS_PER_WORD)
8241 tree real_part, imag_part;
8242 gimple_seq post = NULL;
8244 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8246 /* Copy the value into a temporary, lest the formal temporary
8247 be reused out from under us. */
8248 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8249 gimple_seq_add_seq (pre_p, post);
8251 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8254 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8258 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8261 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8262 f_fpr = TREE_CHAIN (f_gpr);
8263 f_res = TREE_CHAIN (f_fpr);
8264 f_ovf = TREE_CHAIN (f_res);
8265 f_sav = TREE_CHAIN (f_ovf);
8267 valist = build_va_arg_indirect_ref (valist);
8268 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8269 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8271 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8273 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8276 size = int_size_in_bytes (type);
8277 rsize = (size + 3) / 4;
8280 if (TARGET_HARD_FLOAT && TARGET_FPRS
8281 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8282 || (TARGET_DOUBLE_FLOAT
8283 && (TYPE_MODE (type) == DFmode
8284 || TYPE_MODE (type) == TFmode
8285 || TYPE_MODE (type) == SDmode
8286 || TYPE_MODE (type) == DDmode
8287 || TYPE_MODE (type) == TDmode))))
8289 /* FP args go in FP registers, if present. */
8291 n_reg = (size + 7) / 8;
8292 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8293 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8294 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8299 /* Otherwise into GP registers. */
8308 /* Pull the value out of the saved registers.... */
8311 addr = create_tmp_var (ptr_type_node, "addr");
8313 /* AltiVec vectors never go in registers when -mabi=altivec. */
8314 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8318 lab_false = create_artificial_label (input_location);
8319 lab_over = create_artificial_label (input_location);
8321 /* Long long and SPE vectors are aligned in the registers.
8322 As are any other 2 gpr item such as complex int due to a
8323 historical mistake. */
8325 if (n_reg == 2 && reg == gpr)
8328 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8329 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8330 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8331 unshare_expr (reg), u);
8333 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8334 reg number is 0 for f1, so we want to make it odd. */
8335 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8337 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8338 build_int_cst (TREE_TYPE (reg), 1));
8339 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8342 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8343 t = build2 (GE_EXPR, boolean_type_node, u, t);
8344 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8345 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8346 gimplify_and_add (t, pre_p);
8350 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8352 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8353 build_int_cst (TREE_TYPE (reg), n_reg));
8354 u = fold_convert (sizetype, u);
8355 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8356 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8358 /* _Decimal32 varargs are located in the second word of the 64-bit
8359 FP register for 32-bit binaries. */
8360 if (!TARGET_POWERPC64
8361 && TARGET_HARD_FLOAT && TARGET_FPRS
8362 && TYPE_MODE (type) == SDmode)
8363 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8365 gimplify_assign (addr, t, pre_p);
8367 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8369 stmt = gimple_build_label (lab_false);
8370 gimple_seq_add_stmt (pre_p, stmt);
8372 if ((n_reg == 2 && !regalign) || n_reg > 2)
8374 /* Ensure that we don't find any more args in regs.
8375 Alignment has taken care of for special cases. */
8376 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8380 /* ... otherwise out of the overflow area. */
8382 /* Care for on-stack alignment if needed. */
8386 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8387 t = fold_convert (sizetype, t);
8388 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8390 t = fold_convert (TREE_TYPE (ovf), t);
8392 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8394 gimplify_assign (unshare_expr (addr), t, pre_p);
8396 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8397 gimplify_assign (unshare_expr (ovf), t, pre_p);
8401 stmt = gimple_build_label (lab_over);
8402 gimple_seq_add_stmt (pre_p, stmt);
8405 if (STRICT_ALIGNMENT
8406 && (TYPE_ALIGN (type)
8407 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8409 /* The value (of type complex double, for example) may not be
8410 aligned in memory in the saved registers, so copy via a
8411 temporary. (This is the same code as used for SPARC.) */
8412 tree tmp = create_tmp_var (type, "va_arg_tmp");
8413 tree dest_addr = build_fold_addr_expr (tmp);
8415 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8416 3, dest_addr, addr, size_int (rsize * 4));
8418 gimplify_and_add (copy, pre_p);
8422 addr = fold_convert (ptrtype, addr);
8423 return build_va_arg_indirect_ref (addr);
8429 def_builtin (int mask, const char *name, tree type, int code)
8431 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8433 if (rs6000_builtin_decls[code])
8434 fatal_error ("internal error: builtin function to %s already processed.",
8437 rs6000_builtin_decls[code] =
8438 add_builtin_function (name, type, code, BUILT_IN_MD,
8443 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
8445 static const struct builtin_description bdesc_3arg[] =
8447 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
8448 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
8449 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
8450 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
8451 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
8452 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
8453 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
8454 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
8455 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
8456 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
8457 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
8458 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
8459 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
8460 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
8461 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
8462 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
8463 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
8464 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
8465 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
8466 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
8467 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
8468 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
8469 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
8470 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
8471 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
8472 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
8473 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
8474 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
8475 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
8476 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
8477 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
8478 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
8479 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
8480 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
8481 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
8483 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
8484 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
8485 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
8486 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
8487 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
8488 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
8489 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
8490 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
8491 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
8492 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
8493 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
8494 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
8495 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
8496 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
8497 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
8499 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
8500 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
8501 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
8502 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
8504 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
8505 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
8506 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
8507 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
8509 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
8510 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
8512 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
8513 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
8514 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
8515 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
8516 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
8517 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
8518 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
8519 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
8520 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
8521 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
8523 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
8524 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
8525 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
8526 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
8527 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
8528 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
8529 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
8530 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
8531 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
8532 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
8534 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
8535 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
8536 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
8537 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
8538 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
8539 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
8540 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
8541 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
8542 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
8544 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
8545 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
8546 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
8547 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
8548 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
8549 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
8550 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
8552 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
8553 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
8554 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
8555 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
8556 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
8557 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
8558 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
8559 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
8560 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
8563 /* DST operations: void foo (void *, const int, const char). */
8565 static const struct builtin_description bdesc_dst[] =
8567 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
8568 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
8569 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
8570 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
8572 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
8573 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
8574 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
8575 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
8578 /* Simple binary operations: VECc = foo (VECa, VECb). */
8580 static struct builtin_description bdesc_2arg[] =
8582 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
8583 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
8584 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
8585 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
8586 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
8587 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
8588 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
8589 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
8590 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
8591 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
8592 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
8593 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
8594 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
8595 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
8596 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
8597 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
8598 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
8599 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
8600 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
8601 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
8602 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
8603 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
8604 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
8605 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
8606 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
8607 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
8608 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
8609 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
8610 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
8611 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
8612 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
8613 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
8614 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
8615 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
8616 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
8617 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
8618 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
8619 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
8620 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
8621 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
8622 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
8623 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
8624 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
8625 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
8626 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
8627 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
8628 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
8629 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
8630 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
8631 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
8632 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
8633 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
8634 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
8635 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
8636 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
8637 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
8638 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
8639 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
8640 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
8641 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
8642 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
8643 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
8644 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
8645 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
8646 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
8647 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
8648 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
8649 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
8650 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
8651 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
8652 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
8653 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
8654 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
8655 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
8656 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
8657 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
8658 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
8659 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
8660 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
8661 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
8662 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
8663 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
8664 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
8665 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
8666 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
8667 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
8668 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
8669 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
8670 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
8671 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
8672 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
8673 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
8674 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
8675 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
8676 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
8677 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
8678 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
8679 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
8680 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
8681 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
8682 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
8683 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
8684 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
8685 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
8686 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
8687 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
8688 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
8689 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
8690 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
8691 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
8692 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
8693 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
8694 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
8695 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
8696 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
8697 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
8699 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
8700 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
8701 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
8702 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
8703 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
8704 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
8705 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
8706 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
8707 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
8708 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
8709 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
8711 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
8712 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
8713 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
8714 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
8715 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
8716 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
8717 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
8718 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
8719 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
8720 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
8721 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
8723 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
8724 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
8725 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
8726 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
8727 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
8728 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
8730 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
8731 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
8732 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
8733 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
8734 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
8735 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
8736 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
8737 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
8739 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
8740 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
8741 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
8742 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
8743 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
8744 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
8745 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
8746 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
8747 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
8748 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
8749 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
8750 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
8751 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
8752 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
8753 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
8754 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
8755 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
8756 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
8757 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
8758 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
8759 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
8760 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
8761 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
8762 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
8763 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
8764 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
8765 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
8766 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
8767 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
8768 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
8769 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
8770 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
8771 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
8772 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
8773 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
8774 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
8775 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
8776 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
8777 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
8778 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
8779 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
8780 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
8781 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
8782 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
8783 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
8784 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
8785 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
8786 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
8787 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
8788 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
8789 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
8790 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
8791 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
8792 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
8793 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
8794 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
8795 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
8796 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
8797 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
8798 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
8799 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
8800 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
8801 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
8802 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
8803 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
8804 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
8805 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
8806 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
8807 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
8808 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
8809 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
8810 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
8811 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
8812 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
8813 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
8814 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
8815 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
8816 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
8817 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
8818 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
8819 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
8820 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
8821 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
8822 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
8823 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
8824 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
8825 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
8826 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
8827 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
8828 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
8829 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
8830 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
8831 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
8832 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
8833 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
8834 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
8835 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
8836 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
8837 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
8838 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
8839 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
8840 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
8841 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
8842 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
8843 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
8844 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
8845 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
8846 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
8847 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
8848 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
8849 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
8850 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
8851 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
8852 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
8853 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
8854 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
8855 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
8856 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
8857 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
8858 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
8859 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
8860 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
8861 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
8862 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
8863 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
8864 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
8865 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
8866 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
8868 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
8869 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
8871 { 0, CODE_FOR_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
8872 { 0, CODE_FOR_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
8873 { 0, CODE_FOR_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
8874 { 0, CODE_FOR_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
8875 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
8876 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
8877 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
8878 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
8879 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
8880 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
8882 /* Place holder, leave as first spe builtin. */
8883 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
8884 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
8885 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
8886 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
8887 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
8888 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
8889 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
8890 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
8891 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
8892 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
8893 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
8894 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
8895 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
8896 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
8897 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
8898 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
8899 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
8900 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
8901 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
8902 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
8903 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
8904 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
8905 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
8906 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
8907 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
8908 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
8909 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
8910 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
8911 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
8912 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
8913 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
8914 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
8915 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
8916 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
8917 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
8918 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
8919 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
8920 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
8921 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
8922 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
8923 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
8924 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
8925 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
8926 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
8927 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
8928 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
8929 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
8930 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
8931 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
8932 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
8933 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
8934 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
8935 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
8936 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
8937 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
8938 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
8939 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
8940 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
8941 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
8942 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
8943 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
8944 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
8945 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
8946 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
8947 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
8948 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
8949 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
8950 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
8951 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
8952 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
8953 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
8954 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
8955 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
8956 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
8957 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
8958 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
8959 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
8960 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
8961 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
8962 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
8963 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
8964 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
8965 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
8966 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
8967 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
8968 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
8969 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
8970 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
8971 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
8972 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
8973 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
8974 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
8975 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
8976 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
8977 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
8978 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
8979 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
8980 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
8981 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
8982 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
8983 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
8984 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
8985 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
8986 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
8987 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
8988 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
8989 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
8990 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
8991 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
8993 /* SPE binary operations expecting a 5-bit unsigned literal. */
8994 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
8996 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
8997 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
8998 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
8999 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9000 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9001 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9002 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9003 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9004 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9005 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9006 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9007 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9008 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9009 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9010 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9011 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9012 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9013 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9014 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9015 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9016 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9017 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9018 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9019 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9020 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9021 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9023 /* Place-holder. Leave as last binary SPE builtin. */
9024 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9027 /* AltiVec predicates. */
9029 struct builtin_description_predicates
9031 const unsigned int mask;
9032 const enum insn_code icode;
9033 const char *const name;
9034 const enum rs6000_builtins code;
9037 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9039 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9040 ALTIVEC_BUILTIN_VCMPBFP_P },
9041 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9042 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9043 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9044 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9045 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9046 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9047 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9048 ALTIVEC_BUILTIN_VCMPEQUW_P },
9049 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9050 ALTIVEC_BUILTIN_VCMPGTSW_P },
9051 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9052 ALTIVEC_BUILTIN_VCMPGTUW_P },
9053 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9054 ALTIVEC_BUILTIN_VCMPEQUH_P },
9055 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9056 ALTIVEC_BUILTIN_VCMPGTSH_P },
9057 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9058 ALTIVEC_BUILTIN_VCMPGTUH_P },
9059 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9060 ALTIVEC_BUILTIN_VCMPEQUB_P },
9061 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9062 ALTIVEC_BUILTIN_VCMPGTSB_P },
9063 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9064 ALTIVEC_BUILTIN_VCMPGTUB_P },
9066 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9067 VSX_BUILTIN_XVCMPEQSP_P },
9068 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9069 VSX_BUILTIN_XVCMPGESP_P },
9070 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9071 VSX_BUILTIN_XVCMPGTSP_P },
9072 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9073 VSX_BUILTIN_XVCMPEQDP_P },
9074 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9075 VSX_BUILTIN_XVCMPGEDP_P },
9076 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9077 VSX_BUILTIN_XVCMPGTDP_P },
9079 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9080 ALTIVEC_BUILTIN_VCMPEQ_P },
9081 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9082 ALTIVEC_BUILTIN_VCMPGT_P },
9083 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9084 ALTIVEC_BUILTIN_VCMPGE_P }
9087 /* SPE predicates. */
9088 static struct builtin_description bdesc_spe_predicates[] =
9090 /* Place-holder. Leave as first. */
9091 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9092 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9093 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9094 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9095 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9096 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9097 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9098 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9099 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9100 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9101 /* Place-holder. Leave as last. */
9102 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9105 /* SPE evsel predicates. */
9106 static struct builtin_description bdesc_spe_evsel[] =
9108 /* Place-holder. Leave as first. */
9109 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9110 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9111 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9112 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9113 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9114 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9115 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9116 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9117 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9118 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9119 /* Place-holder. Leave as last. */
9120 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9123 /* PAIRED predicates. */
9124 static const struct builtin_description bdesc_paired_preds[] =
9126 /* Place-holder. Leave as first. */
9127 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9128 /* Place-holder. Leave as last. */
9129 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9132 /* ABS* operations. */
9134 static const struct builtin_description bdesc_abs[] =
9136 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9137 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9138 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9139 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9140 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9141 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9142 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9143 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9144 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9145 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9146 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9149 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9152 static struct builtin_description bdesc_1arg[] =
9154 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9155 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9156 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9157 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9158 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9159 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9160 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9161 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9162 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9163 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9164 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9165 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9166 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9167 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9168 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9169 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9170 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9172 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9173 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9174 { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9175 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9176 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9177 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9179 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9180 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9181 { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9182 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9183 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9184 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9186 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9187 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9188 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9189 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9190 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9191 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9193 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9194 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9195 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9196 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9197 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9198 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9200 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9201 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9202 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9203 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9205 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9206 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9207 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9208 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9209 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9210 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9211 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9212 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9213 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9215 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9216 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9217 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9218 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9219 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9220 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9221 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9222 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9223 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9225 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9226 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9227 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9228 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9229 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9231 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9232 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9233 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9234 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9235 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9236 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9237 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9238 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9239 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9240 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9241 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9242 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9243 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9244 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9245 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9246 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9247 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9248 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9249 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9251 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9252 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9253 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9255 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9256 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9257 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9258 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9260 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9261 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9262 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9263 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9264 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9265 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9266 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9267 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9268 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9269 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9270 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9271 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9272 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9273 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9274 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9275 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9276 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9277 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9278 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9279 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9280 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9281 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9282 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9283 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9284 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9285 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9286 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9287 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9288 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9289 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9291 /* Place-holder. Leave as last unary SPE builtin. */
9292 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9294 { 0, CODE_FOR_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9295 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9296 { 0, CODE_FOR_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9297 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9298 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9302 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9305 tree arg0 = CALL_EXPR_ARG (exp, 0);
9306 rtx op0 = expand_normal (arg0);
9307 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9308 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9310 if (icode == CODE_FOR_nothing)
9311 /* Builtin not supported on this processor. */
9314 /* If we got invalid arguments bail out before generating bad rtl. */
9315 if (arg0 == error_mark_node)
9318 if (icode == CODE_FOR_altivec_vspltisb
9319 || icode == CODE_FOR_altivec_vspltish
9320 || icode == CODE_FOR_altivec_vspltisw
9321 || icode == CODE_FOR_spe_evsplatfi
9322 || icode == CODE_FOR_spe_evsplati)
9324 /* Only allow 5-bit *signed* literals. */
9325 if (GET_CODE (op0) != CONST_INT
9326 || INTVAL (op0) > 15
9327 || INTVAL (op0) < -16)
9329 error ("argument 1 must be a 5-bit signed literal");
9335 || GET_MODE (target) != tmode
9336 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9337 target = gen_reg_rtx (tmode);
9339 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9340 op0 = copy_to_mode_reg (mode0, op0);
9342 pat = GEN_FCN (icode) (target, op0);
9351 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9353 rtx pat, scratch1, scratch2;
9354 tree arg0 = CALL_EXPR_ARG (exp, 0);
9355 rtx op0 = expand_normal (arg0);
9356 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9357 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9359 /* If we have invalid arguments, bail out before generating bad rtl. */
9360 if (arg0 == error_mark_node)
9364 || GET_MODE (target) != tmode
9365 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9366 target = gen_reg_rtx (tmode);
9368 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9369 op0 = copy_to_mode_reg (mode0, op0);
9371 scratch1 = gen_reg_rtx (mode0);
9372 scratch2 = gen_reg_rtx (mode0);
9374 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9383 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
9386 tree arg0 = CALL_EXPR_ARG (exp, 0);
9387 tree arg1 = CALL_EXPR_ARG (exp, 1);
9388 rtx op0 = expand_normal (arg0);
9389 rtx op1 = expand_normal (arg1);
9390 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9391 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9392 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9394 if (icode == CODE_FOR_nothing)
9395 /* Builtin not supported on this processor. */
9398 /* If we got invalid arguments bail out before generating bad rtl. */
9399 if (arg0 == error_mark_node || arg1 == error_mark_node)
9402 if (icode == CODE_FOR_altivec_vcfux
9403 || icode == CODE_FOR_altivec_vcfsx
9404 || icode == CODE_FOR_altivec_vctsxs
9405 || icode == CODE_FOR_altivec_vctuxs
9406 || icode == CODE_FOR_altivec_vspltb
9407 || icode == CODE_FOR_altivec_vsplth
9408 || icode == CODE_FOR_altivec_vspltw
9409 || icode == CODE_FOR_spe_evaddiw
9410 || icode == CODE_FOR_spe_evldd
9411 || icode == CODE_FOR_spe_evldh
9412 || icode == CODE_FOR_spe_evldw
9413 || icode == CODE_FOR_spe_evlhhesplat
9414 || icode == CODE_FOR_spe_evlhhossplat
9415 || icode == CODE_FOR_spe_evlhhousplat
9416 || icode == CODE_FOR_spe_evlwhe
9417 || icode == CODE_FOR_spe_evlwhos
9418 || icode == CODE_FOR_spe_evlwhou
9419 || icode == CODE_FOR_spe_evlwhsplat
9420 || icode == CODE_FOR_spe_evlwwsplat
9421 || icode == CODE_FOR_spe_evrlwi
9422 || icode == CODE_FOR_spe_evslwi
9423 || icode == CODE_FOR_spe_evsrwis
9424 || icode == CODE_FOR_spe_evsubifw
9425 || icode == CODE_FOR_spe_evsrwiu)
9427 /* Only allow 5-bit unsigned literals. */
9429 if (TREE_CODE (arg1) != INTEGER_CST
9430 || TREE_INT_CST_LOW (arg1) & ~0x1f)
9432 error ("argument 2 must be a 5-bit unsigned literal");
9438 || GET_MODE (target) != tmode
9439 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9440 target = gen_reg_rtx (tmode);
9442 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9443 op0 = copy_to_mode_reg (mode0, op0);
9444 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9445 op1 = copy_to_mode_reg (mode1, op1);
9447 pat = GEN_FCN (icode) (target, op0, op1);
9456 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
9459 tree cr6_form = CALL_EXPR_ARG (exp, 0);
9460 tree arg0 = CALL_EXPR_ARG (exp, 1);
9461 tree arg1 = CALL_EXPR_ARG (exp, 2);
9462 rtx op0 = expand_normal (arg0);
9463 rtx op1 = expand_normal (arg1);
9464 enum machine_mode tmode = SImode;
9465 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9466 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9469 if (TREE_CODE (cr6_form) != INTEGER_CST)
9471 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9475 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
9477 gcc_assert (mode0 == mode1);
9479 /* If we have invalid arguments, bail out before generating bad rtl. */
9480 if (arg0 == error_mark_node || arg1 == error_mark_node)
9484 || GET_MODE (target) != tmode
9485 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9486 target = gen_reg_rtx (tmode);
9488 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9489 op0 = copy_to_mode_reg (mode0, op0);
9490 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9491 op1 = copy_to_mode_reg (mode1, op1);
9493 scratch = gen_reg_rtx (mode0);
9495 pat = GEN_FCN (icode) (scratch, op0, op1);
9500 /* The vec_any* and vec_all* predicates use the same opcodes for two
9501 different operations, but the bits in CR6 will be different
9502 depending on what information we want. So we have to play tricks
9503 with CR6 to get the right bits out.
9505 If you think this is disgusting, look at the specs for the
9506 AltiVec predicates. */
9508 switch (cr6_form_int)
9511 emit_insn (gen_cr6_test_for_zero (target));
9514 emit_insn (gen_cr6_test_for_zero_reverse (target));
9517 emit_insn (gen_cr6_test_for_lt (target));
9520 emit_insn (gen_cr6_test_for_lt_reverse (target));
9523 error ("argument 1 of __builtin_altivec_predicate is out of range");
9531 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
9534 tree arg0 = CALL_EXPR_ARG (exp, 0);
9535 tree arg1 = CALL_EXPR_ARG (exp, 1);
9536 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9537 enum machine_mode mode0 = Pmode;
9538 enum machine_mode mode1 = Pmode;
9539 rtx op0 = expand_normal (arg0);
9540 rtx op1 = expand_normal (arg1);
9542 if (icode == CODE_FOR_nothing)
9543 /* Builtin not supported on this processor. */
9546 /* If we got invalid arguments bail out before generating bad rtl. */
9547 if (arg0 == error_mark_node || arg1 == error_mark_node)
9551 || GET_MODE (target) != tmode
9552 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9553 target = gen_reg_rtx (tmode);
9555 op1 = copy_to_mode_reg (mode1, op1);
9557 if (op0 == const0_rtx)
9559 addr = gen_rtx_MEM (tmode, op1);
9563 op0 = copy_to_mode_reg (mode0, op0);
9564 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
9567 pat = GEN_FCN (icode) (target, addr);
9577 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
9580 tree arg0 = CALL_EXPR_ARG (exp, 0);
9581 tree arg1 = CALL_EXPR_ARG (exp, 1);
9582 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9583 enum machine_mode mode0 = Pmode;
9584 enum machine_mode mode1 = Pmode;
9585 rtx op0 = expand_normal (arg0);
9586 rtx op1 = expand_normal (arg1);
9588 if (icode == CODE_FOR_nothing)
9589 /* Builtin not supported on this processor. */
9592 /* If we got invalid arguments bail out before generating bad rtl. */
9593 if (arg0 == error_mark_node || arg1 == error_mark_node)
9597 || GET_MODE (target) != tmode
9598 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9599 target = gen_reg_rtx (tmode);
9601 op1 = copy_to_mode_reg (mode1, op1);
9603 if (op0 == const0_rtx)
9605 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
9609 op0 = copy_to_mode_reg (mode0, op0);
9610 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
9613 pat = GEN_FCN (icode) (target, addr);
9623 spe_expand_stv_builtin (enum insn_code icode, tree exp)
9625 tree arg0 = CALL_EXPR_ARG (exp, 0);
9626 tree arg1 = CALL_EXPR_ARG (exp, 1);
9627 tree arg2 = CALL_EXPR_ARG (exp, 2);
9628 rtx op0 = expand_normal (arg0);
9629 rtx op1 = expand_normal (arg1);
9630 rtx op2 = expand_normal (arg2);
9632 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
9633 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
9634 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
9636 /* Invalid arguments. Bail before doing anything stoopid! */
9637 if (arg0 == error_mark_node
9638 || arg1 == error_mark_node
9639 || arg2 == error_mark_node)
9642 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
9643 op0 = copy_to_mode_reg (mode2, op0);
9644 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
9645 op1 = copy_to_mode_reg (mode0, op1);
9646 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
9647 op2 = copy_to_mode_reg (mode1, op2);
9649 pat = GEN_FCN (icode) (op1, op2, op0);
9656 paired_expand_stv_builtin (enum insn_code icode, tree exp)
9658 tree arg0 = CALL_EXPR_ARG (exp, 0);
9659 tree arg1 = CALL_EXPR_ARG (exp, 1);
9660 tree arg2 = CALL_EXPR_ARG (exp, 2);
9661 rtx op0 = expand_normal (arg0);
9662 rtx op1 = expand_normal (arg1);
9663 rtx op2 = expand_normal (arg2);
9665 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9666 enum machine_mode mode1 = Pmode;
9667 enum machine_mode mode2 = Pmode;
9669 /* Invalid arguments. Bail before doing anything stoopid! */
9670 if (arg0 == error_mark_node
9671 || arg1 == error_mark_node
9672 || arg2 == error_mark_node)
9675 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9676 op0 = copy_to_mode_reg (tmode, op0);
9678 op2 = copy_to_mode_reg (mode2, op2);
9680 if (op1 == const0_rtx)
9682 addr = gen_rtx_MEM (tmode, op2);
9686 op1 = copy_to_mode_reg (mode1, op1);
9687 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9690 pat = GEN_FCN (icode) (addr, op0);
9697 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
9699 tree arg0 = CALL_EXPR_ARG (exp, 0);
9700 tree arg1 = CALL_EXPR_ARG (exp, 1);
9701 tree arg2 = CALL_EXPR_ARG (exp, 2);
9702 rtx op0 = expand_normal (arg0);
9703 rtx op1 = expand_normal (arg1);
9704 rtx op2 = expand_normal (arg2);
9706 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9707 enum machine_mode mode1 = Pmode;
9708 enum machine_mode mode2 = Pmode;
9710 /* Invalid arguments. Bail before doing anything stoopid! */
9711 if (arg0 == error_mark_node
9712 || arg1 == error_mark_node
9713 || arg2 == error_mark_node)
9716 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
9717 op0 = copy_to_mode_reg (tmode, op0);
9719 op2 = copy_to_mode_reg (mode2, op2);
9721 if (op1 == const0_rtx)
9723 addr = gen_rtx_MEM (tmode, op2);
9727 op1 = copy_to_mode_reg (mode1, op1);
9728 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
9731 pat = GEN_FCN (icode) (addr, op0);
9738 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
9741 tree arg0 = CALL_EXPR_ARG (exp, 0);
9742 tree arg1 = CALL_EXPR_ARG (exp, 1);
9743 tree arg2 = CALL_EXPR_ARG (exp, 2);
9744 rtx op0 = expand_normal (arg0);
9745 rtx op1 = expand_normal (arg1);
9746 rtx op2 = expand_normal (arg2);
9747 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9748 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9749 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9750 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
9752 if (icode == CODE_FOR_nothing)
9753 /* Builtin not supported on this processor. */
9756 /* If we got invalid arguments bail out before generating bad rtl. */
9757 if (arg0 == error_mark_node
9758 || arg1 == error_mark_node
9759 || arg2 == error_mark_node)
9764 case CODE_FOR_altivec_vsldoi_v4sf:
9765 case CODE_FOR_altivec_vsldoi_v4si:
9766 case CODE_FOR_altivec_vsldoi_v8hi:
9767 case CODE_FOR_altivec_vsldoi_v16qi:
9768 /* Only allow 4-bit unsigned literals. */
9770 if (TREE_CODE (arg2) != INTEGER_CST
9771 || TREE_INT_CST_LOW (arg2) & ~0xf)
9773 error ("argument 3 must be a 4-bit unsigned literal");
9778 case CODE_FOR_vsx_xxpermdi_v2df:
9779 case CODE_FOR_vsx_xxpermdi_v2di:
9780 case CODE_FOR_vsx_xxsldwi_v16qi:
9781 case CODE_FOR_vsx_xxsldwi_v8hi:
9782 case CODE_FOR_vsx_xxsldwi_v4si:
9783 case CODE_FOR_vsx_xxsldwi_v4sf:
9784 case CODE_FOR_vsx_xxsldwi_v2di:
9785 case CODE_FOR_vsx_xxsldwi_v2df:
9786 /* Only allow 2-bit unsigned literals. */
9788 if (TREE_CODE (arg2) != INTEGER_CST
9789 || TREE_INT_CST_LOW (arg2) & ~0x3)
9791 error ("argument 3 must be a 2-bit unsigned literal");
9796 case CODE_FOR_vsx_set_v2df:
9797 case CODE_FOR_vsx_set_v2di:
9798 /* Only allow 1-bit unsigned literals. */
9800 if (TREE_CODE (arg2) != INTEGER_CST
9801 || TREE_INT_CST_LOW (arg2) & ~0x1)
9803 error ("argument 3 must be a 1-bit unsigned literal");
9813 || GET_MODE (target) != tmode
9814 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9815 target = gen_reg_rtx (tmode);
9817 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9818 op0 = copy_to_mode_reg (mode0, op0);
9819 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9820 op1 = copy_to_mode_reg (mode1, op1);
9821 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
9822 op2 = copy_to_mode_reg (mode2, op2);
9824 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
9825 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
9827 pat = GEN_FCN (icode) (target, op0, op1, op2);
9835 /* Expand the lvx builtins. */
9837 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
9839 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9840 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9842 enum machine_mode tmode, mode0;
9844 enum insn_code icode;
9848 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
9849 icode = CODE_FOR_vector_load_v16qi;
9851 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
9852 icode = CODE_FOR_vector_load_v8hi;
9854 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
9855 icode = CODE_FOR_vector_load_v4si;
9857 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
9858 icode = CODE_FOR_vector_load_v4sf;
9867 arg0 = CALL_EXPR_ARG (exp, 0);
9868 op0 = expand_normal (arg0);
9869 tmode = insn_data[icode].operand[0].mode;
9870 mode0 = insn_data[icode].operand[1].mode;
9873 || GET_MODE (target) != tmode
9874 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9875 target = gen_reg_rtx (tmode);
9877 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9878 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
9880 pat = GEN_FCN (icode) (target, op0);
9887 /* Expand the stvx builtins. */
9889 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
9892 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9893 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9895 enum machine_mode mode0, mode1;
9897 enum insn_code icode;
9901 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
9902 icode = CODE_FOR_vector_store_v16qi;
9904 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
9905 icode = CODE_FOR_vector_store_v8hi;
9907 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
9908 icode = CODE_FOR_vector_store_v4si;
9910 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
9911 icode = CODE_FOR_vector_store_v4sf;
9918 arg0 = CALL_EXPR_ARG (exp, 0);
9919 arg1 = CALL_EXPR_ARG (exp, 1);
9920 op0 = expand_normal (arg0);
9921 op1 = expand_normal (arg1);
9922 mode0 = insn_data[icode].operand[0].mode;
9923 mode1 = insn_data[icode].operand[1].mode;
9925 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
9926 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
9927 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
9928 op1 = copy_to_mode_reg (mode1, op1);
9930 pat = GEN_FCN (icode) (op0, op1);
9938 /* Expand the dst builtins. */
9940 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
9943 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9944 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9945 tree arg0, arg1, arg2;
9946 enum machine_mode mode0, mode1, mode2;
9947 rtx pat, op0, op1, op2;
9948 const struct builtin_description *d;
9953 /* Handle DST variants. */
9955 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
9956 if (d->code == fcode)
9958 arg0 = CALL_EXPR_ARG (exp, 0);
9959 arg1 = CALL_EXPR_ARG (exp, 1);
9960 arg2 = CALL_EXPR_ARG (exp, 2);
9961 op0 = expand_normal (arg0);
9962 op1 = expand_normal (arg1);
9963 op2 = expand_normal (arg2);
9964 mode0 = insn_data[d->icode].operand[0].mode;
9965 mode1 = insn_data[d->icode].operand[1].mode;
9966 mode2 = insn_data[d->icode].operand[2].mode;
9968 /* Invalid arguments, bail out before generating bad rtl. */
9969 if (arg0 == error_mark_node
9970 || arg1 == error_mark_node
9971 || arg2 == error_mark_node)
9976 if (TREE_CODE (arg2) != INTEGER_CST
9977 || TREE_INT_CST_LOW (arg2) & ~0x3)
9979 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
9983 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
9984 op0 = copy_to_mode_reg (Pmode, op0);
9985 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
9986 op1 = copy_to_mode_reg (mode1, op1);
9988 pat = GEN_FCN (d->icode) (op0, op1, op2);
9998 /* Expand vec_init builtin. */
10000 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10002 enum machine_mode tmode = TYPE_MODE (type);
10003 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10004 int i, n_elt = GET_MODE_NUNITS (tmode);
10005 rtvec v = rtvec_alloc (n_elt);
10007 gcc_assert (VECTOR_MODE_P (tmode));
10008 gcc_assert (n_elt == call_expr_nargs (exp));
10010 for (i = 0; i < n_elt; ++i)
10012 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10013 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10016 if (!target || !register_operand (target, tmode))
10017 target = gen_reg_rtx (tmode);
10019 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10023 /* Return the integer constant in ARG. Constrain it to be in the range
10024 of the subparts of VEC_TYPE; issue an error if not. */
10027 get_element_number (tree vec_type, tree arg)
10029 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10031 if (!host_integerp (arg, 1)
10032 || (elt = tree_low_cst (arg, 1), elt > max))
10034 error ("selector must be an integer constant in the range 0..%wi", max);
10041 /* Expand vec_set builtin. */
10043 altivec_expand_vec_set_builtin (tree exp)
10045 enum machine_mode tmode, mode1;
10046 tree arg0, arg1, arg2;
10050 arg0 = CALL_EXPR_ARG (exp, 0);
10051 arg1 = CALL_EXPR_ARG (exp, 1);
10052 arg2 = CALL_EXPR_ARG (exp, 2);
10054 tmode = TYPE_MODE (TREE_TYPE (arg0));
10055 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10056 gcc_assert (VECTOR_MODE_P (tmode));
10058 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10059 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10060 elt = get_element_number (TREE_TYPE (arg0), arg2);
10062 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10063 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10065 op0 = force_reg (tmode, op0);
10066 op1 = force_reg (mode1, op1);
10068 rs6000_expand_vector_set (op0, op1, elt);
10073 /* Expand vec_ext builtin. */
10075 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10077 enum machine_mode tmode, mode0;
10082 arg0 = CALL_EXPR_ARG (exp, 0);
10083 arg1 = CALL_EXPR_ARG (exp, 1);
10085 op0 = expand_normal (arg0);
10086 elt = get_element_number (TREE_TYPE (arg0), arg1);
10088 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10089 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10090 gcc_assert (VECTOR_MODE_P (mode0));
10092 op0 = force_reg (mode0, op0);
10094 if (optimize || !target || !register_operand (target, tmode))
10095 target = gen_reg_rtx (tmode);
10097 rs6000_expand_vector_extract (target, op0, elt);
10102 /* Expand the builtin in EXP and store the result in TARGET. Store
10103 true in *EXPANDEDP if we found a builtin to expand. */
10105 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10107 const struct builtin_description *d;
10108 const struct builtin_description_predicates *dp;
10110 enum insn_code icode;
10111 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10114 enum machine_mode tmode, mode0;
10115 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10117 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10118 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10119 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10120 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10123 error ("unresolved overload for Altivec builtin %qF", fndecl);
10127 target = altivec_expand_ld_builtin (exp, target, expandedp);
10131 target = altivec_expand_st_builtin (exp, target, expandedp);
10135 target = altivec_expand_dst_builtin (exp, target, expandedp);
10143 case ALTIVEC_BUILTIN_STVX:
10144 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10145 case ALTIVEC_BUILTIN_STVEBX:
10146 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10147 case ALTIVEC_BUILTIN_STVEHX:
10148 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10149 case ALTIVEC_BUILTIN_STVEWX:
10150 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10151 case ALTIVEC_BUILTIN_STVXL:
10152 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10154 case ALTIVEC_BUILTIN_STVLX:
10155 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10156 case ALTIVEC_BUILTIN_STVLXL:
10157 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10158 case ALTIVEC_BUILTIN_STVRX:
10159 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10160 case ALTIVEC_BUILTIN_STVRXL:
10161 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10163 case ALTIVEC_BUILTIN_MFVSCR:
10164 icode = CODE_FOR_altivec_mfvscr;
10165 tmode = insn_data[icode].operand[0].mode;
10168 || GET_MODE (target) != tmode
10169 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10170 target = gen_reg_rtx (tmode);
10172 pat = GEN_FCN (icode) (target);
10178 case ALTIVEC_BUILTIN_MTVSCR:
10179 icode = CODE_FOR_altivec_mtvscr;
10180 arg0 = CALL_EXPR_ARG (exp, 0);
10181 op0 = expand_normal (arg0);
10182 mode0 = insn_data[icode].operand[0].mode;
10184 /* If we got invalid arguments bail out before generating bad rtl. */
10185 if (arg0 == error_mark_node)
10188 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10189 op0 = copy_to_mode_reg (mode0, op0);
10191 pat = GEN_FCN (icode) (op0);
10196 case ALTIVEC_BUILTIN_DSSALL:
10197 emit_insn (gen_altivec_dssall ());
10200 case ALTIVEC_BUILTIN_DSS:
10201 icode = CODE_FOR_altivec_dss;
10202 arg0 = CALL_EXPR_ARG (exp, 0);
10204 op0 = expand_normal (arg0);
10205 mode0 = insn_data[icode].operand[0].mode;
10207 /* If we got invalid arguments bail out before generating bad rtl. */
10208 if (arg0 == error_mark_node)
10211 if (TREE_CODE (arg0) != INTEGER_CST
10212 || TREE_INT_CST_LOW (arg0) & ~0x3)
10214 error ("argument to dss must be a 2-bit unsigned literal");
10218 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10219 op0 = copy_to_mode_reg (mode0, op0);
10221 emit_insn (gen_altivec_dss (op0));
10224 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10225 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10226 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10227 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10228 case VSX_BUILTIN_VEC_INIT_V2DF:
10229 case VSX_BUILTIN_VEC_INIT_V2DI:
10230 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10232 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10233 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10234 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10235 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10236 case VSX_BUILTIN_VEC_SET_V2DF:
10237 case VSX_BUILTIN_VEC_SET_V2DI:
10238 return altivec_expand_vec_set_builtin (exp);
10240 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10241 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10242 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10243 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10244 case VSX_BUILTIN_VEC_EXT_V2DF:
10245 case VSX_BUILTIN_VEC_EXT_V2DI:
10246 return altivec_expand_vec_ext_builtin (exp, target);
10250 /* Fall through. */
10253 /* Expand abs* operations. */
10255 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10256 if (d->code == fcode)
10257 return altivec_expand_abs_builtin (d->icode, exp, target);
10259 /* Expand the AltiVec predicates. */
10260 dp = bdesc_altivec_preds;
10261 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10262 if (dp->code == fcode)
10263 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10265 /* LV* are funky. We initialized them differently. */
10268 case ALTIVEC_BUILTIN_LVSL:
10269 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10270 exp, target, false);
10271 case ALTIVEC_BUILTIN_LVSR:
10272 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10273 exp, target, false);
10274 case ALTIVEC_BUILTIN_LVEBX:
10275 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10276 exp, target, false);
10277 case ALTIVEC_BUILTIN_LVEHX:
10278 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10279 exp, target, false);
10280 case ALTIVEC_BUILTIN_LVEWX:
10281 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10282 exp, target, false);
10283 case ALTIVEC_BUILTIN_LVXL:
10284 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10285 exp, target, false);
10286 case ALTIVEC_BUILTIN_LVX:
10287 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10288 exp, target, false);
10289 case ALTIVEC_BUILTIN_LVLX:
10290 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10291 exp, target, true);
10292 case ALTIVEC_BUILTIN_LVLXL:
10293 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10294 exp, target, true);
10295 case ALTIVEC_BUILTIN_LVRX:
10296 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10297 exp, target, true);
10298 case ALTIVEC_BUILTIN_LVRXL:
10299 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10300 exp, target, true);
10303 /* Fall through. */
10306 *expandedp = false;
10310 /* Expand the builtin in EXP and store the result in TARGET. Store
10311 true in *EXPANDEDP if we found a builtin to expand. */
10313 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10315 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10316 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10317 const struct builtin_description *d;
10324 case PAIRED_BUILTIN_STX:
10325 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10326 case PAIRED_BUILTIN_LX:
10327 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10330 /* Fall through. */
10333 /* Expand the paired predicates. */
10334 d = bdesc_paired_preds;
10335 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10336 if (d->code == fcode)
10337 return paired_expand_predicate_builtin (d->icode, exp, target);
10339 *expandedp = false;
10343 /* Binops that need to be initialized manually, but can be expanded
10344 automagically by rs6000_expand_binop_builtin. */
10345 static struct builtin_description bdesc_2arg_spe[] =
10347 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10348 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10349 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10350 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10351 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10352 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10353 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10354 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10355 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10356 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10357 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10358 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10359 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10360 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10361 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10362 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10363 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10364 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10365 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10366 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10367 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10368 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10371 /* Expand the builtin in EXP and store the result in TARGET. Store
10372 true in *EXPANDEDP if we found a builtin to expand.
10374 This expands the SPE builtins that are not simple unary and binary
10377 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10379 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10381 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10382 enum insn_code icode;
10383 enum machine_mode tmode, mode0;
10385 struct builtin_description *d;
10390 /* Syntax check for a 5-bit unsigned immediate. */
10393 case SPE_BUILTIN_EVSTDD:
10394 case SPE_BUILTIN_EVSTDH:
10395 case SPE_BUILTIN_EVSTDW:
10396 case SPE_BUILTIN_EVSTWHE:
10397 case SPE_BUILTIN_EVSTWHO:
10398 case SPE_BUILTIN_EVSTWWE:
10399 case SPE_BUILTIN_EVSTWWO:
10400 arg1 = CALL_EXPR_ARG (exp, 2);
10401 if (TREE_CODE (arg1) != INTEGER_CST
10402 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10404 error ("argument 2 must be a 5-bit unsigned literal");
10412 /* The evsplat*i instructions are not quite generic. */
10415 case SPE_BUILTIN_EVSPLATFI:
10416 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
10418 case SPE_BUILTIN_EVSPLATI:
10419 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
10425 d = (struct builtin_description *) bdesc_2arg_spe;
10426 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
10427 if (d->code == fcode)
10428 return rs6000_expand_binop_builtin (d->icode, exp, target);
10430 d = (struct builtin_description *) bdesc_spe_predicates;
10431 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
10432 if (d->code == fcode)
10433 return spe_expand_predicate_builtin (d->icode, exp, target);
10435 d = (struct builtin_description *) bdesc_spe_evsel;
10436 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
10437 if (d->code == fcode)
10438 return spe_expand_evsel_builtin (d->icode, exp, target);
10442 case SPE_BUILTIN_EVSTDDX:
10443 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
10444 case SPE_BUILTIN_EVSTDHX:
10445 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
10446 case SPE_BUILTIN_EVSTDWX:
10447 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
10448 case SPE_BUILTIN_EVSTWHEX:
10449 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
10450 case SPE_BUILTIN_EVSTWHOX:
10451 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
10452 case SPE_BUILTIN_EVSTWWEX:
10453 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
10454 case SPE_BUILTIN_EVSTWWOX:
10455 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
10456 case SPE_BUILTIN_EVSTDD:
10457 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
10458 case SPE_BUILTIN_EVSTDH:
10459 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
10460 case SPE_BUILTIN_EVSTDW:
10461 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
10462 case SPE_BUILTIN_EVSTWHE:
10463 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
10464 case SPE_BUILTIN_EVSTWHO:
10465 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
10466 case SPE_BUILTIN_EVSTWWE:
10467 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
10468 case SPE_BUILTIN_EVSTWWO:
10469 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
10470 case SPE_BUILTIN_MFSPEFSCR:
10471 icode = CODE_FOR_spe_mfspefscr;
10472 tmode = insn_data[icode].operand[0].mode;
10475 || GET_MODE (target) != tmode
10476 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10477 target = gen_reg_rtx (tmode);
10479 pat = GEN_FCN (icode) (target);
10484 case SPE_BUILTIN_MTSPEFSCR:
10485 icode = CODE_FOR_spe_mtspefscr;
10486 arg0 = CALL_EXPR_ARG (exp, 0);
10487 op0 = expand_normal (arg0);
10488 mode0 = insn_data[icode].operand[0].mode;
10490 if (arg0 == error_mark_node)
10493 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10494 op0 = copy_to_mode_reg (mode0, op0);
10496 pat = GEN_FCN (icode) (op0);
10504 *expandedp = false;
10509 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10511 rtx pat, scratch, tmp;
10512 tree form = CALL_EXPR_ARG (exp, 0);
10513 tree arg0 = CALL_EXPR_ARG (exp, 1);
10514 tree arg1 = CALL_EXPR_ARG (exp, 2);
10515 rtx op0 = expand_normal (arg0);
10516 rtx op1 = expand_normal (arg1);
10517 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10518 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10520 enum rtx_code code;
10522 if (TREE_CODE (form) != INTEGER_CST)
10524 error ("argument 1 of __builtin_paired_predicate must be a constant");
10528 form_int = TREE_INT_CST_LOW (form);
10530 gcc_assert (mode0 == mode1);
10532 if (arg0 == error_mark_node || arg1 == error_mark_node)
10536 || GET_MODE (target) != SImode
10537 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
10538 target = gen_reg_rtx (SImode);
10539 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
10540 op0 = copy_to_mode_reg (mode0, op0);
10541 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
10542 op1 = copy_to_mode_reg (mode1, op1);
10544 scratch = gen_reg_rtx (CCFPmode);
10546 pat = GEN_FCN (icode) (scratch, op0, op1);
10568 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10571 error ("argument 1 of __builtin_paired_predicate is out of range");
10575 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10576 emit_move_insn (target, tmp);
10581 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10583 rtx pat, scratch, tmp;
10584 tree form = CALL_EXPR_ARG (exp, 0);
10585 tree arg0 = CALL_EXPR_ARG (exp, 1);
10586 tree arg1 = CALL_EXPR_ARG (exp, 2);
10587 rtx op0 = expand_normal (arg0);
10588 rtx op1 = expand_normal (arg1);
10589 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10590 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10592 enum rtx_code code;
10594 if (TREE_CODE (form) != INTEGER_CST)
10596 error ("argument 1 of __builtin_spe_predicate must be a constant");
10600 form_int = TREE_INT_CST_LOW (form);
10602 gcc_assert (mode0 == mode1);
10604 if (arg0 == error_mark_node || arg1 == error_mark_node)
10608 || GET_MODE (target) != SImode
10609 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
10610 target = gen_reg_rtx (SImode);
10612 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10613 op0 = copy_to_mode_reg (mode0, op0);
10614 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10615 op1 = copy_to_mode_reg (mode1, op1);
10617 scratch = gen_reg_rtx (CCmode);
10619 pat = GEN_FCN (icode) (scratch, op0, op1);
10624 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
10625 _lower_. We use one compare, but look in different bits of the
10626 CR for each variant.
10628 There are 2 elements in each SPE simd type (upper/lower). The CR
10629 bits are set as follows:
10631 BIT0 | BIT 1 | BIT 2 | BIT 3
10632 U | L | (U | L) | (U & L)
10634 So, for an "all" relationship, BIT 3 would be set.
10635 For an "any" relationship, BIT 2 would be set. Etc.
10637 Following traditional nomenclature, these bits map to:
10639 BIT0 | BIT 1 | BIT 2 | BIT 3
10642 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
10647 /* All variant. OV bit. */
10649 /* We need to get to the OV bit, which is the ORDERED bit. We
10650 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
10651 that's ugly and will make validate_condition_mode die.
10652 So let's just use another pattern. */
10653 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
10655 /* Any variant. EQ bit. */
10659 /* Upper variant. LT bit. */
10663 /* Lower variant. GT bit. */
10668 error ("argument 1 of __builtin_spe_predicate is out of range");
10672 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
10673 emit_move_insn (target, tmp);
10678 /* The evsel builtins look like this:
10680 e = __builtin_spe_evsel_OP (a, b, c, d);
10682 and work like this:
10684 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
10685 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
10689 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
10692 tree arg0 = CALL_EXPR_ARG (exp, 0);
10693 tree arg1 = CALL_EXPR_ARG (exp, 1);
10694 tree arg2 = CALL_EXPR_ARG (exp, 2);
10695 tree arg3 = CALL_EXPR_ARG (exp, 3);
10696 rtx op0 = expand_normal (arg0);
10697 rtx op1 = expand_normal (arg1);
10698 rtx op2 = expand_normal (arg2);
10699 rtx op3 = expand_normal (arg3);
10700 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10701 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10703 gcc_assert (mode0 == mode1);
10705 if (arg0 == error_mark_node || arg1 == error_mark_node
10706 || arg2 == error_mark_node || arg3 == error_mark_node)
10710 || GET_MODE (target) != mode0
10711 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
10712 target = gen_reg_rtx (mode0);
10714 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10715 op0 = copy_to_mode_reg (mode0, op0);
10716 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10717 op1 = copy_to_mode_reg (mode0, op1);
10718 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10719 op2 = copy_to_mode_reg (mode0, op2);
10720 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
10721 op3 = copy_to_mode_reg (mode0, op3);
10723 /* Generate the compare. */
10724 scratch = gen_reg_rtx (CCmode);
10725 pat = GEN_FCN (icode) (scratch, op0, op1);
10730 if (mode0 == V2SImode)
10731 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
10733 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
10738 /* Expand an expression EXP that calls a built-in function,
10739 with result going to TARGET if that's convenient
10740 (and in mode MODE if that's convenient).
10741 SUBTARGET may be used as the target for computing one of EXP's operands.
10742 IGNORE is nonzero if the value is to be ignored. */
10745 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10746 enum machine_mode mode ATTRIBUTE_UNUSED,
10747 int ignore ATTRIBUTE_UNUSED)
10749 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10750 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10751 const struct builtin_description *d;
10756 if (fcode == RS6000_BUILTIN_RECIP)
10757 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
10759 if (fcode == RS6000_BUILTIN_RECIPF)
10760 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
10762 if (fcode == RS6000_BUILTIN_RSQRTF)
10763 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
10765 if (fcode == RS6000_BUILTIN_BSWAP_HI)
10766 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
10768 if (fcode == POWER7_BUILTIN_BPERMD)
10769 return rs6000_expand_binop_builtin (((TARGET_64BIT)
10770 ? CODE_FOR_bpermd_di
10771 : CODE_FOR_bpermd_si), exp, target);
10773 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
10774 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10776 int icode = (int) CODE_FOR_altivec_lvsr;
10777 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10778 enum machine_mode mode = insn_data[icode].operand[1].mode;
10782 gcc_assert (TARGET_ALTIVEC);
10784 arg = CALL_EXPR_ARG (exp, 0);
10785 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
10786 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
10787 addr = memory_address (mode, op);
10788 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
10792 /* For the load case need to negate the address. */
10793 op = gen_reg_rtx (GET_MODE (addr));
10794 emit_insn (gen_rtx_SET (VOIDmode, op,
10795 gen_rtx_NEG (GET_MODE (addr), addr)));
10797 op = gen_rtx_MEM (mode, op);
10800 || GET_MODE (target) != tmode
10801 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10802 target = gen_reg_rtx (tmode);
10804 /*pat = gen_altivec_lvsr (target, op);*/
10805 pat = GEN_FCN (icode) (target, op);
10813 /* FIXME: There's got to be a nicer way to handle this case than
10814 constructing a new CALL_EXPR. */
10815 if (fcode == ALTIVEC_BUILTIN_VCFUX
10816 || fcode == ALTIVEC_BUILTIN_VCFSX
10817 || fcode == ALTIVEC_BUILTIN_VCTUXS
10818 || fcode == ALTIVEC_BUILTIN_VCTSXS)
10820 if (call_expr_nargs (exp) == 1)
10821 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
10822 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
10825 if (TARGET_ALTIVEC)
10827 ret = altivec_expand_builtin (exp, target, &success);
10834 ret = spe_expand_builtin (exp, target, &success);
10839 if (TARGET_PAIRED_FLOAT)
10841 ret = paired_expand_builtin (exp, target, &success);
10847 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
10849 /* Handle simple unary operations. */
10850 d = (struct builtin_description *) bdesc_1arg;
10851 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
10852 if (d->code == fcode)
10853 return rs6000_expand_unop_builtin (d->icode, exp, target);
10855 /* Handle simple binary operations. */
10856 d = (struct builtin_description *) bdesc_2arg;
10857 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
10858 if (d->code == fcode)
10859 return rs6000_expand_binop_builtin (d->icode, exp, target);
10861 /* Handle simple ternary operations. */
10863 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
10864 if (d->code == fcode)
10865 return rs6000_expand_ternop_builtin (d->icode, exp, target);
10867 gcc_unreachable ();
10871 rs6000_init_builtins (void)
10875 V2SI_type_node = build_vector_type (intSI_type_node, 2);
10876 V2SF_type_node = build_vector_type (float_type_node, 2);
10877 V2DI_type_node = build_vector_type (intDI_type_node, 2);
10878 V2DF_type_node = build_vector_type (double_type_node, 2);
10879 V4HI_type_node = build_vector_type (intHI_type_node, 4);
10880 V4SI_type_node = build_vector_type (intSI_type_node, 4);
10881 V4SF_type_node = build_vector_type (float_type_node, 4);
10882 V8HI_type_node = build_vector_type (intHI_type_node, 8);
10883 V16QI_type_node = build_vector_type (intQI_type_node, 16);
10885 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
10886 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
10887 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
10888 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
10890 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
10891 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
10892 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
10893 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
10895 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
10896 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
10897 'vector unsigned short'. */
10899 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
10900 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
10901 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
10902 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
10903 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
10905 long_integer_type_internal_node = long_integer_type_node;
10906 long_unsigned_type_internal_node = long_unsigned_type_node;
10907 intQI_type_internal_node = intQI_type_node;
10908 uintQI_type_internal_node = unsigned_intQI_type_node;
10909 intHI_type_internal_node = intHI_type_node;
10910 uintHI_type_internal_node = unsigned_intHI_type_node;
10911 intSI_type_internal_node = intSI_type_node;
10912 uintSI_type_internal_node = unsigned_intSI_type_node;
10913 intDI_type_internal_node = intDI_type_node;
10914 uintDI_type_internal_node = unsigned_intDI_type_node;
10915 float_type_internal_node = float_type_node;
10916 double_type_internal_node = float_type_node;
10917 void_type_internal_node = void_type_node;
10919 /* Initialize the modes for builtin_function_type, mapping a machine mode to
10921 builtin_mode_to_type[QImode][0] = integer_type_node;
10922 builtin_mode_to_type[HImode][0] = integer_type_node;
10923 builtin_mode_to_type[SImode][0] = intSI_type_node;
10924 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
10925 builtin_mode_to_type[DImode][0] = intDI_type_node;
10926 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
10927 builtin_mode_to_type[SFmode][0] = float_type_node;
10928 builtin_mode_to_type[DFmode][0] = double_type_node;
10929 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
10930 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
10931 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
10932 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
10933 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
10934 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
10935 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
10936 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
10937 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
10938 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
10939 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
10940 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
10941 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
10943 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10944 get_identifier ("__bool char"),
10945 bool_char_type_node);
10946 TYPE_NAME (bool_char_type_node) = tdecl;
10947 (*lang_hooks.decls.pushdecl) (tdecl);
10948 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10949 get_identifier ("__bool short"),
10950 bool_short_type_node);
10951 TYPE_NAME (bool_short_type_node) = tdecl;
10952 (*lang_hooks.decls.pushdecl) (tdecl);
10953 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10954 get_identifier ("__bool int"),
10955 bool_int_type_node);
10956 TYPE_NAME (bool_int_type_node) = tdecl;
10957 (*lang_hooks.decls.pushdecl) (tdecl);
10958 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
10960 TYPE_NAME (pixel_type_node) = tdecl;
10961 (*lang_hooks.decls.pushdecl) (tdecl);
10963 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
10964 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
10965 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
10966 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
10967 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
10969 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10970 get_identifier ("__vector unsigned char"),
10971 unsigned_V16QI_type_node);
10972 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
10973 (*lang_hooks.decls.pushdecl) (tdecl);
10974 tdecl = build_decl (BUILTINS_LOCATION,
10975 TYPE_DECL, get_identifier ("__vector signed char"),
10977 TYPE_NAME (V16QI_type_node) = tdecl;
10978 (*lang_hooks.decls.pushdecl) (tdecl);
10979 tdecl = build_decl (BUILTINS_LOCATION,
10980 TYPE_DECL, get_identifier ("__vector __bool char"),
10981 bool_V16QI_type_node);
10982 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
10983 (*lang_hooks.decls.pushdecl) (tdecl);
10985 tdecl = build_decl (BUILTINS_LOCATION,
10986 TYPE_DECL, get_identifier ("__vector unsigned short"),
10987 unsigned_V8HI_type_node);
10988 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
10989 (*lang_hooks.decls.pushdecl) (tdecl);
10990 tdecl = build_decl (BUILTINS_LOCATION,
10991 TYPE_DECL, get_identifier ("__vector signed short"),
10993 TYPE_NAME (V8HI_type_node) = tdecl;
10994 (*lang_hooks.decls.pushdecl) (tdecl);
10995 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
10996 get_identifier ("__vector __bool short"),
10997 bool_V8HI_type_node);
10998 TYPE_NAME (bool_V8HI_type_node) = tdecl;
10999 (*lang_hooks.decls.pushdecl) (tdecl);
11001 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11002 get_identifier ("__vector unsigned int"),
11003 unsigned_V4SI_type_node);
11004 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11005 (*lang_hooks.decls.pushdecl) (tdecl);
11006 tdecl = build_decl (BUILTINS_LOCATION,
11007 TYPE_DECL, get_identifier ("__vector signed int"),
11009 TYPE_NAME (V4SI_type_node) = tdecl;
11010 (*lang_hooks.decls.pushdecl) (tdecl);
11011 tdecl = build_decl (BUILTINS_LOCATION,
11012 TYPE_DECL, get_identifier ("__vector __bool int"),
11013 bool_V4SI_type_node);
11014 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11015 (*lang_hooks.decls.pushdecl) (tdecl);
11017 tdecl = build_decl (BUILTINS_LOCATION,
11018 TYPE_DECL, get_identifier ("__vector float"),
11020 TYPE_NAME (V4SF_type_node) = tdecl;
11021 (*lang_hooks.decls.pushdecl) (tdecl);
11022 tdecl = build_decl (BUILTINS_LOCATION,
11023 TYPE_DECL, get_identifier ("__vector __pixel"),
11024 pixel_V8HI_type_node);
11025 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11026 (*lang_hooks.decls.pushdecl) (tdecl);
11030 tdecl = build_decl (BUILTINS_LOCATION,
11031 TYPE_DECL, get_identifier ("__vector double"),
11033 TYPE_NAME (V2DF_type_node) = tdecl;
11034 (*lang_hooks.decls.pushdecl) (tdecl);
11036 tdecl = build_decl (BUILTINS_LOCATION,
11037 TYPE_DECL, get_identifier ("__vector long"),
11039 TYPE_NAME (V2DI_type_node) = tdecl;
11040 (*lang_hooks.decls.pushdecl) (tdecl);
11042 tdecl = build_decl (BUILTINS_LOCATION,
11043 TYPE_DECL, get_identifier ("__vector unsigned long"),
11044 unsigned_V2DI_type_node);
11045 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11046 (*lang_hooks.decls.pushdecl) (tdecl);
11048 tdecl = build_decl (BUILTINS_LOCATION,
11049 TYPE_DECL, get_identifier ("__vector __bool long"),
11050 bool_V2DI_type_node);
11051 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11052 (*lang_hooks.decls.pushdecl) (tdecl);
11055 if (TARGET_PAIRED_FLOAT)
11056 paired_init_builtins ();
11058 spe_init_builtins ();
11059 if (TARGET_ALTIVEC)
11060 altivec_init_builtins ();
11061 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11062 rs6000_common_init_builtins ();
11063 if (TARGET_PPC_GFXOPT)
11065 tree ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11066 RS6000_BUILTIN_RECIPF,
11067 "__builtin_recipdivf");
11068 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11069 RS6000_BUILTIN_RECIPF);
11071 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11072 RS6000_BUILTIN_RSQRTF,
11073 "__builtin_rsqrtf");
11074 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11075 RS6000_BUILTIN_RSQRTF);
11077 if (TARGET_POPCNTB)
11079 tree ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11080 RS6000_BUILTIN_RECIP,
11081 "__builtin_recipdiv");
11082 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11083 RS6000_BUILTIN_RECIP);
11086 if (TARGET_POPCNTD)
11088 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11089 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11090 POWER7_BUILTIN_BPERMD,
11091 "__builtin_bpermd");
11092 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11093 POWER7_BUILTIN_BPERMD);
11095 if (TARGET_POWERPC)
11097 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11098 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11099 unsigned_intHI_type_node,
11101 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11102 RS6000_BUILTIN_BSWAP_HI);
11106 /* AIX libm provides clog as __clog. */
11107 if (built_in_decls [BUILT_IN_CLOG])
11108 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11111 #ifdef SUBTARGET_INIT_BUILTINS
11112 SUBTARGET_INIT_BUILTINS;
11116 /* Search through a set of builtins and enable the mask bits.
11117 DESC is an array of builtins.
11118 SIZE is the total number of builtins.
11119 START is the builtin enum at which to start.
11120 END is the builtin enum at which to end. */
11122 enable_mask_for_builtins (struct builtin_description *desc, int size,
11123 enum rs6000_builtins start,
11124 enum rs6000_builtins end)
11128 for (i = 0; i < size; ++i)
11129 if (desc[i].code == start)
11135 for (; i < size; ++i)
11137 /* Flip all the bits on. */
11138 desc[i].mask = target_flags;
11139 if (desc[i].code == end)
11145 spe_init_builtins (void)
11147 tree endlink = void_list_node;
11148 tree puint_type_node = build_pointer_type (unsigned_type_node);
11149 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11150 struct builtin_description *d;
11153 tree v2si_ftype_4_v2si
11154 = build_function_type
11155 (opaque_V2SI_type_node,
11156 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11157 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11158 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11159 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11162 tree v2sf_ftype_4_v2sf
11163 = build_function_type
11164 (opaque_V2SF_type_node,
11165 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11166 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11167 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11168 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11171 tree int_ftype_int_v2si_v2si
11172 = build_function_type
11173 (integer_type_node,
11174 tree_cons (NULL_TREE, integer_type_node,
11175 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11176 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11179 tree int_ftype_int_v2sf_v2sf
11180 = build_function_type
11181 (integer_type_node,
11182 tree_cons (NULL_TREE, integer_type_node,
11183 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11184 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11187 tree void_ftype_v2si_puint_int
11188 = build_function_type (void_type_node,
11189 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11190 tree_cons (NULL_TREE, puint_type_node,
11191 tree_cons (NULL_TREE,
11195 tree void_ftype_v2si_puint_char
11196 = build_function_type (void_type_node,
11197 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11198 tree_cons (NULL_TREE, puint_type_node,
11199 tree_cons (NULL_TREE,
11203 tree void_ftype_v2si_pv2si_int
11204 = build_function_type (void_type_node,
11205 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11206 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11207 tree_cons (NULL_TREE,
11211 tree void_ftype_v2si_pv2si_char
11212 = build_function_type (void_type_node,
11213 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11214 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11215 tree_cons (NULL_TREE,
11219 tree void_ftype_int
11220 = build_function_type (void_type_node,
11221 tree_cons (NULL_TREE, integer_type_node, endlink));
11223 tree int_ftype_void
11224 = build_function_type (integer_type_node, endlink);
11226 tree v2si_ftype_pv2si_int
11227 = build_function_type (opaque_V2SI_type_node,
11228 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11229 tree_cons (NULL_TREE, integer_type_node,
11232 tree v2si_ftype_puint_int
11233 = build_function_type (opaque_V2SI_type_node,
11234 tree_cons (NULL_TREE, puint_type_node,
11235 tree_cons (NULL_TREE, integer_type_node,
11238 tree v2si_ftype_pushort_int
11239 = build_function_type (opaque_V2SI_type_node,
11240 tree_cons (NULL_TREE, pushort_type_node,
11241 tree_cons (NULL_TREE, integer_type_node,
11244 tree v2si_ftype_signed_char
11245 = build_function_type (opaque_V2SI_type_node,
11246 tree_cons (NULL_TREE, signed_char_type_node,
11249 /* The initialization of the simple binary and unary builtins is
11250 done in rs6000_common_init_builtins, but we have to enable the
11251 mask bits here manually because we have run out of `target_flags'
11252 bits. We really need to redesign this mask business. */
11254 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11255 ARRAY_SIZE (bdesc_2arg),
11256 SPE_BUILTIN_EVADDW,
11257 SPE_BUILTIN_EVXOR);
11258 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11259 ARRAY_SIZE (bdesc_1arg),
11261 SPE_BUILTIN_EVSUBFUSIAAW);
11262 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11263 ARRAY_SIZE (bdesc_spe_predicates),
11264 SPE_BUILTIN_EVCMPEQ,
11265 SPE_BUILTIN_EVFSTSTLT);
11266 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11267 ARRAY_SIZE (bdesc_spe_evsel),
11268 SPE_BUILTIN_EVSEL_CMPGTS,
11269 SPE_BUILTIN_EVSEL_FSTSTEQ);
11271 (*lang_hooks.decls.pushdecl)
11272 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11273 get_identifier ("__ev64_opaque__"),
11274 opaque_V2SI_type_node));
11276 /* Initialize irregular SPE builtins. */
11278 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11279 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11280 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11281 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11282 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11283 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11284 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11285 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11286 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11287 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11288 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11289 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11290 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11291 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11292 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11293 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11294 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11295 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11298 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11299 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11300 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11301 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11302 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11303 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11304 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11305 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11306 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11307 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11308 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11309 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11310 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11311 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11312 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11313 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11314 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11315 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11316 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11317 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11318 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11319 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11322 d = (struct builtin_description *) bdesc_spe_predicates;
11323 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11327 switch (insn_data[d->icode].operand[1].mode)
11330 type = int_ftype_int_v2si_v2si;
11333 type = int_ftype_int_v2sf_v2sf;
11336 gcc_unreachable ();
11339 def_builtin (d->mask, d->name, type, d->code);
11342 /* Evsel predicates. */
11343 d = (struct builtin_description *) bdesc_spe_evsel;
11344 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11348 switch (insn_data[d->icode].operand[1].mode)
11351 type = v2si_ftype_4_v2si;
11354 type = v2sf_ftype_4_v2sf;
11357 gcc_unreachable ();
11360 def_builtin (d->mask, d->name, type, d->code);
11365 paired_init_builtins (void)
11367 const struct builtin_description *d;
11369 tree endlink = void_list_node;
11371 tree int_ftype_int_v2sf_v2sf
11372 = build_function_type
11373 (integer_type_node,
11374 tree_cons (NULL_TREE, integer_type_node,
11375 tree_cons (NULL_TREE, V2SF_type_node,
11376 tree_cons (NULL_TREE, V2SF_type_node,
11378 tree pcfloat_type_node =
11379 build_pointer_type (build_qualified_type
11380 (float_type_node, TYPE_QUAL_CONST));
11382 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
11383 long_integer_type_node,
11386 tree void_ftype_v2sf_long_pcfloat =
11387 build_function_type_list (void_type_node,
11389 long_integer_type_node,
11394 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
11395 PAIRED_BUILTIN_LX);
11398 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
11399 PAIRED_BUILTIN_STX);
11402 d = bdesc_paired_preds;
11403 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
11407 switch (insn_data[d->icode].operand[1].mode)
11410 type = int_ftype_int_v2sf_v2sf;
11413 gcc_unreachable ();
11416 def_builtin (d->mask, d->name, type, d->code);
11421 altivec_init_builtins (void)
11423 const struct builtin_description *d;
11424 const struct builtin_description_predicates *dp;
11428 tree pfloat_type_node = build_pointer_type (float_type_node);
11429 tree pint_type_node = build_pointer_type (integer_type_node);
11430 tree pshort_type_node = build_pointer_type (short_integer_type_node);
11431 tree pchar_type_node = build_pointer_type (char_type_node);
11433 tree pvoid_type_node = build_pointer_type (void_type_node);
11435 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
11436 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
11437 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
11438 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
11440 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
11442 tree int_ftype_opaque
11443 = build_function_type_list (integer_type_node,
11444 opaque_V4SI_type_node, NULL_TREE);
11445 tree opaque_ftype_opaque
11446 = build_function_type (integer_type_node,
11448 tree opaque_ftype_opaque_int
11449 = build_function_type_list (opaque_V4SI_type_node,
11450 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
11451 tree opaque_ftype_opaque_opaque_int
11452 = build_function_type_list (opaque_V4SI_type_node,
11453 opaque_V4SI_type_node, opaque_V4SI_type_node,
11454 integer_type_node, NULL_TREE);
11455 tree int_ftype_int_opaque_opaque
11456 = build_function_type_list (integer_type_node,
11457 integer_type_node, opaque_V4SI_type_node,
11458 opaque_V4SI_type_node, NULL_TREE);
11459 tree int_ftype_int_v4si_v4si
11460 = build_function_type_list (integer_type_node,
11461 integer_type_node, V4SI_type_node,
11462 V4SI_type_node, NULL_TREE);
11463 tree v4sf_ftype_pcfloat
11464 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
11465 tree void_ftype_pfloat_v4sf
11466 = build_function_type_list (void_type_node,
11467 pfloat_type_node, V4SF_type_node, NULL_TREE);
11468 tree v4si_ftype_pcint
11469 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
11470 tree void_ftype_pint_v4si
11471 = build_function_type_list (void_type_node,
11472 pint_type_node, V4SI_type_node, NULL_TREE);
11473 tree v8hi_ftype_pcshort
11474 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
11475 tree void_ftype_pshort_v8hi
11476 = build_function_type_list (void_type_node,
11477 pshort_type_node, V8HI_type_node, NULL_TREE);
11478 tree v16qi_ftype_pcchar
11479 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
11480 tree void_ftype_pchar_v16qi
11481 = build_function_type_list (void_type_node,
11482 pchar_type_node, V16QI_type_node, NULL_TREE);
11483 tree void_ftype_v4si
11484 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
11485 tree v8hi_ftype_void
11486 = build_function_type (V8HI_type_node, void_list_node);
11487 tree void_ftype_void
11488 = build_function_type (void_type_node, void_list_node);
11489 tree void_ftype_int
11490 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
11492 tree opaque_ftype_long_pcvoid
11493 = build_function_type_list (opaque_V4SI_type_node,
11494 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11495 tree v16qi_ftype_long_pcvoid
11496 = build_function_type_list (V16QI_type_node,
11497 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11498 tree v8hi_ftype_long_pcvoid
11499 = build_function_type_list (V8HI_type_node,
11500 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11501 tree v4si_ftype_long_pcvoid
11502 = build_function_type_list (V4SI_type_node,
11503 long_integer_type_node, pcvoid_type_node, NULL_TREE);
11505 tree void_ftype_opaque_long_pvoid
11506 = build_function_type_list (void_type_node,
11507 opaque_V4SI_type_node, long_integer_type_node,
11508 pvoid_type_node, NULL_TREE);
11509 tree void_ftype_v4si_long_pvoid
11510 = build_function_type_list (void_type_node,
11511 V4SI_type_node, long_integer_type_node,
11512 pvoid_type_node, NULL_TREE);
11513 tree void_ftype_v16qi_long_pvoid
11514 = build_function_type_list (void_type_node,
11515 V16QI_type_node, long_integer_type_node,
11516 pvoid_type_node, NULL_TREE);
11517 tree void_ftype_v8hi_long_pvoid
11518 = build_function_type_list (void_type_node,
11519 V8HI_type_node, long_integer_type_node,
11520 pvoid_type_node, NULL_TREE);
11521 tree int_ftype_int_v8hi_v8hi
11522 = build_function_type_list (integer_type_node,
11523 integer_type_node, V8HI_type_node,
11524 V8HI_type_node, NULL_TREE);
11525 tree int_ftype_int_v16qi_v16qi
11526 = build_function_type_list (integer_type_node,
11527 integer_type_node, V16QI_type_node,
11528 V16QI_type_node, NULL_TREE);
11529 tree int_ftype_int_v4sf_v4sf
11530 = build_function_type_list (integer_type_node,
11531 integer_type_node, V4SF_type_node,
11532 V4SF_type_node, NULL_TREE);
11533 tree int_ftype_int_v2df_v2df
11534 = build_function_type_list (integer_type_node,
11535 integer_type_node, V2DF_type_node,
11536 V2DF_type_node, NULL_TREE);
11537 tree v4si_ftype_v4si
11538 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
11539 tree v8hi_ftype_v8hi
11540 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
11541 tree v16qi_ftype_v16qi
11542 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
11543 tree v4sf_ftype_v4sf
11544 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
11545 tree v2df_ftype_v2df
11546 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
11547 tree void_ftype_pcvoid_int_int
11548 = build_function_type_list (void_type_node,
11549 pcvoid_type_node, integer_type_node,
11550 integer_type_node, NULL_TREE);
11552 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
11553 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
11554 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
11555 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
11556 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
11557 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
11558 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
11559 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
11560 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
11561 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
11562 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
11563 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
11564 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
11565 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
11566 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
11567 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
11568 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
11569 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
11570 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
11571 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
11572 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
11573 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
11574 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
11575 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
11576 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
11577 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
11578 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
11579 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
11580 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
11581 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
11582 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
11583 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
11584 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
11585 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
11586 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
11587 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
11588 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
11589 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
11590 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
11591 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
11592 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
11593 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
11594 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
11595 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
11596 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
11597 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
11599 if (rs6000_cpu == PROCESSOR_CELL)
11601 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
11602 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
11603 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
11604 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
11606 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
11607 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
11608 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
11609 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
11611 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
11612 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
11613 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
11614 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
11616 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
11617 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
11618 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
11619 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
11621 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
11622 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
11623 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
11625 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
11626 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
11627 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
11628 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
11629 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
11630 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
11631 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
11632 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
11633 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
11634 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
11635 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
11636 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
11638 /* Add the DST variants. */
11640 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11641 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
11643 /* Initialize the predicates. */
11644 dp = bdesc_altivec_preds;
11645 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11647 enum machine_mode mode1;
11649 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11650 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11651 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
11652 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
11657 mode1 = insn_data[dp->icode].operand[1].mode;
11662 type = int_ftype_int_opaque_opaque;
11665 type = int_ftype_int_v4si_v4si;
11668 type = int_ftype_int_v8hi_v8hi;
11671 type = int_ftype_int_v16qi_v16qi;
11674 type = int_ftype_int_v4sf_v4sf;
11677 type = int_ftype_int_v2df_v2df;
11680 gcc_unreachable ();
11683 def_builtin (dp->mask, dp->name, type, dp->code);
11686 /* Initialize the abs* operators. */
11688 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11690 enum machine_mode mode0;
11693 mode0 = insn_data[d->icode].operand[0].mode;
11698 type = v4si_ftype_v4si;
11701 type = v8hi_ftype_v8hi;
11704 type = v16qi_ftype_v16qi;
11707 type = v4sf_ftype_v4sf;
11710 type = v2df_ftype_v2df;
11713 gcc_unreachable ();
11716 def_builtin (d->mask, d->name, type, d->code);
11719 if (TARGET_ALTIVEC)
11723 /* Initialize target builtin that implements
11724 targetm.vectorize.builtin_mask_for_load. */
11726 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
11727 v16qi_ftype_long_pcvoid,
11728 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
11729 BUILT_IN_MD, NULL, NULL_TREE);
11730 TREE_READONLY (decl) = 1;
11731 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
11732 altivec_builtin_mask_for_load = decl;
11735 /* Access to the vec_init patterns. */
11736 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
11737 integer_type_node, integer_type_node,
11738 integer_type_node, NULL_TREE);
11739 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
11740 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
11742 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
11743 short_integer_type_node,
11744 short_integer_type_node,
11745 short_integer_type_node,
11746 short_integer_type_node,
11747 short_integer_type_node,
11748 short_integer_type_node,
11749 short_integer_type_node, NULL_TREE);
11750 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
11751 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
11753 ftype = build_function_type_list (V16QI_type_node, char_type_node,
11754 char_type_node, char_type_node,
11755 char_type_node, char_type_node,
11756 char_type_node, char_type_node,
11757 char_type_node, char_type_node,
11758 char_type_node, char_type_node,
11759 char_type_node, char_type_node,
11760 char_type_node, char_type_node,
11761 char_type_node, NULL_TREE);
11762 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
11763 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
11765 ftype = build_function_type_list (V4SF_type_node, float_type_node,
11766 float_type_node, float_type_node,
11767 float_type_node, NULL_TREE);
11768 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
11769 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
11773 ftype = build_function_type_list (V2DF_type_node, double_type_node,
11774 double_type_node, NULL_TREE);
11775 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
11776 VSX_BUILTIN_VEC_INIT_V2DF);
11778 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
11779 intDI_type_node, NULL_TREE);
11780 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
11781 VSX_BUILTIN_VEC_INIT_V2DI);
11784 /* Access to the vec_set patterns. */
11785 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
11787 integer_type_node, NULL_TREE);
11788 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
11789 ALTIVEC_BUILTIN_VEC_SET_V4SI);
11791 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
11793 integer_type_node, NULL_TREE);
11794 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
11795 ALTIVEC_BUILTIN_VEC_SET_V8HI);
11797 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
11799 integer_type_node, NULL_TREE);
11800 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
11801 ALTIVEC_BUILTIN_VEC_SET_V16QI);
11803 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
11805 integer_type_node, NULL_TREE);
11806 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
11807 ALTIVEC_BUILTIN_VEC_SET_V4SF);
11811 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
11813 integer_type_node, NULL_TREE);
11814 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
11815 VSX_BUILTIN_VEC_SET_V2DF);
11817 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
11819 integer_type_node, NULL_TREE);
11820 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
11821 VSX_BUILTIN_VEC_SET_V2DI);
11824 /* Access to the vec_extract patterns. */
11825 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
11826 integer_type_node, NULL_TREE);
11827 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
11828 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
11830 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
11831 integer_type_node, NULL_TREE);
11832 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
11833 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
11835 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
11836 integer_type_node, NULL_TREE);
11837 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
11838 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
11840 ftype = build_function_type_list (float_type_node, V4SF_type_node,
11841 integer_type_node, NULL_TREE);
11842 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
11843 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
11847 ftype = build_function_type_list (double_type_node, V2DF_type_node,
11848 integer_type_node, NULL_TREE);
11849 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
11850 VSX_BUILTIN_VEC_EXT_V2DF);
11852 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
11853 integer_type_node, NULL_TREE);
11854 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
11855 VSX_BUILTIN_VEC_EXT_V2DI);
11859 /* Hash function for builtin functions with up to 3 arguments and a return
11862 builtin_hash_function (const void *hash_entry)
11866 const struct builtin_hash_struct *bh =
11867 (const struct builtin_hash_struct *) hash_entry;
11869 for (i = 0; i < 4; i++)
11871 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
11872 ret = (ret * 2) + bh->uns_p[i];
11878 /* Compare builtin hash entries H1 and H2 for equivalence. */
11880 builtin_hash_eq (const void *h1, const void *h2)
11882 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
11883 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
11885 return ((p1->mode[0] == p2->mode[0])
11886 && (p1->mode[1] == p2->mode[1])
11887 && (p1->mode[2] == p2->mode[2])
11888 && (p1->mode[3] == p2->mode[3])
11889 && (p1->uns_p[0] == p2->uns_p[0])
11890 && (p1->uns_p[1] == p2->uns_p[1])
11891 && (p1->uns_p[2] == p2->uns_p[2])
11892 && (p1->uns_p[3] == p2->uns_p[3]));
11895 /* Map types for builtin functions with an explicit return type and up to 3
11896 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
11897 of the argument. */
11899 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
11900 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
11901 enum rs6000_builtins builtin, const char *name)
11903 struct builtin_hash_struct h;
11904 struct builtin_hash_struct *h2;
11908 tree ret_type = NULL_TREE;
11909 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
11912 /* Create builtin_hash_table. */
11913 if (builtin_hash_table == NULL)
11914 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
11915 builtin_hash_eq, NULL);
11917 h.type = NULL_TREE;
11918 h.mode[0] = mode_ret;
11919 h.mode[1] = mode_arg0;
11920 h.mode[2] = mode_arg1;
11921 h.mode[3] = mode_arg2;
11927 /* If the builtin is a type that produces unsigned results or takes unsigned
11928 arguments, and it is returned as a decl for the vectorizer (such as
11929 widening multiplies, permute), make sure the arguments and return value
11930 are type correct. */
11933 /* unsigned 2 argument functions. */
11934 case ALTIVEC_BUILTIN_VMULEUB_UNS:
11935 case ALTIVEC_BUILTIN_VMULEUH_UNS:
11936 case ALTIVEC_BUILTIN_VMULOUB_UNS:
11937 case ALTIVEC_BUILTIN_VMULOUH_UNS:
11943 /* unsigned 3 argument functions. */
11944 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
11945 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
11946 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
11947 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
11948 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
11949 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
11950 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
11951 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
11952 case VSX_BUILTIN_VPERM_16QI_UNS:
11953 case VSX_BUILTIN_VPERM_8HI_UNS:
11954 case VSX_BUILTIN_VPERM_4SI_UNS:
11955 case VSX_BUILTIN_VPERM_2DI_UNS:
11956 case VSX_BUILTIN_XXSEL_16QI_UNS:
11957 case VSX_BUILTIN_XXSEL_8HI_UNS:
11958 case VSX_BUILTIN_XXSEL_4SI_UNS:
11959 case VSX_BUILTIN_XXSEL_2DI_UNS:
11966 /* signed permute functions with unsigned char mask. */
11967 case ALTIVEC_BUILTIN_VPERM_16QI:
11968 case ALTIVEC_BUILTIN_VPERM_8HI:
11969 case ALTIVEC_BUILTIN_VPERM_4SI:
11970 case ALTIVEC_BUILTIN_VPERM_4SF:
11971 case ALTIVEC_BUILTIN_VPERM_2DI:
11972 case ALTIVEC_BUILTIN_VPERM_2DF:
11973 case VSX_BUILTIN_VPERM_16QI:
11974 case VSX_BUILTIN_VPERM_8HI:
11975 case VSX_BUILTIN_VPERM_4SI:
11976 case VSX_BUILTIN_VPERM_4SF:
11977 case VSX_BUILTIN_VPERM_2DI:
11978 case VSX_BUILTIN_VPERM_2DF:
11982 /* unsigned args, signed return. */
11983 case VSX_BUILTIN_XVCVUXDDP_UNS:
11984 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
11988 /* signed args, unsigned return. */
11989 case VSX_BUILTIN_XVCVDPUXDS_UNS:
11990 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
11998 /* Figure out how many args are present. */
11999 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12003 fatal_error ("internal error: builtin function %s had no type", name);
12005 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12006 if (!ret_type && h.uns_p[0])
12007 ret_type = builtin_mode_to_type[h.mode[0]][0];
12010 fatal_error ("internal error: builtin function %s had an unexpected "
12011 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12013 for (i = 0; i < num_args; i++)
12015 int m = (int) h.mode[i+1];
12016 int uns_p = h.uns_p[i+1];
12018 arg_type[i] = builtin_mode_to_type[m][uns_p];
12019 if (!arg_type[i] && uns_p)
12020 arg_type[i] = builtin_mode_to_type[m][0];
12023 fatal_error ("internal error: builtin function %s, argument %d "
12024 "had unexpected argument type %s", name, i,
12025 GET_MODE_NAME (m));
12028 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12029 if (*found == NULL)
12031 h2 = GGC_NEW (struct builtin_hash_struct);
12033 *found = (void *)h2;
12034 args = void_list_node;
12036 for (i = num_args - 1; i >= 0; i--)
12037 args = tree_cons (NULL_TREE, arg_type[i], args);
12039 h2->type = build_function_type (ret_type, args);
12042 return ((struct builtin_hash_struct *)(*found))->type;
12046 rs6000_common_init_builtins (void)
12048 const struct builtin_description *d;
12051 tree opaque_ftype_opaque = NULL_TREE;
12052 tree opaque_ftype_opaque_opaque = NULL_TREE;
12053 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12054 tree v2si_ftype_qi = NULL_TREE;
12055 tree v2si_ftype_v2si_qi = NULL_TREE;
12056 tree v2si_ftype_int_qi = NULL_TREE;
12058 if (!TARGET_PAIRED_FLOAT)
12060 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12061 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12064 /* Add the ternary operators. */
12066 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12069 int mask = d->mask;
12071 if ((mask != 0 && (mask & target_flags) == 0)
12072 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12075 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12076 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12077 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12078 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12080 if (! (type = opaque_ftype_opaque_opaque_opaque))
12081 type = opaque_ftype_opaque_opaque_opaque
12082 = build_function_type_list (opaque_V4SI_type_node,
12083 opaque_V4SI_type_node,
12084 opaque_V4SI_type_node,
12085 opaque_V4SI_type_node,
12090 enum insn_code icode = d->icode;
12091 if (d->name == 0 || icode == CODE_FOR_nothing)
12094 type = builtin_function_type (insn_data[icode].operand[0].mode,
12095 insn_data[icode].operand[1].mode,
12096 insn_data[icode].operand[2].mode,
12097 insn_data[icode].operand[3].mode,
12101 def_builtin (d->mask, d->name, type, d->code);
12104 /* Add the binary operators. */
12106 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12108 enum machine_mode mode0, mode1, mode2;
12110 int mask = d->mask;
12112 if ((mask != 0 && (mask & target_flags) == 0)
12113 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12116 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12117 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12118 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12119 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12121 if (! (type = opaque_ftype_opaque_opaque))
12122 type = opaque_ftype_opaque_opaque
12123 = build_function_type_list (opaque_V4SI_type_node,
12124 opaque_V4SI_type_node,
12125 opaque_V4SI_type_node,
12130 enum insn_code icode = d->icode;
12131 if (d->name == 0 || icode == CODE_FOR_nothing)
12134 mode0 = insn_data[icode].operand[0].mode;
12135 mode1 = insn_data[icode].operand[1].mode;
12136 mode2 = insn_data[icode].operand[2].mode;
12138 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12140 if (! (type = v2si_ftype_v2si_qi))
12141 type = v2si_ftype_v2si_qi
12142 = build_function_type_list (opaque_V2SI_type_node,
12143 opaque_V2SI_type_node,
12148 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12149 && mode2 == QImode)
12151 if (! (type = v2si_ftype_int_qi))
12152 type = v2si_ftype_int_qi
12153 = build_function_type_list (opaque_V2SI_type_node,
12160 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12164 def_builtin (d->mask, d->name, type, d->code);
12167 /* Add the simple unary operators. */
12168 d = (struct builtin_description *) bdesc_1arg;
12169 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12171 enum machine_mode mode0, mode1;
12173 int mask = d->mask;
12175 if ((mask != 0 && (mask & target_flags) == 0)
12176 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12179 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12180 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12181 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12182 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12184 if (! (type = opaque_ftype_opaque))
12185 type = opaque_ftype_opaque
12186 = build_function_type_list (opaque_V4SI_type_node,
12187 opaque_V4SI_type_node,
12192 enum insn_code icode = d->icode;
12193 if (d->name == 0 || icode == CODE_FOR_nothing)
12196 mode0 = insn_data[icode].operand[0].mode;
12197 mode1 = insn_data[icode].operand[1].mode;
12199 if (mode0 == V2SImode && mode1 == QImode)
12201 if (! (type = v2si_ftype_qi))
12202 type = v2si_ftype_qi
12203 = build_function_type_list (opaque_V2SI_type_node,
12209 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12213 def_builtin (d->mask, d->name, type, d->code);
12218 rs6000_init_libfuncs (void)
12220 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12221 && !TARGET_POWER2 && !TARGET_POWERPC)
12223 /* AIX library routines for float->int conversion. */
12224 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12225 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12226 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12227 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12230 if (!TARGET_IEEEQUAD)
12231 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12232 if (!TARGET_XL_COMPAT)
12234 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12235 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12236 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12237 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12239 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12241 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12242 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12243 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12244 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12245 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12246 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12247 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12249 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12250 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12251 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12252 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12253 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12254 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12255 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12256 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12259 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12260 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12264 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12265 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12266 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12267 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12271 /* 32-bit SVR4 quad floating point routines. */
12273 set_optab_libfunc (add_optab, TFmode, "_q_add");
12274 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12275 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12276 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12277 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12278 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12279 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12281 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12282 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12283 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12284 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12285 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12286 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12288 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12289 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12290 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12291 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12292 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12293 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12294 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12295 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12300 /* Expand a block clear operation, and return 1 if successful. Return 0
12301 if we should let the compiler generate normal code.
12303 operands[0] is the destination
12304 operands[1] is the length
12305 operands[3] is the alignment */
12308 expand_block_clear (rtx operands[])
12310 rtx orig_dest = operands[0];
12311 rtx bytes_rtx = operands[1];
12312 rtx align_rtx = operands[3];
12313 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12314 HOST_WIDE_INT align;
12315 HOST_WIDE_INT bytes;
12320 /* If this is not a fixed size move, just call memcpy */
12324 /* This must be a fixed size alignment */
12325 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12326 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12328 /* Anything to clear? */
12329 bytes = INTVAL (bytes_rtx);
12333 /* Use the builtin memset after a point, to avoid huge code bloat.
12334 When optimize_size, avoid any significant code bloat; calling
12335 memset is about 4 instructions, so allow for one instruction to
12336 load zero and three to do clearing. */
12337 if (TARGET_ALTIVEC && align >= 128)
12339 else if (TARGET_POWERPC64 && align >= 32)
12341 else if (TARGET_SPE && align >= 64)
12346 if (optimize_size && bytes > 3 * clear_step)
12348 if (! optimize_size && bytes > 8 * clear_step)
12351 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12353 enum machine_mode mode = BLKmode;
12356 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
12361 else if (bytes >= 8 && TARGET_SPE && align >= 64)
12366 else if (bytes >= 8 && TARGET_POWERPC64
12367 /* 64-bit loads and stores require word-aligned
12369 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12374 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12375 { /* move 4 bytes */
12379 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12380 { /* move 2 bytes */
12384 else /* move 1 byte at a time */
12390 dest = adjust_address (orig_dest, mode, offset);
12392 emit_move_insn (dest, CONST0_RTX (mode));
12399 /* Expand a block move operation, and return 1 if successful. Return 0
12400 if we should let the compiler generate normal code.
12402 operands[0] is the destination
12403 operands[1] is the source
12404 operands[2] is the length
12405 operands[3] is the alignment */
12407 #define MAX_MOVE_REG 4
12410 expand_block_move (rtx operands[])
12412 rtx orig_dest = operands[0];
12413 rtx orig_src = operands[1];
12414 rtx bytes_rtx = operands[2];
12415 rtx align_rtx = operands[3];
12416 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
12421 rtx stores[MAX_MOVE_REG];
12424 /* If this is not a fixed size move, just call memcpy */
12428 /* This must be a fixed size alignment */
12429 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12430 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12432 /* Anything to move? */
12433 bytes = INTVAL (bytes_rtx);
12437 /* store_one_arg depends on expand_block_move to handle at least the size of
12438 reg_parm_stack_space. */
12439 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
12442 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
12445 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
12446 rtx (*mov) (rtx, rtx);
12448 enum machine_mode mode = BLKmode;
12451 /* Altivec first, since it will be faster than a string move
12452 when it applies, and usually not significantly larger. */
12453 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
12457 gen_func.mov = gen_movv4si;
12459 else if (TARGET_SPE && bytes >= 8 && align >= 64)
12463 gen_func.mov = gen_movv2si;
12465 else if (TARGET_STRING
12466 && bytes > 24 /* move up to 32 bytes at a time */
12472 && ! fixed_regs[10]
12473 && ! fixed_regs[11]
12474 && ! fixed_regs[12])
12476 move_bytes = (bytes > 32) ? 32 : bytes;
12477 gen_func.movmemsi = gen_movmemsi_8reg;
12479 else if (TARGET_STRING
12480 && bytes > 16 /* move up to 24 bytes at a time */
12486 && ! fixed_regs[10])
12488 move_bytes = (bytes > 24) ? 24 : bytes;
12489 gen_func.movmemsi = gen_movmemsi_6reg;
12491 else if (TARGET_STRING
12492 && bytes > 8 /* move up to 16 bytes at a time */
12496 && ! fixed_regs[8])
12498 move_bytes = (bytes > 16) ? 16 : bytes;
12499 gen_func.movmemsi = gen_movmemsi_4reg;
12501 else if (bytes >= 8 && TARGET_POWERPC64
12502 /* 64-bit loads and stores require word-aligned
12504 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12508 gen_func.mov = gen_movdi;
12510 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
12511 { /* move up to 8 bytes at a time */
12512 move_bytes = (bytes > 8) ? 8 : bytes;
12513 gen_func.movmemsi = gen_movmemsi_2reg;
12515 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12516 { /* move 4 bytes */
12519 gen_func.mov = gen_movsi;
12521 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12522 { /* move 2 bytes */
12525 gen_func.mov = gen_movhi;
12527 else if (TARGET_STRING && bytes > 1)
12528 { /* move up to 4 bytes at a time */
12529 move_bytes = (bytes > 4) ? 4 : bytes;
12530 gen_func.movmemsi = gen_movmemsi_1reg;
12532 else /* move 1 byte at a time */
12536 gen_func.mov = gen_movqi;
12539 src = adjust_address (orig_src, mode, offset);
12540 dest = adjust_address (orig_dest, mode, offset);
12542 if (mode != BLKmode)
12544 rtx tmp_reg = gen_reg_rtx (mode);
12546 emit_insn ((*gen_func.mov) (tmp_reg, src));
12547 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
12550 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
12553 for (i = 0; i < num_reg; i++)
12554 emit_insn (stores[i]);
12558 if (mode == BLKmode)
12560 /* Move the address into scratch registers. The movmemsi
12561 patterns require zero offset. */
12562 if (!REG_P (XEXP (src, 0)))
12564 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
12565 src = replace_equiv_address (src, src_reg);
12567 set_mem_size (src, GEN_INT (move_bytes));
12569 if (!REG_P (XEXP (dest, 0)))
12571 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
12572 dest = replace_equiv_address (dest, dest_reg);
12574 set_mem_size (dest, GEN_INT (move_bytes));
12576 emit_insn ((*gen_func.movmemsi) (dest, src,
12577 GEN_INT (move_bytes & 31),
12586 /* Return a string to perform a load_multiple operation.
12587 operands[0] is the vector.
12588 operands[1] is the source address.
12589 operands[2] is the first destination register. */
12592 rs6000_output_load_multiple (rtx operands[3])
12594 /* We have to handle the case where the pseudo used to contain the address
12595 is assigned to one of the output registers. */
12597 int words = XVECLEN (operands[0], 0);
12600 if (XVECLEN (operands[0], 0) == 1)
12601 return "{l|lwz} %2,0(%1)";
12603 for (i = 0; i < words; i++)
12604 if (refers_to_regno_p (REGNO (operands[2]) + i,
12605 REGNO (operands[2]) + i + 1, operands[1], 0))
12609 xop[0] = GEN_INT (4 * (words-1));
12610 xop[1] = operands[1];
12611 xop[2] = operands[2];
12612 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
12617 xop[0] = GEN_INT (4 * (words-1));
12618 xop[1] = operands[1];
12619 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
12620 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);
12625 for (j = 0; j < words; j++)
12628 xop[0] = GEN_INT (j * 4);
12629 xop[1] = operands[1];
12630 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
12631 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
12633 xop[0] = GEN_INT (i * 4);
12634 xop[1] = operands[1];
12635 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
12640 return "{lsi|lswi} %2,%1,%N0";
12644 /* A validation routine: say whether CODE, a condition code, and MODE
12645 match. The other alternatives either don't make sense or should
12646 never be generated. */
12649 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
12651 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
12652 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
12653 && GET_MODE_CLASS (mode) == MODE_CC);
12655 /* These don't make sense. */
12656 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
12657 || mode != CCUNSmode);
12659 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
12660 || mode == CCUNSmode);
12662 gcc_assert (mode == CCFPmode
12663 || (code != ORDERED && code != UNORDERED
12664 && code != UNEQ && code != LTGT
12665 && code != UNGT && code != UNLT
12666 && code != UNGE && code != UNLE));
12668 /* These should never be generated except for
12669 flag_finite_math_only. */
12670 gcc_assert (mode != CCFPmode
12671 || flag_finite_math_only
12672 || (code != LE && code != GE
12673 && code != UNEQ && code != LTGT
12674 && code != UNGT && code != UNLT));
12676 /* These are invalid; the information is not there. */
12677 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
12681 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
12682 mask required to convert the result of a rotate insn into a shift
12683 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
12686 includes_lshift_p (rtx shiftop, rtx andop)
12688 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12690 shift_mask <<= INTVAL (shiftop);
12692 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12695 /* Similar, but for right shift. */
12698 includes_rshift_p (rtx shiftop, rtx andop)
12700 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
12702 shift_mask >>= INTVAL (shiftop);
12704 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
12707 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
12708 to perform a left shift. It must have exactly SHIFTOP least
12709 significant 0's, then one or more 1's, then zero or more 0's. */
12712 includes_rldic_lshift_p (rtx shiftop, rtx andop)
12714 if (GET_CODE (andop) == CONST_INT)
12716 HOST_WIDE_INT c, lsb, shift_mask;
12718 c = INTVAL (andop);
12719 if (c == 0 || c == ~0)
12723 shift_mask <<= INTVAL (shiftop);
12725 /* Find the least significant one bit. */
12728 /* It must coincide with the LSB of the shift mask. */
12729 if (-lsb != shift_mask)
12732 /* Invert to look for the next transition (if any). */
12735 /* Remove the low group of ones (originally low group of zeros). */
12738 /* Again find the lsb, and check we have all 1's above. */
12742 else if (GET_CODE (andop) == CONST_DOUBLE
12743 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12745 HOST_WIDE_INT low, high, lsb;
12746 HOST_WIDE_INT shift_mask_low, shift_mask_high;
12748 low = CONST_DOUBLE_LOW (andop);
12749 if (HOST_BITS_PER_WIDE_INT < 64)
12750 high = CONST_DOUBLE_HIGH (andop);
12752 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
12753 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
12756 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12758 shift_mask_high = ~0;
12759 if (INTVAL (shiftop) > 32)
12760 shift_mask_high <<= INTVAL (shiftop) - 32;
12762 lsb = high & -high;
12764 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
12770 lsb = high & -high;
12771 return high == -lsb;
12774 shift_mask_low = ~0;
12775 shift_mask_low <<= INTVAL (shiftop);
12779 if (-lsb != shift_mask_low)
12782 if (HOST_BITS_PER_WIDE_INT < 64)
12787 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
12789 lsb = high & -high;
12790 return high == -lsb;
12794 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
12800 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
12801 to perform a left shift. It must have SHIFTOP or more least
12802 significant 0's, with the remainder of the word 1's. */
12805 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
12807 if (GET_CODE (andop) == CONST_INT)
12809 HOST_WIDE_INT c, lsb, shift_mask;
12812 shift_mask <<= INTVAL (shiftop);
12813 c = INTVAL (andop);
12815 /* Find the least significant one bit. */
12818 /* It must be covered by the shift mask.
12819 This test also rejects c == 0. */
12820 if ((lsb & shift_mask) == 0)
12823 /* Check we have all 1's above the transition, and reject all 1's. */
12824 return c == -lsb && lsb != 1;
12826 else if (GET_CODE (andop) == CONST_DOUBLE
12827 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
12829 HOST_WIDE_INT low, lsb, shift_mask_low;
12831 low = CONST_DOUBLE_LOW (andop);
12833 if (HOST_BITS_PER_WIDE_INT < 64)
12835 HOST_WIDE_INT high, shift_mask_high;
12837 high = CONST_DOUBLE_HIGH (andop);
12841 shift_mask_high = ~0;
12842 if (INTVAL (shiftop) > 32)
12843 shift_mask_high <<= INTVAL (shiftop) - 32;
12845 lsb = high & -high;
12847 if ((lsb & shift_mask_high) == 0)
12850 return high == -lsb;
12856 shift_mask_low = ~0;
12857 shift_mask_low <<= INTVAL (shiftop);
12861 if ((lsb & shift_mask_low) == 0)
12864 return low == -lsb && lsb != 1;
12870 /* Return 1 if operands will generate a valid arguments to rlwimi
12871 instruction for insert with right shift in 64-bit mode. The mask may
12872 not start on the first bit or stop on the last bit because wrap-around
12873 effects of instruction do not correspond to semantics of RTL insn. */
12876 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
12878 if (INTVAL (startop) > 32
12879 && INTVAL (startop) < 64
12880 && INTVAL (sizeop) > 1
12881 && INTVAL (sizeop) + INTVAL (startop) < 64
12882 && INTVAL (shiftop) > 0
12883 && INTVAL (sizeop) + INTVAL (shiftop) < 32
12884 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
12890 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
12891 for lfq and stfq insns iff the registers are hard registers. */
12894 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
12896 /* We might have been passed a SUBREG. */
12897 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
12900 /* We might have been passed non floating point registers. */
12901 if (!FP_REGNO_P (REGNO (reg1))
12902 || !FP_REGNO_P (REGNO (reg2)))
12905 return (REGNO (reg1) == REGNO (reg2) - 1);
12908 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
12909 addr1 and addr2 must be in consecutive memory locations
12910 (addr2 == addr1 + 8). */
12913 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
12916 unsigned int reg1, reg2;
12917 int offset1, offset2;
12919 /* The mems cannot be volatile. */
12920 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
12923 addr1 = XEXP (mem1, 0);
12924 addr2 = XEXP (mem2, 0);
12926 /* Extract an offset (if used) from the first addr. */
12927 if (GET_CODE (addr1) == PLUS)
12929 /* If not a REG, return zero. */
12930 if (GET_CODE (XEXP (addr1, 0)) != REG)
12934 reg1 = REGNO (XEXP (addr1, 0));
12935 /* The offset must be constant! */
12936 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
12938 offset1 = INTVAL (XEXP (addr1, 1));
12941 else if (GET_CODE (addr1) != REG)
12945 reg1 = REGNO (addr1);
12946 /* This was a simple (mem (reg)) expression. Offset is 0. */
12950 /* And now for the second addr. */
12951 if (GET_CODE (addr2) == PLUS)
12953 /* If not a REG, return zero. */
12954 if (GET_CODE (XEXP (addr2, 0)) != REG)
12958 reg2 = REGNO (XEXP (addr2, 0));
12959 /* The offset must be constant. */
12960 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
12962 offset2 = INTVAL (XEXP (addr2, 1));
12965 else if (GET_CODE (addr2) != REG)
12969 reg2 = REGNO (addr2);
12970 /* This was a simple (mem (reg)) expression. Offset is 0. */
12974 /* Both of these must have the same base register. */
12978 /* The offset for the second addr must be 8 more than the first addr. */
12979 if (offset2 != offset1 + 8)
12982 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
12989 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
12991 static bool eliminated = false;
12994 if (mode != SDmode)
12995 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
12998 rtx mem = cfun->machine->sdmode_stack_slot;
12999 gcc_assert (mem != NULL_RTX);
13003 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13004 cfun->machine->sdmode_stack_slot = mem;
13010 if (TARGET_DEBUG_ADDR)
13012 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13013 GET_MODE_NAME (mode));
13015 fprintf (stderr, "\tNULL_RTX\n");
13024 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13026 /* Don't walk into types. */
13027 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13029 *walk_subtrees = 0;
13033 switch (TREE_CODE (*tp))
13042 case ALIGN_INDIRECT_REF:
13043 case MISALIGNED_INDIRECT_REF:
13044 case VIEW_CONVERT_EXPR:
13045 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13055 enum reload_reg_type {
13057 VECTOR_REGISTER_TYPE,
13058 OTHER_REGISTER_TYPE
13061 static enum reload_reg_type
13062 rs6000_reload_register_type (enum reg_class rclass)
13068 return GPR_REGISTER_TYPE;
13073 return VECTOR_REGISTER_TYPE;
13076 return OTHER_REGISTER_TYPE;
13080 /* Inform reload about cases where moving X with a mode MODE to a register in
13081 RCLASS requires an extra scratch or immediate register. Return the class
13082 needed for the immediate register.
13084 For VSX and Altivec, we may need a register to convert sp+offset into
13087 static enum reg_class
13088 rs6000_secondary_reload (bool in_p,
13090 enum reg_class rclass,
13091 enum machine_mode mode,
13092 secondary_reload_info *sri)
13094 enum reg_class ret = ALL_REGS;
13095 enum insn_code icode;
13096 bool default_p = false;
13098 sri->icode = CODE_FOR_nothing;
13100 /* Convert vector loads and stores into gprs to use an additional base
13102 icode = rs6000_vector_reload[mode][in_p != false];
13103 if (icode != CODE_FOR_nothing)
13106 sri->icode = CODE_FOR_nothing;
13107 sri->extra_cost = 0;
13109 if (GET_CODE (x) == MEM)
13111 rtx addr = XEXP (x, 0);
13113 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13114 an extra register in that case, but it would need an extra
13115 register if the addressing is reg+reg or (reg+reg)&(-16). */
13116 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13118 if (!legitimate_indirect_address_p (addr, false)
13119 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13121 sri->icode = icode;
13122 /* account for splitting the loads, and converting the
13123 address from reg+reg to reg. */
13124 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13125 + ((GET_CODE (addr) == AND) ? 1 : 0));
13128 /* Loads to and stores from vector registers can only do reg+reg
13129 addressing. Altivec registers can also do (reg+reg)&(-16). */
13130 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13131 || rclass == FLOAT_REGS || rclass == NO_REGS)
13133 if (!VECTOR_MEM_ALTIVEC_P (mode)
13134 && GET_CODE (addr) == AND
13135 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13136 && INTVAL (XEXP (addr, 1)) == -16
13137 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13138 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13140 sri->icode = icode;
13141 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13144 else if (!legitimate_indirect_address_p (addr, false)
13145 && (rclass == NO_REGS
13146 || !legitimate_indexed_address_p (addr, false)))
13148 sri->icode = icode;
13149 sri->extra_cost = 1;
13152 icode = CODE_FOR_nothing;
13154 /* Any other loads, including to pseudo registers which haven't been
13155 assigned to a register yet, default to require a scratch
13159 sri->icode = icode;
13160 sri->extra_cost = 2;
13163 else if (REG_P (x))
13165 int regno = true_regnum (x);
13167 icode = CODE_FOR_nothing;
13168 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13172 enum reg_class xclass = REGNO_REG_CLASS (regno);
13173 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13174 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13176 /* If memory is needed, use default_secondary_reload to create the
13178 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13191 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13193 gcc_assert (ret != ALL_REGS);
13195 if (TARGET_DEBUG_ADDR)
13198 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13200 reg_class_names[ret],
13201 in_p ? "true" : "false",
13202 reg_class_names[rclass],
13203 GET_MODE_NAME (mode));
13206 fprintf (stderr, ", default secondary reload");
13208 if (sri->icode != CODE_FOR_nothing)
13209 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13210 insn_data[sri->icode].name, sri->extra_cost);
13212 fprintf (stderr, "\n");
13220 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13221 to SP+reg addressing. */
13224 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13226 int regno = true_regnum (reg);
13227 enum machine_mode mode = GET_MODE (reg);
13228 enum reg_class rclass;
13230 rtx and_op2 = NULL_RTX;
13233 rtx scratch_or_premodify = scratch;
13237 if (TARGET_DEBUG_ADDR)
13239 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13240 store_p ? "store" : "load");
13241 fprintf (stderr, "reg:\n");
13243 fprintf (stderr, "mem:\n");
13245 fprintf (stderr, "scratch:\n");
13246 debug_rtx (scratch);
13249 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13250 gcc_assert (GET_CODE (mem) == MEM);
13251 rclass = REGNO_REG_CLASS (regno);
13252 addr = XEXP (mem, 0);
13256 /* GPRs can handle reg + small constant, all other addresses need to use
13257 the scratch register. */
13260 if (GET_CODE (addr) == AND)
13262 and_op2 = XEXP (addr, 1);
13263 addr = XEXP (addr, 0);
13266 if (GET_CODE (addr) == PRE_MODIFY)
13268 scratch_or_premodify = XEXP (addr, 0);
13269 gcc_assert (REG_P (scratch_or_premodify));
13270 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13271 addr = XEXP (addr, 1);
13274 if (GET_CODE (addr) == PLUS
13275 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13276 || and_op2 != NULL_RTX))
13278 addr_op1 = XEXP (addr, 0);
13279 addr_op2 = XEXP (addr, 1);
13280 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13282 if (!REG_P (addr_op2)
13283 && (GET_CODE (addr_op2) != CONST_INT
13284 || !satisfies_constraint_I (addr_op2)))
13286 if (TARGET_DEBUG_ADDR)
13289 "\nMove plus addr to register %s, mode = %s: ",
13290 rs6000_reg_names[REGNO (scratch)],
13291 GET_MODE_NAME (mode));
13292 debug_rtx (addr_op2);
13294 rs6000_emit_move (scratch, addr_op2, Pmode);
13295 addr_op2 = scratch;
13298 emit_insn (gen_rtx_SET (VOIDmode,
13299 scratch_or_premodify,
13300 gen_rtx_PLUS (Pmode,
13304 addr = scratch_or_premodify;
13305 scratch_or_premodify = scratch;
13307 else if (!legitimate_indirect_address_p (addr, false)
13308 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13310 if (TARGET_DEBUG_ADDR)
13312 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13313 rs6000_reg_names[REGNO (scratch_or_premodify)],
13314 GET_MODE_NAME (mode));
13317 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13318 addr = scratch_or_premodify;
13319 scratch_or_premodify = scratch;
13323 /* Float/Altivec registers can only handle reg+reg addressing. Move
13324 other addresses into a scratch register. */
13329 /* With float regs, we need to handle the AND ourselves, since we can't
13330 use the Altivec instruction with an implicit AND -16. Allow scalar
13331 loads to float registers to use reg+offset even if VSX. */
13332 if (GET_CODE (addr) == AND
13333 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13334 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13335 || INTVAL (XEXP (addr, 1)) != -16
13336 || !VECTOR_MEM_ALTIVEC_P (mode)))
13338 and_op2 = XEXP (addr, 1);
13339 addr = XEXP (addr, 0);
13342 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13343 as the address later. */
13344 if (GET_CODE (addr) == PRE_MODIFY
13345 && (!VECTOR_MEM_VSX_P (mode)
13346 || and_op2 != NULL_RTX
13347 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13349 scratch_or_premodify = XEXP (addr, 0);
13350 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13352 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13353 addr = XEXP (addr, 1);
13356 if (legitimate_indirect_address_p (addr, false) /* reg */
13357 || legitimate_indexed_address_p (addr, false) /* reg+reg */
13358 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
13359 || (GET_CODE (addr) == AND /* Altivec memory */
13360 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13361 && INTVAL (XEXP (addr, 1)) == -16
13362 && VECTOR_MEM_ALTIVEC_P (mode))
13363 || (rclass == FLOAT_REGS /* legacy float mem */
13364 && GET_MODE_SIZE (mode) == 8
13365 && and_op2 == NULL_RTX
13366 && scratch_or_premodify == scratch
13367 && rs6000_legitimate_offset_address_p (mode, addr, false)))
13370 else if (GET_CODE (addr) == PLUS)
13372 addr_op1 = XEXP (addr, 0);
13373 addr_op2 = XEXP (addr, 1);
13374 gcc_assert (REG_P (addr_op1));
13376 if (TARGET_DEBUG_ADDR)
13378 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
13379 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13380 debug_rtx (addr_op2);
13382 rs6000_emit_move (scratch, addr_op2, Pmode);
13383 emit_insn (gen_rtx_SET (VOIDmode,
13384 scratch_or_premodify,
13385 gen_rtx_PLUS (Pmode,
13388 addr = scratch_or_premodify;
13389 scratch_or_premodify = scratch;
13392 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
13393 || GET_CODE (addr) == CONST_INT || REG_P (addr))
13395 if (TARGET_DEBUG_ADDR)
13397 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13398 rs6000_reg_names[REGNO (scratch_or_premodify)],
13399 GET_MODE_NAME (mode));
13403 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13404 addr = scratch_or_premodify;
13405 scratch_or_premodify = scratch;
13409 gcc_unreachable ();
13414 gcc_unreachable ();
13417 /* If the original address involved a pre-modify that we couldn't use the VSX
13418 memory instruction with update, and we haven't taken care of already,
13419 store the address in the pre-modify register and use that as the
13421 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
13423 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
13424 addr = scratch_or_premodify;
13427 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
13428 memory instruction, recreate the AND now, including the clobber which is
13429 generated by the general ANDSI3/ANDDI3 patterns for the
13430 andi. instruction. */
13431 if (and_op2 != NULL_RTX)
13433 if (! legitimate_indirect_address_p (addr, false))
13435 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
13439 if (TARGET_DEBUG_ADDR)
13441 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
13442 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13443 debug_rtx (and_op2);
13446 and_rtx = gen_rtx_SET (VOIDmode,
13448 gen_rtx_AND (Pmode,
13452 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
13453 emit_insn (gen_rtx_PARALLEL (VOIDmode,
13454 gen_rtvec (2, and_rtx, cc_clobber)));
13458 /* Adjust the address if it changed. */
13459 if (addr != XEXP (mem, 0))
13461 mem = change_address (mem, mode, addr);
13462 if (TARGET_DEBUG_ADDR)
13463 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
13466 /* Now create the move. */
13468 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
13470 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
13475 /* Target hook to return the cover classes for Integrated Register Allocator.
13476 Cover classes is a set of non-intersected register classes covering all hard
13477 registers used for register allocation purpose. Any move between two
13478 registers of a cover class should be cheaper than load or store of the
13479 registers. The value is array of register classes with LIM_REG_CLASSES used
13482 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
13483 account for the Altivec and Floating registers being subsets of the VSX
13484 register set under VSX, but distinct register sets on pre-VSX machines. */
13486 static const enum reg_class *
13487 rs6000_ira_cover_classes (void)
13489 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
13490 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
13492 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
13495 /* Allocate a 64-bit stack slot to be used for copying SDmode
13496 values through if this function has any SDmode references. */
13499 rs6000_alloc_sdmode_stack_slot (void)
13503 gimple_stmt_iterator gsi;
13505 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
13508 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
13510 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
13513 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13514 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13520 /* Check for any SDmode parameters of the function. */
13521 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
13523 if (TREE_TYPE (t) == error_mark_node)
13526 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
13527 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
13529 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
13530 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
13538 rs6000_instantiate_decls (void)
13540 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
13541 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
13544 /* Given an rtx X being reloaded into a reg required to be
13545 in class CLASS, return the class of reg to actually use.
13546 In general this is just CLASS; but on some machines
13547 in some cases it is preferable to use a more restrictive class.
13549 On the RS/6000, we have to return NO_REGS when we want to reload a
13550 floating-point CONST_DOUBLE to force it to be copied to memory.
13552 We also don't want to reload integer values into floating-point
13553 registers if we can at all help it. In fact, this can
13554 cause reload to die, if it tries to generate a reload of CTR
13555 into a FP register and discovers it doesn't have the memory location
13558 ??? Would it be a good idea to have reload do the converse, that is
13559 try to reload floating modes into FP registers if possible?
13562 static enum reg_class
13563 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
13565 enum machine_mode mode = GET_MODE (x);
13567 if (VECTOR_UNIT_VSX_P (mode)
13568 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
13571 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
13572 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
13573 && easy_vector_constant (x, mode))
13574 return ALTIVEC_REGS;
13576 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
13579 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
13580 return GENERAL_REGS;
13582 /* For VSX, prefer the traditional registers for DF if the address is of the
13583 form reg+offset because we can use the non-VSX loads. Prefer the Altivec
13584 registers if Altivec is handling the vector operations (i.e. V16QI, V8HI,
13586 if (rclass == VSX_REGS && VECTOR_MEM_VSX_P (mode))
13588 if (mode == DFmode && GET_CODE (x) == MEM)
13590 rtx addr = XEXP (x, 0);
13592 if (legitimate_indirect_address_p (addr, false)) /* reg */
13595 if (legitimate_indexed_address_p (addr, false)) /* reg+reg */
13598 if (GET_CODE (addr) == PRE_MODIFY
13599 && legitimate_indexed_address_p (XEXP (addr, 0), false))
13605 if (VECTOR_UNIT_ALTIVEC_P (mode))
13606 return ALTIVEC_REGS;
13614 /* Debug version of rs6000_preferred_reload_class. */
13615 static enum reg_class
13616 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
13618 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
13621 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
13623 reg_class_names[ret], reg_class_names[rclass],
13624 GET_MODE_NAME (GET_MODE (x)));
13630 /* If we are copying between FP or AltiVec registers and anything else, we need
13631 a memory location. The exception is when we are targeting ppc64 and the
13632 move to/from fpr to gpr instructions are available. Also, under VSX, you
13633 can copy vector registers from the FP register set to the Altivec register
13634 set and vice versa. */
13637 rs6000_secondary_memory_needed (enum reg_class class1,
13638 enum reg_class class2,
13639 enum machine_mode mode)
13641 if (class1 == class2)
13644 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
13645 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
13646 between these classes. But we need memory for other things that can go in
13647 FLOAT_REGS like SFmode. */
13649 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
13650 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
13651 || class1 == FLOAT_REGS))
13652 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
13653 && class2 != FLOAT_REGS);
13655 if (class1 == VSX_REGS || class2 == VSX_REGS)
13658 if (class1 == FLOAT_REGS
13659 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13660 || ((mode != DFmode)
13661 && (mode != DDmode)
13662 && (mode != DImode))))
13665 if (class2 == FLOAT_REGS
13666 && (!TARGET_MFPGPR || !TARGET_POWERPC64
13667 || ((mode != DFmode)
13668 && (mode != DDmode)
13669 && (mode != DImode))))
13672 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
13678 /* Debug version of rs6000_secondary_memory_needed. */
13680 rs6000_debug_secondary_memory_needed (enum reg_class class1,
13681 enum reg_class class2,
13682 enum machine_mode mode)
13684 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
13687 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
13688 "class2 = %s, mode = %s\n",
13689 ret ? "true" : "false", reg_class_names[class1],
13690 reg_class_names[class2], GET_MODE_NAME (mode));
13695 /* Return the register class of a scratch register needed to copy IN into
13696 or out of a register in RCLASS in MODE. If it can be done directly,
13697 NO_REGS is returned. */
13699 static enum reg_class
13700 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
13705 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
13707 && MACHOPIC_INDIRECT
13711 /* We cannot copy a symbolic operand directly into anything
13712 other than BASE_REGS for TARGET_ELF. So indicate that a
13713 register from BASE_REGS is needed as an intermediate
13716 On Darwin, pic addresses require a load from memory, which
13717 needs a base register. */
13718 if (rclass != BASE_REGS
13719 && (GET_CODE (in) == SYMBOL_REF
13720 || GET_CODE (in) == HIGH
13721 || GET_CODE (in) == LABEL_REF
13722 || GET_CODE (in) == CONST))
13726 if (GET_CODE (in) == REG)
13728 regno = REGNO (in);
13729 if (regno >= FIRST_PSEUDO_REGISTER)
13731 regno = true_regnum (in);
13732 if (regno >= FIRST_PSEUDO_REGISTER)
13736 else if (GET_CODE (in) == SUBREG)
13738 regno = true_regnum (in);
13739 if (regno >= FIRST_PSEUDO_REGISTER)
13745 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
13747 if (rclass == GENERAL_REGS || rclass == BASE_REGS
13748 || (regno >= 0 && INT_REGNO_P (regno)))
13751 /* Constants, memory, and FP registers can go into FP registers. */
13752 if ((regno == -1 || FP_REGNO_P (regno))
13753 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
13754 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
13756 /* Memory, and FP/altivec registers can go into fp/altivec registers under
13759 && (regno == -1 || VSX_REGNO_P (regno))
13760 && VSX_REG_CLASS_P (rclass))
13763 /* Memory, and AltiVec registers can go into AltiVec registers. */
13764 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
13765 && rclass == ALTIVEC_REGS)
13768 /* We can copy among the CR registers. */
13769 if ((rclass == CR_REGS || rclass == CR0_REGS)
13770 && regno >= 0 && CR_REGNO_P (regno))
13773 /* Otherwise, we need GENERAL_REGS. */
13774 return GENERAL_REGS;
13777 /* Debug version of rs6000_secondary_reload_class. */
13778 static enum reg_class
13779 rs6000_debug_secondary_reload_class (enum reg_class rclass,
13780 enum machine_mode mode, rtx in)
13782 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
13784 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
13785 "mode = %s, input rtx:\n",
13786 reg_class_names[ret], reg_class_names[rclass],
13787 GET_MODE_NAME (mode));
13793 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
13796 rs6000_cannot_change_mode_class (enum machine_mode from,
13797 enum machine_mode to,
13798 enum reg_class rclass)
13800 unsigned from_size = GET_MODE_SIZE (from);
13801 unsigned to_size = GET_MODE_SIZE (to);
13803 if (from_size != to_size)
13805 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
13806 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
13807 && reg_classes_intersect_p (xclass, rclass));
13810 if (TARGET_E500_DOUBLE
13811 && ((((to) == DFmode) + ((from) == DFmode)) == 1
13812 || (((to) == TFmode) + ((from) == TFmode)) == 1
13813 || (((to) == DDmode) + ((from) == DDmode)) == 1
13814 || (((to) == TDmode) + ((from) == TDmode)) == 1
13815 || (((to) == DImode) + ((from) == DImode)) == 1))
13818 /* Since the VSX register set includes traditional floating point registers
13819 and altivec registers, just check for the size being different instead of
13820 trying to check whether the modes are vector modes. Otherwise it won't
13821 allow say DF and DI to change classes. */
13822 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
13823 return (from_size != 8 && from_size != 16);
13825 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
13826 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
13829 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
13830 && reg_classes_intersect_p (GENERAL_REGS, rclass))
13836 /* Debug version of rs6000_cannot_change_mode_class. */
13838 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
13839 enum machine_mode to,
13840 enum reg_class rclass)
13842 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
13845 "rs6000_cannot_change_mode_class, return %s, from = %s, "
13846 "to = %s, rclass = %s\n",
13847 ret ? "true" : "false",
13848 GET_MODE_NAME (from), GET_MODE_NAME (to),
13849 reg_class_names[rclass]);
13854 /* Given a comparison operation, return the bit number in CCR to test. We
13855 know this is a valid comparison.
13857 SCC_P is 1 if this is for an scc. That means that %D will have been
13858 used instead of %C, so the bits will be in different places.
13860 Return -1 if OP isn't a valid comparison for some reason. */
13863 ccr_bit (rtx op, int scc_p)
13865 enum rtx_code code = GET_CODE (op);
13866 enum machine_mode cc_mode;
13871 if (!COMPARISON_P (op))
13874 reg = XEXP (op, 0);
13876 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
13878 cc_mode = GET_MODE (reg);
13879 cc_regnum = REGNO (reg);
13880 base_bit = 4 * (cc_regnum - CR0_REGNO);
13882 validate_condition_mode (code, cc_mode);
13884 /* When generating a sCOND operation, only positive conditions are
13887 || code == EQ || code == GT || code == LT || code == UNORDERED
13888 || code == GTU || code == LTU);
13893 return scc_p ? base_bit + 3 : base_bit + 2;
13895 return base_bit + 2;
13896 case GT: case GTU: case UNLE:
13897 return base_bit + 1;
13898 case LT: case LTU: case UNGE:
13900 case ORDERED: case UNORDERED:
13901 return base_bit + 3;
13904 /* If scc, we will have done a cror to put the bit in the
13905 unordered position. So test that bit. For integer, this is ! LT
13906 unless this is an scc insn. */
13907 return scc_p ? base_bit + 3 : base_bit;
13910 return scc_p ? base_bit + 3 : base_bit + 1;
13913 gcc_unreachable ();
13917 /* Return the GOT register. */
13920 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
13922 /* The second flow pass currently (June 1999) can't update
13923 regs_ever_live without disturbing other parts of the compiler, so
13924 update it here to make the prolog/epilogue code happy. */
13925 if (!can_create_pseudo_p ()
13926 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
13927 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
13929 crtl->uses_pic_offset_table = 1;
13931 return pic_offset_table_rtx;
13934 /* Function to init struct machine_function.
13935 This will be called, via a pointer variable,
13936 from push_function_context. */
13938 static struct machine_function *
13939 rs6000_init_machine_status (void)
13941 return GGC_CNEW (machine_function);
13944 /* These macros test for integers and extract the low-order bits. */
13946 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
13947 && GET_MODE (X) == VOIDmode)
13949 #define INT_LOWPART(X) \
13950 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
13953 extract_MB (rtx op)
13956 unsigned long val = INT_LOWPART (op);
13958 /* If the high bit is zero, the value is the first 1 bit we find
13960 if ((val & 0x80000000) == 0)
13962 gcc_assert (val & 0xffffffff);
13965 while (((val <<= 1) & 0x80000000) == 0)
13970 /* If the high bit is set and the low bit is not, or the mask is all
13971 1's, the value is zero. */
13972 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
13975 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
13978 while (((val >>= 1) & 1) != 0)
13985 extract_ME (rtx op)
13988 unsigned long val = INT_LOWPART (op);
13990 /* If the low bit is zero, the value is the first 1 bit we find from
13992 if ((val & 1) == 0)
13994 gcc_assert (val & 0xffffffff);
13997 while (((val >>= 1) & 1) == 0)
14003 /* If the low bit is set and the high bit is not, or the mask is all
14004 1's, the value is 31. */
14005 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14008 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14011 while (((val <<= 1) & 0x80000000) != 0)
14017 /* Locate some local-dynamic symbol still in use by this function
14018 so that we can print its name in some tls_ld pattern. */
14020 static const char *
14021 rs6000_get_some_local_dynamic_name (void)
14025 if (cfun->machine->some_ld_name)
14026 return cfun->machine->some_ld_name;
14028 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14030 && for_each_rtx (&PATTERN (insn),
14031 rs6000_get_some_local_dynamic_name_1, 0))
14032 return cfun->machine->some_ld_name;
14034 gcc_unreachable ();
14037 /* Helper function for rs6000_get_some_local_dynamic_name. */
14040 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14044 if (GET_CODE (x) == SYMBOL_REF)
14046 const char *str = XSTR (x, 0);
14047 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14049 cfun->machine->some_ld_name = str;
14057 /* Write out a function code label. */
14060 rs6000_output_function_entry (FILE *file, const char *fname)
14062 if (fname[0] != '.')
14064 switch (DEFAULT_ABI)
14067 gcc_unreachable ();
14073 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14082 RS6000_OUTPUT_BASENAME (file, fname);
14084 assemble_name (file, fname);
14087 /* Print an operand. Recognize special options, documented below. */
14090 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14091 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14093 #define SMALL_DATA_RELOC "sda21"
14094 #define SMALL_DATA_REG 0
14098 print_operand (FILE *file, rtx x, int code)
14102 unsigned HOST_WIDE_INT uval;
14107 /* Write out an instruction after the call which may be replaced
14108 with glue code by the loader. This depends on the AIX version. */
14109 asm_fprintf (file, RS6000_CALL_GLUE);
14112 /* %a is output_address. */
14115 /* If X is a constant integer whose low-order 5 bits are zero,
14116 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14117 in the AIX assembler where "sri" with a zero shift count
14118 writes a trash instruction. */
14119 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14126 /* If constant, low-order 16 bits of constant, unsigned.
14127 Otherwise, write normally. */
14129 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14131 print_operand (file, x, 0);
14135 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14136 for 64-bit mask direction. */
14137 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14140 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14144 /* X is a CR register. Print the number of the GT bit of the CR. */
14145 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14146 output_operand_lossage ("invalid %%c value");
14148 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14152 /* Like 'J' but get to the GT bit only. */
14153 gcc_assert (GET_CODE (x) == REG);
14155 /* Bit 1 is GT bit. */
14156 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14158 /* Add one for shift count in rlinm for scc. */
14159 fprintf (file, "%d", i + 1);
14163 /* X is a CR register. Print the number of the EQ bit of the CR */
14164 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14165 output_operand_lossage ("invalid %%E value");
14167 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14171 /* X is a CR register. Print the shift count needed to move it
14172 to the high-order four bits. */
14173 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14174 output_operand_lossage ("invalid %%f value");
14176 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14180 /* Similar, but print the count for the rotate in the opposite
14182 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14183 output_operand_lossage ("invalid %%F value");
14185 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14189 /* X is a constant integer. If it is negative, print "m",
14190 otherwise print "z". This is to make an aze or ame insn. */
14191 if (GET_CODE (x) != CONST_INT)
14192 output_operand_lossage ("invalid %%G value");
14193 else if (INTVAL (x) >= 0)
14200 /* If constant, output low-order five bits. Otherwise, write
14203 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14205 print_operand (file, x, 0);
14209 /* If constant, output low-order six bits. Otherwise, write
14212 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14214 print_operand (file, x, 0);
14218 /* Print `i' if this is a constant, else nothing. */
14224 /* Write the bit number in CCR for jump. */
14225 i = ccr_bit (x, 0);
14227 output_operand_lossage ("invalid %%j code");
14229 fprintf (file, "%d", i);
14233 /* Similar, but add one for shift count in rlinm for scc and pass
14234 scc flag to `ccr_bit'. */
14235 i = ccr_bit (x, 1);
14237 output_operand_lossage ("invalid %%J code");
14239 /* If we want bit 31, write a shift count of zero, not 32. */
14240 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14244 /* X must be a constant. Write the 1's complement of the
14247 output_operand_lossage ("invalid %%k value");
14249 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14253 /* X must be a symbolic constant on ELF. Write an
14254 expression suitable for an 'addi' that adds in the low 16
14255 bits of the MEM. */
14256 if (GET_CODE (x) != CONST)
14258 print_operand_address (file, x);
14259 fputs ("@l", file);
14263 if (GET_CODE (XEXP (x, 0)) != PLUS
14264 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14265 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14266 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14267 output_operand_lossage ("invalid %%K value");
14268 print_operand_address (file, XEXP (XEXP (x, 0), 0));
14269 fputs ("@l", file);
14270 /* For GNU as, there must be a non-alphanumeric character
14271 between 'l' and the number. The '-' is added by
14272 print_operand() already. */
14273 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
14275 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
14279 /* %l is output_asm_label. */
14282 /* Write second word of DImode or DFmode reference. Works on register
14283 or non-indexed memory only. */
14284 if (GET_CODE (x) == REG)
14285 fputs (reg_names[REGNO (x) + 1], file);
14286 else if (GET_CODE (x) == MEM)
14288 /* Handle possible auto-increment. Since it is pre-increment and
14289 we have already done it, we can just use an offset of word. */
14290 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14291 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14292 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14294 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14295 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14298 output_address (XEXP (adjust_address_nv (x, SImode,
14302 if (small_data_operand (x, GET_MODE (x)))
14303 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14304 reg_names[SMALL_DATA_REG]);
14309 /* MB value for a mask operand. */
14310 if (! mask_operand (x, SImode))
14311 output_operand_lossage ("invalid %%m value");
14313 fprintf (file, "%d", extract_MB (x));
14317 /* ME value for a mask operand. */
14318 if (! mask_operand (x, SImode))
14319 output_operand_lossage ("invalid %%M value");
14321 fprintf (file, "%d", extract_ME (x));
14324 /* %n outputs the negative of its operand. */
14327 /* Write the number of elements in the vector times 4. */
14328 if (GET_CODE (x) != PARALLEL)
14329 output_operand_lossage ("invalid %%N value");
14331 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14335 /* Similar, but subtract 1 first. */
14336 if (GET_CODE (x) != PARALLEL)
14337 output_operand_lossage ("invalid %%O value");
14339 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14343 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14345 || INT_LOWPART (x) < 0
14346 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14347 output_operand_lossage ("invalid %%p value");
14349 fprintf (file, "%d", i);
14353 /* The operand must be an indirect memory reference. The result
14354 is the register name. */
14355 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14356 || REGNO (XEXP (x, 0)) >= 32)
14357 output_operand_lossage ("invalid %%P value");
14359 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14363 /* This outputs the logical code corresponding to a boolean
14364 expression. The expression may have one or both operands
14365 negated (if one, only the first one). For condition register
14366 logical operations, it will also treat the negated
14367 CR codes as NOTs, but not handle NOTs of them. */
14369 const char *const *t = 0;
14371 enum rtx_code code = GET_CODE (x);
14372 static const char * const tbl[3][3] = {
14373 { "and", "andc", "nor" },
14374 { "or", "orc", "nand" },
14375 { "xor", "eqv", "xor" } };
14379 else if (code == IOR)
14381 else if (code == XOR)
14384 output_operand_lossage ("invalid %%q value");
14386 if (GET_CODE (XEXP (x, 0)) != NOT)
14390 if (GET_CODE (XEXP (x, 1)) == NOT)
14408 /* X is a CR register. Print the mask for `mtcrf'. */
14409 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14410 output_operand_lossage ("invalid %%R value");
14412 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
14416 /* Low 5 bits of 32 - value */
14418 output_operand_lossage ("invalid %%s value");
14420 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
14424 /* PowerPC64 mask position. All 0's is excluded.
14425 CONST_INT 32-bit mask is considered sign-extended so any
14426 transition must occur within the CONST_INT, not on the boundary. */
14427 if (! mask64_operand (x, DImode))
14428 output_operand_lossage ("invalid %%S value");
14430 uval = INT_LOWPART (x);
14432 if (uval & 1) /* Clear Left */
14434 #if HOST_BITS_PER_WIDE_INT > 64
14435 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14439 else /* Clear Right */
14442 #if HOST_BITS_PER_WIDE_INT > 64
14443 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14449 gcc_assert (i >= 0);
14450 fprintf (file, "%d", i);
14454 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
14455 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
14457 /* Bit 3 is OV bit. */
14458 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
14460 /* If we want bit 31, write a shift count of zero, not 32. */
14461 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14465 /* Print the symbolic name of a branch target register. */
14466 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
14467 && REGNO (x) != CTR_REGNO))
14468 output_operand_lossage ("invalid %%T value");
14469 else if (REGNO (x) == LR_REGNO)
14470 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
14472 fputs ("ctr", file);
14476 /* High-order 16 bits of constant for use in unsigned operand. */
14478 output_operand_lossage ("invalid %%u value");
14480 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14481 (INT_LOWPART (x) >> 16) & 0xffff);
14485 /* High-order 16 bits of constant for use in signed operand. */
14487 output_operand_lossage ("invalid %%v value");
14489 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
14490 (INT_LOWPART (x) >> 16) & 0xffff);
14494 /* Print `u' if this has an auto-increment or auto-decrement. */
14495 if (GET_CODE (x) == MEM
14496 && (GET_CODE (XEXP (x, 0)) == PRE_INC
14497 || GET_CODE (XEXP (x, 0)) == PRE_DEC
14498 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
14503 /* Print the trap code for this operand. */
14504 switch (GET_CODE (x))
14507 fputs ("eq", file); /* 4 */
14510 fputs ("ne", file); /* 24 */
14513 fputs ("lt", file); /* 16 */
14516 fputs ("le", file); /* 20 */
14519 fputs ("gt", file); /* 8 */
14522 fputs ("ge", file); /* 12 */
14525 fputs ("llt", file); /* 2 */
14528 fputs ("lle", file); /* 6 */
14531 fputs ("lgt", file); /* 1 */
14534 fputs ("lge", file); /* 5 */
14537 gcc_unreachable ();
14542 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
14545 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
14546 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
14548 print_operand (file, x, 0);
14552 /* MB value for a PowerPC64 rldic operand. */
14553 val = (GET_CODE (x) == CONST_INT
14554 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
14559 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
14560 if ((val <<= 1) < 0)
14563 #if HOST_BITS_PER_WIDE_INT == 32
14564 if (GET_CODE (x) == CONST_INT && i >= 0)
14565 i += 32; /* zero-extend high-part was all 0's */
14566 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
14568 val = CONST_DOUBLE_LOW (x);
14574 for ( ; i < 64; i++)
14575 if ((val <<= 1) < 0)
14580 fprintf (file, "%d", i + 1);
14584 /* X is a FPR or Altivec register used in a VSX context. */
14585 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
14586 output_operand_lossage ("invalid %%x value");
14589 int reg = REGNO (x);
14590 int vsx_reg = (FP_REGNO_P (reg)
14592 : reg - FIRST_ALTIVEC_REGNO + 32);
14594 #ifdef TARGET_REGNAMES
14595 if (TARGET_REGNAMES)
14596 fprintf (file, "%%vs%d", vsx_reg);
14599 fprintf (file, "%d", vsx_reg);
14604 if (GET_CODE (x) == MEM
14605 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
14606 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
14607 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
14612 /* Like 'L', for third word of TImode */
14613 if (GET_CODE (x) == REG)
14614 fputs (reg_names[REGNO (x) + 2], file);
14615 else if (GET_CODE (x) == MEM)
14617 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14618 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14619 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14620 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14621 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
14623 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
14624 if (small_data_operand (x, GET_MODE (x)))
14625 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14626 reg_names[SMALL_DATA_REG]);
14631 /* X is a SYMBOL_REF. Write out the name preceded by a
14632 period and without any trailing data in brackets. Used for function
14633 names. If we are configured for System V (or the embedded ABI) on
14634 the PowerPC, do not emit the period, since those systems do not use
14635 TOCs and the like. */
14636 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14638 /* Mark the decl as referenced so that cgraph will output the
14640 if (SYMBOL_REF_DECL (x))
14641 mark_decl_referenced (SYMBOL_REF_DECL (x));
14643 /* For macho, check to see if we need a stub. */
14646 const char *name = XSTR (x, 0);
14648 if (MACHOPIC_INDIRECT
14649 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
14650 name = machopic_indirection_name (x, /*stub_p=*/true);
14652 assemble_name (file, name);
14654 else if (!DOT_SYMBOLS)
14655 assemble_name (file, XSTR (x, 0));
14657 rs6000_output_function_entry (file, XSTR (x, 0));
14661 /* Like 'L', for last word of TImode. */
14662 if (GET_CODE (x) == REG)
14663 fputs (reg_names[REGNO (x) + 3], file);
14664 else if (GET_CODE (x) == MEM)
14666 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14667 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14668 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14669 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14670 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
14672 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
14673 if (small_data_operand (x, GET_MODE (x)))
14674 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14675 reg_names[SMALL_DATA_REG]);
14679 /* Print AltiVec or SPE memory operand. */
14684 gcc_assert (GET_CODE (x) == MEM);
14688 /* Ugly hack because %y is overloaded. */
14689 if ((TARGET_SPE || TARGET_E500_DOUBLE)
14690 && (GET_MODE_SIZE (GET_MODE (x)) == 8
14691 || GET_MODE (x) == TFmode
14692 || GET_MODE (x) == TImode))
14694 /* Handle [reg]. */
14695 if (GET_CODE (tmp) == REG)
14697 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
14700 /* Handle [reg+UIMM]. */
14701 else if (GET_CODE (tmp) == PLUS &&
14702 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
14706 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
14708 x = INTVAL (XEXP (tmp, 1));
14709 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
14713 /* Fall through. Must be [reg+reg]. */
14715 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
14716 && GET_CODE (tmp) == AND
14717 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
14718 && INTVAL (XEXP (tmp, 1)) == -16)
14719 tmp = XEXP (tmp, 0);
14720 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
14721 && GET_CODE (tmp) == PRE_MODIFY)
14722 tmp = XEXP (tmp, 1);
14723 if (GET_CODE (tmp) == REG)
14724 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
14727 if (!GET_CODE (tmp) == PLUS
14728 || !REG_P (XEXP (tmp, 0))
14729 || !REG_P (XEXP (tmp, 1)))
14731 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
14735 if (REGNO (XEXP (tmp, 0)) == 0)
14736 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
14737 reg_names[ REGNO (XEXP (tmp, 0)) ]);
14739 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
14740 reg_names[ REGNO (XEXP (tmp, 1)) ]);
14746 if (GET_CODE (x) == REG)
14747 fprintf (file, "%s", reg_names[REGNO (x)]);
14748 else if (GET_CODE (x) == MEM)
14750 /* We need to handle PRE_INC and PRE_DEC here, since we need to
14751 know the width from the mode. */
14752 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
14753 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
14754 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14755 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
14756 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
14757 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
14758 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14759 output_address (XEXP (XEXP (x, 0), 1));
14761 output_address (XEXP (x, 0));
14764 output_addr_const (file, x);
14768 assemble_name (file, rs6000_get_some_local_dynamic_name ());
14772 output_operand_lossage ("invalid %%xn code");
14776 /* Print the address of an operand. */
14779 print_operand_address (FILE *file, rtx x)
14781 if (GET_CODE (x) == REG)
14782 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
14783 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
14784 || GET_CODE (x) == LABEL_REF)
14786 output_addr_const (file, x);
14787 if (small_data_operand (x, GET_MODE (x)))
14788 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14789 reg_names[SMALL_DATA_REG]);
14791 gcc_assert (!TARGET_TOC);
14793 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
14795 gcc_assert (REG_P (XEXP (x, 0)));
14796 if (REGNO (XEXP (x, 0)) == 0)
14797 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
14798 reg_names[ REGNO (XEXP (x, 0)) ]);
14800 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
14801 reg_names[ REGNO (XEXP (x, 1)) ]);
14803 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
14804 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
14805 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
14807 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
14808 && CONSTANT_P (XEXP (x, 1)))
14810 output_addr_const (file, XEXP (x, 1));
14811 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
14815 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
14816 && CONSTANT_P (XEXP (x, 1)))
14818 fprintf (file, "lo16(");
14819 output_addr_const (file, XEXP (x, 1));
14820 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
14823 else if (legitimate_constant_pool_address_p (x))
14825 output_addr_const (file, XEXP (x, 1));
14826 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
14829 gcc_unreachable ();
14832 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
14835 rs6000_output_addr_const_extra (FILE *file, rtx x)
14837 if (GET_CODE (x) == UNSPEC)
14838 switch (XINT (x, 1))
14840 case UNSPEC_TOCREL:
14841 x = XVECEXP (x, 0, 0);
14842 gcc_assert (GET_CODE (x) == SYMBOL_REF);
14843 output_addr_const (file, x);
14844 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
14847 assemble_name (file, toc_label_name);
14849 else if (TARGET_ELF)
14850 fputs ("@toc", file);
14854 case UNSPEC_MACHOPIC_OFFSET:
14855 output_addr_const (file, XVECEXP (x, 0, 0));
14857 machopic_output_function_base_name (file);
14864 /* Target hook for assembling integer objects. The PowerPC version has
14865 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
14866 is defined. It also needs to handle DI-mode objects on 64-bit
14870 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
14872 #ifdef RELOCATABLE_NEEDS_FIXUP
14873 /* Special handling for SI values. */
14874 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
14876 static int recurse = 0;
14878 /* For -mrelocatable, we mark all addresses that need to be fixed up
14879 in the .fixup section. */
14880 if (TARGET_RELOCATABLE
14881 && in_section != toc_section
14882 && in_section != text_section
14883 && !unlikely_text_section_p (in_section)
14885 && GET_CODE (x) != CONST_INT
14886 && GET_CODE (x) != CONST_DOUBLE
14892 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
14894 ASM_OUTPUT_LABEL (asm_out_file, buf);
14895 fprintf (asm_out_file, "\t.long\t(");
14896 output_addr_const (asm_out_file, x);
14897 fprintf (asm_out_file, ")@fixup\n");
14898 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
14899 ASM_OUTPUT_ALIGN (asm_out_file, 2);
14900 fprintf (asm_out_file, "\t.long\t");
14901 assemble_name (asm_out_file, buf);
14902 fprintf (asm_out_file, "\n\t.previous\n");
14906 /* Remove initial .'s to turn a -mcall-aixdesc function
14907 address into the address of the descriptor, not the function
14909 else if (GET_CODE (x) == SYMBOL_REF
14910 && XSTR (x, 0)[0] == '.'
14911 && DEFAULT_ABI == ABI_AIX)
14913 const char *name = XSTR (x, 0);
14914 while (*name == '.')
14917 fprintf (asm_out_file, "\t.long\t%s\n", name);
14921 #endif /* RELOCATABLE_NEEDS_FIXUP */
14922 return default_assemble_integer (x, size, aligned_p);
14925 #ifdef HAVE_GAS_HIDDEN
14926 /* Emit an assembler directive to set symbol visibility for DECL to
14927 VISIBILITY_TYPE. */
14930 rs6000_assemble_visibility (tree decl, int vis)
14932 /* Functions need to have their entry point symbol visibility set as
14933 well as their descriptor symbol visibility. */
14934 if (DEFAULT_ABI == ABI_AIX
14936 && TREE_CODE (decl) == FUNCTION_DECL)
14938 static const char * const visibility_types[] = {
14939 NULL, "internal", "hidden", "protected"
14942 const char *name, *type;
14944 name = ((* targetm.strip_name_encoding)
14945 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
14946 type = visibility_types[vis];
14948 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
14949 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
14952 default_assemble_visibility (decl, vis);
14957 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
14959 /* Reversal of FP compares takes care -- an ordered compare
14960 becomes an unordered compare and vice versa. */
14961 if (mode == CCFPmode
14962 && (!flag_finite_math_only
14963 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
14964 || code == UNEQ || code == LTGT))
14965 return reverse_condition_maybe_unordered (code);
14967 return reverse_condition (code);
14970 /* Generate a compare for CODE. Return a brand-new rtx that
14971 represents the result of the compare. */
14974 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
14976 enum machine_mode comp_mode;
14977 rtx compare_result;
14978 enum rtx_code code = GET_CODE (cmp);
14979 rtx op0 = XEXP (cmp, 0);
14980 rtx op1 = XEXP (cmp, 1);
14982 if (FLOAT_MODE_P (mode))
14983 comp_mode = CCFPmode;
14984 else if (code == GTU || code == LTU
14985 || code == GEU || code == LEU)
14986 comp_mode = CCUNSmode;
14987 else if ((code == EQ || code == NE)
14988 && GET_CODE (op0) == SUBREG
14989 && GET_CODE (op1) == SUBREG
14990 && SUBREG_PROMOTED_UNSIGNED_P (op0)
14991 && SUBREG_PROMOTED_UNSIGNED_P (op1))
14992 /* These are unsigned values, perhaps there will be a later
14993 ordering compare that can be shared with this one.
14994 Unfortunately we cannot detect the signedness of the operands
14995 for non-subregs. */
14996 comp_mode = CCUNSmode;
14998 comp_mode = CCmode;
15000 /* First, the compare. */
15001 compare_result = gen_reg_rtx (comp_mode);
15003 /* E500 FP compare instructions on the GPRs. Yuck! */
15004 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15005 && FLOAT_MODE_P (mode))
15007 rtx cmp, or_result, compare_result2;
15008 enum machine_mode op_mode = GET_MODE (op0);
15010 if (op_mode == VOIDmode)
15011 op_mode = GET_MODE (op1);
15013 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15014 This explains the following mess. */
15018 case EQ: case UNEQ: case NE: case LTGT:
15022 cmp = (flag_finite_math_only && !flag_trapping_math)
15023 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15024 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15028 cmp = (flag_finite_math_only && !flag_trapping_math)
15029 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15030 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15034 cmp = (flag_finite_math_only && !flag_trapping_math)
15035 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15036 : gen_cmptfeq_gpr (compare_result, op0, op1);
15040 gcc_unreachable ();
15044 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15048 cmp = (flag_finite_math_only && !flag_trapping_math)
15049 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15050 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15054 cmp = (flag_finite_math_only && !flag_trapping_math)
15055 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15056 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15060 cmp = (flag_finite_math_only && !flag_trapping_math)
15061 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15062 : gen_cmptfgt_gpr (compare_result, op0, op1);
15066 gcc_unreachable ();
15070 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15074 cmp = (flag_finite_math_only && !flag_trapping_math)
15075 ? gen_tstsflt_gpr (compare_result, op0, op1)
15076 : gen_cmpsflt_gpr (compare_result, op0, op1);
15080 cmp = (flag_finite_math_only && !flag_trapping_math)
15081 ? gen_tstdflt_gpr (compare_result, op0, op1)
15082 : gen_cmpdflt_gpr (compare_result, op0, op1);
15086 cmp = (flag_finite_math_only && !flag_trapping_math)
15087 ? gen_tsttflt_gpr (compare_result, op0, op1)
15088 : gen_cmptflt_gpr (compare_result, op0, op1);
15092 gcc_unreachable ();
15096 gcc_unreachable ();
15099 /* Synthesize LE and GE from LT/GT || EQ. */
15100 if (code == LE || code == GE || code == LEU || code == GEU)
15106 case LE: code = LT; break;
15107 case GE: code = GT; break;
15108 case LEU: code = LT; break;
15109 case GEU: code = GT; break;
15110 default: gcc_unreachable ();
15113 compare_result2 = gen_reg_rtx (CCFPmode);
15119 cmp = (flag_finite_math_only && !flag_trapping_math)
15120 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15121 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15125 cmp = (flag_finite_math_only && !flag_trapping_math)
15126 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15127 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15131 cmp = (flag_finite_math_only && !flag_trapping_math)
15132 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15133 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15137 gcc_unreachable ();
15141 /* OR them together. */
15142 or_result = gen_reg_rtx (CCFPmode);
15143 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15145 compare_result = or_result;
15150 if (code == NE || code == LTGT)
15160 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15161 CLOBBERs to match cmptf_internal2 pattern. */
15162 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15163 && GET_MODE (op0) == TFmode
15164 && !TARGET_IEEEQUAD
15165 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15166 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15168 gen_rtx_SET (VOIDmode,
15170 gen_rtx_COMPARE (comp_mode, op0, op1)),
15171 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15172 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15173 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15174 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15175 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15176 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15177 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15178 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
15179 else if (GET_CODE (op1) == UNSPEC
15180 && XINT (op1, 1) == UNSPEC_SP_TEST)
15182 rtx op1b = XVECEXP (op1, 0, 0);
15183 comp_mode = CCEQmode;
15184 compare_result = gen_reg_rtx (CCEQmode);
15186 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15188 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15191 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15192 gen_rtx_COMPARE (comp_mode, op0, op1)));
15195 /* Some kinds of FP comparisons need an OR operation;
15196 under flag_finite_math_only we don't bother. */
15197 if (FLOAT_MODE_P (mode)
15198 && !flag_finite_math_only
15199 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15200 && (code == LE || code == GE
15201 || code == UNEQ || code == LTGT
15202 || code == UNGT || code == UNLT))
15204 enum rtx_code or1, or2;
15205 rtx or1_rtx, or2_rtx, compare2_rtx;
15206 rtx or_result = gen_reg_rtx (CCEQmode);
15210 case LE: or1 = LT; or2 = EQ; break;
15211 case GE: or1 = GT; or2 = EQ; break;
15212 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15213 case LTGT: or1 = LT; or2 = GT; break;
15214 case UNGT: or1 = UNORDERED; or2 = GT; break;
15215 case UNLT: or1 = UNORDERED; or2 = LT; break;
15216 default: gcc_unreachable ();
15218 validate_condition_mode (or1, comp_mode);
15219 validate_condition_mode (or2, comp_mode);
15220 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15221 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15222 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15223 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15225 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15227 compare_result = or_result;
15231 validate_condition_mode (code, GET_MODE (compare_result));
15233 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15237 /* Emit the RTL for an sCOND pattern. */
15240 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15243 enum machine_mode op_mode;
15244 enum rtx_code cond_code;
15245 rtx result = operands[0];
15247 condition_rtx = rs6000_generate_compare (operands[1], mode);
15248 cond_code = GET_CODE (condition_rtx);
15250 if (FLOAT_MODE_P (mode)
15251 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15255 PUT_MODE (condition_rtx, SImode);
15256 t = XEXP (condition_rtx, 0);
15258 gcc_assert (cond_code == NE || cond_code == EQ);
15260 if (cond_code == NE)
15261 emit_insn (gen_e500_flip_gt_bit (t, t));
15263 emit_insn (gen_move_from_CR_gt_bit (result, t));
15267 if (cond_code == NE
15268 || cond_code == GE || cond_code == LE
15269 || cond_code == GEU || cond_code == LEU
15270 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15272 rtx not_result = gen_reg_rtx (CCEQmode);
15273 rtx not_op, rev_cond_rtx;
15274 enum machine_mode cc_mode;
15276 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15278 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15279 SImode, XEXP (condition_rtx, 0), const0_rtx);
15280 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15281 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15282 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15285 op_mode = GET_MODE (XEXP (operands[1], 0));
15286 if (op_mode == VOIDmode)
15287 op_mode = GET_MODE (XEXP (operands[1], 1));
15289 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15291 PUT_MODE (condition_rtx, DImode);
15292 convert_move (result, condition_rtx, 0);
15296 PUT_MODE (condition_rtx, SImode);
15297 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15301 /* Emit a branch of kind CODE to location LOC. */
15304 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15306 rtx condition_rtx, loc_ref;
15308 condition_rtx = rs6000_generate_compare (operands[0], mode);
15309 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15310 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15311 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15312 loc_ref, pc_rtx)));
15315 /* Return the string to output a conditional branch to LABEL, which is
15316 the operand number of the label, or -1 if the branch is really a
15317 conditional return.
15319 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15320 condition code register and its mode specifies what kind of
15321 comparison we made.
15323 REVERSED is nonzero if we should reverse the sense of the comparison.
15325 INSN is the insn. */
15328 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
15330 static char string[64];
15331 enum rtx_code code = GET_CODE (op);
15332 rtx cc_reg = XEXP (op, 0);
15333 enum machine_mode mode = GET_MODE (cc_reg);
15334 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
15335 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
15336 int really_reversed = reversed ^ need_longbranch;
15342 validate_condition_mode (code, mode);
15344 /* Work out which way this really branches. We could use
15345 reverse_condition_maybe_unordered here always but this
15346 makes the resulting assembler clearer. */
15347 if (really_reversed)
15349 /* Reversal of FP compares takes care -- an ordered compare
15350 becomes an unordered compare and vice versa. */
15351 if (mode == CCFPmode)
15352 code = reverse_condition_maybe_unordered (code);
15354 code = reverse_condition (code);
15357 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
15359 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
15364 /* Opposite of GT. */
15373 gcc_unreachable ();
15379 /* Not all of these are actually distinct opcodes, but
15380 we distinguish them for clarity of the resulting assembler. */
15381 case NE: case LTGT:
15382 ccode = "ne"; break;
15383 case EQ: case UNEQ:
15384 ccode = "eq"; break;
15386 ccode = "ge"; break;
15387 case GT: case GTU: case UNGT:
15388 ccode = "gt"; break;
15390 ccode = "le"; break;
15391 case LT: case LTU: case UNLT:
15392 ccode = "lt"; break;
15393 case UNORDERED: ccode = "un"; break;
15394 case ORDERED: ccode = "nu"; break;
15395 case UNGE: ccode = "nl"; break;
15396 case UNLE: ccode = "ng"; break;
15398 gcc_unreachable ();
15401 /* Maybe we have a guess as to how likely the branch is.
15402 The old mnemonics don't have a way to specify this information. */
15404 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
15405 if (note != NULL_RTX)
15407 /* PROB is the difference from 50%. */
15408 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
15410 /* Only hint for highly probable/improbable branches on newer
15411 cpus as static prediction overrides processor dynamic
15412 prediction. For older cpus we may as well always hint, but
15413 assume not taken for branches that are very close to 50% as a
15414 mispredicted taken branch is more expensive than a
15415 mispredicted not-taken branch. */
15416 if (rs6000_always_hint
15417 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
15418 && br_prob_note_reliable_p (note)))
15420 if (abs (prob) > REG_BR_PROB_BASE / 20
15421 && ((prob > 0) ^ need_longbranch))
15429 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
15431 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
15433 /* We need to escape any '%' characters in the reg_names string.
15434 Assume they'd only be the first character.... */
15435 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
15437 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
15441 /* If the branch distance was too far, we may have to use an
15442 unconditional branch to go the distance. */
15443 if (need_longbranch)
15444 s += sprintf (s, ",$+8\n\tb %s", label);
15446 s += sprintf (s, ",%s", label);
15452 /* Return the string to flip the GT bit on a CR. */
15454 output_e500_flip_gt_bit (rtx dst, rtx src)
15456 static char string[64];
15459 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
15460 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
15463 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
15464 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
15466 sprintf (string, "crnot %d,%d", a, b);
15470 /* Return insn for VSX or Altivec comparisons. */
15473 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
15476 enum machine_mode mode = GET_MODE (op0);
15484 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
15490 mask = gen_reg_rtx (mode);
15491 emit_insn (gen_rtx_SET (VOIDmode,
15493 gen_rtx_fmt_ee (code, mode, op0, op1)));
15500 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
15501 DMODE is expected destination mode. This is a recursive function. */
15504 rs6000_emit_vector_compare (enum rtx_code rcode,
15506 enum machine_mode dmode)
15509 bool swap_operands = false;
15510 bool try_again = false;
15512 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
15513 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
15515 /* See if the comparison works as is. */
15516 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15524 swap_operands = true;
15529 swap_operands = true;
15537 /* Invert condition and try again.
15538 e.g., A != B becomes ~(A==B). */
15540 enum rtx_code rev_code;
15541 enum insn_code nor_code;
15544 rev_code = reverse_condition_maybe_unordered (rcode);
15545 if (rev_code == UNKNOWN)
15548 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
15549 if (nor_code == CODE_FOR_nothing)
15552 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
15556 mask = gen_reg_rtx (dmode);
15557 emit_insn (GEN_FCN (nor_code) (mask, mask2));
15565 /* Try GT/GTU/LT/LTU OR EQ */
15568 enum insn_code ior_code;
15569 enum rtx_code new_code;
15590 gcc_unreachable ();
15593 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
15594 if (ior_code == CODE_FOR_nothing)
15597 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
15601 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
15605 mask = gen_reg_rtx (dmode);
15606 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
15624 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
15629 /* You only get two chances. */
15633 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
15634 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
15635 operands for the relation operation COND. */
15638 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
15639 rtx cond, rtx cc_op0, rtx cc_op1)
15641 enum machine_mode dest_mode = GET_MODE (dest);
15642 enum rtx_code rcode = GET_CODE (cond);
15643 enum machine_mode cc_mode = CCmode;
15647 bool invert_move = false;
15649 if (VECTOR_UNIT_NONE_P (dest_mode))
15654 /* Swap operands if we can, and fall back to doing the operation as
15655 specified, and doing a NOR to invert the test. */
15661 /* Invert condition and try again.
15662 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
15663 invert_move = true;
15664 rcode = reverse_condition_maybe_unordered (rcode);
15665 if (rcode == UNKNOWN)
15669 /* Mark unsigned tests with CCUNSmode. */
15674 cc_mode = CCUNSmode;
15681 /* Get the vector mask for the given relational operations. */
15682 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
15690 op_true = op_false;
15694 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
15695 emit_insn (gen_rtx_SET (VOIDmode,
15697 gen_rtx_IF_THEN_ELSE (dest_mode,
15704 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
15705 operands of the last comparison is nonzero/true, FALSE_COND if it
15706 is zero/false. Return 0 if the hardware has no such operation. */
15709 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15711 enum rtx_code code = GET_CODE (op);
15712 rtx op0 = XEXP (op, 0);
15713 rtx op1 = XEXP (op, 1);
15714 REAL_VALUE_TYPE c1;
15715 enum machine_mode compare_mode = GET_MODE (op0);
15716 enum machine_mode result_mode = GET_MODE (dest);
15718 bool is_against_zero;
15720 /* These modes should always match. */
15721 if (GET_MODE (op1) != compare_mode
15722 /* In the isel case however, we can use a compare immediate, so
15723 op1 may be a small constant. */
15724 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
15726 if (GET_MODE (true_cond) != result_mode)
15728 if (GET_MODE (false_cond) != result_mode)
15731 /* First, work out if the hardware can do this at all, or
15732 if it's too slow.... */
15733 if (!FLOAT_MODE_P (compare_mode))
15736 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
15739 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
15740 && SCALAR_FLOAT_MODE_P (compare_mode))
15743 is_against_zero = op1 == CONST0_RTX (compare_mode);
15745 /* A floating-point subtract might overflow, underflow, or produce
15746 an inexact result, thus changing the floating-point flags, so it
15747 can't be generated if we care about that. It's safe if one side
15748 of the construct is zero, since then no subtract will be
15750 if (SCALAR_FLOAT_MODE_P (compare_mode)
15751 && flag_trapping_math && ! is_against_zero)
15754 /* Eliminate half of the comparisons by switching operands, this
15755 makes the remaining code simpler. */
15756 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
15757 || code == LTGT || code == LT || code == UNLE)
15759 code = reverse_condition_maybe_unordered (code);
15761 true_cond = false_cond;
15765 /* UNEQ and LTGT take four instructions for a comparison with zero,
15766 it'll probably be faster to use a branch here too. */
15767 if (code == UNEQ && HONOR_NANS (compare_mode))
15770 if (GET_CODE (op1) == CONST_DOUBLE)
15771 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
15773 /* We're going to try to implement comparisons by performing
15774 a subtract, then comparing against zero. Unfortunately,
15775 Inf - Inf is NaN which is not zero, and so if we don't
15776 know that the operand is finite and the comparison
15777 would treat EQ different to UNORDERED, we can't do it. */
15778 if (HONOR_INFINITIES (compare_mode)
15779 && code != GT && code != UNGE
15780 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
15781 /* Constructs of the form (a OP b ? a : b) are safe. */
15782 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
15783 || (! rtx_equal_p (op0, true_cond)
15784 && ! rtx_equal_p (op1, true_cond))))
15787 /* At this point we know we can use fsel. */
15789 /* Reduce the comparison to a comparison against zero. */
15790 if (! is_against_zero)
15792 temp = gen_reg_rtx (compare_mode);
15793 emit_insn (gen_rtx_SET (VOIDmode, temp,
15794 gen_rtx_MINUS (compare_mode, op0, op1)));
15796 op1 = CONST0_RTX (compare_mode);
15799 /* If we don't care about NaNs we can reduce some of the comparisons
15800 down to faster ones. */
15801 if (! HONOR_NANS (compare_mode))
15807 true_cond = false_cond;
15820 /* Now, reduce everything down to a GE. */
15827 temp = gen_reg_rtx (compare_mode);
15828 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15833 temp = gen_reg_rtx (compare_mode);
15834 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
15839 temp = gen_reg_rtx (compare_mode);
15840 emit_insn (gen_rtx_SET (VOIDmode, temp,
15841 gen_rtx_NEG (compare_mode,
15842 gen_rtx_ABS (compare_mode, op0))));
15847 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
15848 temp = gen_reg_rtx (result_mode);
15849 emit_insn (gen_rtx_SET (VOIDmode, temp,
15850 gen_rtx_IF_THEN_ELSE (result_mode,
15851 gen_rtx_GE (VOIDmode,
15853 true_cond, false_cond)));
15854 false_cond = true_cond;
15857 temp = gen_reg_rtx (compare_mode);
15858 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15863 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
15864 temp = gen_reg_rtx (result_mode);
15865 emit_insn (gen_rtx_SET (VOIDmode, temp,
15866 gen_rtx_IF_THEN_ELSE (result_mode,
15867 gen_rtx_GE (VOIDmode,
15869 true_cond, false_cond)));
15870 true_cond = false_cond;
15873 temp = gen_reg_rtx (compare_mode);
15874 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
15879 gcc_unreachable ();
15882 emit_insn (gen_rtx_SET (VOIDmode, dest,
15883 gen_rtx_IF_THEN_ELSE (result_mode,
15884 gen_rtx_GE (VOIDmode,
15886 true_cond, false_cond)));
15890 /* Same as above, but for ints (isel). */
15893 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
15895 rtx condition_rtx, cr;
15896 enum machine_mode mode = GET_MODE (XEXP (op, 0));
15898 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
15901 /* We still have to do the compare, because isel doesn't do a
15902 compare, it just looks at the CRx bits set by a previous compare
15904 condition_rtx = rs6000_generate_compare (op, SImode);
15905 cr = XEXP (condition_rtx, 0);
15907 if (mode == SImode)
15909 if (GET_MODE (cr) == CCmode)
15910 emit_insn (gen_isel_signed_si (dest, condition_rtx,
15911 true_cond, false_cond, cr));
15913 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
15914 true_cond, false_cond, cr));
15918 if (GET_MODE (cr) == CCmode)
15919 emit_insn (gen_isel_signed_di (dest, condition_rtx,
15920 true_cond, false_cond, cr));
15922 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
15923 true_cond, false_cond, cr));
15930 output_isel (rtx *operands)
15932 enum rtx_code code;
15934 code = GET_CODE (operands[1]);
15935 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
15937 PUT_CODE (operands[1], reverse_condition (code));
15938 return "isel %0,%3,%2,%j1";
15941 return "isel %0,%2,%3,%j1";
15945 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
15947 enum machine_mode mode = GET_MODE (op0);
15951 /* VSX/altivec have direct min/max insns. */
15952 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
15954 emit_insn (gen_rtx_SET (VOIDmode,
15956 gen_rtx_fmt_ee (code, mode, op0, op1)));
15960 if (code == SMAX || code == SMIN)
15965 if (code == SMAX || code == UMAX)
15966 target = emit_conditional_move (dest, c, op0, op1, mode,
15967 op0, op1, mode, 0);
15969 target = emit_conditional_move (dest, c, op0, op1, mode,
15970 op1, op0, mode, 0);
15971 gcc_assert (target);
15972 if (target != dest)
15973 emit_move_insn (dest, target);
15976 /* Emit instructions to perform a load-reserved/store-conditional operation.
15977 The operation performed is an atomic
15978 (set M (CODE:MODE M OP))
15979 If not NULL, BEFORE is atomically set to M before the operation, and
15980 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
15981 If SYNC_P then a memory barrier is emitted before the operation.
15982 Either OP or M may be wrapped in a NOT operation. */
15985 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
15986 rtx m, rtx op, rtx before_param, rtx after_param,
15989 enum machine_mode used_mode;
15990 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
15993 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
15994 rtx shift = NULL_RTX;
15997 emit_insn (gen_lwsync ());
16001 /* If this is smaller than SImode, we'll have to use SImode with
16003 if (mode == QImode || mode == HImode)
16007 if (MEM_ALIGN (used_m) >= 32)
16010 if (BYTES_BIG_ENDIAN)
16011 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16013 shift = GEN_INT (ishift);
16014 used_m = change_address (used_m, SImode, 0);
16018 rtx addrSI, aligned_addr;
16019 int shift_mask = mode == QImode ? 0x18 : 0x10;
16021 addrSI = gen_lowpart_common (SImode,
16022 force_reg (Pmode, XEXP (used_m, 0)));
16023 addrSI = force_reg (SImode, addrSI);
16024 shift = gen_reg_rtx (SImode);
16026 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16027 GEN_INT (shift_mask)));
16028 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16030 aligned_addr = expand_binop (Pmode, and_optab,
16032 GEN_INT (-4), NULL_RTX,
16033 1, OPTAB_LIB_WIDEN);
16034 used_m = change_address (used_m, SImode, aligned_addr);
16035 set_mem_align (used_m, 32);
16037 /* It's safe to keep the old alias set of USED_M, because
16038 the operation is atomic and only affects the original
16042 if (GET_CODE (op) == NOT)
16044 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16045 oldop = gen_rtx_NOT (SImode, oldop);
16048 oldop = lowpart_subreg (SImode, op, mode);
16054 newop = expand_binop (SImode, and_optab,
16055 oldop, GEN_INT (imask), NULL_RTX,
16056 1, OPTAB_LIB_WIDEN);
16057 emit_insn (gen_ashlsi3 (newop, newop, shift));
16060 case NOT: /* NAND */
16061 newop = expand_binop (SImode, ior_optab,
16062 oldop, GEN_INT (~imask), NULL_RTX,
16063 1, OPTAB_LIB_WIDEN);
16064 emit_insn (gen_rotlsi3 (newop, newop, shift));
16068 newop = expand_binop (SImode, ior_optab,
16069 oldop, GEN_INT (~imask), NULL_RTX,
16070 1, OPTAB_LIB_WIDEN);
16071 emit_insn (gen_rotlsi3 (newop, newop, shift));
16079 newop = expand_binop (SImode, and_optab,
16080 oldop, GEN_INT (imask), NULL_RTX,
16081 1, OPTAB_LIB_WIDEN);
16082 emit_insn (gen_ashlsi3 (newop, newop, shift));
16084 mask = gen_reg_rtx (SImode);
16085 emit_move_insn (mask, GEN_INT (imask));
16086 emit_insn (gen_ashlsi3 (mask, mask, shift));
16089 newop = gen_rtx_PLUS (SImode, m, newop);
16091 newop = gen_rtx_MINUS (SImode, m, newop);
16092 newop = gen_rtx_AND (SImode, newop, mask);
16093 newop = gen_rtx_IOR (SImode, newop,
16094 gen_rtx_AND (SImode,
16095 gen_rtx_NOT (SImode, mask),
16101 gcc_unreachable ();
16105 used_mode = SImode;
16106 before = gen_reg_rtx (used_mode);
16107 after = gen_reg_rtx (used_mode);
16112 before = before_param;
16113 after = after_param;
16115 if (before == NULL_RTX)
16116 before = gen_reg_rtx (used_mode);
16117 if (after == NULL_RTX)
16118 after = gen_reg_rtx (used_mode);
16121 if ((code == PLUS || code == MINUS)
16122 && used_mode != mode)
16123 the_op = op; /* Computed above. */
16124 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16125 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16126 else if (code == NOT)
16127 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16128 gen_rtx_NOT (used_mode, m),
16129 gen_rtx_NOT (used_mode, op));
16131 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16133 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16134 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16135 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16136 gen_rtx_UNSPEC (used_mode,
16137 gen_rtvec (1, the_op),
16139 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16141 if ((code == PLUS || code == MINUS) && used_mode != mode)
16142 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16143 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16145 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16146 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16148 /* Shift and mask the return values properly. */
16149 if (used_mode != mode && before_param)
16151 emit_insn (gen_lshrsi3 (before, before, shift));
16152 convert_move (before_param, before, 1);
16155 if (used_mode != mode && after_param)
16157 emit_insn (gen_lshrsi3 (after, after, shift));
16158 convert_move (after_param, after, 1);
16161 /* The previous sequence will end with a branch that's dependent on
16162 the conditional store, so placing an isync will ensure that no
16163 other instructions (especially, no load or store instructions)
16164 can start before the atomic operation completes. */
16166 emit_insn (gen_isync ());
16169 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16170 COND is true. Mark the jump as unlikely to be taken. */
16173 emit_unlikely_jump (rtx cond, rtx label)
16175 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16178 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16179 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16180 add_reg_note (x, REG_BR_PROB, very_unlikely);
16183 /* A subroutine of the atomic operation splitters. Emit a load-locked
16184 instruction in MODE. */
16187 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16189 rtx (*fn) (rtx, rtx) = NULL;
16190 if (mode == SImode)
16191 fn = gen_load_locked_si;
16192 else if (mode == DImode)
16193 fn = gen_load_locked_di;
16194 emit_insn (fn (reg, mem));
16197 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16198 instruction in MODE. */
16201 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16203 rtx (*fn) (rtx, rtx, rtx) = NULL;
16204 if (mode == SImode)
16205 fn = gen_store_conditional_si;
16206 else if (mode == DImode)
16207 fn = gen_store_conditional_di;
16209 /* Emit sync before stwcx. to address PPC405 Erratum. */
16210 if (PPC405_ERRATUM77)
16211 emit_insn (gen_memory_barrier ());
16213 emit_insn (fn (res, mem, val));
16216 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16217 to perform. MEM is the memory on which to operate. VAL is the second
16218 operand of the binary operator. BEFORE and AFTER are optional locations to
16219 return the value of MEM either before of after the operation. SCRATCH is
16220 a scratch register. */
16223 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16224 rtx before, rtx after, rtx scratch)
16226 enum machine_mode mode = GET_MODE (mem);
16227 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16229 emit_insn (gen_lwsync ());
16231 label = gen_label_rtx ();
16232 emit_label (label);
16233 label = gen_rtx_LABEL_REF (VOIDmode, label);
16235 if (before == NULL_RTX)
16237 emit_load_locked (mode, before, mem);
16240 x = gen_rtx_IOR (mode,
16241 gen_rtx_NOT (mode, before),
16242 gen_rtx_NOT (mode, val));
16243 else if (code == AND)
16244 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16246 x = gen_rtx_fmt_ee (code, mode, before, val);
16248 if (after != NULL_RTX)
16249 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16250 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16252 emit_store_conditional (mode, cond, mem, scratch);
16254 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16255 emit_unlikely_jump (x, label);
16257 emit_insn (gen_isync ());
16260 /* Expand an atomic compare and swap operation. MEM is the memory on which
16261 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16262 value to be stored. SCRATCH is a scratch GPR. */
16265 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16268 enum machine_mode mode = GET_MODE (mem);
16269 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16271 emit_insn (gen_lwsync ());
16273 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16274 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16275 emit_label (XEXP (label1, 0));
16277 emit_load_locked (mode, retval, mem);
16279 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16280 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16282 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16283 emit_unlikely_jump (x, label2);
16285 emit_move_insn (scratch, newval);
16286 emit_store_conditional (mode, cond, mem, scratch);
16288 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16289 emit_unlikely_jump (x, label1);
16291 emit_insn (gen_isync ());
16292 emit_label (XEXP (label2, 0));
16295 /* Expand an atomic test and set operation. MEM is the memory on which
16296 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16299 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16301 enum machine_mode mode = GET_MODE (mem);
16302 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16304 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16305 emit_label (XEXP (label, 0));
16307 emit_load_locked (mode, retval, mem);
16308 emit_move_insn (scratch, val);
16309 emit_store_conditional (mode, cond, mem, scratch);
16311 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16312 emit_unlikely_jump (x, label);
16314 emit_insn (gen_isync ());
16318 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
16320 enum machine_mode mode = GET_MODE (mem);
16321 rtx addrSI, align, wdst, shift, mask;
16322 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
16323 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16325 /* Shift amount for subword relative to aligned word. */
16326 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
16327 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
16328 shift = gen_reg_rtx (SImode);
16329 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16330 GEN_INT (shift_mask)));
16331 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16333 /* Shift and mask old value into position within word. */
16334 oldval = convert_modes (SImode, mode, oldval, 1);
16335 oldval = expand_binop (SImode, and_optab,
16336 oldval, GEN_INT (imask), NULL_RTX,
16337 1, OPTAB_LIB_WIDEN);
16338 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
16340 /* Shift and mask new value into position within word. */
16341 newval = convert_modes (SImode, mode, newval, 1);
16342 newval = expand_binop (SImode, and_optab,
16343 newval, GEN_INT (imask), NULL_RTX,
16344 1, OPTAB_LIB_WIDEN);
16345 emit_insn (gen_ashlsi3 (newval, newval, shift));
16347 /* Mask for insertion. */
16348 mask = gen_reg_rtx (SImode);
16349 emit_move_insn (mask, GEN_INT (imask));
16350 emit_insn (gen_ashlsi3 (mask, mask, shift));
16352 /* Address of aligned word containing subword. */
16353 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
16354 NULL_RTX, 1, OPTAB_LIB_WIDEN);
16355 mem = change_address (mem, SImode, align);
16356 set_mem_align (mem, 32);
16357 MEM_VOLATILE_P (mem) = 1;
16359 wdst = gen_reg_rtx (SImode);
16360 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
16361 oldval, newval, mem));
16363 /* Shift the result back. */
16364 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
16366 emit_move_insn (dst, gen_lowpart (mode, wdst));
16370 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
16371 rtx oldval, rtx newval, rtx mem,
16374 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16376 emit_insn (gen_lwsync ());
16377 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16378 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16379 emit_label (XEXP (label1, 0));
16381 emit_load_locked (SImode, scratch, mem);
16383 /* Mask subword within loaded value for comparison with oldval.
16384 Use UNSPEC_AND to avoid clobber.*/
16385 emit_insn (gen_rtx_SET (SImode, dest,
16386 gen_rtx_UNSPEC (SImode,
16387 gen_rtvec (2, scratch, mask),
16390 x = gen_rtx_COMPARE (CCmode, dest, oldval);
16391 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16393 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16394 emit_unlikely_jump (x, label2);
16396 /* Clear subword within loaded value for insertion of new value. */
16397 emit_insn (gen_rtx_SET (SImode, scratch,
16398 gen_rtx_AND (SImode,
16399 gen_rtx_NOT (SImode, mask), scratch)));
16400 emit_insn (gen_iorsi3 (scratch, scratch, newval));
16401 emit_store_conditional (SImode, cond, mem, scratch);
16403 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16404 emit_unlikely_jump (x, label1);
16406 emit_insn (gen_isync ());
16407 emit_label (XEXP (label2, 0));
16411 /* Emit instructions to move SRC to DST. Called by splitters for
16412 multi-register moves. It will emit at most one instruction for
16413 each register that is accessed; that is, it won't emit li/lis pairs
16414 (or equivalent for 64-bit code). One of SRC or DST must be a hard
16418 rs6000_split_multireg_move (rtx dst, rtx src)
16420 /* The register number of the first register being moved. */
16422 /* The mode that is to be moved. */
16423 enum machine_mode mode;
16424 /* The mode that the move is being done in, and its size. */
16425 enum machine_mode reg_mode;
16427 /* The number of registers that will be moved. */
16430 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
16431 mode = GET_MODE (dst);
16432 nregs = hard_regno_nregs[reg][mode];
16433 if (FP_REGNO_P (reg))
16434 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
16435 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
16436 else if (ALTIVEC_REGNO_P (reg))
16437 reg_mode = V16QImode;
16438 else if (TARGET_E500_DOUBLE && mode == TFmode)
16441 reg_mode = word_mode;
16442 reg_mode_size = GET_MODE_SIZE (reg_mode);
16444 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
16446 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
16448 /* Move register range backwards, if we might have destructive
16451 for (i = nregs - 1; i >= 0; i--)
16452 emit_insn (gen_rtx_SET (VOIDmode,
16453 simplify_gen_subreg (reg_mode, dst, mode,
16454 i * reg_mode_size),
16455 simplify_gen_subreg (reg_mode, src, mode,
16456 i * reg_mode_size)));
16462 bool used_update = false;
16464 if (MEM_P (src) && INT_REGNO_P (reg))
16468 if (GET_CODE (XEXP (src, 0)) == PRE_INC
16469 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
16472 breg = XEXP (XEXP (src, 0), 0);
16473 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
16474 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
16475 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
16476 emit_insn (TARGET_32BIT
16477 ? gen_addsi3 (breg, breg, delta_rtx)
16478 : gen_adddi3 (breg, breg, delta_rtx));
16479 src = replace_equiv_address (src, breg);
16481 else if (! rs6000_offsettable_memref_p (src))
16484 basereg = gen_rtx_REG (Pmode, reg);
16485 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
16486 src = replace_equiv_address (src, basereg);
16489 breg = XEXP (src, 0);
16490 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
16491 breg = XEXP (breg, 0);
16493 /* If the base register we are using to address memory is
16494 also a destination reg, then change that register last. */
16496 && REGNO (breg) >= REGNO (dst)
16497 && REGNO (breg) < REGNO (dst) + nregs)
16498 j = REGNO (breg) - REGNO (dst);
16501 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
16505 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
16506 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
16509 breg = XEXP (XEXP (dst, 0), 0);
16510 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
16511 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
16512 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
16514 /* We have to update the breg before doing the store.
16515 Use store with update, if available. */
16519 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
16520 emit_insn (TARGET_32BIT
16521 ? (TARGET_POWERPC64
16522 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
16523 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
16524 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
16525 used_update = true;
16528 emit_insn (TARGET_32BIT
16529 ? gen_addsi3 (breg, breg, delta_rtx)
16530 : gen_adddi3 (breg, breg, delta_rtx));
16531 dst = replace_equiv_address (dst, breg);
16534 gcc_assert (rs6000_offsettable_memref_p (dst));
16537 for (i = 0; i < nregs; i++)
16539 /* Calculate index to next subword. */
16544 /* If compiler already emitted move of first word by
16545 store with update, no need to do anything. */
16546 if (j == 0 && used_update)
16549 emit_insn (gen_rtx_SET (VOIDmode,
16550 simplify_gen_subreg (reg_mode, dst, mode,
16551 j * reg_mode_size),
16552 simplify_gen_subreg (reg_mode, src, mode,
16553 j * reg_mode_size)));
16559 /* This page contains routines that are used to determine what the
16560 function prologue and epilogue code will do and write them out. */
16562 /* Return the first fixed-point register that is required to be
16563 saved. 32 if none. */
16566 first_reg_to_save (void)
16570 /* Find lowest numbered live register. */
16571 for (first_reg = 13; first_reg <= 31; first_reg++)
16572 if (df_regs_ever_live_p (first_reg)
16573 && (! call_used_regs[first_reg]
16574 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
16575 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
16576 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
16577 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
16582 && crtl->uses_pic_offset_table
16583 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
16584 return RS6000_PIC_OFFSET_TABLE_REGNUM;
16590 /* Similar, for FP regs. */
16593 first_fp_reg_to_save (void)
16597 /* Find lowest numbered live register. */
16598 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
16599 if (df_regs_ever_live_p (first_reg))
16605 /* Similar, for AltiVec regs. */
16608 first_altivec_reg_to_save (void)
16612 /* Stack frame remains as is unless we are in AltiVec ABI. */
16613 if (! TARGET_ALTIVEC_ABI)
16614 return LAST_ALTIVEC_REGNO + 1;
16616 /* On Darwin, the unwind routines are compiled without
16617 TARGET_ALTIVEC, and use save_world to save/restore the
16618 altivec registers when necessary. */
16619 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16620 && ! TARGET_ALTIVEC)
16621 return FIRST_ALTIVEC_REGNO + 20;
16623 /* Find lowest numbered live register. */
16624 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
16625 if (df_regs_ever_live_p (i))
16631 /* Return a 32-bit mask of the AltiVec registers we need to set in
16632 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
16633 the 32-bit word is 0. */
16635 static unsigned int
16636 compute_vrsave_mask (void)
16638 unsigned int i, mask = 0;
16640 /* On Darwin, the unwind routines are compiled without
16641 TARGET_ALTIVEC, and use save_world to save/restore the
16642 call-saved altivec registers when necessary. */
16643 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
16644 && ! TARGET_ALTIVEC)
16647 /* First, find out if we use _any_ altivec registers. */
16648 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
16649 if (df_regs_ever_live_p (i))
16650 mask |= ALTIVEC_REG_BIT (i);
16655 /* Next, remove the argument registers from the set. These must
16656 be in the VRSAVE mask set by the caller, so we don't need to add
16657 them in again. More importantly, the mask we compute here is
16658 used to generate CLOBBERs in the set_vrsave insn, and we do not
16659 wish the argument registers to die. */
16660 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
16661 mask &= ~ALTIVEC_REG_BIT (i);
16663 /* Similarly, remove the return value from the set. */
16666 diddle_return_value (is_altivec_return_reg, &yes);
16668 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
16674 /* For a very restricted set of circumstances, we can cut down the
16675 size of prologues/epilogues by calling our own save/restore-the-world
16679 compute_save_world_info (rs6000_stack_t *info_ptr)
16681 info_ptr->world_save_p = 1;
16682 info_ptr->world_save_p
16683 = (WORLD_SAVE_P (info_ptr)
16684 && DEFAULT_ABI == ABI_DARWIN
16685 && ! (cfun->calls_setjmp && flag_exceptions)
16686 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
16687 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
16688 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
16689 && info_ptr->cr_save_p);
16691 /* This will not work in conjunction with sibcalls. Make sure there
16692 are none. (This check is expensive, but seldom executed.) */
16693 if (WORLD_SAVE_P (info_ptr))
16696 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
16697 if ( GET_CODE (insn) == CALL_INSN
16698 && SIBLING_CALL_P (insn))
16700 info_ptr->world_save_p = 0;
16705 if (WORLD_SAVE_P (info_ptr))
16707 /* Even if we're not touching VRsave, make sure there's room on the
16708 stack for it, if it looks like we're calling SAVE_WORLD, which
16709 will attempt to save it. */
16710 info_ptr->vrsave_size = 4;
16712 /* If we are going to save the world, we need to save the link register too. */
16713 info_ptr->lr_save_p = 1;
16715 /* "Save" the VRsave register too if we're saving the world. */
16716 if (info_ptr->vrsave_mask == 0)
16717 info_ptr->vrsave_mask = compute_vrsave_mask ();
16719 /* Because the Darwin register save/restore routines only handle
16720 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
16722 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
16723 && (info_ptr->first_altivec_reg_save
16724 >= FIRST_SAVED_ALTIVEC_REGNO));
16731 is_altivec_return_reg (rtx reg, void *xyes)
16733 bool *yes = (bool *) xyes;
16734 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
16739 /* Calculate the stack information for the current function. This is
16740 complicated by having two separate calling sequences, the AIX calling
16741 sequence and the V.4 calling sequence.
16743 AIX (and Darwin/Mac OS X) stack frames look like:
16745 SP----> +---------------------------------------+
16746 | back chain to caller | 0 0
16747 +---------------------------------------+
16748 | saved CR | 4 8 (8-11)
16749 +---------------------------------------+
16751 +---------------------------------------+
16752 | reserved for compilers | 12 24
16753 +---------------------------------------+
16754 | reserved for binders | 16 32
16755 +---------------------------------------+
16756 | saved TOC pointer | 20 40
16757 +---------------------------------------+
16758 | Parameter save area (P) | 24 48
16759 +---------------------------------------+
16760 | Alloca space (A) | 24+P etc.
16761 +---------------------------------------+
16762 | Local variable space (L) | 24+P+A
16763 +---------------------------------------+
16764 | Float/int conversion temporary (X) | 24+P+A+L
16765 +---------------------------------------+
16766 | Save area for AltiVec registers (W) | 24+P+A+L+X
16767 +---------------------------------------+
16768 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
16769 +---------------------------------------+
16770 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
16771 +---------------------------------------+
16772 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
16773 +---------------------------------------+
16774 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
16775 +---------------------------------------+
16776 old SP->| back chain to caller's caller |
16777 +---------------------------------------+
16779 The required alignment for AIX configurations is two words (i.e., 8
16783 V.4 stack frames look like:
16785 SP----> +---------------------------------------+
16786 | back chain to caller | 0
16787 +---------------------------------------+
16788 | caller's saved LR | 4
16789 +---------------------------------------+
16790 | Parameter save area (P) | 8
16791 +---------------------------------------+
16792 | Alloca space (A) | 8+P
16793 +---------------------------------------+
16794 | Varargs save area (V) | 8+P+A
16795 +---------------------------------------+
16796 | Local variable space (L) | 8+P+A+V
16797 +---------------------------------------+
16798 | Float/int conversion temporary (X) | 8+P+A+V+L
16799 +---------------------------------------+
16800 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
16801 +---------------------------------------+
16802 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
16803 +---------------------------------------+
16804 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
16805 +---------------------------------------+
16806 | SPE: area for 64-bit GP registers |
16807 +---------------------------------------+
16808 | SPE alignment padding |
16809 +---------------------------------------+
16810 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
16811 +---------------------------------------+
16812 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
16813 +---------------------------------------+
16814 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
16815 +---------------------------------------+
16816 old SP->| back chain to caller's caller |
16817 +---------------------------------------+
16819 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
16820 given. (But note below and in sysv4.h that we require only 8 and
16821 may round up the size of our stack frame anyways. The historical
16822 reason is early versions of powerpc-linux which didn't properly
16823 align the stack at program startup. A happy side-effect is that
16824 -mno-eabi libraries can be used with -meabi programs.)
16826 The EABI configuration defaults to the V.4 layout. However,
16827 the stack alignment requirements may differ. If -mno-eabi is not
16828 given, the required stack alignment is 8 bytes; if -mno-eabi is
16829 given, the required alignment is 16 bytes. (But see V.4 comment
16832 #ifndef ABI_STACK_BOUNDARY
16833 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
16836 static rs6000_stack_t *
16837 rs6000_stack_info (void)
16839 static rs6000_stack_t info;
16840 rs6000_stack_t *info_ptr = &info;
16841 int reg_size = TARGET_32BIT ? 4 : 8;
16845 HOST_WIDE_INT non_fixed_size;
16847 memset (&info, 0, sizeof (info));
16851 /* Cache value so we don't rescan instruction chain over and over. */
16852 if (cfun->machine->insn_chain_scanned_p == 0)
16853 cfun->machine->insn_chain_scanned_p
16854 = spe_func_has_64bit_regs_p () + 1;
16855 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
16858 /* Select which calling sequence. */
16859 info_ptr->abi = DEFAULT_ABI;
16861 /* Calculate which registers need to be saved & save area size. */
16862 info_ptr->first_gp_reg_save = first_reg_to_save ();
16863 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
16864 even if it currently looks like we won't. Reload may need it to
16865 get at a constant; if so, it will have already created a constant
16866 pool entry for it. */
16867 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
16868 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
16869 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
16870 && crtl->uses_const_pool
16871 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
16872 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
16874 first_gp = info_ptr->first_gp_reg_save;
16876 info_ptr->gp_size = reg_size * (32 - first_gp);
16878 /* For the SPE, we have an additional upper 32-bits on each GPR.
16879 Ideally we should save the entire 64-bits only when the upper
16880 half is used in SIMD instructions. Since we only record
16881 registers live (not the size they are used in), this proves
16882 difficult because we'd have to traverse the instruction chain at
16883 the right time, taking reload into account. This is a real pain,
16884 so we opt to save the GPRs in 64-bits always if but one register
16885 gets used in 64-bits. Otherwise, all the registers in the frame
16886 get saved in 32-bits.
16888 So... since when we save all GPRs (except the SP) in 64-bits, the
16889 traditional GP save area will be empty. */
16890 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
16891 info_ptr->gp_size = 0;
16893 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
16894 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
16896 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
16897 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
16898 - info_ptr->first_altivec_reg_save);
16900 /* Does this function call anything? */
16901 info_ptr->calls_p = (! current_function_is_leaf
16902 || cfun->machine->ra_needs_full_frame);
16904 /* Determine if we need to save the link register. */
16905 if ((DEFAULT_ABI == ABI_AIX
16907 && !TARGET_PROFILE_KERNEL)
16908 #ifdef TARGET_RELOCATABLE
16909 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
16911 || (info_ptr->first_fp_reg_save != 64
16912 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
16913 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
16914 || info_ptr->calls_p
16915 || rs6000_ra_ever_killed ())
16917 info_ptr->lr_save_p = 1;
16918 df_set_regs_ever_live (LR_REGNO, true);
16921 /* Determine if we need to save the condition code registers. */
16922 if (df_regs_ever_live_p (CR2_REGNO)
16923 || df_regs_ever_live_p (CR3_REGNO)
16924 || df_regs_ever_live_p (CR4_REGNO))
16926 info_ptr->cr_save_p = 1;
16927 if (DEFAULT_ABI == ABI_V4)
16928 info_ptr->cr_size = reg_size;
16931 /* If the current function calls __builtin_eh_return, then we need
16932 to allocate stack space for registers that will hold data for
16933 the exception handler. */
16934 if (crtl->calls_eh_return)
16937 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
16940 /* SPE saves EH registers in 64-bits. */
16941 ehrd_size = i * (TARGET_SPE_ABI
16942 && info_ptr->spe_64bit_regs_used != 0
16943 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
16948 /* Determine various sizes. */
16949 info_ptr->reg_size = reg_size;
16950 info_ptr->fixed_size = RS6000_SAVE_AREA;
16951 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
16952 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
16953 TARGET_ALTIVEC ? 16 : 8);
16954 if (FRAME_GROWS_DOWNWARD)
16955 info_ptr->vars_size
16956 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
16957 + info_ptr->parm_size,
16958 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
16959 - (info_ptr->fixed_size + info_ptr->vars_size
16960 + info_ptr->parm_size);
16962 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
16963 info_ptr->spe_gp_size = 8 * (32 - first_gp);
16965 info_ptr->spe_gp_size = 0;
16967 if (TARGET_ALTIVEC_ABI)
16968 info_ptr->vrsave_mask = compute_vrsave_mask ();
16970 info_ptr->vrsave_mask = 0;
16972 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
16973 info_ptr->vrsave_size = 4;
16975 info_ptr->vrsave_size = 0;
16977 compute_save_world_info (info_ptr);
16979 /* Calculate the offsets. */
16980 switch (DEFAULT_ABI)
16984 gcc_unreachable ();
16988 info_ptr->fp_save_offset = - info_ptr->fp_size;
16989 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
16991 if (TARGET_ALTIVEC_ABI)
16993 info_ptr->vrsave_save_offset
16994 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
16996 /* Align stack so vector save area is on a quadword boundary.
16997 The padding goes above the vectors. */
16998 if (info_ptr->altivec_size != 0)
16999 info_ptr->altivec_padding_size
17000 = info_ptr->vrsave_save_offset & 0xF;
17002 info_ptr->altivec_padding_size = 0;
17004 info_ptr->altivec_save_offset
17005 = info_ptr->vrsave_save_offset
17006 - info_ptr->altivec_padding_size
17007 - info_ptr->altivec_size;
17008 gcc_assert (info_ptr->altivec_size == 0
17009 || info_ptr->altivec_save_offset % 16 == 0);
17011 /* Adjust for AltiVec case. */
17012 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17015 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17016 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17017 info_ptr->lr_save_offset = 2*reg_size;
17021 info_ptr->fp_save_offset = - info_ptr->fp_size;
17022 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17023 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17025 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17027 /* Align stack so SPE GPR save area is aligned on a
17028 double-word boundary. */
17029 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17030 info_ptr->spe_padding_size
17031 = 8 - (-info_ptr->cr_save_offset % 8);
17033 info_ptr->spe_padding_size = 0;
17035 info_ptr->spe_gp_save_offset
17036 = info_ptr->cr_save_offset
17037 - info_ptr->spe_padding_size
17038 - info_ptr->spe_gp_size;
17040 /* Adjust for SPE case. */
17041 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17043 else if (TARGET_ALTIVEC_ABI)
17045 info_ptr->vrsave_save_offset
17046 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17048 /* Align stack so vector save area is on a quadword boundary. */
17049 if (info_ptr->altivec_size != 0)
17050 info_ptr->altivec_padding_size
17051 = 16 - (-info_ptr->vrsave_save_offset % 16);
17053 info_ptr->altivec_padding_size = 0;
17055 info_ptr->altivec_save_offset
17056 = info_ptr->vrsave_save_offset
17057 - info_ptr->altivec_padding_size
17058 - info_ptr->altivec_size;
17060 /* Adjust for AltiVec case. */
17061 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17064 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17065 info_ptr->ehrd_offset -= ehrd_size;
17066 info_ptr->lr_save_offset = reg_size;
17070 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17071 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17072 + info_ptr->gp_size
17073 + info_ptr->altivec_size
17074 + info_ptr->altivec_padding_size
17075 + info_ptr->spe_gp_size
17076 + info_ptr->spe_padding_size
17078 + info_ptr->cr_size
17079 + info_ptr->vrsave_size,
17082 non_fixed_size = (info_ptr->vars_size
17083 + info_ptr->parm_size
17084 + info_ptr->save_size);
17086 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17087 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17089 /* Determine if we need to allocate any stack frame:
17091 For AIX we need to push the stack if a frame pointer is needed
17092 (because the stack might be dynamically adjusted), if we are
17093 debugging, if we make calls, or if the sum of fp_save, gp_save,
17094 and local variables are more than the space needed to save all
17095 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17096 + 18*8 = 288 (GPR13 reserved).
17098 For V.4 we don't have the stack cushion that AIX uses, but assume
17099 that the debugger can handle stackless frames. */
17101 if (info_ptr->calls_p)
17102 info_ptr->push_p = 1;
17104 else if (DEFAULT_ABI == ABI_V4)
17105 info_ptr->push_p = non_fixed_size != 0;
17107 else if (frame_pointer_needed)
17108 info_ptr->push_p = 1;
17110 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17111 info_ptr->push_p = 1;
17114 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17116 /* Zero offsets if we're not saving those registers. */
17117 if (info_ptr->fp_size == 0)
17118 info_ptr->fp_save_offset = 0;
17120 if (info_ptr->gp_size == 0)
17121 info_ptr->gp_save_offset = 0;
17123 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17124 info_ptr->altivec_save_offset = 0;
17126 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17127 info_ptr->vrsave_save_offset = 0;
17129 if (! TARGET_SPE_ABI
17130 || info_ptr->spe_64bit_regs_used == 0
17131 || info_ptr->spe_gp_size == 0)
17132 info_ptr->spe_gp_save_offset = 0;
17134 if (! info_ptr->lr_save_p)
17135 info_ptr->lr_save_offset = 0;
17137 if (! info_ptr->cr_save_p)
17138 info_ptr->cr_save_offset = 0;
17143 /* Return true if the current function uses any GPRs in 64-bit SIMD
17147 spe_func_has_64bit_regs_p (void)
17151 /* Functions that save and restore all the call-saved registers will
17152 need to save/restore the registers in 64-bits. */
17153 if (crtl->calls_eh_return
17154 || cfun->calls_setjmp
17155 || crtl->has_nonlocal_goto)
17158 insns = get_insns ();
17160 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17166 /* FIXME: This should be implemented with attributes...
17168 (set_attr "spe64" "true")....then,
17169 if (get_spe64(insn)) return true;
17171 It's the only reliable way to do the stuff below. */
17173 i = PATTERN (insn);
17174 if (GET_CODE (i) == SET)
17176 enum machine_mode mode = GET_MODE (SET_SRC (i));
17178 if (SPE_VECTOR_MODE (mode))
17180 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17190 debug_stack_info (rs6000_stack_t *info)
17192 const char *abi_string;
17195 info = rs6000_stack_info ();
17197 fprintf (stderr, "\nStack information for function %s:\n",
17198 ((current_function_decl && DECL_NAME (current_function_decl))
17199 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17204 default: abi_string = "Unknown"; break;
17205 case ABI_NONE: abi_string = "NONE"; break;
17206 case ABI_AIX: abi_string = "AIX"; break;
17207 case ABI_DARWIN: abi_string = "Darwin"; break;
17208 case ABI_V4: abi_string = "V.4"; break;
17211 fprintf (stderr, "\tABI = %5s\n", abi_string);
17213 if (TARGET_ALTIVEC_ABI)
17214 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17216 if (TARGET_SPE_ABI)
17217 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17219 if (info->first_gp_reg_save != 32)
17220 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17222 if (info->first_fp_reg_save != 64)
17223 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17225 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17226 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17227 info->first_altivec_reg_save);
17229 if (info->lr_save_p)
17230 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17232 if (info->cr_save_p)
17233 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17235 if (info->vrsave_mask)
17236 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17239 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17242 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17244 if (info->gp_save_offset)
17245 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17247 if (info->fp_save_offset)
17248 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17250 if (info->altivec_save_offset)
17251 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17252 info->altivec_save_offset);
17254 if (info->spe_gp_save_offset)
17255 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17256 info->spe_gp_save_offset);
17258 if (info->vrsave_save_offset)
17259 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17260 info->vrsave_save_offset);
17262 if (info->lr_save_offset)
17263 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
17265 if (info->cr_save_offset)
17266 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
17268 if (info->varargs_save_offset)
17269 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
17271 if (info->total_size)
17272 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17275 if (info->vars_size)
17276 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17279 if (info->parm_size)
17280 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
17282 if (info->fixed_size)
17283 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
17286 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
17288 if (info->spe_gp_size)
17289 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
17292 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
17294 if (info->altivec_size)
17295 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
17297 if (info->vrsave_size)
17298 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
17300 if (info->altivec_padding_size)
17301 fprintf (stderr, "\taltivec_padding_size= %5d\n",
17302 info->altivec_padding_size);
17304 if (info->spe_padding_size)
17305 fprintf (stderr, "\tspe_padding_size = %5d\n",
17306 info->spe_padding_size);
17309 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
17311 if (info->save_size)
17312 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
17314 if (info->reg_size != 4)
17315 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
17317 fprintf (stderr, "\n");
17321 rs6000_return_addr (int count, rtx frame)
17323 /* Currently we don't optimize very well between prolog and body
17324 code and for PIC code the code can be actually quite bad, so
17325 don't try to be too clever here. */
17326 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
17328 cfun->machine->ra_needs_full_frame = 1;
17335 plus_constant (copy_to_reg
17336 (gen_rtx_MEM (Pmode,
17337 memory_address (Pmode, frame))),
17338 RETURN_ADDRESS_OFFSET)));
17341 cfun->machine->ra_need_lr = 1;
17342 return get_hard_reg_initial_val (Pmode, LR_REGNO);
17345 /* Say whether a function is a candidate for sibcall handling or not.
17346 We do not allow indirect calls to be optimized into sibling calls.
17347 Also, we can't do it if there are any vector parameters; there's
17348 nowhere to put the VRsave code so it works; note that functions with
17349 vector parameters are required to have a prototype, so the argument
17350 type info must be available here. (The tail recursion case can work
17351 with vector parameters, but there's no way to distinguish here.) */
17353 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
17358 if (TARGET_ALTIVEC_VRSAVE)
17360 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
17361 type; type = TREE_CHAIN (type))
17363 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
17367 if (DEFAULT_ABI == ABI_DARWIN
17368 || ((*targetm.binds_local_p) (decl)
17369 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
17371 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
17373 if (!lookup_attribute ("longcall", attr_list)
17374 || lookup_attribute ("shortcall", attr_list))
17381 /* NULL if INSN insn is valid within a low-overhead loop.
17382 Otherwise return why doloop cannot be applied.
17383 PowerPC uses the COUNT register for branch on table instructions. */
17385 static const char *
17386 rs6000_invalid_within_doloop (const_rtx insn)
17389 return "Function call in the loop.";
17392 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
17393 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
17394 return "Computed branch in the loop.";
17400 rs6000_ra_ever_killed (void)
17406 if (cfun->is_thunk)
17409 /* regs_ever_live has LR marked as used if any sibcalls are present,
17410 but this should not force saving and restoring in the
17411 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
17412 clobbers LR, so that is inappropriate. */
17414 /* Also, the prologue can generate a store into LR that
17415 doesn't really count, like this:
17418 bcl to set PIC register
17422 When we're called from the epilogue, we need to avoid counting
17423 this as a store. */
17425 push_topmost_sequence ();
17426 top = get_insns ();
17427 pop_topmost_sequence ();
17428 reg = gen_rtx_REG (Pmode, LR_REGNO);
17430 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
17436 if (!SIBLING_CALL_P (insn))
17439 else if (find_regno_note (insn, REG_INC, LR_REGNO))
17441 else if (set_of (reg, insn) != NULL_RTX
17442 && !prologue_epilogue_contains (insn))
17449 /* Emit instructions needed to load the TOC register.
17450 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
17451 a constant pool; or for SVR4 -fpic. */
17454 rs6000_emit_load_toc_table (int fromprolog)
17457 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
17459 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
17462 rtx lab, tmp1, tmp2, got;
17464 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17465 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17467 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17469 got = rs6000_got_sym ();
17470 tmp1 = tmp2 = dest;
17473 tmp1 = gen_reg_rtx (Pmode);
17474 tmp2 = gen_reg_rtx (Pmode);
17476 emit_insn (gen_load_toc_v4_PIC_1 (lab));
17477 emit_move_insn (tmp1,
17478 gen_rtx_REG (Pmode, LR_REGNO));
17479 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
17480 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
17482 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
17484 emit_insn (gen_load_toc_v4_pic_si ());
17485 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
17487 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
17490 rtx temp0 = (fromprolog
17491 ? gen_rtx_REG (Pmode, 0)
17492 : gen_reg_rtx (Pmode));
17498 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
17499 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17501 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
17502 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17504 emit_insn (gen_load_toc_v4_PIC_1 (symF));
17505 emit_move_insn (dest,
17506 gen_rtx_REG (Pmode, LR_REGNO));
17507 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
17513 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
17514 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
17515 emit_move_insn (dest,
17516 gen_rtx_REG (Pmode, LR_REGNO));
17517 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
17519 emit_insn (gen_addsi3 (dest, temp0, dest));
17521 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
17523 /* This is for AIX code running in non-PIC ELF32. */
17526 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
17527 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
17529 emit_insn (gen_elf_high (dest, realsym));
17530 emit_insn (gen_elf_low (dest, dest, realsym));
17534 gcc_assert (DEFAULT_ABI == ABI_AIX);
17537 emit_insn (gen_load_toc_aix_si (dest));
17539 emit_insn (gen_load_toc_aix_di (dest));
17543 /* Emit instructions to restore the link register after determining where
17544 its value has been stored. */
17547 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
17549 rs6000_stack_t *info = rs6000_stack_info ();
17552 operands[0] = source;
17553 operands[1] = scratch;
17555 if (info->lr_save_p)
17557 rtx frame_rtx = stack_pointer_rtx;
17558 HOST_WIDE_INT sp_offset = 0;
17561 if (frame_pointer_needed
17562 || cfun->calls_alloca
17563 || info->total_size > 32767)
17565 tmp = gen_frame_mem (Pmode, frame_rtx);
17566 emit_move_insn (operands[1], tmp);
17567 frame_rtx = operands[1];
17569 else if (info->push_p)
17570 sp_offset = info->total_size;
17572 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
17573 tmp = gen_frame_mem (Pmode, tmp);
17574 emit_move_insn (tmp, operands[0]);
17577 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
17580 static GTY(()) alias_set_type set = -1;
17583 get_TOC_alias_set (void)
17586 set = new_alias_set ();
17590 /* This returns nonzero if the current function uses the TOC. This is
17591 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
17592 is generated by the ABI_V4 load_toc_* patterns. */
17599 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
17602 rtx pat = PATTERN (insn);
17605 if (GET_CODE (pat) == PARALLEL)
17606 for (i = 0; i < XVECLEN (pat, 0); i++)
17608 rtx sub = XVECEXP (pat, 0, i);
17609 if (GET_CODE (sub) == USE)
17611 sub = XEXP (sub, 0);
17612 if (GET_CODE (sub) == UNSPEC
17613 && XINT (sub, 1) == UNSPEC_TOC)
17623 create_TOC_reference (rtx symbol)
17625 if (TARGET_DEBUG_ADDR)
17627 if (GET_CODE (symbol) == SYMBOL_REF)
17628 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
17632 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
17633 GET_RTX_NAME (GET_CODE (symbol)));
17634 debug_rtx (symbol);
17638 if (!can_create_pseudo_p ())
17639 df_set_regs_ever_live (TOC_REGISTER, true);
17640 return gen_rtx_PLUS (Pmode,
17641 gen_rtx_REG (Pmode, TOC_REGISTER),
17642 gen_rtx_CONST (Pmode,
17643 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL)));
17646 /* Issue assembly directives that create a reference to the given DWARF
17647 FRAME_TABLE_LABEL from the current function section. */
17649 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
17651 fprintf (asm_out_file, "\t.ref %s\n",
17652 TARGET_STRIP_NAME_ENCODING (frame_table_label));
17655 /* If _Unwind_* has been called from within the same module,
17656 toc register is not guaranteed to be saved to 40(1) on function
17657 entry. Save it there in that case. */
17660 rs6000_aix_emit_builtin_unwind_init (void)
17663 rtx stack_top = gen_reg_rtx (Pmode);
17664 rtx opcode_addr = gen_reg_rtx (Pmode);
17665 rtx opcode = gen_reg_rtx (SImode);
17666 rtx tocompare = gen_reg_rtx (SImode);
17667 rtx no_toc_save_needed = gen_label_rtx ();
17669 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
17670 emit_move_insn (stack_top, mem);
17672 mem = gen_frame_mem (Pmode,
17673 gen_rtx_PLUS (Pmode, stack_top,
17674 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
17675 emit_move_insn (opcode_addr, mem);
17676 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
17677 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
17678 : 0xE8410028, SImode));
17680 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
17681 SImode, NULL_RTX, NULL_RTX,
17682 no_toc_save_needed);
17684 mem = gen_frame_mem (Pmode,
17685 gen_rtx_PLUS (Pmode, stack_top,
17686 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
17687 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
17688 emit_label (no_toc_save_needed);
17691 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
17692 and the change to the stack pointer. */
17695 rs6000_emit_stack_tie (void)
17697 rtx mem = gen_frame_mem (BLKmode,
17698 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
17700 emit_insn (gen_stack_tie (mem));
17703 /* Emit the correct code for allocating stack space, as insns.
17704 If COPY_R12, make sure a copy of the old frame is left in r12.
17705 If COPY_R11, make sure a copy of the old frame is left in r11,
17706 in preference to r12 if COPY_R12.
17707 The generated code may use hard register 0 as a temporary. */
17710 rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
17713 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
17714 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
17715 rtx todec = gen_int_mode (-size, Pmode);
17718 if (INTVAL (todec) != -size)
17720 warning (0, "stack frame too large");
17721 emit_insn (gen_trap ());
17725 if (crtl->limit_stack)
17727 if (REG_P (stack_limit_rtx)
17728 && REGNO (stack_limit_rtx) > 1
17729 && REGNO (stack_limit_rtx) <= 31)
17731 emit_insn (TARGET_32BIT
17732 ? gen_addsi3 (tmp_reg,
17735 : gen_adddi3 (tmp_reg,
17739 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
17742 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
17744 && DEFAULT_ABI == ABI_V4)
17746 rtx toload = gen_rtx_CONST (VOIDmode,
17747 gen_rtx_PLUS (Pmode,
17751 emit_insn (gen_elf_high (tmp_reg, toload));
17752 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
17753 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
17757 warning (0, "stack limit expression is not supported");
17760 if (copy_r12 || copy_r11)
17761 emit_move_insn (copy_r11
17762 ? gen_rtx_REG (Pmode, 11)
17763 : gen_rtx_REG (Pmode, 12),
17768 /* Need a note here so that try_split doesn't get confused. */
17769 if (get_last_insn () == NULL_RTX)
17770 emit_note (NOTE_INSN_DELETED);
17771 insn = emit_move_insn (tmp_reg, todec);
17772 try_split (PATTERN (insn), insn, 0);
17776 insn = emit_insn (TARGET_32BIT
17777 ? gen_movsi_update_stack (stack_reg, stack_reg,
17779 : gen_movdi_di_update_stack (stack_reg, stack_reg,
17780 todec, stack_reg));
17781 /* Since we didn't use gen_frame_mem to generate the MEM, grab
17782 it now and set the alias set/attributes. The above gen_*_update
17783 calls will generate a PARALLEL with the MEM set being the first
17785 par = PATTERN (insn);
17786 gcc_assert (GET_CODE (par) == PARALLEL);
17787 set = XVECEXP (par, 0, 0);
17788 gcc_assert (GET_CODE (set) == SET);
17789 mem = SET_DEST (set);
17790 gcc_assert (MEM_P (mem));
17791 MEM_NOTRAP_P (mem) = 1;
17792 set_mem_alias_set (mem, get_frame_alias_set ());
17794 RTX_FRAME_RELATED_P (insn) = 1;
17795 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
17796 gen_rtx_SET (VOIDmode, stack_reg,
17797 gen_rtx_PLUS (Pmode, stack_reg,
17798 GEN_INT (-size))));
17801 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
17802 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
17803 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
17804 deduce these equivalences by itself so it wasn't necessary to hold
17805 its hand so much. */
17808 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
17809 rtx reg2, rtx rreg)
17813 /* copy_rtx will not make unique copies of registers, so we need to
17814 ensure we don't have unwanted sharing here. */
17816 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
17819 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
17821 real = copy_rtx (PATTERN (insn));
17823 if (reg2 != NULL_RTX)
17824 real = replace_rtx (real, reg2, rreg);
17826 real = replace_rtx (real, reg,
17827 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
17828 STACK_POINTER_REGNUM),
17831 /* We expect that 'real' is either a SET or a PARALLEL containing
17832 SETs (and possibly other stuff). In a PARALLEL, all the SETs
17833 are important so they all have to be marked RTX_FRAME_RELATED_P. */
17835 if (GET_CODE (real) == SET)
17839 temp = simplify_rtx (SET_SRC (set));
17841 SET_SRC (set) = temp;
17842 temp = simplify_rtx (SET_DEST (set));
17844 SET_DEST (set) = temp;
17845 if (GET_CODE (SET_DEST (set)) == MEM)
17847 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
17849 XEXP (SET_DEST (set), 0) = temp;
17856 gcc_assert (GET_CODE (real) == PARALLEL);
17857 for (i = 0; i < XVECLEN (real, 0); i++)
17858 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
17860 rtx set = XVECEXP (real, 0, i);
17862 temp = simplify_rtx (SET_SRC (set));
17864 SET_SRC (set) = temp;
17865 temp = simplify_rtx (SET_DEST (set));
17867 SET_DEST (set) = temp;
17868 if (GET_CODE (SET_DEST (set)) == MEM)
17870 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
17872 XEXP (SET_DEST (set), 0) = temp;
17874 RTX_FRAME_RELATED_P (set) = 1;
17878 RTX_FRAME_RELATED_P (insn) = 1;
17879 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
17882 /* Returns an insn that has a vrsave set operation with the
17883 appropriate CLOBBERs. */
17886 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
17889 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
17890 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
17893 = gen_rtx_SET (VOIDmode,
17895 gen_rtx_UNSPEC_VOLATILE (SImode,
17896 gen_rtvec (2, reg, vrsave),
17897 UNSPECV_SET_VRSAVE));
17901 /* We need to clobber the registers in the mask so the scheduler
17902 does not move sets to VRSAVE before sets of AltiVec registers.
17904 However, if the function receives nonlocal gotos, reload will set
17905 all call saved registers live. We will end up with:
17907 (set (reg 999) (mem))
17908 (parallel [ (set (reg vrsave) (unspec blah))
17909 (clobber (reg 999))])
17911 The clobber will cause the store into reg 999 to be dead, and
17912 flow will attempt to delete an epilogue insn. In this case, we
17913 need an unspec use/set of the register. */
17915 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17916 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
17918 if (!epiloguep || call_used_regs [i])
17919 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
17920 gen_rtx_REG (V4SImode, i));
17923 rtx reg = gen_rtx_REG (V4SImode, i);
17926 = gen_rtx_SET (VOIDmode,
17928 gen_rtx_UNSPEC (V4SImode,
17929 gen_rtvec (1, reg), 27));
17933 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
17935 for (i = 0; i < nclobs; ++i)
17936 XVECEXP (insn, 0, i) = clobs[i];
17941 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
17942 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
17945 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
17946 unsigned int regno, int offset, HOST_WIDE_INT total_size)
17948 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
17949 rtx replacea, replaceb;
17951 int_rtx = GEN_INT (offset);
17953 /* Some cases that need register indexed addressing. */
17954 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
17955 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
17956 || (TARGET_E500_DOUBLE && mode == DFmode)
17958 && SPE_VECTOR_MODE (mode)
17959 && !SPE_CONST_OFFSET_OK (offset)))
17961 /* Whomever calls us must make sure r11 is available in the
17962 flow path of instructions in the prologue. */
17963 offset_rtx = gen_rtx_REG (Pmode, 11);
17964 emit_move_insn (offset_rtx, int_rtx);
17966 replacea = offset_rtx;
17967 replaceb = int_rtx;
17971 offset_rtx = int_rtx;
17972 replacea = NULL_RTX;
17973 replaceb = NULL_RTX;
17976 reg = gen_rtx_REG (mode, regno);
17977 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
17978 mem = gen_frame_mem (mode, addr);
17980 insn = emit_move_insn (mem, reg);
17982 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
17985 /* Emit an offset memory reference suitable for a frame store, while
17986 converting to a valid addressing mode. */
17989 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
17991 rtx int_rtx, offset_rtx;
17993 int_rtx = GEN_INT (offset);
17995 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
17996 || (TARGET_E500_DOUBLE && mode == DFmode))
17998 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
17999 emit_move_insn (offset_rtx, int_rtx);
18002 offset_rtx = int_rtx;
18004 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18007 /* Look for user-defined global regs. We should not save and restore these,
18008 and cannot use stmw/lmw if there are any in its range. */
18011 no_global_regs_above (int first, bool gpr)
18014 for (i = first; i < gpr ? 32 : 64 ; i++)
18015 if (global_regs[i])
18020 #ifndef TARGET_FIX_AND_CONTINUE
18021 #define TARGET_FIX_AND_CONTINUE 0
18024 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18025 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18026 #define LAST_SAVRES_REGISTER 31
18027 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18029 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18031 /* Return the symbol for an out-of-line register save/restore routine.
18032 We are saving/restoring GPRs if GPR is true. */
18035 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep, bool gpr, bool exitp)
18037 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18039 int select = ((savep ? 1 : 0) << 2
18041 /* On the SPE, we never have any FPRs, but we do have
18042 32/64-bit versions of the routines. */
18043 ? (TARGET_SPE_ABI && info->spe_64bit_regs_used ? 1 : 0)
18047 /* Don't generate bogus routine names. */
18048 gcc_assert (FIRST_SAVRES_REGISTER <= regno && regno <= LAST_SAVRES_REGISTER);
18050 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18055 const char *action;
18056 const char *regkind;
18057 const char *exit_suffix;
18059 action = savep ? "save" : "rest";
18061 /* SPE has slightly different names for its routines depending on
18062 whether we are saving 32-bit or 64-bit registers. */
18063 if (TARGET_SPE_ABI)
18065 /* No floating point saves on the SPE. */
18068 regkind = info->spe_64bit_regs_used ? "64gpr" : "32gpr";
18071 regkind = gpr ? "gpr" : "fpr";
18073 exit_suffix = exitp ? "_x" : "";
18075 sprintf (name, "_%s%s_%d%s", action, regkind, regno, exit_suffix);
18077 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18078 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18084 /* Emit a sequence of insns, including a stack tie if needed, for
18085 resetting the stack pointer. If SAVRES is true, then don't reset the
18086 stack pointer, but move the base of the frame into r11 for use by
18087 out-of-line register restore routines. */
18090 rs6000_emit_stack_reset (rs6000_stack_t *info,
18091 rtx sp_reg_rtx, rtx frame_reg_rtx,
18092 int sp_offset, bool savres)
18094 /* This blockage is needed so that sched doesn't decide to move
18095 the sp change before the register restores. */
18096 if (frame_reg_rtx != sp_reg_rtx
18098 && info->spe_64bit_regs_used != 0
18099 && info->first_gp_reg_save != 32))
18100 rs6000_emit_stack_tie ();
18102 if (frame_reg_rtx != sp_reg_rtx)
18104 if (sp_offset != 0)
18105 return emit_insn (gen_addsi3 (sp_reg_rtx, frame_reg_rtx,
18106 GEN_INT (sp_offset)));
18108 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18110 else if (sp_offset != 0)
18112 /* If we are restoring registers out-of-line, we will be using the
18113 "exit" variants of the restore routines, which will reset the
18114 stack for us. But we do need to point r11 into the right place
18115 for those routines. */
18116 rtx dest_reg = (savres
18117 ? gen_rtx_REG (Pmode, 11)
18120 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18121 GEN_INT (sp_offset)));
18128 /* Construct a parallel rtx describing the effect of a call to an
18129 out-of-line register save/restore routine. */
18132 rs6000_make_savres_rtx (rs6000_stack_t *info,
18133 rtx frame_reg_rtx, int save_area_offset,
18134 enum machine_mode reg_mode,
18135 bool savep, bool gpr, bool exitp)
18138 int offset, start_reg, end_reg, n_regs;
18139 int reg_size = GET_MODE_SIZE (reg_mode);
18145 ? info->first_gp_reg_save
18146 : info->first_fp_reg_save);
18147 end_reg = gpr ? 32 : 64;
18148 n_regs = end_reg - start_reg;
18149 p = rtvec_alloc ((exitp ? 4 : 3) + n_regs);
18151 /* If we're saving registers, then we should never say we're exiting. */
18152 gcc_assert ((savep && !exitp) || !savep);
18155 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18157 RTVEC_ELT (p, offset++)
18158 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18160 sym = rs6000_savres_routine_sym (info, savep, gpr, exitp);
18161 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18162 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 11));
18164 for (i = 0; i < end_reg - start_reg; i++)
18166 rtx addr, reg, mem;
18167 reg = gen_rtx_REG (reg_mode, start_reg + i);
18168 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18169 GEN_INT (save_area_offset + reg_size*i));
18170 mem = gen_frame_mem (reg_mode, addr);
18172 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
18174 savep ? reg : mem);
18177 return gen_rtx_PARALLEL (VOIDmode, p);
18180 /* Determine whether the gp REG is really used. */
18183 rs6000_reg_live_or_pic_offset_p (int reg)
18185 return ((df_regs_ever_live_p (reg)
18186 && (!call_used_regs[reg]
18187 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18188 && TARGET_TOC && TARGET_MINIMAL_TOC)))
18189 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18190 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18191 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
18195 SAVRES_MULTIPLE = 0x1,
18196 SAVRES_INLINE_FPRS = 0x2,
18197 SAVRES_INLINE_GPRS = 0x4
18200 /* Determine the strategy for savings/restoring registers. */
18203 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
18204 int using_static_chain_p, int sibcall)
18206 bool using_multiple_p;
18208 bool savres_fprs_inline;
18209 bool savres_gprs_inline;
18210 bool noclobber_global_gprs
18211 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
18213 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
18214 && (!TARGET_SPE_ABI
18215 || info->spe_64bit_regs_used == 0)
18216 && info->first_gp_reg_save < 31
18217 && noclobber_global_gprs);
18218 /* Don't bother to try to save things out-of-line if r11 is occupied
18219 by the static chain. It would require too much fiddling and the
18220 static chain is rarely used anyway. */
18221 common = (using_static_chain_p
18223 || crtl->calls_eh_return
18224 || !info->lr_save_p
18225 || cfun->machine->ra_need_lr
18226 || info->total_size > 32767);
18227 savres_fprs_inline = (common
18228 || info->first_fp_reg_save == 64
18229 || !no_global_regs_above (info->first_fp_reg_save,
18231 || FP_SAVE_INLINE (info->first_fp_reg_save));
18232 savres_gprs_inline = (common
18233 /* Saving CR interferes with the exit routines
18234 used on the SPE, so just punt here. */
18237 && info->spe_64bit_regs_used != 0
18238 && info->cr_save_p != 0)
18239 || info->first_gp_reg_save == 32
18240 || !noclobber_global_gprs
18241 || GP_SAVE_INLINE (info->first_gp_reg_save));
18244 /* If we are going to use store multiple, then don't even bother
18245 with the out-of-line routines, since the store-multiple instruction
18246 will always be smaller. */
18247 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18250 /* The situation is more complicated with load multiple. We'd
18251 prefer to use the out-of-line routines for restores, since the
18252 "exit" out-of-line routines can handle the restore of LR and
18253 the frame teardown. But we can only use the out-of-line
18254 routines if we know that we've used store multiple or
18255 out-of-line routines in the prologue, i.e. if we've saved all
18256 the registers from first_gp_reg_save. Otherwise, we risk
18257 loading garbage from the stack. Furthermore, we can only use
18258 the "exit" out-of-line gpr restore if we haven't saved any
18260 bool saved_all = !savres_gprs_inline || using_multiple_p;
18262 if (saved_all && info->first_fp_reg_save != 64)
18263 /* We can't use the exit routine; use load multiple if it's
18265 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18268 return (using_multiple_p
18269 | (savres_fprs_inline << 1)
18270 | (savres_gprs_inline << 2));
18273 /* Emit function prologue as insns. */
18276 rs6000_emit_prologue (void)
18278 rs6000_stack_t *info = rs6000_stack_info ();
18279 enum machine_mode reg_mode = Pmode;
18280 int reg_size = TARGET_32BIT ? 4 : 8;
18281 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18282 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
18283 rtx frame_reg_rtx = sp_reg_rtx;
18284 rtx cr_save_rtx = NULL_RTX;
18287 int saving_FPRs_inline;
18288 int saving_GPRs_inline;
18289 int using_store_multiple;
18290 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18291 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18292 && !call_used_regs[STATIC_CHAIN_REGNUM]);
18293 HOST_WIDE_INT sp_offset = 0;
18295 if (TARGET_FIX_AND_CONTINUE)
18297 /* gdb on darwin arranges to forward a function from the old
18298 address by modifying the first 5 instructions of the function
18299 to branch to the overriding function. This is necessary to
18300 permit function pointers that point to the old function to
18301 actually forward to the new function. */
18302 emit_insn (gen_nop ());
18303 emit_insn (gen_nop ());
18304 emit_insn (gen_nop ());
18305 emit_insn (gen_nop ());
18306 emit_insn (gen_nop ());
18309 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
18311 reg_mode = V2SImode;
18315 strategy = rs6000_savres_strategy (info, /*savep=*/true,
18316 /*static_chain_p=*/using_static_chain_p,
18318 using_store_multiple = strategy & SAVRES_MULTIPLE;
18319 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
18320 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
18322 /* For V.4, update stack before we do any saving and set back pointer. */
18323 if (! WORLD_SAVE_P (info)
18325 && (DEFAULT_ABI == ABI_V4
18326 || crtl->calls_eh_return))
18328 bool need_r11 = (TARGET_SPE
18329 ? (!saving_GPRs_inline
18330 && info->spe_64bit_regs_used == 0)
18331 : (!saving_FPRs_inline || !saving_GPRs_inline));
18332 if (info->total_size < 32767)
18333 sp_offset = info->total_size;
18335 frame_reg_rtx = (need_r11
18336 ? gen_rtx_REG (Pmode, 11)
18338 rs6000_emit_allocate_stack (info->total_size,
18339 (frame_reg_rtx != sp_reg_rtx
18340 && (info->cr_save_p
18342 || info->first_fp_reg_save < 64
18343 || info->first_gp_reg_save < 32
18346 if (frame_reg_rtx != sp_reg_rtx)
18347 rs6000_emit_stack_tie ();
18350 /* Handle world saves specially here. */
18351 if (WORLD_SAVE_P (info))
18358 /* save_world expects lr in r0. */
18359 reg0 = gen_rtx_REG (Pmode, 0);
18360 if (info->lr_save_p)
18362 insn = emit_move_insn (reg0,
18363 gen_rtx_REG (Pmode, LR_REGNO));
18364 RTX_FRAME_RELATED_P (insn) = 1;
18367 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
18368 assumptions about the offsets of various bits of the stack
18370 gcc_assert (info->gp_save_offset == -220
18371 && info->fp_save_offset == -144
18372 && info->lr_save_offset == 8
18373 && info->cr_save_offset == 4
18376 && (!crtl->calls_eh_return
18377 || info->ehrd_offset == -432)
18378 && info->vrsave_save_offset == -224
18379 && info->altivec_save_offset == -416);
18381 treg = gen_rtx_REG (SImode, 11);
18382 emit_move_insn (treg, GEN_INT (-info->total_size));
18384 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
18385 in R11. It also clobbers R12, so beware! */
18387 /* Preserve CR2 for save_world prologues */
18389 sz += 32 - info->first_gp_reg_save;
18390 sz += 64 - info->first_fp_reg_save;
18391 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
18392 p = rtvec_alloc (sz);
18394 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
18395 gen_rtx_REG (SImode,
18397 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
18398 gen_rtx_SYMBOL_REF (Pmode,
18400 /* We do floats first so that the instruction pattern matches
18402 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18404 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18405 ? DFmode : SFmode),
18406 info->first_fp_reg_save + i);
18407 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18408 GEN_INT (info->fp_save_offset
18409 + sp_offset + 8 * i));
18410 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18411 ? DFmode : SFmode), addr);
18413 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18415 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
18417 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
18418 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18419 GEN_INT (info->altivec_save_offset
18420 + sp_offset + 16 * i));
18421 rtx mem = gen_frame_mem (V4SImode, addr);
18423 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18425 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18427 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18428 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18429 GEN_INT (info->gp_save_offset
18430 + sp_offset + reg_size * i));
18431 rtx mem = gen_frame_mem (reg_mode, addr);
18433 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18437 /* CR register traditionally saved as CR2. */
18438 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
18439 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18440 GEN_INT (info->cr_save_offset
18442 rtx mem = gen_frame_mem (reg_mode, addr);
18444 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
18446 /* Explain about use of R0. */
18447 if (info->lr_save_p)
18449 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18450 GEN_INT (info->lr_save_offset
18452 rtx mem = gen_frame_mem (reg_mode, addr);
18454 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
18456 /* Explain what happens to the stack pointer. */
18458 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
18459 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
18462 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18463 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18464 treg, GEN_INT (-info->total_size));
18465 sp_offset = info->total_size;
18468 /* If we use the link register, get it into r0. */
18469 if (!WORLD_SAVE_P (info) && info->lr_save_p)
18471 rtx addr, reg, mem;
18473 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
18474 gen_rtx_REG (Pmode, LR_REGNO));
18475 RTX_FRAME_RELATED_P (insn) = 1;
18477 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18478 GEN_INT (info->lr_save_offset + sp_offset));
18479 reg = gen_rtx_REG (Pmode, 0);
18480 mem = gen_rtx_MEM (Pmode, addr);
18481 /* This should not be of rs6000_sr_alias_set, because of
18482 __builtin_return_address. */
18484 insn = emit_move_insn (mem, reg);
18485 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18486 NULL_RTX, NULL_RTX);
18489 /* If we need to save CR, put it into r12. */
18490 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
18494 cr_save_rtx = gen_rtx_REG (SImode, 12);
18495 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18496 RTX_FRAME_RELATED_P (insn) = 1;
18497 /* Now, there's no way that dwarf2out_frame_debug_expr is going
18498 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
18499 But that's OK. All we have to do is specify that _one_ condition
18500 code register is saved in this stack slot. The thrower's epilogue
18501 will then restore all the call-saved registers.
18502 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
18503 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
18504 gen_rtx_REG (SImode, CR2_REGNO));
18505 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18508 /* Do any required saving of fpr's. If only one or two to save, do
18509 it ourselves. Otherwise, call function. */
18510 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
18513 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
18514 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
18515 && ! call_used_regs[info->first_fp_reg_save+i]))
18516 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
18517 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
18519 info->first_fp_reg_save + i,
18520 info->fp_save_offset + sp_offset + 8 * i,
18523 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
18527 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18528 info->fp_save_offset + sp_offset,
18530 /*savep=*/true, /*gpr=*/false,
18532 insn = emit_insn (par);
18533 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18534 NULL_RTX, NULL_RTX);
18537 /* Save GPRs. This is done as a PARALLEL if we are using
18538 the store-multiple instructions. */
18539 if (!WORLD_SAVE_P (info)
18541 && info->spe_64bit_regs_used != 0
18542 && info->first_gp_reg_save != 32)
18545 rtx spe_save_area_ptr;
18547 /* Determine whether we can address all of the registers that need
18548 to be saved with an offset from the stack pointer that fits in
18549 the small const field for SPE memory instructions. */
18550 int spe_regs_addressable_via_sp
18551 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
18552 + (32 - info->first_gp_reg_save - 1) * reg_size)
18553 && saving_GPRs_inline);
18556 if (spe_regs_addressable_via_sp)
18558 spe_save_area_ptr = frame_reg_rtx;
18559 spe_offset = info->spe_gp_save_offset + sp_offset;
18563 /* Make r11 point to the start of the SPE save area. We need
18564 to be careful here if r11 is holding the static chain. If
18565 it is, then temporarily save it in r0. We would use r0 as
18566 our base register here, but using r0 as a base register in
18567 loads and stores means something different from what we
18569 int ool_adjust = (saving_GPRs_inline
18571 : (info->first_gp_reg_save
18572 - (FIRST_SAVRES_REGISTER+1))*8);
18573 HOST_WIDE_INT offset = (info->spe_gp_save_offset
18574 + sp_offset - ool_adjust);
18576 if (using_static_chain_p)
18578 rtx r0 = gen_rtx_REG (Pmode, 0);
18579 gcc_assert (info->first_gp_reg_save > 11);
18581 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
18584 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
18585 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
18587 GEN_INT (offset)));
18588 /* We need to make sure the move to r11 gets noted for
18589 properly outputting unwind information. */
18590 if (!saving_GPRs_inline)
18591 rs6000_frame_related (insn, frame_reg_rtx, offset,
18592 NULL_RTX, NULL_RTX);
18596 if (saving_GPRs_inline)
18598 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18599 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
18601 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18602 rtx offset, addr, mem;
18604 /* We're doing all this to ensure that the offset fits into
18605 the immediate offset of 'evstdd'. */
18606 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
18608 offset = GEN_INT (reg_size * i + spe_offset);
18609 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
18610 mem = gen_rtx_MEM (V2SImode, addr);
18612 insn = emit_move_insn (mem, reg);
18614 rs6000_frame_related (insn, spe_save_area_ptr,
18615 info->spe_gp_save_offset
18616 + sp_offset + reg_size * i,
18617 offset, const0_rtx);
18624 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
18626 /*savep=*/true, /*gpr=*/true,
18628 insn = emit_insn (par);
18629 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18630 NULL_RTX, NULL_RTX);
18634 /* Move the static chain pointer back. */
18635 if (using_static_chain_p && !spe_regs_addressable_via_sp)
18636 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
18638 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
18642 /* Need to adjust r11 if we saved any FPRs. */
18643 if (info->first_fp_reg_save != 64)
18645 rtx r11 = gen_rtx_REG (reg_mode, 11);
18646 rtx offset = GEN_INT (info->total_size
18647 + (-8 * (64-info->first_fp_reg_save)));
18648 rtx ptr_reg = (sp_reg_rtx == frame_reg_rtx
18649 ? sp_reg_rtx : r11);
18651 emit_insn (TARGET_32BIT
18652 ? gen_addsi3 (r11, ptr_reg, offset)
18653 : gen_adddi3 (r11, ptr_reg, offset));
18656 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
18657 info->gp_save_offset + sp_offset,
18659 /*savep=*/true, /*gpr=*/true,
18661 insn = emit_insn (par);
18662 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18663 NULL_RTX, NULL_RTX);
18665 else if (!WORLD_SAVE_P (info) && using_store_multiple)
18669 p = rtvec_alloc (32 - info->first_gp_reg_save);
18670 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18672 rtx addr, reg, mem;
18673 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18674 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18675 GEN_INT (info->gp_save_offset
18678 mem = gen_frame_mem (reg_mode, addr);
18680 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
18682 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
18683 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18684 NULL_RTX, NULL_RTX);
18686 else if (!WORLD_SAVE_P (info))
18689 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
18690 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
18692 rtx addr, reg, mem;
18693 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
18695 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18696 GEN_INT (info->gp_save_offset
18699 mem = gen_frame_mem (reg_mode, addr);
18701 insn = emit_move_insn (mem, reg);
18702 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18703 NULL_RTX, NULL_RTX);
18707 /* ??? There's no need to emit actual instructions here, but it's the
18708 easiest way to get the frame unwind information emitted. */
18709 if (crtl->calls_eh_return)
18711 unsigned int i, regno;
18713 /* In AIX ABI we need to pretend we save r2 here. */
18716 rtx addr, reg, mem;
18718 reg = gen_rtx_REG (reg_mode, 2);
18719 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18720 GEN_INT (sp_offset + 5 * reg_size));
18721 mem = gen_frame_mem (reg_mode, addr);
18723 insn = emit_move_insn (mem, reg);
18724 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18725 NULL_RTX, NULL_RTX);
18726 PATTERN (insn) = gen_blockage ();
18731 regno = EH_RETURN_DATA_REGNO (i);
18732 if (regno == INVALID_REGNUM)
18735 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
18736 info->ehrd_offset + sp_offset
18737 + reg_size * (int) i,
18742 /* Save CR if we use any that must be preserved. */
18743 if (!WORLD_SAVE_P (info) && info->cr_save_p)
18745 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18746 GEN_INT (info->cr_save_offset + sp_offset));
18747 rtx mem = gen_frame_mem (SImode, addr);
18748 /* See the large comment above about why CR2_REGNO is used. */
18749 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
18751 /* If r12 was used to hold the original sp, copy cr into r0 now
18753 if (REGNO (frame_reg_rtx) == 12)
18757 cr_save_rtx = gen_rtx_REG (SImode, 0);
18758 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
18759 RTX_FRAME_RELATED_P (insn) = 1;
18760 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
18761 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
18763 insn = emit_move_insn (mem, cr_save_rtx);
18765 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18766 NULL_RTX, NULL_RTX);
18769 /* Update stack and set back pointer unless this is V.4,
18770 for which it was done previously. */
18771 if (!WORLD_SAVE_P (info) && info->push_p
18772 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
18774 if (info->total_size < 32767)
18775 sp_offset = info->total_size;
18777 frame_reg_rtx = frame_ptr_rtx;
18778 rs6000_emit_allocate_stack (info->total_size,
18779 (frame_reg_rtx != sp_reg_rtx
18780 && ((info->altivec_size != 0)
18781 || (info->vrsave_mask != 0)
18784 if (frame_reg_rtx != sp_reg_rtx)
18785 rs6000_emit_stack_tie ();
18788 /* Set frame pointer, if needed. */
18789 if (frame_pointer_needed)
18791 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
18793 RTX_FRAME_RELATED_P (insn) = 1;
18796 /* Save AltiVec registers if needed. Save here because the red zone does
18797 not include AltiVec registers. */
18798 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
18802 /* There should be a non inline version of this, for when we
18803 are saving lots of vector registers. */
18804 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
18805 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18807 rtx areg, savereg, mem;
18810 offset = info->altivec_save_offset + sp_offset
18811 + 16 * (i - info->first_altivec_reg_save);
18813 savereg = gen_rtx_REG (V4SImode, i);
18815 areg = gen_rtx_REG (Pmode, 0);
18816 emit_move_insn (areg, GEN_INT (offset));
18818 /* AltiVec addressing mode is [reg+reg]. */
18819 mem = gen_frame_mem (V4SImode,
18820 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
18822 insn = emit_move_insn (mem, savereg);
18824 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
18825 areg, GEN_INT (offset));
18829 /* VRSAVE is a bit vector representing which AltiVec registers
18830 are used. The OS uses this to determine which vector
18831 registers to save on a context switch. We need to save
18832 VRSAVE on the stack frame, add whatever AltiVec registers we
18833 used in this function, and do the corresponding magic in the
18836 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
18837 && info->vrsave_mask != 0)
18839 rtx reg, mem, vrsave;
18842 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
18843 as frame_reg_rtx and r11 as the static chain pointer for
18844 nested functions. */
18845 reg = gen_rtx_REG (SImode, 0);
18846 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18848 emit_insn (gen_get_vrsave_internal (reg));
18850 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
18852 if (!WORLD_SAVE_P (info))
18855 offset = info->vrsave_save_offset + sp_offset;
18856 mem = gen_frame_mem (SImode,
18857 gen_rtx_PLUS (Pmode, frame_reg_rtx,
18858 GEN_INT (offset)));
18859 insn = emit_move_insn (mem, reg);
18862 /* Include the registers in the mask. */
18863 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
18865 insn = emit_insn (generate_set_vrsave (reg, info, 0));
18868 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
18869 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
18870 || (DEFAULT_ABI == ABI_V4
18871 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
18872 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
18874 /* If emit_load_toc_table will use the link register, we need to save
18875 it. We use R12 for this purpose because emit_load_toc_table
18876 can use register 0. This allows us to use a plain 'blr' to return
18877 from the procedure more often. */
18878 int save_LR_around_toc_setup = (TARGET_ELF
18879 && DEFAULT_ABI != ABI_AIX
18881 && ! info->lr_save_p
18882 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
18883 if (save_LR_around_toc_setup)
18885 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
18887 insn = emit_move_insn (frame_ptr_rtx, lr);
18888 RTX_FRAME_RELATED_P (insn) = 1;
18890 rs6000_emit_load_toc_table (TRUE);
18892 insn = emit_move_insn (lr, frame_ptr_rtx);
18893 RTX_FRAME_RELATED_P (insn) = 1;
18896 rs6000_emit_load_toc_table (TRUE);
18900 if (DEFAULT_ABI == ABI_DARWIN
18901 && flag_pic && crtl->uses_pic_offset_table)
18903 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
18904 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
18906 /* Save and restore LR locally around this call (in R0). */
18907 if (!info->lr_save_p)
18908 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
18910 emit_insn (gen_load_macho_picbase (src));
18912 emit_move_insn (gen_rtx_REG (Pmode,
18913 RS6000_PIC_OFFSET_TABLE_REGNUM),
18916 if (!info->lr_save_p)
18917 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
18922 /* Write function prologue. */
18925 rs6000_output_function_prologue (FILE *file,
18926 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
18928 rs6000_stack_t *info = rs6000_stack_info ();
18930 if (TARGET_DEBUG_STACK)
18931 debug_stack_info (info);
18933 /* Write .extern for any function we will call to save and restore
18935 if (info->first_fp_reg_save < 64
18936 && !FP_SAVE_INLINE (info->first_fp_reg_save))
18937 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
18938 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
18939 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
18941 /* Write .extern for AIX common mode routines, if needed. */
18942 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
18944 fputs ("\t.extern __mulh\n", file);
18945 fputs ("\t.extern __mull\n", file);
18946 fputs ("\t.extern __divss\n", file);
18947 fputs ("\t.extern __divus\n", file);
18948 fputs ("\t.extern __quoss\n", file);
18949 fputs ("\t.extern __quous\n", file);
18950 common_mode_defined = 1;
18953 if (! HAVE_prologue)
18957 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
18958 the "toplevel" insn chain. */
18959 emit_note (NOTE_INSN_DELETED);
18960 rs6000_emit_prologue ();
18961 emit_note (NOTE_INSN_DELETED);
18963 /* Expand INSN_ADDRESSES so final() doesn't crash. */
18967 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
18969 INSN_ADDRESSES_NEW (insn, addr);
18974 if (TARGET_DEBUG_STACK)
18975 debug_rtx_list (get_insns (), 100);
18976 final (get_insns (), file, FALSE);
18980 rs6000_pic_labelno++;
18983 /* Non-zero if vmx regs are restored before the frame pop, zero if
18984 we restore after the pop when possible. */
18985 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
18987 /* Reload CR from REG. */
18990 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
18995 if (using_mfcr_multiple)
18997 for (i = 0; i < 8; i++)
18998 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19000 gcc_assert (count);
19003 if (using_mfcr_multiple && count > 1)
19008 p = rtvec_alloc (count);
19011 for (i = 0; i < 8; i++)
19012 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19014 rtvec r = rtvec_alloc (2);
19015 RTVEC_ELT (r, 0) = reg;
19016 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19017 RTVEC_ELT (p, ndx) =
19018 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19019 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19022 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19023 gcc_assert (ndx == count);
19026 for (i = 0; i < 8; i++)
19027 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19029 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19035 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19036 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19037 below stack pointer not cloberred by signals. */
19040 offset_below_red_zone_p (HOST_WIDE_INT offset)
19042 return offset < (DEFAULT_ABI == ABI_V4
19044 : TARGET_32BIT ? -220 : -288);
19047 /* Emit function epilogue as insns. */
19050 rs6000_emit_epilogue (int sibcall)
19052 rs6000_stack_t *info;
19053 int restoring_GPRs_inline;
19054 int restoring_FPRs_inline;
19055 int using_load_multiple;
19056 int using_mtcr_multiple;
19057 int use_backchain_to_restore_sp;
19061 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19062 rtx frame_reg_rtx = sp_reg_rtx;
19063 rtx cfa_restores = NULL_RTX;
19065 enum machine_mode reg_mode = Pmode;
19066 int reg_size = TARGET_32BIT ? 4 : 8;
19069 info = rs6000_stack_info ();
19071 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19073 reg_mode = V2SImode;
19077 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19078 /*static_chain_p=*/0, sibcall);
19079 using_load_multiple = strategy & SAVRES_MULTIPLE;
19080 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19081 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19082 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19083 || rs6000_cpu == PROCESSOR_PPC603
19084 || rs6000_cpu == PROCESSOR_PPC750
19086 /* Restore via the backchain when we have a large frame, since this
19087 is more efficient than an addis, addi pair. The second condition
19088 here will not trigger at the moment; We don't actually need a
19089 frame pointer for alloca, but the generic parts of the compiler
19090 give us one anyway. */
19091 use_backchain_to_restore_sp = (info->total_size > 32767
19092 || info->total_size
19093 + (info->lr_save_p ? info->lr_save_offset : 0)
19095 || (cfun->calls_alloca
19096 && !frame_pointer_needed));
19097 restore_lr = (info->lr_save_p
19098 && restoring_GPRs_inline
19099 && restoring_FPRs_inline);
19101 if (WORLD_SAVE_P (info))
19105 const char *alloc_rname;
19108 /* eh_rest_world_r10 will return to the location saved in the LR
19109 stack slot (which is not likely to be our caller.)
19110 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19111 rest_world is similar, except any R10 parameter is ignored.
19112 The exception-handling stuff that was here in 2.95 is no
19113 longer necessary. */
19117 + 32 - info->first_gp_reg_save
19118 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
19119 + 63 + 1 - info->first_fp_reg_save);
19121 strcpy (rname, ((crtl->calls_eh_return) ?
19122 "*eh_rest_world_r10" : "*rest_world"));
19123 alloc_rname = ggc_strdup (rname);
19126 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
19127 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19128 gen_rtx_REG (Pmode,
19131 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
19132 /* The instruction pattern requires a clobber here;
19133 it is shared with the restVEC helper. */
19135 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
19138 /* CR register traditionally saved as CR2. */
19139 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19140 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19141 GEN_INT (info->cr_save_offset));
19142 rtx mem = gen_frame_mem (reg_mode, addr);
19144 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19147 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19149 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19150 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19151 GEN_INT (info->gp_save_offset
19153 rtx mem = gen_frame_mem (reg_mode, addr);
19155 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19157 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19159 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19160 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19161 GEN_INT (info->altivec_save_offset
19163 rtx mem = gen_frame_mem (V4SImode, addr);
19165 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19167 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
19169 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19170 ? DFmode : SFmode),
19171 info->first_fp_reg_save + i);
19172 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19173 GEN_INT (info->fp_save_offset
19175 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19176 ? DFmode : SFmode), addr);
19178 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19181 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
19183 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
19185 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
19187 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
19189 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
19190 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19195 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
19197 sp_offset = info->total_size;
19199 /* Restore AltiVec registers if we must do so before adjusting the
19201 if (TARGET_ALTIVEC_ABI
19202 && info->altivec_size != 0
19203 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19204 || (DEFAULT_ABI != ABI_V4
19205 && offset_below_red_zone_p (info->altivec_save_offset))))
19209 if (use_backchain_to_restore_sp)
19211 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19212 emit_move_insn (frame_reg_rtx,
19213 gen_rtx_MEM (Pmode, sp_reg_rtx));
19216 else if (frame_pointer_needed)
19217 frame_reg_rtx = hard_frame_pointer_rtx;
19219 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19220 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19222 rtx addr, areg, mem, reg;
19224 areg = gen_rtx_REG (Pmode, 0);
19226 (areg, GEN_INT (info->altivec_save_offset
19228 + 16 * (i - info->first_altivec_reg_save)));
19230 /* AltiVec addressing mode is [reg+reg]. */
19231 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19232 mem = gen_frame_mem (V4SImode, addr);
19234 reg = gen_rtx_REG (V4SImode, i);
19235 emit_move_insn (reg, mem);
19236 if (offset_below_red_zone_p (info->altivec_save_offset
19237 + (i - info->first_altivec_reg_save)
19239 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19244 /* Restore VRSAVE if we must do so before adjusting the stack. */
19246 && TARGET_ALTIVEC_VRSAVE
19247 && info->vrsave_mask != 0
19248 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19249 || (DEFAULT_ABI != ABI_V4
19250 && offset_below_red_zone_p (info->vrsave_save_offset))))
19252 rtx addr, mem, reg;
19254 if (frame_reg_rtx == sp_reg_rtx)
19256 if (use_backchain_to_restore_sp)
19258 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19259 emit_move_insn (frame_reg_rtx,
19260 gen_rtx_MEM (Pmode, sp_reg_rtx));
19263 else if (frame_pointer_needed)
19264 frame_reg_rtx = hard_frame_pointer_rtx;
19267 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19268 GEN_INT (info->vrsave_save_offset + sp_offset));
19269 mem = gen_frame_mem (SImode, addr);
19270 reg = gen_rtx_REG (SImode, 12);
19271 emit_move_insn (reg, mem);
19273 emit_insn (generate_set_vrsave (reg, info, 1));
19277 /* If we have a large stack frame, restore the old stack pointer
19278 using the backchain. */
19279 if (use_backchain_to_restore_sp)
19281 if (frame_reg_rtx == sp_reg_rtx)
19283 /* Under V.4, don't reset the stack pointer until after we're done
19284 loading the saved registers. */
19285 if (DEFAULT_ABI == ABI_V4)
19286 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19288 insn = emit_move_insn (frame_reg_rtx,
19289 gen_rtx_MEM (Pmode, sp_reg_rtx));
19292 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19293 && DEFAULT_ABI == ABI_V4)
19294 /* frame_reg_rtx has been set up by the altivec restore. */
19298 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19299 frame_reg_rtx = sp_reg_rtx;
19302 /* If we have a frame pointer, we can restore the old stack pointer
19304 else if (frame_pointer_needed)
19306 frame_reg_rtx = sp_reg_rtx;
19307 if (DEFAULT_ABI == ABI_V4)
19308 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19310 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
19311 GEN_INT (info->total_size)));
19314 else if (info->push_p
19315 && DEFAULT_ABI != ABI_V4
19316 && !crtl->calls_eh_return)
19318 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
19319 GEN_INT (info->total_size)));
19322 if (insn && frame_reg_rtx == sp_reg_rtx)
19326 REG_NOTES (insn) = cfa_restores;
19327 cfa_restores = NULL_RTX;
19329 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19330 RTX_FRAME_RELATED_P (insn) = 1;
19333 /* Restore AltiVec registers if we have not done so already. */
19334 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19335 && TARGET_ALTIVEC_ABI
19336 && info->altivec_size != 0
19337 && (DEFAULT_ABI == ABI_V4
19338 || !offset_below_red_zone_p (info->altivec_save_offset)))
19342 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19343 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19345 rtx addr, areg, mem, reg;
19347 areg = gen_rtx_REG (Pmode, 0);
19349 (areg, GEN_INT (info->altivec_save_offset
19351 + 16 * (i - info->first_altivec_reg_save)));
19353 /* AltiVec addressing mode is [reg+reg]. */
19354 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
19355 mem = gen_frame_mem (V4SImode, addr);
19357 reg = gen_rtx_REG (V4SImode, i);
19358 emit_move_insn (reg, mem);
19359 if (DEFAULT_ABI == ABI_V4)
19360 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19365 /* Restore VRSAVE if we have not done so already. */
19366 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19368 && TARGET_ALTIVEC_VRSAVE
19369 && info->vrsave_mask != 0
19370 && (DEFAULT_ABI == ABI_V4
19371 || !offset_below_red_zone_p (info->vrsave_save_offset)))
19373 rtx addr, mem, reg;
19375 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19376 GEN_INT (info->vrsave_save_offset + sp_offset));
19377 mem = gen_frame_mem (SImode, addr);
19378 reg = gen_rtx_REG (SImode, 12);
19379 emit_move_insn (reg, mem);
19381 emit_insn (generate_set_vrsave (reg, info, 1));
19384 /* Get the old lr if we saved it. If we are restoring registers
19385 out-of-line, then the out-of-line routines can do this for us. */
19388 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
19389 info->lr_save_offset + sp_offset);
19391 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
19394 /* Get the old cr if we saved it. */
19395 if (info->cr_save_p)
19397 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19398 GEN_INT (info->cr_save_offset + sp_offset));
19399 rtx mem = gen_frame_mem (SImode, addr);
19401 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
19404 /* Set LR here to try to overlap restores below. LR is always saved
19405 above incoming stack, so it never needs REG_CFA_RESTORE. */
19407 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
19408 gen_rtx_REG (Pmode, 0));
19410 /* Load exception handler data registers, if needed. */
19411 if (crtl->calls_eh_return)
19413 unsigned int i, regno;
19417 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19418 GEN_INT (sp_offset + 5 * reg_size));
19419 rtx mem = gen_frame_mem (reg_mode, addr);
19421 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
19428 regno = EH_RETURN_DATA_REGNO (i);
19429 if (regno == INVALID_REGNUM)
19432 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
19433 info->ehrd_offset + sp_offset
19434 + reg_size * (int) i);
19436 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
19440 /* Restore GPRs. This is done as a PARALLEL if we are using
19441 the load-multiple instructions. */
19443 && info->spe_64bit_regs_used != 0
19444 && info->first_gp_reg_save != 32)
19446 /* Determine whether we can address all of the registers that need
19447 to be saved with an offset from the stack pointer that fits in
19448 the small const field for SPE memory instructions. */
19449 int spe_regs_addressable_via_sp
19450 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19451 + (32 - info->first_gp_reg_save - 1) * reg_size)
19452 && restoring_GPRs_inline);
19455 if (spe_regs_addressable_via_sp)
19456 spe_offset = info->spe_gp_save_offset + sp_offset;
19459 rtx old_frame_reg_rtx = frame_reg_rtx;
19460 /* Make r11 point to the start of the SPE save area. We worried about
19461 not clobbering it when we were saving registers in the prologue.
19462 There's no need to worry here because the static chain is passed
19463 anew to every function. */
19464 int ool_adjust = (restoring_GPRs_inline
19466 : (info->first_gp_reg_save
19467 - (FIRST_SAVRES_REGISTER+1))*8);
19469 if (frame_reg_rtx == sp_reg_rtx)
19470 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19471 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
19472 GEN_INT (info->spe_gp_save_offset
19475 /* Keep the invariant that frame_reg_rtx + sp_offset points
19476 at the top of the stack frame. */
19477 sp_offset = -info->spe_gp_save_offset;
19482 if (restoring_GPRs_inline)
19484 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19485 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19487 rtx offset, addr, mem, reg;
19489 /* We're doing all this to ensure that the immediate offset
19490 fits into the immediate field of 'evldd'. */
19491 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
19493 offset = GEN_INT (spe_offset + reg_size * i);
19494 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
19495 mem = gen_rtx_MEM (V2SImode, addr);
19496 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19498 insn = emit_move_insn (reg, mem);
19499 if (DEFAULT_ABI == ABI_V4)
19501 if (frame_pointer_needed
19502 && info->first_gp_reg_save + i
19503 == HARD_FRAME_POINTER_REGNUM)
19505 add_reg_note (insn, REG_CFA_DEF_CFA,
19506 plus_constant (frame_reg_rtx,
19508 RTX_FRAME_RELATED_P (insn) = 1;
19511 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19520 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19522 /*savep=*/false, /*gpr=*/true,
19524 emit_jump_insn (par);
19525 /* We don't want anybody else emitting things after we jumped
19530 else if (!restoring_GPRs_inline)
19532 /* We are jumping to an out-of-line function. */
19533 bool can_use_exit = info->first_fp_reg_save == 64;
19536 /* Emit stack reset code if we need it. */
19538 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19539 sp_offset, can_use_exit);
19541 emit_insn (gen_addsi3 (gen_rtx_REG (Pmode, 11),
19543 GEN_INT (sp_offset - info->fp_size)));
19545 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19546 info->gp_save_offset, reg_mode,
19547 /*savep=*/false, /*gpr=*/true,
19548 /*exitp=*/can_use_exit);
19552 if (info->cr_save_p)
19554 rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12),
19555 using_mtcr_multiple);
19556 if (DEFAULT_ABI == ABI_V4)
19558 = alloc_reg_note (REG_CFA_RESTORE,
19559 gen_rtx_REG (SImode, CR2_REGNO),
19563 emit_jump_insn (par);
19565 /* We don't want anybody else emitting things after we jumped
19570 insn = emit_insn (par);
19571 if (DEFAULT_ABI == ABI_V4)
19573 if (frame_pointer_needed)
19575 add_reg_note (insn, REG_CFA_DEF_CFA,
19576 plus_constant (frame_reg_rtx, sp_offset));
19577 RTX_FRAME_RELATED_P (insn) = 1;
19580 for (i = info->first_gp_reg_save; i < 32; i++)
19582 = alloc_reg_note (REG_CFA_RESTORE,
19583 gen_rtx_REG (reg_mode, i), cfa_restores);
19586 else if (using_load_multiple)
19589 p = rtvec_alloc (32 - info->first_gp_reg_save);
19590 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19592 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19593 GEN_INT (info->gp_save_offset
19596 rtx mem = gen_frame_mem (reg_mode, addr);
19597 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19599 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
19600 if (DEFAULT_ABI == ABI_V4)
19601 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19604 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19605 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
19607 add_reg_note (insn, REG_CFA_DEF_CFA,
19608 plus_constant (frame_reg_rtx, sp_offset));
19609 RTX_FRAME_RELATED_P (insn) = 1;
19614 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19615 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19617 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19618 GEN_INT (info->gp_save_offset
19621 rtx mem = gen_frame_mem (reg_mode, addr);
19622 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19624 insn = emit_move_insn (reg, mem);
19625 if (DEFAULT_ABI == ABI_V4)
19627 if (frame_pointer_needed
19628 && info->first_gp_reg_save + i
19629 == HARD_FRAME_POINTER_REGNUM)
19631 add_reg_note (insn, REG_CFA_DEF_CFA,
19632 plus_constant (frame_reg_rtx, sp_offset));
19633 RTX_FRAME_RELATED_P (insn) = 1;
19636 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19642 /* Restore fpr's if we need to do it without calling a function. */
19643 if (restoring_FPRs_inline)
19644 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19645 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
19646 && ! call_used_regs[info->first_fp_reg_save+i]))
19648 rtx addr, mem, reg;
19649 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19650 GEN_INT (info->fp_save_offset
19653 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19654 ? DFmode : SFmode), addr);
19655 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19656 ? DFmode : SFmode),
19657 info->first_fp_reg_save + i);
19659 emit_move_insn (reg, mem);
19660 if (DEFAULT_ABI == ABI_V4)
19661 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
19665 /* If we saved cr, restore it here. Just those that were used. */
19666 if (info->cr_save_p)
19668 rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12), using_mtcr_multiple);
19669 if (DEFAULT_ABI == ABI_V4)
19671 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
19675 /* If this is V.4, unwind the stack pointer after all of the loads
19677 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
19678 sp_offset, !restoring_FPRs_inline);
19683 REG_NOTES (insn) = cfa_restores;
19684 cfa_restores = NULL_RTX;
19686 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
19687 RTX_FRAME_RELATED_P (insn) = 1;
19690 if (crtl->calls_eh_return)
19692 rtx sa = EH_RETURN_STACKADJ_RTX;
19693 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
19699 if (! restoring_FPRs_inline)
19700 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
19702 p = rtvec_alloc (2);
19704 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
19705 RTVEC_ELT (p, 1) = (restoring_FPRs_inline
19706 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
19707 : gen_rtx_CLOBBER (VOIDmode,
19708 gen_rtx_REG (Pmode, 65)));
19710 /* If we have to restore more than two FP registers, branch to the
19711 restore function. It will return to our caller. */
19712 if (! restoring_FPRs_inline)
19717 sym = rs6000_savres_routine_sym (info,
19721 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
19722 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
19723 gen_rtx_REG (Pmode, 11));
19724 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19727 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
19728 GEN_INT (info->fp_save_offset + 8*i));
19729 mem = gen_frame_mem (DFmode, addr);
19731 RTVEC_ELT (p, i+4) =
19732 gen_rtx_SET (VOIDmode,
19733 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
19738 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19742 /* Write function epilogue. */
19745 rs6000_output_function_epilogue (FILE *file,
19746 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19748 if (! HAVE_epilogue)
19750 rtx insn = get_last_insn ();
19751 /* If the last insn was a BARRIER, we don't have to write anything except
19752 the trace table. */
19753 if (GET_CODE (insn) == NOTE)
19754 insn = prev_nonnote_insn (insn);
19755 if (insn == 0 || GET_CODE (insn) != BARRIER)
19757 /* This is slightly ugly, but at least we don't have two
19758 copies of the epilogue-emitting code. */
19761 /* A NOTE_INSN_DELETED is supposed to be at the start
19762 and end of the "toplevel" insn chain. */
19763 emit_note (NOTE_INSN_DELETED);
19764 rs6000_emit_epilogue (FALSE);
19765 emit_note (NOTE_INSN_DELETED);
19767 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19771 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19773 INSN_ADDRESSES_NEW (insn, addr);
19778 if (TARGET_DEBUG_STACK)
19779 debug_rtx_list (get_insns (), 100);
19780 final (get_insns (), file, FALSE);
19786 macho_branch_islands ();
19787 /* Mach-O doesn't support labels at the end of objects, so if
19788 it looks like we might want one, insert a NOP. */
19790 rtx insn = get_last_insn ();
19793 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
19794 insn = PREV_INSN (insn);
19798 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
19799 fputs ("\tnop\n", file);
19803 /* Output a traceback table here. See /usr/include/sys/debug.h for info
19806 We don't output a traceback table if -finhibit-size-directive was
19807 used. The documentation for -finhibit-size-directive reads
19808 ``don't output a @code{.size} assembler directive, or anything
19809 else that would cause trouble if the function is split in the
19810 middle, and the two halves are placed at locations far apart in
19811 memory.'' The traceback table has this property, since it
19812 includes the offset from the start of the function to the
19813 traceback table itself.
19815 System V.4 Powerpc's (and the embedded ABI derived from it) use a
19816 different traceback table. */
19817 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
19818 && rs6000_traceback != traceback_none && !cfun->is_thunk)
19820 const char *fname = NULL;
19821 const char *language_string = lang_hooks.name;
19822 int fixed_parms = 0, float_parms = 0, parm_info = 0;
19824 int optional_tbtab;
19825 rs6000_stack_t *info = rs6000_stack_info ();
19827 if (rs6000_traceback == traceback_full)
19828 optional_tbtab = 1;
19829 else if (rs6000_traceback == traceback_part)
19830 optional_tbtab = 0;
19832 optional_tbtab = !optimize_size && !TARGET_ELF;
19834 if (optional_tbtab)
19836 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
19837 while (*fname == '.') /* V.4 encodes . in the name */
19840 /* Need label immediately before tbtab, so we can compute
19841 its offset from the function start. */
19842 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
19843 ASM_OUTPUT_LABEL (file, fname);
19846 /* The .tbtab pseudo-op can only be used for the first eight
19847 expressions, since it can't handle the possibly variable
19848 length fields that follow. However, if you omit the optional
19849 fields, the assembler outputs zeros for all optional fields
19850 anyways, giving each variable length field is minimum length
19851 (as defined in sys/debug.h). Thus we can not use the .tbtab
19852 pseudo-op at all. */
19854 /* An all-zero word flags the start of the tbtab, for debuggers
19855 that have to find it by searching forward from the entry
19856 point or from the current pc. */
19857 fputs ("\t.long 0\n", file);
19859 /* Tbtab format type. Use format type 0. */
19860 fputs ("\t.byte 0,", file);
19862 /* Language type. Unfortunately, there does not seem to be any
19863 official way to discover the language being compiled, so we
19864 use language_string.
19865 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
19866 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
19867 a number, so for now use 9. */
19868 if (! strcmp (language_string, "GNU C"))
19870 else if (! strcmp (language_string, "GNU F77")
19871 || ! strcmp (language_string, "GNU Fortran"))
19873 else if (! strcmp (language_string, "GNU Pascal"))
19875 else if (! strcmp (language_string, "GNU Ada"))
19877 else if (! strcmp (language_string, "GNU C++")
19878 || ! strcmp (language_string, "GNU Objective-C++"))
19880 else if (! strcmp (language_string, "GNU Java"))
19882 else if (! strcmp (language_string, "GNU Objective-C"))
19885 gcc_unreachable ();
19886 fprintf (file, "%d,", i);
19888 /* 8 single bit fields: global linkage (not set for C extern linkage,
19889 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
19890 from start of procedure stored in tbtab, internal function, function
19891 has controlled storage, function has no toc, function uses fp,
19892 function logs/aborts fp operations. */
19893 /* Assume that fp operations are used if any fp reg must be saved. */
19894 fprintf (file, "%d,",
19895 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
19897 /* 6 bitfields: function is interrupt handler, name present in
19898 proc table, function calls alloca, on condition directives
19899 (controls stack walks, 3 bits), saves condition reg, saves
19901 /* The `function calls alloca' bit seems to be set whenever reg 31 is
19902 set up as a frame pointer, even when there is no alloca call. */
19903 fprintf (file, "%d,",
19904 ((optional_tbtab << 6)
19905 | ((optional_tbtab & frame_pointer_needed) << 5)
19906 | (info->cr_save_p << 1)
19907 | (info->lr_save_p)));
19909 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
19911 fprintf (file, "%d,",
19912 (info->push_p << 7) | (64 - info->first_fp_reg_save));
19914 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
19915 fprintf (file, "%d,", (32 - first_reg_to_save ()));
19917 if (optional_tbtab)
19919 /* Compute the parameter info from the function decl argument
19922 int next_parm_info_bit = 31;
19924 for (decl = DECL_ARGUMENTS (current_function_decl);
19925 decl; decl = TREE_CHAIN (decl))
19927 rtx parameter = DECL_INCOMING_RTL (decl);
19928 enum machine_mode mode = GET_MODE (parameter);
19930 if (GET_CODE (parameter) == REG)
19932 if (SCALAR_FLOAT_MODE_P (mode))
19953 gcc_unreachable ();
19956 /* If only one bit will fit, don't or in this entry. */
19957 if (next_parm_info_bit > 0)
19958 parm_info |= (bits << (next_parm_info_bit - 1));
19959 next_parm_info_bit -= 2;
19963 fixed_parms += ((GET_MODE_SIZE (mode)
19964 + (UNITS_PER_WORD - 1))
19966 next_parm_info_bit -= 1;
19972 /* Number of fixed point parameters. */
19973 /* This is actually the number of words of fixed point parameters; thus
19974 an 8 byte struct counts as 2; and thus the maximum value is 8. */
19975 fprintf (file, "%d,", fixed_parms);
19977 /* 2 bitfields: number of floating point parameters (7 bits), parameters
19979 /* This is actually the number of fp registers that hold parameters;
19980 and thus the maximum value is 13. */
19981 /* Set parameters on stack bit if parameters are not in their original
19982 registers, regardless of whether they are on the stack? Xlc
19983 seems to set the bit when not optimizing. */
19984 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
19986 if (! optional_tbtab)
19989 /* Optional fields follow. Some are variable length. */
19991 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
19992 11 double float. */
19993 /* There is an entry for each parameter in a register, in the order that
19994 they occur in the parameter list. Any intervening arguments on the
19995 stack are ignored. If the list overflows a long (max possible length
19996 34 bits) then completely leave off all elements that don't fit. */
19997 /* Only emit this long if there was at least one parameter. */
19998 if (fixed_parms || float_parms)
19999 fprintf (file, "\t.long %d\n", parm_info);
20001 /* Offset from start of code to tb table. */
20002 fputs ("\t.long ", file);
20003 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20005 RS6000_OUTPUT_BASENAME (file, fname);
20007 assemble_name (file, fname);
20009 rs6000_output_function_entry (file, fname);
20012 /* Interrupt handler mask. */
20013 /* Omit this long, since we never set the interrupt handler bit
20016 /* Number of CTL (controlled storage) anchors. */
20017 /* Omit this long, since the has_ctl bit is never set above. */
20019 /* Displacement into stack of each CTL anchor. */
20020 /* Omit this list of longs, because there are no CTL anchors. */
20022 /* Length of function name. */
20025 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20027 /* Function name. */
20028 assemble_string (fname, strlen (fname));
20030 /* Register for alloca automatic storage; this is always reg 31.
20031 Only emit this if the alloca bit was set above. */
20032 if (frame_pointer_needed)
20033 fputs ("\t.byte 31\n", file);
20035 fputs ("\t.align 2\n", file);
20039 /* A C compound statement that outputs the assembler code for a thunk
20040 function, used to implement C++ virtual function calls with
20041 multiple inheritance. The thunk acts as a wrapper around a virtual
20042 function, adjusting the implicit object parameter before handing
20043 control off to the real function.
20045 First, emit code to add the integer DELTA to the location that
20046 contains the incoming first argument. Assume that this argument
20047 contains a pointer, and is the one used to pass the `this' pointer
20048 in C++. This is the incoming argument *before* the function
20049 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20050 values of all other incoming arguments.
20052 After the addition, emit code to jump to FUNCTION, which is a
20053 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20054 not touch the return address. Hence returning from FUNCTION will
20055 return to whoever called the current `thunk'.
20057 The effect must be as if FUNCTION had been called directly with the
20058 adjusted first argument. This macro is responsible for emitting
20059 all of the code for a thunk function; output_function_prologue()
20060 and output_function_epilogue() are not invoked.
20062 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20063 been extracted from it.) It might possibly be useful on some
20064 targets, but probably not.
20066 If you do not define this macro, the target-independent code in the
20067 C++ frontend will generate a less efficient heavyweight thunk that
20068 calls FUNCTION instead of jumping to it. The generic approach does
20069 not support varargs. */
20072 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
20073 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
20076 rtx this_rtx, insn, funexp;
20078 reload_completed = 1;
20079 epilogue_completed = 1;
20081 /* Mark the end of the (empty) prologue. */
20082 emit_note (NOTE_INSN_PROLOGUE_END);
20084 /* Find the "this" pointer. If the function returns a structure,
20085 the structure return pointer is in r3. */
20086 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
20087 this_rtx = gen_rtx_REG (Pmode, 4);
20089 this_rtx = gen_rtx_REG (Pmode, 3);
20091 /* Apply the constant offset, if required. */
20094 rtx delta_rtx = GEN_INT (delta);
20095 emit_insn (TARGET_32BIT
20096 ? gen_addsi3 (this_rtx, this_rtx, delta_rtx)
20097 : gen_adddi3 (this_rtx, this_rtx, delta_rtx));
20100 /* Apply the offset from the vtable, if required. */
20103 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
20104 rtx tmp = gen_rtx_REG (Pmode, 12);
20106 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
20107 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
20109 emit_insn (TARGET_32BIT
20110 ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
20111 : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
20112 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
20116 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
20118 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
20120 emit_insn (TARGET_32BIT
20121 ? gen_addsi3 (this_rtx, this_rtx, tmp)
20122 : gen_adddi3 (this_rtx, this_rtx, tmp));
20125 /* Generate a tail call to the target function. */
20126 if (!TREE_USED (function))
20128 assemble_external (function);
20129 TREE_USED (function) = 1;
20131 funexp = XEXP (DECL_RTL (function), 0);
20132 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
20135 if (MACHOPIC_INDIRECT)
20136 funexp = machopic_indirect_call_target (funexp);
20139 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
20140 generate sibcall RTL explicitly. */
20141 insn = emit_call_insn (
20142 gen_rtx_PARALLEL (VOIDmode,
20144 gen_rtx_CALL (VOIDmode,
20145 funexp, const0_rtx),
20146 gen_rtx_USE (VOIDmode, const0_rtx),
20147 gen_rtx_USE (VOIDmode,
20148 gen_rtx_REG (SImode,
20150 gen_rtx_RETURN (VOIDmode))));
20151 SIBLING_CALL_P (insn) = 1;
20154 /* Run just enough of rest_of_compilation to get the insns emitted.
20155 There's not really enough bulk here to make other passes such as
20156 instruction scheduling worth while. Note that use_thunk calls
20157 assemble_start_function and assemble_end_function. */
20158 insn = get_insns ();
20159 insn_locators_alloc ();
20160 shorten_branches (insn);
20161 final_start_function (insn, file, 1);
20162 final (insn, file, 1);
20163 final_end_function ();
20165 reload_completed = 0;
20166 epilogue_completed = 0;
20169 /* A quick summary of the various types of 'constant-pool tables'
20172 Target Flags Name One table per
20173 AIX (none) AIX TOC object file
20174 AIX -mfull-toc AIX TOC object file
20175 AIX -mminimal-toc AIX minimal TOC translation unit
20176 SVR4/EABI (none) SVR4 SDATA object file
20177 SVR4/EABI -fpic SVR4 pic object file
20178 SVR4/EABI -fPIC SVR4 PIC translation unit
20179 SVR4/EABI -mrelocatable EABI TOC function
20180 SVR4/EABI -maix AIX TOC object file
20181 SVR4/EABI -maix -mminimal-toc
20182 AIX minimal TOC translation unit
20184 Name Reg. Set by entries contains:
20185 made by addrs? fp? sum?
20187 AIX TOC 2 crt0 as Y option option
20188 AIX minimal TOC 30 prolog gcc Y Y option
20189 SVR4 SDATA 13 crt0 gcc N Y N
20190 SVR4 pic 30 prolog ld Y not yet N
20191 SVR4 PIC 30 prolog gcc Y option option
20192 EABI TOC 30 prolog gcc Y option option
20196 /* Hash functions for the hash table. */
20199 rs6000_hash_constant (rtx k)
20201 enum rtx_code code = GET_CODE (k);
20202 enum machine_mode mode = GET_MODE (k);
20203 unsigned result = (code << 3) ^ mode;
20204 const char *format;
20207 format = GET_RTX_FORMAT (code);
20208 flen = strlen (format);
20214 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
20217 if (mode != VOIDmode)
20218 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
20230 for (; fidx < flen; fidx++)
20231 switch (format[fidx])
20236 const char *str = XSTR (k, fidx);
20237 len = strlen (str);
20238 result = result * 613 + len;
20239 for (i = 0; i < len; i++)
20240 result = result * 613 + (unsigned) str[i];
20245 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
20249 result = result * 613 + (unsigned) XINT (k, fidx);
20252 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
20253 result = result * 613 + (unsigned) XWINT (k, fidx);
20257 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
20258 result = result * 613 + (unsigned) (XWINT (k, fidx)
20265 gcc_unreachable ();
20272 toc_hash_function (const void *hash_entry)
20274 const struct toc_hash_struct *thc =
20275 (const struct toc_hash_struct *) hash_entry;
20276 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
20279 /* Compare H1 and H2 for equivalence. */
20282 toc_hash_eq (const void *h1, const void *h2)
20284 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
20285 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
20287 if (((const struct toc_hash_struct *) h1)->key_mode
20288 != ((const struct toc_hash_struct *) h2)->key_mode)
20291 return rtx_equal_p (r1, r2);
20294 /* These are the names given by the C++ front-end to vtables, and
20295 vtable-like objects. Ideally, this logic should not be here;
20296 instead, there should be some programmatic way of inquiring as
20297 to whether or not an object is a vtable. */
20299 #define VTABLE_NAME_P(NAME) \
20300 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
20301 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
20302 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
20303 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
20304 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
20306 #ifdef NO_DOLLAR_IN_LABEL
20307 /* Return a GGC-allocated character string translating dollar signs in
20308 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
20311 rs6000_xcoff_strip_dollar (const char *name)
20316 p = strchr (name, '$');
20318 if (p == 0 || p == name)
20321 len = strlen (name);
20322 strip = (char *) alloca (len + 1);
20323 strcpy (strip, name);
20324 p = strchr (strip, '$');
20328 p = strchr (p + 1, '$');
20331 return ggc_alloc_string (strip, len);
20336 rs6000_output_symbol_ref (FILE *file, rtx x)
20338 /* Currently C++ toc references to vtables can be emitted before it
20339 is decided whether the vtable is public or private. If this is
20340 the case, then the linker will eventually complain that there is
20341 a reference to an unknown section. Thus, for vtables only,
20342 we emit the TOC reference to reference the symbol and not the
20344 const char *name = XSTR (x, 0);
20346 if (VTABLE_NAME_P (name))
20348 RS6000_OUTPUT_BASENAME (file, name);
20351 assemble_name (file, name);
20354 /* Output a TOC entry. We derive the entry name from what is being
20358 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
20361 const char *name = buf;
20363 HOST_WIDE_INT offset = 0;
20365 gcc_assert (!TARGET_NO_TOC);
20367 /* When the linker won't eliminate them, don't output duplicate
20368 TOC entries (this happens on AIX if there is any kind of TOC,
20369 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
20371 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
20373 struct toc_hash_struct *h;
20376 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
20377 time because GGC is not initialized at that point. */
20378 if (toc_hash_table == NULL)
20379 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
20380 toc_hash_eq, NULL);
20382 h = GGC_NEW (struct toc_hash_struct);
20384 h->key_mode = mode;
20385 h->labelno = labelno;
20387 found = htab_find_slot (toc_hash_table, h, INSERT);
20388 if (*found == NULL)
20390 else /* This is indeed a duplicate.
20391 Set this label equal to that label. */
20393 fputs ("\t.set ", file);
20394 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20395 fprintf (file, "%d,", labelno);
20396 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
20397 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
20403 /* If we're going to put a double constant in the TOC, make sure it's
20404 aligned properly when strict alignment is on. */
20405 if (GET_CODE (x) == CONST_DOUBLE
20406 && STRICT_ALIGNMENT
20407 && GET_MODE_BITSIZE (mode) >= 64
20408 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
20409 ASM_OUTPUT_ALIGN (file, 3);
20412 (*targetm.asm_out.internal_label) (file, "LC", labelno);
20414 /* Handle FP constants specially. Note that if we have a minimal
20415 TOC, things we put here aren't actually in the TOC, so we can allow
20417 if (GET_CODE (x) == CONST_DOUBLE &&
20418 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
20420 REAL_VALUE_TYPE rv;
20423 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20424 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20425 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
20427 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
20431 if (TARGET_MINIMAL_TOC)
20432 fputs (DOUBLE_INT_ASM_OP, file);
20434 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20435 k[0] & 0xffffffff, k[1] & 0xffffffff,
20436 k[2] & 0xffffffff, k[3] & 0xffffffff);
20437 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
20438 k[0] & 0xffffffff, k[1] & 0xffffffff,
20439 k[2] & 0xffffffff, k[3] & 0xffffffff);
20444 if (TARGET_MINIMAL_TOC)
20445 fputs ("\t.long ", file);
20447 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20448 k[0] & 0xffffffff, k[1] & 0xffffffff,
20449 k[2] & 0xffffffff, k[3] & 0xffffffff);
20450 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
20451 k[0] & 0xffffffff, k[1] & 0xffffffff,
20452 k[2] & 0xffffffff, k[3] & 0xffffffff);
20456 else if (GET_CODE (x) == CONST_DOUBLE &&
20457 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
20459 REAL_VALUE_TYPE rv;
20462 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20464 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20465 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
20467 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
20471 if (TARGET_MINIMAL_TOC)
20472 fputs (DOUBLE_INT_ASM_OP, file);
20474 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20475 k[0] & 0xffffffff, k[1] & 0xffffffff);
20476 fprintf (file, "0x%lx%08lx\n",
20477 k[0] & 0xffffffff, k[1] & 0xffffffff);
20482 if (TARGET_MINIMAL_TOC)
20483 fputs ("\t.long ", file);
20485 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
20486 k[0] & 0xffffffff, k[1] & 0xffffffff);
20487 fprintf (file, "0x%lx,0x%lx\n",
20488 k[0] & 0xffffffff, k[1] & 0xffffffff);
20492 else if (GET_CODE (x) == CONST_DOUBLE &&
20493 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
20495 REAL_VALUE_TYPE rv;
20498 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
20499 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
20500 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
20502 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
20506 if (TARGET_MINIMAL_TOC)
20507 fputs (DOUBLE_INT_ASM_OP, file);
20509 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20510 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
20515 if (TARGET_MINIMAL_TOC)
20516 fputs ("\t.long ", file);
20518 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
20519 fprintf (file, "0x%lx\n", l & 0xffffffff);
20523 else if (GET_MODE (x) == VOIDmode
20524 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
20526 unsigned HOST_WIDE_INT low;
20527 HOST_WIDE_INT high;
20529 if (GET_CODE (x) == CONST_DOUBLE)
20531 low = CONST_DOUBLE_LOW (x);
20532 high = CONST_DOUBLE_HIGH (x);
20535 #if HOST_BITS_PER_WIDE_INT == 32
20538 high = (low & 0x80000000) ? ~0 : 0;
20542 low = INTVAL (x) & 0xffffffff;
20543 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
20547 /* TOC entries are always Pmode-sized, but since this
20548 is a bigendian machine then if we're putting smaller
20549 integer constants in the TOC we have to pad them.
20550 (This is still a win over putting the constants in
20551 a separate constant pool, because then we'd have
20552 to have both a TOC entry _and_ the actual constant.)
20554 For a 32-bit target, CONST_INT values are loaded and shifted
20555 entirely within `low' and can be stored in one TOC entry. */
20557 /* It would be easy to make this work, but it doesn't now. */
20558 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
20560 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
20562 #if HOST_BITS_PER_WIDE_INT == 32
20563 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
20564 POINTER_SIZE, &low, &high, 0);
20567 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
20568 high = (HOST_WIDE_INT) low >> 32;
20575 if (TARGET_MINIMAL_TOC)
20576 fputs (DOUBLE_INT_ASM_OP, file);
20578 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
20579 (long) high & 0xffffffff, (long) low & 0xffffffff);
20580 fprintf (file, "0x%lx%08lx\n",
20581 (long) high & 0xffffffff, (long) low & 0xffffffff);
20586 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
20588 if (TARGET_MINIMAL_TOC)
20589 fputs ("\t.long ", file);
20591 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
20592 (long) high & 0xffffffff, (long) low & 0xffffffff);
20593 fprintf (file, "0x%lx,0x%lx\n",
20594 (long) high & 0xffffffff, (long) low & 0xffffffff);
20598 if (TARGET_MINIMAL_TOC)
20599 fputs ("\t.long ", file);
20601 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
20602 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
20608 if (GET_CODE (x) == CONST)
20610 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
20611 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
20613 base = XEXP (XEXP (x, 0), 0);
20614 offset = INTVAL (XEXP (XEXP (x, 0), 1));
20617 switch (GET_CODE (base))
20620 name = XSTR (base, 0);
20624 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
20625 CODE_LABEL_NUMBER (XEXP (base, 0)));
20629 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
20633 gcc_unreachable ();
20636 if (TARGET_MINIMAL_TOC)
20637 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
20640 fputs ("\t.tc ", file);
20641 RS6000_OUTPUT_BASENAME (file, name);
20644 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
20646 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
20648 fputs ("[TC],", file);
20651 /* Currently C++ toc references to vtables can be emitted before it
20652 is decided whether the vtable is public or private. If this is
20653 the case, then the linker will eventually complain that there is
20654 a TOC reference to an unknown section. Thus, for vtables only,
20655 we emit the TOC reference to reference the symbol and not the
20657 if (VTABLE_NAME_P (name))
20659 RS6000_OUTPUT_BASENAME (file, name);
20661 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
20662 else if (offset > 0)
20663 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
20666 output_addr_const (file, x);
20670 /* Output an assembler pseudo-op to write an ASCII string of N characters
20671 starting at P to FILE.
20673 On the RS/6000, we have to do this using the .byte operation and
20674 write out special characters outside the quoted string.
20675 Also, the assembler is broken; very long strings are truncated,
20676 so we must artificially break them up early. */
20679 output_ascii (FILE *file, const char *p, int n)
20682 int i, count_string;
20683 const char *for_string = "\t.byte \"";
20684 const char *for_decimal = "\t.byte ";
20685 const char *to_close = NULL;
20688 for (i = 0; i < n; i++)
20691 if (c >= ' ' && c < 0177)
20694 fputs (for_string, file);
20697 /* Write two quotes to get one. */
20705 for_decimal = "\"\n\t.byte ";
20709 if (count_string >= 512)
20711 fputs (to_close, file);
20713 for_string = "\t.byte \"";
20714 for_decimal = "\t.byte ";
20722 fputs (for_decimal, file);
20723 fprintf (file, "%d", c);
20725 for_string = "\n\t.byte \"";
20726 for_decimal = ", ";
20732 /* Now close the string if we have written one. Then end the line. */
20734 fputs (to_close, file);
20737 /* Generate a unique section name for FILENAME for a section type
20738 represented by SECTION_DESC. Output goes into BUF.
20740 SECTION_DESC can be any string, as long as it is different for each
20741 possible section type.
20743 We name the section in the same manner as xlc. The name begins with an
20744 underscore followed by the filename (after stripping any leading directory
20745 names) with the last period replaced by the string SECTION_DESC. If
20746 FILENAME does not contain a period, SECTION_DESC is appended to the end of
20750 rs6000_gen_section_name (char **buf, const char *filename,
20751 const char *section_desc)
20753 const char *q, *after_last_slash, *last_period = 0;
20757 after_last_slash = filename;
20758 for (q = filename; *q; q++)
20761 after_last_slash = q + 1;
20762 else if (*q == '.')
20766 len = strlen (after_last_slash) + strlen (section_desc) + 2;
20767 *buf = (char *) xmalloc (len);
20772 for (q = after_last_slash; *q; q++)
20774 if (q == last_period)
20776 strcpy (p, section_desc);
20777 p += strlen (section_desc);
20781 else if (ISALNUM (*q))
20785 if (last_period == 0)
20786 strcpy (p, section_desc);
20791 /* Emit profile function. */
20794 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
20796 /* Non-standard profiling for kernels, which just saves LR then calls
20797 _mcount without worrying about arg saves. The idea is to change
20798 the function prologue as little as possible as it isn't easy to
20799 account for arg save/restore code added just for _mcount. */
20800 if (TARGET_PROFILE_KERNEL)
20803 if (DEFAULT_ABI == ABI_AIX)
20805 #ifndef NO_PROFILE_COUNTERS
20806 # define NO_PROFILE_COUNTERS 0
20808 if (NO_PROFILE_COUNTERS)
20809 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
20810 LCT_NORMAL, VOIDmode, 0);
20814 const char *label_name;
20817 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
20818 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
20819 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
20821 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
20822 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
20825 else if (DEFAULT_ABI == ABI_DARWIN)
20827 const char *mcount_name = RS6000_MCOUNT;
20828 int caller_addr_regno = LR_REGNO;
20830 /* Be conservative and always set this, at least for now. */
20831 crtl->uses_pic_offset_table = 1;
20834 /* For PIC code, set up a stub and collect the caller's address
20835 from r0, which is where the prologue puts it. */
20836 if (MACHOPIC_INDIRECT
20837 && crtl->uses_pic_offset_table)
20838 caller_addr_regno = 0;
20840 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
20841 LCT_NORMAL, VOIDmode, 1,
20842 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
20846 /* Write function profiler code. */
20849 output_function_profiler (FILE *file, int labelno)
20853 switch (DEFAULT_ABI)
20856 gcc_unreachable ();
20861 warning (0, "no profiling of 64-bit code for this ABI");
20864 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
20865 fprintf (file, "\tmflr %s\n", reg_names[0]);
20866 if (NO_PROFILE_COUNTERS)
20868 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
20869 reg_names[0], reg_names[1]);
20871 else if (TARGET_SECURE_PLT && flag_pic)
20873 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
20874 reg_names[0], reg_names[1]);
20875 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
20876 asm_fprintf (file, "\t{cau|addis} %s,%s,",
20877 reg_names[12], reg_names[12]);
20878 assemble_name (file, buf);
20879 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
20880 assemble_name (file, buf);
20881 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
20883 else if (flag_pic == 1)
20885 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
20886 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
20887 reg_names[0], reg_names[1]);
20888 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
20889 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
20890 assemble_name (file, buf);
20891 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
20893 else if (flag_pic > 1)
20895 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
20896 reg_names[0], reg_names[1]);
20897 /* Now, we need to get the address of the label. */
20898 fputs ("\tbcl 20,31,1f\n\t.long ", file);
20899 assemble_name (file, buf);
20900 fputs ("-.\n1:", file);
20901 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
20902 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
20903 reg_names[0], reg_names[11]);
20904 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
20905 reg_names[0], reg_names[0], reg_names[11]);
20909 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
20910 assemble_name (file, buf);
20911 fputs ("@ha\n", file);
20912 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
20913 reg_names[0], reg_names[1]);
20914 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
20915 assemble_name (file, buf);
20916 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
20919 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
20920 fprintf (file, "\tbl %s%s\n",
20921 RS6000_MCOUNT, flag_pic ? "@plt" : "");
20926 if (!TARGET_PROFILE_KERNEL)
20928 /* Don't do anything, done in output_profile_hook (). */
20932 gcc_assert (!TARGET_32BIT);
20934 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
20935 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
20937 if (cfun->static_chain_decl != NULL)
20939 asm_fprintf (file, "\tstd %s,24(%s)\n",
20940 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
20941 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
20942 asm_fprintf (file, "\tld %s,24(%s)\n",
20943 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
20946 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
20954 /* The following variable value is the last issued insn. */
20956 static rtx last_scheduled_insn;
20958 /* The following variable helps to balance issuing of load and
20959 store instructions */
20961 static int load_store_pendulum;
20963 /* Power4 load update and store update instructions are cracked into a
20964 load or store and an integer insn which are executed in the same cycle.
20965 Branches have their own dispatch slot which does not count against the
20966 GCC issue rate, but it changes the program flow so there are no other
20967 instructions to issue in this cycle. */
20970 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
20971 int verbose ATTRIBUTE_UNUSED,
20972 rtx insn, int more)
20974 last_scheduled_insn = insn;
20975 if (GET_CODE (PATTERN (insn)) == USE
20976 || GET_CODE (PATTERN (insn)) == CLOBBER)
20978 cached_can_issue_more = more;
20979 return cached_can_issue_more;
20982 if (insn_terminates_group_p (insn, current_group))
20984 cached_can_issue_more = 0;
20985 return cached_can_issue_more;
20988 /* If no reservation, but reach here */
20989 if (recog_memoized (insn) < 0)
20992 if (rs6000_sched_groups)
20994 if (is_microcoded_insn (insn))
20995 cached_can_issue_more = 0;
20996 else if (is_cracked_insn (insn))
20997 cached_can_issue_more = more > 2 ? more - 2 : 0;
20999 cached_can_issue_more = more - 1;
21001 return cached_can_issue_more;
21004 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21007 cached_can_issue_more = more - 1;
21008 return cached_can_issue_more;
21011 /* Adjust the cost of a scheduling dependency. Return the new cost of
21012 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21015 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21017 enum attr_type attr_type;
21019 if (! recog_memoized (insn))
21022 switch (REG_NOTE_KIND (link))
21026 /* Data dependency; DEP_INSN writes a register that INSN reads
21027 some cycles later. */
21029 /* Separate a load from a narrower, dependent store. */
21030 if (rs6000_sched_groups
21031 && GET_CODE (PATTERN (insn)) == SET
21032 && GET_CODE (PATTERN (dep_insn)) == SET
21033 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21034 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21035 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21036 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21039 attr_type = get_attr_type (insn);
21044 /* Tell the first scheduling pass about the latency between
21045 a mtctr and bctr (and mtlr and br/blr). The first
21046 scheduling pass will not know about this latency since
21047 the mtctr instruction, which has the latency associated
21048 to it, will be generated by reload. */
21049 return TARGET_POWER ? 5 : 4;
21051 /* Leave some extra cycles between a compare and its
21052 dependent branch, to inhibit expensive mispredicts. */
21053 if ((rs6000_cpu_attr == CPU_PPC603
21054 || rs6000_cpu_attr == CPU_PPC604
21055 || rs6000_cpu_attr == CPU_PPC604E
21056 || rs6000_cpu_attr == CPU_PPC620
21057 || rs6000_cpu_attr == CPU_PPC630
21058 || rs6000_cpu_attr == CPU_PPC750
21059 || rs6000_cpu_attr == CPU_PPC7400
21060 || rs6000_cpu_attr == CPU_PPC7450
21061 || rs6000_cpu_attr == CPU_POWER4
21062 || rs6000_cpu_attr == CPU_POWER5
21063 || rs6000_cpu_attr == CPU_POWER7
21064 || rs6000_cpu_attr == CPU_CELL)
21065 && recog_memoized (dep_insn)
21066 && (INSN_CODE (dep_insn) >= 0))
21068 switch (get_attr_type (dep_insn))
21072 case TYPE_DELAYED_COMPARE:
21073 case TYPE_IMUL_COMPARE:
21074 case TYPE_LMUL_COMPARE:
21075 case TYPE_FPCOMPARE:
21076 case TYPE_CR_LOGICAL:
21077 case TYPE_DELAYED_CR:
21086 case TYPE_STORE_UX:
21088 case TYPE_FPSTORE_U:
21089 case TYPE_FPSTORE_UX:
21090 if ((rs6000_cpu == PROCESSOR_POWER6)
21091 && recog_memoized (dep_insn)
21092 && (INSN_CODE (dep_insn) >= 0))
21095 if (GET_CODE (PATTERN (insn)) != SET)
21096 /* If this happens, we have to extend this to schedule
21097 optimally. Return default for now. */
21100 /* Adjust the cost for the case where the value written
21101 by a fixed point operation is used as the address
21102 gen value on a store. */
21103 switch (get_attr_type (dep_insn))
21110 if (! store_data_bypass_p (dep_insn, insn))
21114 case TYPE_LOAD_EXT:
21115 case TYPE_LOAD_EXT_U:
21116 case TYPE_LOAD_EXT_UX:
21117 case TYPE_VAR_SHIFT_ROTATE:
21118 case TYPE_VAR_DELAYED_COMPARE:
21120 if (! store_data_bypass_p (dep_insn, insn))
21126 case TYPE_FAST_COMPARE:
21129 case TYPE_INSERT_WORD:
21130 case TYPE_INSERT_DWORD:
21131 case TYPE_FPLOAD_U:
21132 case TYPE_FPLOAD_UX:
21134 case TYPE_STORE_UX:
21135 case TYPE_FPSTORE_U:
21136 case TYPE_FPSTORE_UX:
21138 if (! store_data_bypass_p (dep_insn, insn))
21146 case TYPE_IMUL_COMPARE:
21147 case TYPE_LMUL_COMPARE:
21149 if (! store_data_bypass_p (dep_insn, insn))
21155 if (! store_data_bypass_p (dep_insn, insn))
21161 if (! store_data_bypass_p (dep_insn, insn))
21174 case TYPE_LOAD_EXT:
21175 case TYPE_LOAD_EXT_U:
21176 case TYPE_LOAD_EXT_UX:
21177 if ((rs6000_cpu == PROCESSOR_POWER6)
21178 && recog_memoized (dep_insn)
21179 && (INSN_CODE (dep_insn) >= 0))
21182 /* Adjust the cost for the case where the value written
21183 by a fixed point instruction is used within the address
21184 gen portion of a subsequent load(u)(x) */
21185 switch (get_attr_type (dep_insn))
21192 if (set_to_load_agen (dep_insn, insn))
21196 case TYPE_LOAD_EXT:
21197 case TYPE_LOAD_EXT_U:
21198 case TYPE_LOAD_EXT_UX:
21199 case TYPE_VAR_SHIFT_ROTATE:
21200 case TYPE_VAR_DELAYED_COMPARE:
21202 if (set_to_load_agen (dep_insn, insn))
21208 case TYPE_FAST_COMPARE:
21211 case TYPE_INSERT_WORD:
21212 case TYPE_INSERT_DWORD:
21213 case TYPE_FPLOAD_U:
21214 case TYPE_FPLOAD_UX:
21216 case TYPE_STORE_UX:
21217 case TYPE_FPSTORE_U:
21218 case TYPE_FPSTORE_UX:
21220 if (set_to_load_agen (dep_insn, insn))
21228 case TYPE_IMUL_COMPARE:
21229 case TYPE_LMUL_COMPARE:
21231 if (set_to_load_agen (dep_insn, insn))
21237 if (set_to_load_agen (dep_insn, insn))
21243 if (set_to_load_agen (dep_insn, insn))
21254 if ((rs6000_cpu == PROCESSOR_POWER6)
21255 && recog_memoized (dep_insn)
21256 && (INSN_CODE (dep_insn) >= 0)
21257 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
21264 /* Fall out to return default cost. */
21268 case REG_DEP_OUTPUT:
21269 /* Output dependency; DEP_INSN writes a register that INSN writes some
21271 if ((rs6000_cpu == PROCESSOR_POWER6)
21272 && recog_memoized (dep_insn)
21273 && (INSN_CODE (dep_insn) >= 0))
21275 attr_type = get_attr_type (insn);
21280 if (get_attr_type (dep_insn) == TYPE_FP)
21284 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
21292 /* Anti dependency; DEP_INSN reads a register that INSN writes some
21297 gcc_unreachable ();
21303 /* Debug version of rs6000_adjust_cost. */
21306 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21308 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
21314 switch (REG_NOTE_KIND (link))
21316 default: dep = "unknown depencency"; break;
21317 case REG_DEP_TRUE: dep = "data dependency"; break;
21318 case REG_DEP_OUTPUT: dep = "output dependency"; break;
21319 case REG_DEP_ANTI: dep = "anti depencency"; break;
21323 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
21324 "%s, insn:\n", ret, cost, dep);
21332 /* The function returns a true if INSN is microcoded.
21333 Return false otherwise. */
21336 is_microcoded_insn (rtx insn)
21338 if (!insn || !NONDEBUG_INSN_P (insn)
21339 || GET_CODE (PATTERN (insn)) == USE
21340 || GET_CODE (PATTERN (insn)) == CLOBBER)
21343 if (rs6000_cpu_attr == CPU_CELL)
21344 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
21346 if (rs6000_sched_groups)
21348 enum attr_type type = get_attr_type (insn);
21349 if (type == TYPE_LOAD_EXT_U
21350 || type == TYPE_LOAD_EXT_UX
21351 || type == TYPE_LOAD_UX
21352 || type == TYPE_STORE_UX
21353 || type == TYPE_MFCR)
21360 /* The function returns true if INSN is cracked into 2 instructions
21361 by the processor (and therefore occupies 2 issue slots). */
21364 is_cracked_insn (rtx insn)
21366 if (!insn || !NONDEBUG_INSN_P (insn)
21367 || GET_CODE (PATTERN (insn)) == USE
21368 || GET_CODE (PATTERN (insn)) == CLOBBER)
21371 if (rs6000_sched_groups)
21373 enum attr_type type = get_attr_type (insn);
21374 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
21375 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
21376 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
21377 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
21378 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
21379 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
21380 || type == TYPE_IDIV || type == TYPE_LDIV
21381 || type == TYPE_INSERT_WORD)
21388 /* The function returns true if INSN can be issued only from
21389 the branch slot. */
21392 is_branch_slot_insn (rtx insn)
21394 if (!insn || !NONDEBUG_INSN_P (insn)
21395 || GET_CODE (PATTERN (insn)) == USE
21396 || GET_CODE (PATTERN (insn)) == CLOBBER)
21399 if (rs6000_sched_groups)
21401 enum attr_type type = get_attr_type (insn);
21402 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
21410 /* The function returns true if out_inst sets a value that is
21411 used in the address generation computation of in_insn */
21413 set_to_load_agen (rtx out_insn, rtx in_insn)
21415 rtx out_set, in_set;
21417 /* For performance reasons, only handle the simple case where
21418 both loads are a single_set. */
21419 out_set = single_set (out_insn);
21422 in_set = single_set (in_insn);
21424 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
21430 /* The function returns true if the target storage location of
21431 out_insn is adjacent to the target storage location of in_insn */
21432 /* Return 1 if memory locations are adjacent. */
21435 adjacent_mem_locations (rtx insn1, rtx insn2)
21438 rtx a = get_store_dest (PATTERN (insn1));
21439 rtx b = get_store_dest (PATTERN (insn2));
21441 if ((GET_CODE (XEXP (a, 0)) == REG
21442 || (GET_CODE (XEXP (a, 0)) == PLUS
21443 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
21444 && (GET_CODE (XEXP (b, 0)) == REG
21445 || (GET_CODE (XEXP (b, 0)) == PLUS
21446 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
21448 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
21451 if (GET_CODE (XEXP (a, 0)) == PLUS)
21453 reg0 = XEXP (XEXP (a, 0), 0);
21454 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
21457 reg0 = XEXP (a, 0);
21459 if (GET_CODE (XEXP (b, 0)) == PLUS)
21461 reg1 = XEXP (XEXP (b, 0), 0);
21462 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
21465 reg1 = XEXP (b, 0);
21467 val_diff = val1 - val0;
21469 return ((REGNO (reg0) == REGNO (reg1))
21470 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
21471 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
21477 /* A C statement (sans semicolon) to update the integer scheduling
21478 priority INSN_PRIORITY (INSN). Increase the priority to execute the
21479 INSN earlier, reduce the priority to execute INSN later. Do not
21480 define this macro if you do not need to adjust the scheduling
21481 priorities of insns. */
21484 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
21486 /* On machines (like the 750) which have asymmetric integer units,
21487 where one integer unit can do multiply and divides and the other
21488 can't, reduce the priority of multiply/divide so it is scheduled
21489 before other integer operations. */
21492 if (! INSN_P (insn))
21495 if (GET_CODE (PATTERN (insn)) == USE)
21498 switch (rs6000_cpu_attr) {
21500 switch (get_attr_type (insn))
21507 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
21508 priority, priority);
21509 if (priority >= 0 && priority < 0x01000000)
21516 if (insn_must_be_first_in_group (insn)
21517 && reload_completed
21518 && current_sched_info->sched_max_insns_priority
21519 && rs6000_sched_restricted_insns_priority)
21522 /* Prioritize insns that can be dispatched only in the first
21524 if (rs6000_sched_restricted_insns_priority == 1)
21525 /* Attach highest priority to insn. This means that in
21526 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
21527 precede 'priority' (critical path) considerations. */
21528 return current_sched_info->sched_max_insns_priority;
21529 else if (rs6000_sched_restricted_insns_priority == 2)
21530 /* Increase priority of insn by a minimal amount. This means that in
21531 haifa-sched.c:ready_sort(), only 'priority' (critical path)
21532 considerations precede dispatch-slot restriction considerations. */
21533 return (priority + 1);
21536 if (rs6000_cpu == PROCESSOR_POWER6
21537 && ((load_store_pendulum == -2 && is_load_insn (insn))
21538 || (load_store_pendulum == 2 && is_store_insn (insn))))
21539 /* Attach highest priority to insn if the scheduler has just issued two
21540 stores and this instruction is a load, or two loads and this instruction
21541 is a store. Power6 wants loads and stores scheduled alternately
21543 return current_sched_info->sched_max_insns_priority;
21548 /* Return true if the instruction is nonpipelined on the Cell. */
21550 is_nonpipeline_insn (rtx insn)
21552 enum attr_type type;
21553 if (!insn || !NONDEBUG_INSN_P (insn)
21554 || GET_CODE (PATTERN (insn)) == USE
21555 || GET_CODE (PATTERN (insn)) == CLOBBER)
21558 type = get_attr_type (insn);
21559 if (type == TYPE_IMUL
21560 || type == TYPE_IMUL2
21561 || type == TYPE_IMUL3
21562 || type == TYPE_LMUL
21563 || type == TYPE_IDIV
21564 || type == TYPE_LDIV
21565 || type == TYPE_SDIV
21566 || type == TYPE_DDIV
21567 || type == TYPE_SSQRT
21568 || type == TYPE_DSQRT
21569 || type == TYPE_MFCR
21570 || type == TYPE_MFCRF
21571 || type == TYPE_MFJMPR)
21579 /* Return how many instructions the machine can issue per cycle. */
21582 rs6000_issue_rate (void)
21584 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
21585 if (!reload_completed)
21588 switch (rs6000_cpu_attr) {
21589 case CPU_RIOS1: /* ? */
21591 case CPU_PPC601: /* ? */
21600 case CPU_PPCE300C2:
21601 case CPU_PPCE300C3:
21602 case CPU_PPCE500MC:
21620 /* Return how many instructions to look ahead for better insn
21624 rs6000_use_sched_lookahead (void)
21626 if (rs6000_cpu_attr == CPU_PPC8540)
21628 if (rs6000_cpu_attr == CPU_CELL)
21629 return (reload_completed ? 8 : 0);
21633 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
21635 rs6000_use_sched_lookahead_guard (rtx insn)
21637 if (rs6000_cpu_attr != CPU_CELL)
21640 if (insn == NULL_RTX || !INSN_P (insn))
21643 if (!reload_completed
21644 || is_nonpipeline_insn (insn)
21645 || is_microcoded_insn (insn))
21651 /* Determine is PAT refers to memory. */
21654 is_mem_ref (rtx pat)
21660 /* stack_tie does not produce any real memory traffic. */
21661 if (GET_CODE (pat) == UNSPEC
21662 && XINT (pat, 1) == UNSPEC_TIE)
21665 if (GET_CODE (pat) == MEM)
21668 /* Recursively process the pattern. */
21669 fmt = GET_RTX_FORMAT (GET_CODE (pat));
21671 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
21674 ret |= is_mem_ref (XEXP (pat, i));
21675 else if (fmt[i] == 'E')
21676 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
21677 ret |= is_mem_ref (XVECEXP (pat, i, j));
21683 /* Determine if PAT is a PATTERN of a load insn. */
21686 is_load_insn1 (rtx pat)
21688 if (!pat || pat == NULL_RTX)
21691 if (GET_CODE (pat) == SET)
21692 return is_mem_ref (SET_SRC (pat));
21694 if (GET_CODE (pat) == PARALLEL)
21698 for (i = 0; i < XVECLEN (pat, 0); i++)
21699 if (is_load_insn1 (XVECEXP (pat, 0, i)))
21706 /* Determine if INSN loads from memory. */
21709 is_load_insn (rtx insn)
21711 if (!insn || !INSN_P (insn))
21714 if (GET_CODE (insn) == CALL_INSN)
21717 return is_load_insn1 (PATTERN (insn));
21720 /* Determine if PAT is a PATTERN of a store insn. */
21723 is_store_insn1 (rtx pat)
21725 if (!pat || pat == NULL_RTX)
21728 if (GET_CODE (pat) == SET)
21729 return is_mem_ref (SET_DEST (pat));
21731 if (GET_CODE (pat) == PARALLEL)
21735 for (i = 0; i < XVECLEN (pat, 0); i++)
21736 if (is_store_insn1 (XVECEXP (pat, 0, i)))
21743 /* Determine if INSN stores to memory. */
21746 is_store_insn (rtx insn)
21748 if (!insn || !INSN_P (insn))
21751 return is_store_insn1 (PATTERN (insn));
21754 /* Return the dest of a store insn. */
21757 get_store_dest (rtx pat)
21759 gcc_assert (is_store_insn1 (pat));
21761 if (GET_CODE (pat) == SET)
21762 return SET_DEST (pat);
21763 else if (GET_CODE (pat) == PARALLEL)
21767 for (i = 0; i < XVECLEN (pat, 0); i++)
21769 rtx inner_pat = XVECEXP (pat, 0, i);
21770 if (GET_CODE (inner_pat) == SET
21771 && is_mem_ref (SET_DEST (inner_pat)))
21775 /* We shouldn't get here, because we should have either a simple
21776 store insn or a store with update which are covered above. */
21780 /* Returns whether the dependence between INSN and NEXT is considered
21781 costly by the given target. */
21784 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
21789 /* If the flag is not enabled - no dependence is considered costly;
21790 allow all dependent insns in the same group.
21791 This is the most aggressive option. */
21792 if (rs6000_sched_costly_dep == no_dep_costly)
21795 /* If the flag is set to 1 - a dependence is always considered costly;
21796 do not allow dependent instructions in the same group.
21797 This is the most conservative option. */
21798 if (rs6000_sched_costly_dep == all_deps_costly)
21801 insn = DEP_PRO (dep);
21802 next = DEP_CON (dep);
21804 if (rs6000_sched_costly_dep == store_to_load_dep_costly
21805 && is_load_insn (next)
21806 && is_store_insn (insn))
21807 /* Prevent load after store in the same group. */
21810 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
21811 && is_load_insn (next)
21812 && is_store_insn (insn)
21813 && DEP_TYPE (dep) == REG_DEP_TRUE)
21814 /* Prevent load after store in the same group if it is a true
21818 /* The flag is set to X; dependences with latency >= X are considered costly,
21819 and will not be scheduled in the same group. */
21820 if (rs6000_sched_costly_dep <= max_dep_latency
21821 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
21827 /* Return the next insn after INSN that is found before TAIL is reached,
21828 skipping any "non-active" insns - insns that will not actually occupy
21829 an issue slot. Return NULL_RTX if such an insn is not found. */
21832 get_next_active_insn (rtx insn, rtx tail)
21834 if (insn == NULL_RTX || insn == tail)
21839 insn = NEXT_INSN (insn);
21840 if (insn == NULL_RTX || insn == tail)
21845 || (NONJUMP_INSN_P (insn)
21846 && GET_CODE (PATTERN (insn)) != USE
21847 && GET_CODE (PATTERN (insn)) != CLOBBER
21848 && INSN_CODE (insn) != CODE_FOR_stack_tie))
21854 /* We are about to begin issuing insns for this clock cycle. */
21857 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
21858 rtx *ready ATTRIBUTE_UNUSED,
21859 int *pn_ready ATTRIBUTE_UNUSED,
21860 int clock_var ATTRIBUTE_UNUSED)
21862 int n_ready = *pn_ready;
21865 fprintf (dump, "// rs6000_sched_reorder :\n");
21867 /* Reorder the ready list, if the second to last ready insn
21868 is a nonepipeline insn. */
21869 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
21871 if (is_nonpipeline_insn (ready[n_ready - 1])
21872 && (recog_memoized (ready[n_ready - 2]) > 0))
21873 /* Simply swap first two insns. */
21875 rtx tmp = ready[n_ready - 1];
21876 ready[n_ready - 1] = ready[n_ready - 2];
21877 ready[n_ready - 2] = tmp;
21881 if (rs6000_cpu == PROCESSOR_POWER6)
21882 load_store_pendulum = 0;
21884 return rs6000_issue_rate ();
21887 /* Like rs6000_sched_reorder, but called after issuing each insn. */
21890 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
21891 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
21894 fprintf (dump, "// rs6000_sched_reorder2 :\n");
21896 /* For Power6, we need to handle some special cases to try and keep the
21897 store queue from overflowing and triggering expensive flushes.
21899 This code monitors how load and store instructions are being issued
21900 and skews the ready list one way or the other to increase the likelihood
21901 that a desired instruction is issued at the proper time.
21903 A couple of things are done. First, we maintain a "load_store_pendulum"
21904 to track the current state of load/store issue.
21906 - If the pendulum is at zero, then no loads or stores have been
21907 issued in the current cycle so we do nothing.
21909 - If the pendulum is 1, then a single load has been issued in this
21910 cycle and we attempt to locate another load in the ready list to
21913 - If the pendulum is -2, then two stores have already been
21914 issued in this cycle, so we increase the priority of the first load
21915 in the ready list to increase it's likelihood of being chosen first
21918 - If the pendulum is -1, then a single store has been issued in this
21919 cycle and we attempt to locate another store in the ready list to
21920 issue with it, preferring a store to an adjacent memory location to
21921 facilitate store pairing in the store queue.
21923 - If the pendulum is 2, then two loads have already been
21924 issued in this cycle, so we increase the priority of the first store
21925 in the ready list to increase it's likelihood of being chosen first
21928 - If the pendulum < -2 or > 2, then do nothing.
21930 Note: This code covers the most common scenarios. There exist non
21931 load/store instructions which make use of the LSU and which
21932 would need to be accounted for to strictly model the behavior
21933 of the machine. Those instructions are currently unaccounted
21934 for to help minimize compile time overhead of this code.
21936 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
21942 if (is_store_insn (last_scheduled_insn))
21943 /* Issuing a store, swing the load_store_pendulum to the left */
21944 load_store_pendulum--;
21945 else if (is_load_insn (last_scheduled_insn))
21946 /* Issuing a load, swing the load_store_pendulum to the right */
21947 load_store_pendulum++;
21949 return cached_can_issue_more;
21951 /* If the pendulum is balanced, or there is only one instruction on
21952 the ready list, then all is well, so return. */
21953 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
21954 return cached_can_issue_more;
21956 if (load_store_pendulum == 1)
21958 /* A load has been issued in this cycle. Scan the ready list
21959 for another load to issue with it */
21964 if (is_load_insn (ready[pos]))
21966 /* Found a load. Move it to the head of the ready list,
21967 and adjust it's priority so that it is more likely to
21970 for (i=pos; i<*pn_ready-1; i++)
21971 ready[i] = ready[i + 1];
21972 ready[*pn_ready-1] = tmp;
21974 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
21975 INSN_PRIORITY (tmp)++;
21981 else if (load_store_pendulum == -2)
21983 /* Two stores have been issued in this cycle. Increase the
21984 priority of the first load in the ready list to favor it for
21985 issuing in the next cycle. */
21990 if (is_load_insn (ready[pos])
21992 && INSN_PRIORITY_KNOWN (ready[pos]))
21994 INSN_PRIORITY (ready[pos])++;
21996 /* Adjust the pendulum to account for the fact that a load
21997 was found and increased in priority. This is to prevent
21998 increasing the priority of multiple loads */
21999 load_store_pendulum--;
22006 else if (load_store_pendulum == -1)
22008 /* A store has been issued in this cycle. Scan the ready list for
22009 another store to issue with it, preferring a store to an adjacent
22011 int first_store_pos = -1;
22017 if (is_store_insn (ready[pos]))
22019 /* Maintain the index of the first store found on the
22021 if (first_store_pos == -1)
22022 first_store_pos = pos;
22024 if (is_store_insn (last_scheduled_insn)
22025 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22027 /* Found an adjacent store. Move it to the head of the
22028 ready list, and adjust it's priority so that it is
22029 more likely to stay there */
22031 for (i=pos; i<*pn_ready-1; i++)
22032 ready[i] = ready[i + 1];
22033 ready[*pn_ready-1] = tmp;
22035 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22036 INSN_PRIORITY (tmp)++;
22038 first_store_pos = -1;
22046 if (first_store_pos >= 0)
22048 /* An adjacent store wasn't found, but a non-adjacent store was,
22049 so move the non-adjacent store to the front of the ready
22050 list, and adjust its priority so that it is more likely to
22052 tmp = ready[first_store_pos];
22053 for (i=first_store_pos; i<*pn_ready-1; i++)
22054 ready[i] = ready[i + 1];
22055 ready[*pn_ready-1] = tmp;
22056 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22057 INSN_PRIORITY (tmp)++;
22060 else if (load_store_pendulum == 2)
22062 /* Two loads have been issued in this cycle. Increase the priority
22063 of the first store in the ready list to favor it for issuing in
22069 if (is_store_insn (ready[pos])
22071 && INSN_PRIORITY_KNOWN (ready[pos]))
22073 INSN_PRIORITY (ready[pos])++;
22075 /* Adjust the pendulum to account for the fact that a store
22076 was found and increased in priority. This is to prevent
22077 increasing the priority of multiple stores */
22078 load_store_pendulum++;
22087 return cached_can_issue_more;
22090 /* Return whether the presence of INSN causes a dispatch group termination
22091 of group WHICH_GROUP.
22093 If WHICH_GROUP == current_group, this function will return true if INSN
22094 causes the termination of the current group (i.e, the dispatch group to
22095 which INSN belongs). This means that INSN will be the last insn in the
22096 group it belongs to.
22098 If WHICH_GROUP == previous_group, this function will return true if INSN
22099 causes the termination of the previous group (i.e, the dispatch group that
22100 precedes the group to which INSN belongs). This means that INSN will be
22101 the first insn in the group it belongs to). */
22104 insn_terminates_group_p (rtx insn, enum group_termination which_group)
22111 first = insn_must_be_first_in_group (insn);
22112 last = insn_must_be_last_in_group (insn);
22117 if (which_group == current_group)
22119 else if (which_group == previous_group)
22127 insn_must_be_first_in_group (rtx insn)
22129 enum attr_type type;
22132 || GET_CODE (insn) == NOTE
22133 || DEBUG_INSN_P (insn)
22134 || GET_CODE (PATTERN (insn)) == USE
22135 || GET_CODE (PATTERN (insn)) == CLOBBER)
22138 switch (rs6000_cpu)
22140 case PROCESSOR_POWER5:
22141 if (is_cracked_insn (insn))
22143 case PROCESSOR_POWER4:
22144 if (is_microcoded_insn (insn))
22147 if (!rs6000_sched_groups)
22150 type = get_attr_type (insn);
22157 case TYPE_DELAYED_CR:
22158 case TYPE_CR_LOGICAL:
22172 case PROCESSOR_POWER6:
22173 type = get_attr_type (insn);
22177 case TYPE_INSERT_DWORD:
22181 case TYPE_VAR_SHIFT_ROTATE:
22188 case TYPE_INSERT_WORD:
22189 case TYPE_DELAYED_COMPARE:
22190 case TYPE_IMUL_COMPARE:
22191 case TYPE_LMUL_COMPARE:
22192 case TYPE_FPCOMPARE:
22203 case TYPE_LOAD_EXT_UX:
22205 case TYPE_STORE_UX:
22206 case TYPE_FPLOAD_U:
22207 case TYPE_FPLOAD_UX:
22208 case TYPE_FPSTORE_U:
22209 case TYPE_FPSTORE_UX:
22215 case PROCESSOR_POWER7:
22216 type = get_attr_type (insn);
22220 case TYPE_CR_LOGICAL:
22227 case TYPE_DELAYED_COMPARE:
22228 case TYPE_VAR_DELAYED_COMPARE:
22234 case TYPE_LOAD_EXT:
22235 case TYPE_LOAD_EXT_U:
22236 case TYPE_LOAD_EXT_UX:
22238 case TYPE_STORE_UX:
22239 case TYPE_FPLOAD_U:
22240 case TYPE_FPLOAD_UX:
22241 case TYPE_FPSTORE_U:
22242 case TYPE_FPSTORE_UX:
22258 insn_must_be_last_in_group (rtx insn)
22260 enum attr_type type;
22263 || GET_CODE (insn) == NOTE
22264 || DEBUG_INSN_P (insn)
22265 || GET_CODE (PATTERN (insn)) == USE
22266 || GET_CODE (PATTERN (insn)) == CLOBBER)
22269 switch (rs6000_cpu) {
22270 case PROCESSOR_POWER4:
22271 case PROCESSOR_POWER5:
22272 if (is_microcoded_insn (insn))
22275 if (is_branch_slot_insn (insn))
22279 case PROCESSOR_POWER6:
22280 type = get_attr_type (insn);
22287 case TYPE_VAR_SHIFT_ROTATE:
22294 case TYPE_DELAYED_COMPARE:
22295 case TYPE_IMUL_COMPARE:
22296 case TYPE_LMUL_COMPARE:
22297 case TYPE_FPCOMPARE:
22311 case PROCESSOR_POWER7:
22312 type = get_attr_type (insn);
22320 case TYPE_LOAD_EXT_U:
22321 case TYPE_LOAD_EXT_UX:
22322 case TYPE_STORE_UX:
22335 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
22336 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
22339 is_costly_group (rtx *group_insns, rtx next_insn)
22342 int issue_rate = rs6000_issue_rate ();
22344 for (i = 0; i < issue_rate; i++)
22346 sd_iterator_def sd_it;
22348 rtx insn = group_insns[i];
22353 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
22355 rtx next = DEP_CON (dep);
22357 if (next == next_insn
22358 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
22366 /* Utility of the function redefine_groups.
22367 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
22368 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
22369 to keep it "far" (in a separate group) from GROUP_INSNS, following
22370 one of the following schemes, depending on the value of the flag
22371 -minsert_sched_nops = X:
22372 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
22373 in order to force NEXT_INSN into a separate group.
22374 (2) X < sched_finish_regroup_exact: insert exactly X nops.
22375 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
22376 insertion (has a group just ended, how many vacant issue slots remain in the
22377 last group, and how many dispatch groups were encountered so far). */
22380 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
22381 rtx next_insn, bool *group_end, int can_issue_more,
22386 int issue_rate = rs6000_issue_rate ();
22387 bool end = *group_end;
22390 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
22391 return can_issue_more;
22393 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
22394 return can_issue_more;
22396 force = is_costly_group (group_insns, next_insn);
22398 return can_issue_more;
22400 if (sched_verbose > 6)
22401 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
22402 *group_count ,can_issue_more);
22404 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
22407 can_issue_more = 0;
22409 /* Since only a branch can be issued in the last issue_slot, it is
22410 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
22411 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
22412 in this case the last nop will start a new group and the branch
22413 will be forced to the new group. */
22414 if (can_issue_more && !is_branch_slot_insn (next_insn))
22417 while (can_issue_more > 0)
22420 emit_insn_before (nop, next_insn);
22428 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
22430 int n_nops = rs6000_sched_insert_nops;
22432 /* Nops can't be issued from the branch slot, so the effective
22433 issue_rate for nops is 'issue_rate - 1'. */
22434 if (can_issue_more == 0)
22435 can_issue_more = issue_rate;
22437 if (can_issue_more == 0)
22439 can_issue_more = issue_rate - 1;
22442 for (i = 0; i < issue_rate; i++)
22444 group_insns[i] = 0;
22451 emit_insn_before (nop, next_insn);
22452 if (can_issue_more == issue_rate - 1) /* new group begins */
22455 if (can_issue_more == 0)
22457 can_issue_more = issue_rate - 1;
22460 for (i = 0; i < issue_rate; i++)
22462 group_insns[i] = 0;
22468 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
22471 /* Is next_insn going to start a new group? */
22474 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22475 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22476 || (can_issue_more < issue_rate &&
22477 insn_terminates_group_p (next_insn, previous_group)));
22478 if (*group_end && end)
22481 if (sched_verbose > 6)
22482 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
22483 *group_count, can_issue_more);
22484 return can_issue_more;
22487 return can_issue_more;
22490 /* This function tries to synch the dispatch groups that the compiler "sees"
22491 with the dispatch groups that the processor dispatcher is expected to
22492 form in practice. It tries to achieve this synchronization by forcing the
22493 estimated processor grouping on the compiler (as opposed to the function
22494 'pad_goups' which tries to force the scheduler's grouping on the processor).
22496 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
22497 examines the (estimated) dispatch groups that will be formed by the processor
22498 dispatcher. It marks these group boundaries to reflect the estimated
22499 processor grouping, overriding the grouping that the scheduler had marked.
22500 Depending on the value of the flag '-minsert-sched-nops' this function can
22501 force certain insns into separate groups or force a certain distance between
22502 them by inserting nops, for example, if there exists a "costly dependence"
22505 The function estimates the group boundaries that the processor will form as
22506 follows: It keeps track of how many vacant issue slots are available after
22507 each insn. A subsequent insn will start a new group if one of the following
22509 - no more vacant issue slots remain in the current dispatch group.
22510 - only the last issue slot, which is the branch slot, is vacant, but the next
22511 insn is not a branch.
22512 - only the last 2 or less issue slots, including the branch slot, are vacant,
22513 which means that a cracked insn (which occupies two issue slots) can't be
22514 issued in this group.
22515 - less than 'issue_rate' slots are vacant, and the next insn always needs to
22516 start a new group. */
22519 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22521 rtx insn, next_insn;
22523 int can_issue_more;
22526 int group_count = 0;
22530 issue_rate = rs6000_issue_rate ();
22531 group_insns = XALLOCAVEC (rtx, issue_rate);
22532 for (i = 0; i < issue_rate; i++)
22534 group_insns[i] = 0;
22536 can_issue_more = issue_rate;
22538 insn = get_next_active_insn (prev_head_insn, tail);
22541 while (insn != NULL_RTX)
22543 slot = (issue_rate - can_issue_more);
22544 group_insns[slot] = insn;
22546 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
22547 if (insn_terminates_group_p (insn, current_group))
22548 can_issue_more = 0;
22550 next_insn = get_next_active_insn (insn, tail);
22551 if (next_insn == NULL_RTX)
22552 return group_count + 1;
22554 /* Is next_insn going to start a new group? */
22556 = (can_issue_more == 0
22557 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
22558 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
22559 || (can_issue_more < issue_rate &&
22560 insn_terminates_group_p (next_insn, previous_group)));
22562 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
22563 next_insn, &group_end, can_issue_more,
22569 can_issue_more = 0;
22570 for (i = 0; i < issue_rate; i++)
22572 group_insns[i] = 0;
22576 if (GET_MODE (next_insn) == TImode && can_issue_more)
22577 PUT_MODE (next_insn, VOIDmode);
22578 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
22579 PUT_MODE (next_insn, TImode);
22582 if (can_issue_more == 0)
22583 can_issue_more = issue_rate;
22586 return group_count;
22589 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
22590 dispatch group boundaries that the scheduler had marked. Pad with nops
22591 any dispatch groups which have vacant issue slots, in order to force the
22592 scheduler's grouping on the processor dispatcher. The function
22593 returns the number of dispatch groups found. */
22596 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
22598 rtx insn, next_insn;
22601 int can_issue_more;
22603 int group_count = 0;
22605 /* Initialize issue_rate. */
22606 issue_rate = rs6000_issue_rate ();
22607 can_issue_more = issue_rate;
22609 insn = get_next_active_insn (prev_head_insn, tail);
22610 next_insn = get_next_active_insn (insn, tail);
22612 while (insn != NULL_RTX)
22615 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
22617 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
22619 if (next_insn == NULL_RTX)
22624 /* If the scheduler had marked group termination at this location
22625 (between insn and next_insn), and neither insn nor next_insn will
22626 force group termination, pad the group with nops to force group
22629 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
22630 && !insn_terminates_group_p (insn, current_group)
22631 && !insn_terminates_group_p (next_insn, previous_group))
22633 if (!is_branch_slot_insn (next_insn))
22636 while (can_issue_more)
22639 emit_insn_before (nop, next_insn);
22644 can_issue_more = issue_rate;
22649 next_insn = get_next_active_insn (insn, tail);
22652 return group_count;
22655 /* We're beginning a new block. Initialize data structures as necessary. */
22658 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
22659 int sched_verbose ATTRIBUTE_UNUSED,
22660 int max_ready ATTRIBUTE_UNUSED)
22662 last_scheduled_insn = NULL_RTX;
22663 load_store_pendulum = 0;
22666 /* The following function is called at the end of scheduling BB.
22667 After reload, it inserts nops at insn group bundling. */
22670 rs6000_sched_finish (FILE *dump, int sched_verbose)
22675 fprintf (dump, "=== Finishing schedule.\n");
22677 if (reload_completed && rs6000_sched_groups)
22679 /* Do not run sched_finish hook when selective scheduling enabled. */
22680 if (sel_sched_p ())
22683 if (rs6000_sched_insert_nops == sched_finish_none)
22686 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
22687 n_groups = pad_groups (dump, sched_verbose,
22688 current_sched_info->prev_head,
22689 current_sched_info->next_tail);
22691 n_groups = redefine_groups (dump, sched_verbose,
22692 current_sched_info->prev_head,
22693 current_sched_info->next_tail);
22695 if (sched_verbose >= 6)
22697 fprintf (dump, "ngroups = %d\n", n_groups);
22698 print_rtl (dump, current_sched_info->prev_head);
22699 fprintf (dump, "Done finish_sched\n");
22704 struct _rs6000_sched_context
22706 short cached_can_issue_more;
22707 rtx last_scheduled_insn;
22708 int load_store_pendulum;
22711 typedef struct _rs6000_sched_context rs6000_sched_context_def;
22712 typedef rs6000_sched_context_def *rs6000_sched_context_t;
22714 /* Allocate store for new scheduling context. */
22716 rs6000_alloc_sched_context (void)
22718 return xmalloc (sizeof (rs6000_sched_context_def));
22721 /* If CLEAN_P is true then initializes _SC with clean data,
22722 and from the global context otherwise. */
22724 rs6000_init_sched_context (void *_sc, bool clean_p)
22726 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
22730 sc->cached_can_issue_more = 0;
22731 sc->last_scheduled_insn = NULL_RTX;
22732 sc->load_store_pendulum = 0;
22736 sc->cached_can_issue_more = cached_can_issue_more;
22737 sc->last_scheduled_insn = last_scheduled_insn;
22738 sc->load_store_pendulum = load_store_pendulum;
22742 /* Sets the global scheduling context to the one pointed to by _SC. */
22744 rs6000_set_sched_context (void *_sc)
22746 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
22748 gcc_assert (sc != NULL);
22750 cached_can_issue_more = sc->cached_can_issue_more;
22751 last_scheduled_insn = sc->last_scheduled_insn;
22752 load_store_pendulum = sc->load_store_pendulum;
22757 rs6000_free_sched_context (void *_sc)
22759 gcc_assert (_sc != NULL);
22765 /* Length in units of the trampoline for entering a nested function. */
22768 rs6000_trampoline_size (void)
22772 switch (DEFAULT_ABI)
22775 gcc_unreachable ();
22778 ret = (TARGET_32BIT) ? 12 : 24;
22783 ret = (TARGET_32BIT) ? 40 : 48;
22790 /* Emit RTL insns to initialize the variable parts of a trampoline.
22791 FNADDR is an RTX for the address of the function's pure code.
22792 CXT is an RTX for the static chain value for the function. */
22795 rs6000_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
22797 int regsize = (TARGET_32BIT) ? 4 : 8;
22798 rtx ctx_reg = force_reg (Pmode, cxt);
22800 switch (DEFAULT_ABI)
22803 gcc_unreachable ();
22805 /* Macros to shorten the code expansions below. */
22806 #define MEM_DEREF(addr) gen_rtx_MEM (Pmode, memory_address (Pmode, addr))
22807 #define MEM_PLUS(addr,offset) \
22808 gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (addr, offset)))
22810 /* Under AIX, just build the 3 word function descriptor */
22813 rtx fn_reg = gen_reg_rtx (Pmode);
22814 rtx toc_reg = gen_reg_rtx (Pmode);
22815 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
22816 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
22817 emit_move_insn (MEM_DEREF (addr), fn_reg);
22818 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
22819 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
22823 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
22826 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
22827 LCT_NORMAL, VOIDmode, 4,
22829 GEN_INT (rs6000_trampoline_size ()), SImode,
22839 /* Handle the "altivec" attribute. The attribute may have
22840 arguments as follows:
22842 __attribute__((altivec(vector__)))
22843 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
22844 __attribute__((altivec(bool__))) (always followed by 'unsigned')
22846 and may appear more than once (e.g., 'vector bool char') in a
22847 given declaration. */
22850 rs6000_handle_altivec_attribute (tree *node,
22851 tree name ATTRIBUTE_UNUSED,
22853 int flags ATTRIBUTE_UNUSED,
22854 bool *no_add_attrs)
22856 tree type = *node, result = NULL_TREE;
22857 enum machine_mode mode;
22860 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
22861 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
22862 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
22865 while (POINTER_TYPE_P (type)
22866 || TREE_CODE (type) == FUNCTION_TYPE
22867 || TREE_CODE (type) == METHOD_TYPE
22868 || TREE_CODE (type) == ARRAY_TYPE)
22869 type = TREE_TYPE (type);
22871 mode = TYPE_MODE (type);
22873 /* Check for invalid AltiVec type qualifiers. */
22874 if (type == long_double_type_node)
22875 error ("use of %<long double%> in AltiVec types is invalid");
22876 else if (type == boolean_type_node)
22877 error ("use of boolean types in AltiVec types is invalid");
22878 else if (TREE_CODE (type) == COMPLEX_TYPE)
22879 error ("use of %<complex%> in AltiVec types is invalid");
22880 else if (DECIMAL_FLOAT_MODE_P (mode))
22881 error ("use of decimal floating point types in AltiVec types is invalid");
22882 else if (!TARGET_VSX)
22884 if (type == long_unsigned_type_node || type == long_integer_type_node)
22887 error ("use of %<long%> in AltiVec types is invalid for "
22888 "64-bit code without -mvsx");
22889 else if (rs6000_warn_altivec_long)
22890 warning (0, "use of %<long%> in AltiVec types is deprecated; "
22893 else if (type == long_long_unsigned_type_node
22894 || type == long_long_integer_type_node)
22895 error ("use of %<long long%> in AltiVec types is invalid without "
22897 else if (type == double_type_node)
22898 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
22901 switch (altivec_type)
22904 unsigned_p = TYPE_UNSIGNED (type);
22908 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
22911 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
22914 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
22917 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
22919 case SFmode: result = V4SF_type_node; break;
22920 case DFmode: result = V2DF_type_node; break;
22921 /* If the user says 'vector int bool', we may be handed the 'bool'
22922 attribute _before_ the 'vector' attribute, and so select the
22923 proper type in the 'b' case below. */
22924 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
22925 case V2DImode: case V2DFmode:
22933 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
22934 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
22935 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
22936 case QImode: case V16QImode: result = bool_V16QI_type_node;
22943 case V8HImode: result = pixel_V8HI_type_node;
22949 /* Propagate qualifiers attached to the element type
22950 onto the vector type. */
22951 if (result && result != type && TYPE_QUALS (type))
22952 result = build_qualified_type (result, TYPE_QUALS (type));
22954 *no_add_attrs = true; /* No need to hang on to the attribute. */
22957 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
22962 /* AltiVec defines four built-in scalar types that serve as vector
22963 elements; we must teach the compiler how to mangle them. */
22965 static const char *
22966 rs6000_mangle_type (const_tree type)
22968 type = TYPE_MAIN_VARIANT (type);
22970 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
22971 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
22974 if (type == bool_char_type_node) return "U6__boolc";
22975 if (type == bool_short_type_node) return "U6__bools";
22976 if (type == pixel_type_node) return "u7__pixel";
22977 if (type == bool_int_type_node) return "U6__booli";
22978 if (type == bool_long_type_node) return "U6__booll";
22980 /* Mangle IBM extended float long double as `g' (__float128) on
22981 powerpc*-linux where long-double-64 previously was the default. */
22982 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
22984 && TARGET_LONG_DOUBLE_128
22985 && !TARGET_IEEEQUAD)
22988 /* For all other types, use normal C++ mangling. */
22992 /* Handle a "longcall" or "shortcall" attribute; arguments as in
22993 struct attribute_spec.handler. */
22996 rs6000_handle_longcall_attribute (tree *node, tree name,
22997 tree args ATTRIBUTE_UNUSED,
22998 int flags ATTRIBUTE_UNUSED,
22999 bool *no_add_attrs)
23001 if (TREE_CODE (*node) != FUNCTION_TYPE
23002 && TREE_CODE (*node) != FIELD_DECL
23003 && TREE_CODE (*node) != TYPE_DECL)
23005 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23007 *no_add_attrs = true;
23013 /* Set longcall attributes on all functions declared when
23014 rs6000_default_long_calls is true. */
23016 rs6000_set_default_type_attributes (tree type)
23018 if (rs6000_default_long_calls
23019 && (TREE_CODE (type) == FUNCTION_TYPE
23020 || TREE_CODE (type) == METHOD_TYPE))
23021 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23023 TYPE_ATTRIBUTES (type));
23026 darwin_set_default_type_attributes (type);
23030 /* Return a reference suitable for calling a function with the
23031 longcall attribute. */
23034 rs6000_longcall_ref (rtx call_ref)
23036 const char *call_name;
23039 if (GET_CODE (call_ref) != SYMBOL_REF)
23042 /* System V adds '.' to the internal name, so skip them. */
23043 call_name = XSTR (call_ref, 0);
23044 if (*call_name == '.')
23046 while (*call_name == '.')
23049 node = get_identifier (call_name);
23050 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
23053 return force_reg (Pmode, call_ref);
23056 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23057 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23060 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23061 struct attribute_spec.handler. */
23063 rs6000_handle_struct_attribute (tree *node, tree name,
23064 tree args ATTRIBUTE_UNUSED,
23065 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
23068 if (DECL_P (*node))
23070 if (TREE_CODE (*node) == TYPE_DECL)
23071 type = &TREE_TYPE (*node);
23076 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
23077 || TREE_CODE (*type) == UNION_TYPE)))
23079 warning (OPT_Wattributes, "%qE attribute ignored", name);
23080 *no_add_attrs = true;
23083 else if ((is_attribute_p ("ms_struct", name)
23084 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
23085 || ((is_attribute_p ("gcc_struct", name)
23086 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
23088 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
23090 *no_add_attrs = true;
23097 rs6000_ms_bitfield_layout_p (const_tree record_type)
23099 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
23100 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
23101 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
23104 #ifdef USING_ELFOS_H
23106 /* A get_unnamed_section callback, used for switching to toc_section. */
23109 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23111 if (DEFAULT_ABI == ABI_AIX
23112 && TARGET_MINIMAL_TOC
23113 && !TARGET_RELOCATABLE)
23115 if (!toc_initialized)
23117 toc_initialized = 1;
23118 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23119 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
23120 fprintf (asm_out_file, "\t.tc ");
23121 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
23122 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23123 fprintf (asm_out_file, "\n");
23125 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23126 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23127 fprintf (asm_out_file, " = .+32768\n");
23130 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23132 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
23133 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23136 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23137 if (!toc_initialized)
23139 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23140 fprintf (asm_out_file, " = .+32768\n");
23141 toc_initialized = 1;
23146 /* Implement TARGET_ASM_INIT_SECTIONS. */
23149 rs6000_elf_asm_init_sections (void)
23152 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
23155 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
23156 SDATA2_SECTION_ASM_OP);
23159 /* Implement TARGET_SELECT_RTX_SECTION. */
23162 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
23163 unsigned HOST_WIDE_INT align)
23165 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23166 return toc_section;
23168 return default_elf_select_rtx_section (mode, x, align);
23171 /* For a SYMBOL_REF, set generic flags and then perform some
23172 target-specific processing.
23174 When the AIX ABI is requested on a non-AIX system, replace the
23175 function name with the real name (with a leading .) rather than the
23176 function descriptor name. This saves a lot of overriding code to
23177 read the prefixes. */
23180 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
23182 default_encode_section_info (decl, rtl, first);
23185 && TREE_CODE (decl) == FUNCTION_DECL
23187 && DEFAULT_ABI == ABI_AIX)
23189 rtx sym_ref = XEXP (rtl, 0);
23190 size_t len = strlen (XSTR (sym_ref, 0));
23191 char *str = XALLOCAVEC (char, len + 2);
23193 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
23194 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
23199 compare_section_name (const char *section, const char *templ)
23203 len = strlen (templ);
23204 return (strncmp (section, templ, len) == 0
23205 && (section[len] == 0 || section[len] == '.'));
23209 rs6000_elf_in_small_data_p (const_tree decl)
23211 if (rs6000_sdata == SDATA_NONE)
23214 /* We want to merge strings, so we never consider them small data. */
23215 if (TREE_CODE (decl) == STRING_CST)
23218 /* Functions are never in the small data area. */
23219 if (TREE_CODE (decl) == FUNCTION_DECL)
23222 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
23224 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
23225 if (compare_section_name (section, ".sdata")
23226 || compare_section_name (section, ".sdata2")
23227 || compare_section_name (section, ".gnu.linkonce.s")
23228 || compare_section_name (section, ".sbss")
23229 || compare_section_name (section, ".sbss2")
23230 || compare_section_name (section, ".gnu.linkonce.sb")
23231 || strcmp (section, ".PPC.EMB.sdata0") == 0
23232 || strcmp (section, ".PPC.EMB.sbss0") == 0)
23237 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
23240 && (unsigned HOST_WIDE_INT) size <= g_switch_value
23241 /* If it's not public, and we're not going to reference it there,
23242 there's no need to put it in the small data section. */
23243 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
23250 #endif /* USING_ELFOS_H */
23252 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
23255 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
23257 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
23260 /* Return a REG that occurs in ADDR with coefficient 1.
23261 ADDR can be effectively incremented by incrementing REG.
23263 r0 is special and we must not select it as an address
23264 register by this routine since our caller will try to
23265 increment the returned register via an "la" instruction. */
23268 find_addr_reg (rtx addr)
23270 while (GET_CODE (addr) == PLUS)
23272 if (GET_CODE (XEXP (addr, 0)) == REG
23273 && REGNO (XEXP (addr, 0)) != 0)
23274 addr = XEXP (addr, 0);
23275 else if (GET_CODE (XEXP (addr, 1)) == REG
23276 && REGNO (XEXP (addr, 1)) != 0)
23277 addr = XEXP (addr, 1);
23278 else if (CONSTANT_P (XEXP (addr, 0)))
23279 addr = XEXP (addr, 1);
23280 else if (CONSTANT_P (XEXP (addr, 1)))
23281 addr = XEXP (addr, 0);
23283 gcc_unreachable ();
23285 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
23290 rs6000_fatal_bad_address (rtx op)
23292 fatal_insn ("bad address", op);
23297 static tree branch_island_list = 0;
23299 /* Remember to generate a branch island for far calls to the given
23303 add_compiler_branch_island (tree label_name, tree function_name,
23306 tree branch_island = build_tree_list (function_name, label_name);
23307 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
23308 TREE_CHAIN (branch_island) = branch_island_list;
23309 branch_island_list = branch_island;
23312 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
23313 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
23314 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
23315 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
23317 /* Generate far-jump branch islands for everything on the
23318 branch_island_list. Invoked immediately after the last instruction
23319 of the epilogue has been emitted; the branch-islands must be
23320 appended to, and contiguous with, the function body. Mach-O stubs
23321 are generated in machopic_output_stub(). */
23324 macho_branch_islands (void)
23327 tree branch_island;
23329 for (branch_island = branch_island_list;
23331 branch_island = TREE_CHAIN (branch_island))
23333 const char *label =
23334 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
23336 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
23337 char name_buf[512];
23338 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
23339 if (name[0] == '*' || name[0] == '&')
23340 strcpy (name_buf, name+1);
23344 strcpy (name_buf+1, name);
23346 strcpy (tmp_buf, "\n");
23347 strcat (tmp_buf, label);
23348 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23349 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23350 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23351 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23354 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
23355 strcat (tmp_buf, label);
23356 strcat (tmp_buf, "_pic\n");
23357 strcat (tmp_buf, label);
23358 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
23360 strcat (tmp_buf, "\taddis r11,r11,ha16(");
23361 strcat (tmp_buf, name_buf);
23362 strcat (tmp_buf, " - ");
23363 strcat (tmp_buf, label);
23364 strcat (tmp_buf, "_pic)\n");
23366 strcat (tmp_buf, "\tmtlr r0\n");
23368 strcat (tmp_buf, "\taddi r12,r11,lo16(");
23369 strcat (tmp_buf, name_buf);
23370 strcat (tmp_buf, " - ");
23371 strcat (tmp_buf, label);
23372 strcat (tmp_buf, "_pic)\n");
23374 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
23378 strcat (tmp_buf, ":\nlis r12,hi16(");
23379 strcat (tmp_buf, name_buf);
23380 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
23381 strcat (tmp_buf, name_buf);
23382 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
23384 output_asm_insn (tmp_buf, 0);
23385 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23386 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
23387 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
23388 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23391 branch_island_list = 0;
23394 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
23395 already there or not. */
23398 no_previous_def (tree function_name)
23400 tree branch_island;
23401 for (branch_island = branch_island_list;
23403 branch_island = TREE_CHAIN (branch_island))
23404 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23409 /* GET_PREV_LABEL gets the label name from the previous definition of
23413 get_prev_label (tree function_name)
23415 tree branch_island;
23416 for (branch_island = branch_island_list;
23418 branch_island = TREE_CHAIN (branch_island))
23419 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
23420 return BRANCH_ISLAND_LABEL_NAME (branch_island);
23424 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
23425 #define DARWIN_LINKER_GENERATES_ISLANDS 0
23428 /* KEXTs still need branch islands. */
23429 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
23430 || flag_mkernel || flag_apple_kext)
23432 /* INSN is either a function call or a millicode call. It may have an
23433 unconditional jump in its delay slot.
23435 CALL_DEST is the routine we are calling. */
23438 output_call (rtx insn, rtx *operands, int dest_operand_number,
23439 int cookie_operand_number)
23441 static char buf[256];
23442 if (DARWIN_GENERATE_ISLANDS
23443 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
23444 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
23447 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
23449 if (no_previous_def (funname))
23451 rtx label_rtx = gen_label_rtx ();
23452 char *label_buf, temp_buf[256];
23453 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
23454 CODE_LABEL_NUMBER (label_rtx));
23455 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
23456 labelname = get_identifier (label_buf);
23457 add_compiler_branch_island (labelname, funname, insn_line (insn));
23460 labelname = get_prev_label (funname);
23462 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
23463 instruction will reach 'foo', otherwise link as 'bl L42'".
23464 "L42" should be a 'branch island', that will do a far jump to
23465 'foo'. Branch islands are generated in
23466 macho_branch_islands(). */
23467 sprintf (buf, "jbsr %%z%d,%.246s",
23468 dest_operand_number, IDENTIFIER_POINTER (labelname));
23471 sprintf (buf, "bl %%z%d", dest_operand_number);
23475 /* Generate PIC and indirect symbol stubs. */
23478 machopic_output_stub (FILE *file, const char *symb, const char *stub)
23480 unsigned int length;
23481 char *symbol_name, *lazy_ptr_name;
23482 char *local_label_0;
23483 static int label = 0;
23485 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
23486 symb = (*targetm.strip_name_encoding) (symb);
23489 length = strlen (symb);
23490 symbol_name = XALLOCAVEC (char, length + 32);
23491 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
23493 lazy_ptr_name = XALLOCAVEC (char, length + 32);
23494 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
23497 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
23499 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
23503 fprintf (file, "\t.align 5\n");
23505 fprintf (file, "%s:\n", stub);
23506 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23509 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
23510 sprintf (local_label_0, "\"L%011d$spb\"", label);
23512 fprintf (file, "\tmflr r0\n");
23513 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
23514 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
23515 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
23516 lazy_ptr_name, local_label_0);
23517 fprintf (file, "\tmtlr r0\n");
23518 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
23519 (TARGET_64BIT ? "ldu" : "lwzu"),
23520 lazy_ptr_name, local_label_0);
23521 fprintf (file, "\tmtctr r12\n");
23522 fprintf (file, "\tbctr\n");
23526 fprintf (file, "\t.align 4\n");
23528 fprintf (file, "%s:\n", stub);
23529 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23531 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
23532 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
23533 (TARGET_64BIT ? "ldu" : "lwzu"),
23535 fprintf (file, "\tmtctr r12\n");
23536 fprintf (file, "\tbctr\n");
23539 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
23540 fprintf (file, "%s:\n", lazy_ptr_name);
23541 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23542 fprintf (file, "%sdyld_stub_binding_helper\n",
23543 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
23546 /* Legitimize PIC addresses. If the address is already
23547 position-independent, we return ORIG. Newly generated
23548 position-independent addresses go into a reg. This is REG if non
23549 zero, otherwise we allocate register(s) as necessary. */
23551 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
23554 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
23559 if (reg == NULL && ! reload_in_progress && ! reload_completed)
23560 reg = gen_reg_rtx (Pmode);
23562 if (GET_CODE (orig) == CONST)
23566 if (GET_CODE (XEXP (orig, 0)) == PLUS
23567 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
23570 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
23572 /* Use a different reg for the intermediate value, as
23573 it will be marked UNCHANGING. */
23574 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
23575 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
23578 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
23581 if (GET_CODE (offset) == CONST_INT)
23583 if (SMALL_INT (offset))
23584 return plus_constant (base, INTVAL (offset));
23585 else if (! reload_in_progress && ! reload_completed)
23586 offset = force_reg (Pmode, offset);
23589 rtx mem = force_const_mem (Pmode, orig);
23590 return machopic_legitimize_pic_address (mem, Pmode, reg);
23593 return gen_rtx_PLUS (Pmode, base, offset);
23596 /* Fall back on generic machopic code. */
23597 return machopic_legitimize_pic_address (orig, mode, reg);
23600 /* Output a .machine directive for the Darwin assembler, and call
23601 the generic start_file routine. */
23604 rs6000_darwin_file_start (void)
23606 static const struct
23612 { "ppc64", "ppc64", MASK_64BIT },
23613 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
23614 { "power4", "ppc970", 0 },
23615 { "G5", "ppc970", 0 },
23616 { "7450", "ppc7450", 0 },
23617 { "7400", "ppc7400", MASK_ALTIVEC },
23618 { "G4", "ppc7400", 0 },
23619 { "750", "ppc750", 0 },
23620 { "740", "ppc750", 0 },
23621 { "G3", "ppc750", 0 },
23622 { "604e", "ppc604e", 0 },
23623 { "604", "ppc604", 0 },
23624 { "603e", "ppc603", 0 },
23625 { "603", "ppc603", 0 },
23626 { "601", "ppc601", 0 },
23627 { NULL, "ppc", 0 } };
23628 const char *cpu_id = "";
23631 rs6000_file_start ();
23632 darwin_file_start ();
23634 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
23635 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
23636 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
23637 && rs6000_select[i].string[0] != '\0')
23638 cpu_id = rs6000_select[i].string;
23640 /* Look through the mapping array. Pick the first name that either
23641 matches the argument, has a bit set in IF_SET that is also set
23642 in the target flags, or has a NULL name. */
23645 while (mapping[i].arg != NULL
23646 && strcmp (mapping[i].arg, cpu_id) != 0
23647 && (mapping[i].if_set & target_flags) == 0)
23650 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
23653 #endif /* TARGET_MACHO */
23657 rs6000_elf_reloc_rw_mask (void)
23661 else if (DEFAULT_ABI == ABI_AIX)
23667 /* Record an element in the table of global constructors. SYMBOL is
23668 a SYMBOL_REF of the function to be called; PRIORITY is a number
23669 between 0 and MAX_INIT_PRIORITY.
23671 This differs from default_named_section_asm_out_constructor in
23672 that we have special handling for -mrelocatable. */
23675 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
23677 const char *section = ".ctors";
23680 if (priority != DEFAULT_INIT_PRIORITY)
23682 sprintf (buf, ".ctors.%.5u",
23683 /* Invert the numbering so the linker puts us in the proper
23684 order; constructors are run from right to left, and the
23685 linker sorts in increasing order. */
23686 MAX_INIT_PRIORITY - priority);
23690 switch_to_section (get_section (section, SECTION_WRITE, NULL));
23691 assemble_align (POINTER_SIZE);
23693 if (TARGET_RELOCATABLE)
23695 fputs ("\t.long (", asm_out_file);
23696 output_addr_const (asm_out_file, symbol);
23697 fputs (")@fixup\n", asm_out_file);
23700 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
23704 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
23706 const char *section = ".dtors";
23709 if (priority != DEFAULT_INIT_PRIORITY)
23711 sprintf (buf, ".dtors.%.5u",
23712 /* Invert the numbering so the linker puts us in the proper
23713 order; constructors are run from right to left, and the
23714 linker sorts in increasing order. */
23715 MAX_INIT_PRIORITY - priority);
23719 switch_to_section (get_section (section, SECTION_WRITE, NULL));
23720 assemble_align (POINTER_SIZE);
23722 if (TARGET_RELOCATABLE)
23724 fputs ("\t.long (", asm_out_file);
23725 output_addr_const (asm_out_file, symbol);
23726 fputs (")@fixup\n", asm_out_file);
23729 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
23733 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
23737 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
23738 ASM_OUTPUT_LABEL (file, name);
23739 fputs (DOUBLE_INT_ASM_OP, file);
23740 rs6000_output_function_entry (file, name);
23741 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
23744 fputs ("\t.size\t", file);
23745 assemble_name (file, name);
23746 fputs (",24\n\t.type\t.", file);
23747 assemble_name (file, name);
23748 fputs (",@function\n", file);
23749 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
23751 fputs ("\t.globl\t.", file);
23752 assemble_name (file, name);
23757 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
23758 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
23759 rs6000_output_function_entry (file, name);
23760 fputs (":\n", file);
23764 if (TARGET_RELOCATABLE
23765 && !TARGET_SECURE_PLT
23766 && (get_pool_size () != 0 || crtl->profile)
23771 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
23773 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
23774 fprintf (file, "\t.long ");
23775 assemble_name (file, buf);
23777 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
23778 assemble_name (file, buf);
23782 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
23783 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
23785 if (DEFAULT_ABI == ABI_AIX)
23787 const char *desc_name, *orig_name;
23789 orig_name = (*targetm.strip_name_encoding) (name);
23790 desc_name = orig_name;
23791 while (*desc_name == '.')
23794 if (TREE_PUBLIC (decl))
23795 fprintf (file, "\t.globl %s\n", desc_name);
23797 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23798 fprintf (file, "%s:\n", desc_name);
23799 fprintf (file, "\t.long %s\n", orig_name);
23800 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
23801 if (DEFAULT_ABI == ABI_AIX)
23802 fputs ("\t.long 0\n", file);
23803 fprintf (file, "\t.previous\n");
23805 ASM_OUTPUT_LABEL (file, name);
23809 rs6000_elf_end_indicate_exec_stack (void)
23812 file_end_indicate_exec_stack ();
23818 rs6000_xcoff_asm_output_anchor (rtx symbol)
23822 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
23823 SYMBOL_REF_BLOCK_OFFSET (symbol));
23824 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
23828 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
23830 fputs (GLOBAL_ASM_OP, stream);
23831 RS6000_OUTPUT_BASENAME (stream, name);
23832 putc ('\n', stream);
23835 /* A get_unnamed_decl callback, used for read-only sections. PTR
23836 points to the section string variable. */
23839 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
23841 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
23842 *(const char *const *) directive,
23843 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
23846 /* Likewise for read-write sections. */
23849 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
23851 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
23852 *(const char *const *) directive,
23853 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
23856 /* A get_unnamed_section callback, used for switching to toc_section. */
23859 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23861 if (TARGET_MINIMAL_TOC)
23863 /* toc_section is always selected at least once from
23864 rs6000_xcoff_file_start, so this is guaranteed to
23865 always be defined once and only once in each file. */
23866 if (!toc_initialized)
23868 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
23869 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
23870 toc_initialized = 1;
23872 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
23873 (TARGET_32BIT ? "" : ",3"));
23876 fputs ("\t.toc\n", asm_out_file);
23879 /* Implement TARGET_ASM_INIT_SECTIONS. */
23882 rs6000_xcoff_asm_init_sections (void)
23884 read_only_data_section
23885 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
23886 &xcoff_read_only_section_name);
23888 private_data_section
23889 = get_unnamed_section (SECTION_WRITE,
23890 rs6000_xcoff_output_readwrite_section_asm_op,
23891 &xcoff_private_data_section_name);
23893 read_only_private_data_section
23894 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
23895 &xcoff_private_data_section_name);
23898 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
23900 readonly_data_section = read_only_data_section;
23901 exception_section = data_section;
23905 rs6000_xcoff_reloc_rw_mask (void)
23911 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
23912 tree decl ATTRIBUTE_UNUSED)
23915 static const char * const suffix[3] = { "PR", "RO", "RW" };
23917 if (flags & SECTION_CODE)
23919 else if (flags & SECTION_WRITE)
23924 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
23925 (flags & SECTION_CODE) ? "." : "",
23926 name, suffix[smclass], flags & SECTION_ENTSIZE);
23930 rs6000_xcoff_select_section (tree decl, int reloc,
23931 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
23933 if (decl_readonly_section (decl, reloc))
23935 if (TREE_PUBLIC (decl))
23936 return read_only_data_section;
23938 return read_only_private_data_section;
23942 if (TREE_PUBLIC (decl))
23943 return data_section;
23945 return private_data_section;
23950 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
23954 /* Use select_section for private and uninitialized data. */
23955 if (!TREE_PUBLIC (decl)
23956 || DECL_COMMON (decl)
23957 || DECL_INITIAL (decl) == NULL_TREE
23958 || DECL_INITIAL (decl) == error_mark_node
23959 || (flag_zero_initialized_in_bss
23960 && initializer_zerop (DECL_INITIAL (decl))))
23963 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
23964 name = (*targetm.strip_name_encoding) (name);
23965 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
23968 /* Select section for constant in constant pool.
23970 On RS/6000, all constants are in the private read-only data area.
23971 However, if this is being placed in the TOC it must be output as a
23975 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
23976 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
23978 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
23979 return toc_section;
23981 return read_only_private_data_section;
23984 /* Remove any trailing [DS] or the like from the symbol name. */
23986 static const char *
23987 rs6000_xcoff_strip_name_encoding (const char *name)
23992 len = strlen (name);
23993 if (name[len - 1] == ']')
23994 return ggc_alloc_string (name, len - 4);
23999 /* Section attributes. AIX is always PIC. */
24001 static unsigned int
24002 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24004 unsigned int align;
24005 unsigned int flags = default_section_type_flags (decl, name, reloc);
24007 /* Align to at least UNIT size. */
24008 if (flags & SECTION_CODE)
24009 align = MIN_UNITS_PER_WORD;
24011 /* Increase alignment of large objects if not already stricter. */
24012 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24013 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24014 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24016 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24019 /* Output at beginning of assembler file.
24021 Initialize the section names for the RS/6000 at this point.
24023 Specify filename, including full path, to assembler.
24025 We want to go into the TOC section so at least one .toc will be emitted.
24026 Also, in order to output proper .bs/.es pairs, we need at least one static
24027 [RW] section emitted.
24029 Finally, declare mcount when profiling to make the assembler happy. */
24032 rs6000_xcoff_file_start (void)
24034 rs6000_gen_section_name (&xcoff_bss_section_name,
24035 main_input_filename, ".bss_");
24036 rs6000_gen_section_name (&xcoff_private_data_section_name,
24037 main_input_filename, ".rw_");
24038 rs6000_gen_section_name (&xcoff_read_only_section_name,
24039 main_input_filename, ".ro_");
24041 fputs ("\t.file\t", asm_out_file);
24042 output_quoted_string (asm_out_file, main_input_filename);
24043 fputc ('\n', asm_out_file);
24044 if (write_symbols != NO_DEBUG)
24045 switch_to_section (private_data_section);
24046 switch_to_section (text_section);
24048 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
24049 rs6000_file_start ();
24052 /* Output at end of assembler file.
24053 On the RS/6000, referencing data should automatically pull in text. */
24056 rs6000_xcoff_file_end (void)
24058 switch_to_section (text_section);
24059 fputs ("_section_.text:\n", asm_out_file);
24060 switch_to_section (data_section);
24061 fputs (TARGET_32BIT
24062 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24065 #endif /* TARGET_XCOFF */
24067 /* Compute a (partial) cost for rtx X. Return true if the complete
24068 cost has been computed, and false if subexpressions should be
24069 scanned. In either case, *TOTAL contains the cost result. */
24072 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
24075 enum machine_mode mode = GET_MODE (x);
24079 /* On the RS/6000, if it is valid in the insn, it is free. */
24081 if (((outer_code == SET
24082 || outer_code == PLUS
24083 || outer_code == MINUS)
24084 && (satisfies_constraint_I (x)
24085 || satisfies_constraint_L (x)))
24086 || (outer_code == AND
24087 && (satisfies_constraint_K (x)
24089 ? satisfies_constraint_L (x)
24090 : satisfies_constraint_J (x))
24091 || mask_operand (x, mode)
24093 && mask64_operand (x, DImode))))
24094 || ((outer_code == IOR || outer_code == XOR)
24095 && (satisfies_constraint_K (x)
24097 ? satisfies_constraint_L (x)
24098 : satisfies_constraint_J (x))))
24099 || outer_code == ASHIFT
24100 || outer_code == ASHIFTRT
24101 || outer_code == LSHIFTRT
24102 || outer_code == ROTATE
24103 || outer_code == ROTATERT
24104 || outer_code == ZERO_EXTRACT
24105 || (outer_code == MULT
24106 && satisfies_constraint_I (x))
24107 || ((outer_code == DIV || outer_code == UDIV
24108 || outer_code == MOD || outer_code == UMOD)
24109 && exact_log2 (INTVAL (x)) >= 0)
24110 || (outer_code == COMPARE
24111 && (satisfies_constraint_I (x)
24112 || satisfies_constraint_K (x)))
24113 || (outer_code == EQ
24114 && (satisfies_constraint_I (x)
24115 || satisfies_constraint_K (x)
24117 ? satisfies_constraint_L (x)
24118 : satisfies_constraint_J (x))))
24119 || (outer_code == GTU
24120 && satisfies_constraint_I (x))
24121 || (outer_code == LTU
24122 && satisfies_constraint_P (x)))
24127 else if ((outer_code == PLUS
24128 && reg_or_add_cint_operand (x, VOIDmode))
24129 || (outer_code == MINUS
24130 && reg_or_sub_cint_operand (x, VOIDmode))
24131 || ((outer_code == SET
24132 || outer_code == IOR
24133 || outer_code == XOR)
24135 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
24137 *total = COSTS_N_INSNS (1);
24143 if (mode == DImode && code == CONST_DOUBLE)
24145 if ((outer_code == IOR || outer_code == XOR)
24146 && CONST_DOUBLE_HIGH (x) == 0
24147 && (CONST_DOUBLE_LOW (x)
24148 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
24153 else if ((outer_code == AND && and64_2_operand (x, DImode))
24154 || ((outer_code == SET
24155 || outer_code == IOR
24156 || outer_code == XOR)
24157 && CONST_DOUBLE_HIGH (x) == 0))
24159 *total = COSTS_N_INSNS (1);
24169 /* When optimizing for size, MEM should be slightly more expensive
24170 than generating address, e.g., (plus (reg) (const)).
24171 L1 cache latency is about two instructions. */
24172 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
24180 if (mode == DFmode)
24182 if (GET_CODE (XEXP (x, 0)) == MULT)
24184 /* FNMA accounted in outer NEG. */
24185 if (outer_code == NEG)
24186 *total = rs6000_cost->dmul - rs6000_cost->fp;
24188 *total = rs6000_cost->dmul;
24191 *total = rs6000_cost->fp;
24193 else if (mode == SFmode)
24195 /* FNMA accounted in outer NEG. */
24196 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24199 *total = rs6000_cost->fp;
24202 *total = COSTS_N_INSNS (1);
24206 if (mode == DFmode)
24208 if (GET_CODE (XEXP (x, 0)) == MULT
24209 || GET_CODE (XEXP (x, 1)) == MULT)
24211 /* FNMA accounted in outer NEG. */
24212 if (outer_code == NEG)
24213 *total = rs6000_cost->dmul - rs6000_cost->fp;
24215 *total = rs6000_cost->dmul;
24218 *total = rs6000_cost->fp;
24220 else if (mode == SFmode)
24222 /* FNMA accounted in outer NEG. */
24223 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
24226 *total = rs6000_cost->fp;
24229 *total = COSTS_N_INSNS (1);
24233 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24234 && satisfies_constraint_I (XEXP (x, 1)))
24236 if (INTVAL (XEXP (x, 1)) >= -256
24237 && INTVAL (XEXP (x, 1)) <= 255)
24238 *total = rs6000_cost->mulsi_const9;
24240 *total = rs6000_cost->mulsi_const;
24242 /* FMA accounted in outer PLUS/MINUS. */
24243 else if ((mode == DFmode || mode == SFmode)
24244 && (outer_code == PLUS || outer_code == MINUS))
24246 else if (mode == DFmode)
24247 *total = rs6000_cost->dmul;
24248 else if (mode == SFmode)
24249 *total = rs6000_cost->fp;
24250 else if (mode == DImode)
24251 *total = rs6000_cost->muldi;
24253 *total = rs6000_cost->mulsi;
24258 if (FLOAT_MODE_P (mode))
24260 *total = mode == DFmode ? rs6000_cost->ddiv
24261 : rs6000_cost->sdiv;
24268 if (GET_CODE (XEXP (x, 1)) == CONST_INT
24269 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
24271 if (code == DIV || code == MOD)
24273 *total = COSTS_N_INSNS (2);
24276 *total = COSTS_N_INSNS (1);
24280 if (GET_MODE (XEXP (x, 1)) == DImode)
24281 *total = rs6000_cost->divdi;
24283 *total = rs6000_cost->divsi;
24285 /* Add in shift and subtract for MOD. */
24286 if (code == MOD || code == UMOD)
24287 *total += COSTS_N_INSNS (2);
24292 *total = COSTS_N_INSNS (4);
24296 *total = COSTS_N_INSNS (6);
24300 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
24312 *total = COSTS_N_INSNS (1);
24320 /* Handle mul_highpart. */
24321 if (outer_code == TRUNCATE
24322 && GET_CODE (XEXP (x, 0)) == MULT)
24324 if (mode == DImode)
24325 *total = rs6000_cost->muldi;
24327 *total = rs6000_cost->mulsi;
24330 else if (outer_code == AND)
24333 *total = COSTS_N_INSNS (1);
24338 if (GET_CODE (XEXP (x, 0)) == MEM)
24341 *total = COSTS_N_INSNS (1);
24347 if (!FLOAT_MODE_P (mode))
24349 *total = COSTS_N_INSNS (1);
24355 case UNSIGNED_FLOAT:
24358 case FLOAT_TRUNCATE:
24359 *total = rs6000_cost->fp;
24363 if (mode == DFmode)
24366 *total = rs6000_cost->fp;
24370 switch (XINT (x, 1))
24373 *total = rs6000_cost->fp;
24385 *total = COSTS_N_INSNS (1);
24388 else if (FLOAT_MODE_P (mode)
24389 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
24391 *total = rs6000_cost->fp;
24399 /* Carry bit requires mode == Pmode.
24400 NEG or PLUS already counted so only add one. */
24402 && (outer_code == NEG || outer_code == PLUS))
24404 *total = COSTS_N_INSNS (1);
24407 if (outer_code == SET)
24409 if (XEXP (x, 1) == const0_rtx)
24411 *total = COSTS_N_INSNS (2);
24414 else if (mode == Pmode)
24416 *total = COSTS_N_INSNS (3);
24425 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
24427 *total = COSTS_N_INSNS (2);
24431 if (outer_code == COMPARE)
24445 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
24448 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
24451 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
24454 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
24455 "total = %d, speed = %s, x:\n",
24456 ret ? "complete" : "scan inner",
24457 GET_RTX_NAME (code),
24458 GET_RTX_NAME (outer_code),
24460 speed ? "true" : "false");
24467 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
24470 rs6000_debug_address_cost (rtx x, bool speed)
24472 int ret = TARGET_ADDRESS_COST (x, speed);
24474 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
24475 ret, speed ? "true" : "false");
24482 /* A C expression returning the cost of moving data from a register of class
24483 CLASS1 to one of CLASS2. */
24486 rs6000_register_move_cost (enum machine_mode mode,
24487 enum reg_class from, enum reg_class to)
24491 /* Moves from/to GENERAL_REGS. */
24492 if (reg_classes_intersect_p (to, GENERAL_REGS)
24493 || reg_classes_intersect_p (from, GENERAL_REGS))
24495 if (! reg_classes_intersect_p (to, GENERAL_REGS))
24498 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
24499 ret = (rs6000_memory_move_cost (mode, from, 0)
24500 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
24502 /* It's more expensive to move CR_REGS than CR0_REGS because of the
24504 else if (from == CR_REGS)
24507 /* Power6 has slower LR/CTR moves so make them more expensive than
24508 memory in order to bias spills to memory .*/
24509 else if (rs6000_cpu == PROCESSOR_POWER6
24510 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
24511 ret = 6 * hard_regno_nregs[0][mode];
24514 /* A move will cost one instruction per GPR moved. */
24515 ret = 2 * hard_regno_nregs[0][mode];
24518 /* If we have VSX, we can easily move between FPR or Altivec registers. */
24519 else if (VECTOR_UNIT_VSX_P (mode)
24520 && reg_classes_intersect_p (to, VSX_REGS)
24521 && reg_classes_intersect_p (from, VSX_REGS))
24522 ret = 2 * hard_regno_nregs[32][mode];
24524 /* Moving between two similar registers is just one instruction. */
24525 else if (reg_classes_intersect_p (to, from))
24526 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
24528 /* Everything else has to go through GENERAL_REGS. */
24530 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
24531 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
24533 if (TARGET_DEBUG_COST)
24535 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
24536 ret, GET_MODE_NAME (mode), reg_class_names[from],
24537 reg_class_names[to]);
24542 /* A C expressions returning the cost of moving data of MODE from a register to
24546 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
24547 int in ATTRIBUTE_UNUSED)
24551 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
24552 ret = 4 * hard_regno_nregs[0][mode];
24553 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
24554 ret = 4 * hard_regno_nregs[32][mode];
24555 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
24556 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
24558 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
24560 if (TARGET_DEBUG_COST)
24562 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
24563 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
24568 /* Returns a code for a target-specific builtin that implements
24569 reciprocal of the function, or NULL_TREE if not available. */
24572 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
24573 bool sqrt ATTRIBUTE_UNUSED)
24575 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
24576 && flag_finite_math_only && !flag_trapping_math
24577 && flag_unsafe_math_optimizations))
24585 case BUILT_IN_SQRTF:
24586 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
24593 /* Newton-Raphson approximation of single-precision floating point divide n/d.
24594 Assumes no trapping math and finite arguments. */
24597 rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
24599 rtx x0, e0, e1, y1, u0, v0, one;
24601 x0 = gen_reg_rtx (SFmode);
24602 e0 = gen_reg_rtx (SFmode);
24603 e1 = gen_reg_rtx (SFmode);
24604 y1 = gen_reg_rtx (SFmode);
24605 u0 = gen_reg_rtx (SFmode);
24606 v0 = gen_reg_rtx (SFmode);
24607 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
24609 /* x0 = 1./d estimate */
24610 emit_insn (gen_rtx_SET (VOIDmode, x0,
24611 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
24613 /* e0 = 1. - d * x0 */
24614 emit_insn (gen_rtx_SET (VOIDmode, e0,
24615 gen_rtx_MINUS (SFmode, one,
24616 gen_rtx_MULT (SFmode, d, x0))));
24617 /* e1 = e0 + e0 * e0 */
24618 emit_insn (gen_rtx_SET (VOIDmode, e1,
24619 gen_rtx_PLUS (SFmode,
24620 gen_rtx_MULT (SFmode, e0, e0), e0)));
24621 /* y1 = x0 + e1 * x0 */
24622 emit_insn (gen_rtx_SET (VOIDmode, y1,
24623 gen_rtx_PLUS (SFmode,
24624 gen_rtx_MULT (SFmode, e1, x0), x0)));
24626 emit_insn (gen_rtx_SET (VOIDmode, u0,
24627 gen_rtx_MULT (SFmode, n, y1)));
24628 /* v0 = n - d * u0 */
24629 emit_insn (gen_rtx_SET (VOIDmode, v0,
24630 gen_rtx_MINUS (SFmode, n,
24631 gen_rtx_MULT (SFmode, d, u0))));
24632 /* dst = u0 + v0 * y1 */
24633 emit_insn (gen_rtx_SET (VOIDmode, dst,
24634 gen_rtx_PLUS (SFmode,
24635 gen_rtx_MULT (SFmode, v0, y1), u0)));
24638 /* Newton-Raphson approximation of double-precision floating point divide n/d.
24639 Assumes no trapping math and finite arguments. */
24642 rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
24644 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
24646 x0 = gen_reg_rtx (DFmode);
24647 e0 = gen_reg_rtx (DFmode);
24648 e1 = gen_reg_rtx (DFmode);
24649 e2 = gen_reg_rtx (DFmode);
24650 y1 = gen_reg_rtx (DFmode);
24651 y2 = gen_reg_rtx (DFmode);
24652 y3 = gen_reg_rtx (DFmode);
24653 u0 = gen_reg_rtx (DFmode);
24654 v0 = gen_reg_rtx (DFmode);
24655 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
24657 /* x0 = 1./d estimate */
24658 emit_insn (gen_rtx_SET (VOIDmode, x0,
24659 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
24661 /* e0 = 1. - d * x0 */
24662 emit_insn (gen_rtx_SET (VOIDmode, e0,
24663 gen_rtx_MINUS (DFmode, one,
24664 gen_rtx_MULT (SFmode, d, x0))));
24665 /* y1 = x0 + e0 * x0 */
24666 emit_insn (gen_rtx_SET (VOIDmode, y1,
24667 gen_rtx_PLUS (DFmode,
24668 gen_rtx_MULT (DFmode, e0, x0), x0)));
24670 emit_insn (gen_rtx_SET (VOIDmode, e1,
24671 gen_rtx_MULT (DFmode, e0, e0)));
24672 /* y2 = y1 + e1 * y1 */
24673 emit_insn (gen_rtx_SET (VOIDmode, y2,
24674 gen_rtx_PLUS (DFmode,
24675 gen_rtx_MULT (DFmode, e1, y1), y1)));
24677 emit_insn (gen_rtx_SET (VOIDmode, e2,
24678 gen_rtx_MULT (DFmode, e1, e1)));
24679 /* y3 = y2 + e2 * y2 */
24680 emit_insn (gen_rtx_SET (VOIDmode, y3,
24681 gen_rtx_PLUS (DFmode,
24682 gen_rtx_MULT (DFmode, e2, y2), y2)));
24684 emit_insn (gen_rtx_SET (VOIDmode, u0,
24685 gen_rtx_MULT (DFmode, n, y3)));
24686 /* v0 = n - d * u0 */
24687 emit_insn (gen_rtx_SET (VOIDmode, v0,
24688 gen_rtx_MINUS (DFmode, n,
24689 gen_rtx_MULT (DFmode, d, u0))));
24690 /* dst = u0 + v0 * y3 */
24691 emit_insn (gen_rtx_SET (VOIDmode, dst,
24692 gen_rtx_PLUS (DFmode,
24693 gen_rtx_MULT (DFmode, v0, y3), u0)));
24697 /* Newton-Raphson approximation of single-precision floating point rsqrt.
24698 Assumes no trapping math and finite arguments. */
24701 rs6000_emit_swrsqrtsf (rtx dst, rtx src)
24703 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
24704 half, one, halfthree, c1, cond, label;
24706 x0 = gen_reg_rtx (SFmode);
24707 x1 = gen_reg_rtx (SFmode);
24708 x2 = gen_reg_rtx (SFmode);
24709 y1 = gen_reg_rtx (SFmode);
24710 u0 = gen_reg_rtx (SFmode);
24711 u1 = gen_reg_rtx (SFmode);
24712 u2 = gen_reg_rtx (SFmode);
24713 v0 = gen_reg_rtx (SFmode);
24714 v1 = gen_reg_rtx (SFmode);
24715 v2 = gen_reg_rtx (SFmode);
24716 t0 = gen_reg_rtx (SFmode);
24717 halfthree = gen_reg_rtx (SFmode);
24718 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
24719 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
24721 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
24722 emit_insn (gen_rtx_SET (VOIDmode, t0,
24723 gen_rtx_MULT (SFmode, src, src)));
24725 emit_insn (gen_rtx_SET (VOIDmode, cond,
24726 gen_rtx_COMPARE (CCFPmode, t0, src)));
24727 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
24728 emit_unlikely_jump (c1, label);
24730 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
24731 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
24733 /* halfthree = 1.5 = 1.0 + 0.5 */
24734 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
24735 gen_rtx_PLUS (SFmode, one, half)));
24737 /* x0 = rsqrt estimate */
24738 emit_insn (gen_rtx_SET (VOIDmode, x0,
24739 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
24742 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
24743 emit_insn (gen_rtx_SET (VOIDmode, y1,
24744 gen_rtx_MINUS (SFmode,
24745 gen_rtx_MULT (SFmode, src, halfthree),
24748 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
24749 emit_insn (gen_rtx_SET (VOIDmode, u0,
24750 gen_rtx_MULT (SFmode, x0, x0)));
24751 emit_insn (gen_rtx_SET (VOIDmode, v0,
24752 gen_rtx_MINUS (SFmode,
24754 gen_rtx_MULT (SFmode, y1, u0))));
24755 emit_insn (gen_rtx_SET (VOIDmode, x1,
24756 gen_rtx_MULT (SFmode, x0, v0)));
24758 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
24759 emit_insn (gen_rtx_SET (VOIDmode, u1,
24760 gen_rtx_MULT (SFmode, x1, x1)));
24761 emit_insn (gen_rtx_SET (VOIDmode, v1,
24762 gen_rtx_MINUS (SFmode,
24764 gen_rtx_MULT (SFmode, y1, u1))));
24765 emit_insn (gen_rtx_SET (VOIDmode, x2,
24766 gen_rtx_MULT (SFmode, x1, v1)));
24768 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
24769 emit_insn (gen_rtx_SET (VOIDmode, u2,
24770 gen_rtx_MULT (SFmode, x2, x2)));
24771 emit_insn (gen_rtx_SET (VOIDmode, v2,
24772 gen_rtx_MINUS (SFmode,
24774 gen_rtx_MULT (SFmode, y1, u2))));
24775 emit_insn (gen_rtx_SET (VOIDmode, dst,
24776 gen_rtx_MULT (SFmode, x2, v2)));
24778 emit_label (XEXP (label, 0));
24781 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
24782 (Power7) targets. DST is the target, and SRC is the argument operand. */
24785 rs6000_emit_popcount (rtx dst, rtx src)
24787 enum machine_mode mode = GET_MODE (dst);
24790 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
24791 if (TARGET_POPCNTD)
24793 if (mode == SImode)
24794 emit_insn (gen_popcntwsi2 (dst, src));
24796 emit_insn (gen_popcntddi2 (dst, src));
24800 tmp1 = gen_reg_rtx (mode);
24802 if (mode == SImode)
24804 emit_insn (gen_popcntbsi2 (tmp1, src));
24805 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
24807 tmp2 = force_reg (SImode, tmp2);
24808 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
24812 emit_insn (gen_popcntbdi2 (tmp1, src));
24813 tmp2 = expand_mult (DImode, tmp1,
24814 GEN_INT ((HOST_WIDE_INT)
24815 0x01010101 << 32 | 0x01010101),
24817 tmp2 = force_reg (DImode, tmp2);
24818 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
24823 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
24824 target, and SRC is the argument operand. */
24827 rs6000_emit_parity (rtx dst, rtx src)
24829 enum machine_mode mode = GET_MODE (dst);
24832 tmp = gen_reg_rtx (mode);
24833 if (mode == SImode)
24835 /* Is mult+shift >= shift+xor+shift+xor? */
24836 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
24838 rtx tmp1, tmp2, tmp3, tmp4;
24840 tmp1 = gen_reg_rtx (SImode);
24841 emit_insn (gen_popcntbsi2 (tmp1, src));
24843 tmp2 = gen_reg_rtx (SImode);
24844 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
24845 tmp3 = gen_reg_rtx (SImode);
24846 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
24848 tmp4 = gen_reg_rtx (SImode);
24849 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
24850 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
24853 rs6000_emit_popcount (tmp, src);
24854 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
24858 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
24859 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
24861 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
24863 tmp1 = gen_reg_rtx (DImode);
24864 emit_insn (gen_popcntbdi2 (tmp1, src));
24866 tmp2 = gen_reg_rtx (DImode);
24867 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
24868 tmp3 = gen_reg_rtx (DImode);
24869 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
24871 tmp4 = gen_reg_rtx (DImode);
24872 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
24873 tmp5 = gen_reg_rtx (DImode);
24874 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
24876 tmp6 = gen_reg_rtx (DImode);
24877 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
24878 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
24881 rs6000_emit_popcount (tmp, src);
24882 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
24886 /* Return an RTX representing where to find the function value of a
24887 function returning MODE. */
24889 rs6000_complex_function_value (enum machine_mode mode)
24891 unsigned int regno;
24893 enum machine_mode inner = GET_MODE_INNER (mode);
24894 unsigned int inner_bytes = GET_MODE_SIZE (inner);
24896 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
24897 regno = FP_ARG_RETURN;
24900 regno = GP_ARG_RETURN;
24902 /* 32-bit is OK since it'll go in r3/r4. */
24903 if (TARGET_32BIT && inner_bytes >= 4)
24904 return gen_rtx_REG (mode, regno);
24907 if (inner_bytes >= 8)
24908 return gen_rtx_REG (mode, regno);
24910 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
24912 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
24913 GEN_INT (inner_bytes));
24914 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
24917 /* Define how to find the value returned by a function.
24918 VALTYPE is the data type of the value (as a tree).
24919 If the precise function being called is known, FUNC is its FUNCTION_DECL;
24920 otherwise, FUNC is 0.
24922 On the SPE, both FPs and vectors are returned in r3.
24924 On RS/6000 an integer value is in r3 and a floating-point value is in
24925 fp1, unless -msoft-float. */
24928 rs6000_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
24930 enum machine_mode mode;
24931 unsigned int regno;
24933 /* Special handling for structs in darwin64. */
24934 if (rs6000_darwin64_abi
24935 && TYPE_MODE (valtype) == BLKmode
24936 && TREE_CODE (valtype) == RECORD_TYPE
24937 && int_size_in_bytes (valtype) > 0)
24939 CUMULATIVE_ARGS valcum;
24943 valcum.fregno = FP_ARG_MIN_REG;
24944 valcum.vregno = ALTIVEC_ARG_MIN_REG;
24945 /* Do a trial code generation as if this were going to be passed as
24946 an argument; if any part goes in memory, we return NULL. */
24947 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
24950 /* Otherwise fall through to standard ABI rules. */
24953 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
24955 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
24956 return gen_rtx_PARALLEL (DImode,
24958 gen_rtx_EXPR_LIST (VOIDmode,
24959 gen_rtx_REG (SImode, GP_ARG_RETURN),
24961 gen_rtx_EXPR_LIST (VOIDmode,
24962 gen_rtx_REG (SImode,
24963 GP_ARG_RETURN + 1),
24966 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
24968 return gen_rtx_PARALLEL (DCmode,
24970 gen_rtx_EXPR_LIST (VOIDmode,
24971 gen_rtx_REG (SImode, GP_ARG_RETURN),
24973 gen_rtx_EXPR_LIST (VOIDmode,
24974 gen_rtx_REG (SImode,
24975 GP_ARG_RETURN + 1),
24977 gen_rtx_EXPR_LIST (VOIDmode,
24978 gen_rtx_REG (SImode,
24979 GP_ARG_RETURN + 2),
24981 gen_rtx_EXPR_LIST (VOIDmode,
24982 gen_rtx_REG (SImode,
24983 GP_ARG_RETURN + 3),
24987 mode = TYPE_MODE (valtype);
24988 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
24989 || POINTER_TYPE_P (valtype))
24990 mode = TARGET_32BIT ? SImode : DImode;
24992 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
24993 /* _Decimal128 must use an even/odd register pair. */
24994 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
24995 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
24996 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
24997 regno = FP_ARG_RETURN;
24998 else if (TREE_CODE (valtype) == COMPLEX_TYPE
24999 && targetm.calls.split_complex_arg)
25000 return rs6000_complex_function_value (mode);
25001 else if (TREE_CODE (valtype) == VECTOR_TYPE
25002 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
25003 && ALTIVEC_VECTOR_MODE (mode))
25004 regno = ALTIVEC_ARG_RETURN;
25005 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25006 && (mode == DFmode || mode == DCmode
25007 || mode == TFmode || mode == TCmode))
25008 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25010 regno = GP_ARG_RETURN;
25012 return gen_rtx_REG (mode, regno);
25015 /* Define how to find the value returned by a library function
25016 assuming the value has mode MODE. */
25018 rs6000_libcall_value (enum machine_mode mode)
25020 unsigned int regno;
25022 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
25024 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25025 return gen_rtx_PARALLEL (DImode,
25027 gen_rtx_EXPR_LIST (VOIDmode,
25028 gen_rtx_REG (SImode, GP_ARG_RETURN),
25030 gen_rtx_EXPR_LIST (VOIDmode,
25031 gen_rtx_REG (SImode,
25032 GP_ARG_RETURN + 1),
25036 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25037 /* _Decimal128 must use an even/odd register pair. */
25038 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25039 else if (SCALAR_FLOAT_MODE_P (mode)
25040 && TARGET_HARD_FLOAT && TARGET_FPRS
25041 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
25042 regno = FP_ARG_RETURN;
25043 else if (ALTIVEC_VECTOR_MODE (mode)
25044 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
25045 regno = ALTIVEC_ARG_RETURN;
25046 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
25047 return rs6000_complex_function_value (mode);
25048 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25049 && (mode == DFmode || mode == DCmode
25050 || mode == TFmode || mode == TCmode))
25051 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25053 regno = GP_ARG_RETURN;
25055 return gen_rtx_REG (mode, regno);
25059 /* Given FROM and TO register numbers, say whether this elimination is allowed.
25060 Frame pointer elimination is automatically handled.
25062 For the RS/6000, if frame pointer elimination is being done, we would like
25063 to convert ap into fp, not sp.
25065 We need r30 if -mminimal-toc was specified, and there are constant pool
25069 rs6000_can_eliminate (const int from, const int to)
25071 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
25072 ? ! frame_pointer_needed
25073 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
25074 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
25078 /* Define the offset between two registers, FROM to be eliminated and its
25079 replacement TO, at the start of a routine. */
25081 rs6000_initial_elimination_offset (int from, int to)
25083 rs6000_stack_t *info = rs6000_stack_info ();
25084 HOST_WIDE_INT offset;
25086 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25087 offset = info->push_p ? 0 : -info->total_size;
25088 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25090 offset = info->push_p ? 0 : -info->total_size;
25091 if (FRAME_GROWS_DOWNWARD)
25092 offset += info->fixed_size + info->vars_size + info->parm_size;
25094 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25095 offset = FRAME_GROWS_DOWNWARD
25096 ? info->fixed_size + info->vars_size + info->parm_size
25098 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
25099 offset = info->total_size;
25100 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
25101 offset = info->push_p ? info->total_size : 0;
25102 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
25105 gcc_unreachable ();
25111 rs6000_dwarf_register_span (rtx reg)
25115 unsigned regno = REGNO (reg);
25116 enum machine_mode mode = GET_MODE (reg);
25120 && (SPE_VECTOR_MODE (GET_MODE (reg))
25121 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
25122 && mode != SFmode && mode != SDmode && mode != SCmode)))
25127 regno = REGNO (reg);
25129 /* The duality of the SPE register size wreaks all kinds of havoc.
25130 This is a way of distinguishing r0 in 32-bits from r0 in
25132 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
25133 gcc_assert (words <= 4);
25134 for (i = 0; i < words; i++, regno++)
25136 if (BYTES_BIG_ENDIAN)
25138 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
25139 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
25143 parts[2 * i] = gen_rtx_REG (SImode, regno);
25144 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
25148 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
25151 /* Fill in sizes for SPE register high parts in table used by unwinder. */
25154 rs6000_init_dwarf_reg_sizes_extra (tree address)
25159 enum machine_mode mode = TYPE_MODE (char_type_node);
25160 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
25161 rtx mem = gen_rtx_MEM (BLKmode, addr);
25162 rtx value = gen_int_mode (4, mode);
25164 for (i = 1201; i < 1232; i++)
25166 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
25167 HOST_WIDE_INT offset
25168 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
25170 emit_move_insn (adjust_address (mem, mode, offset), value);
25175 /* Map internal gcc register numbers to DWARF2 register numbers. */
25178 rs6000_dbx_register_number (unsigned int regno)
25180 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
25182 if (regno == MQ_REGNO)
25184 if (regno == LR_REGNO)
25186 if (regno == CTR_REGNO)
25188 if (CR_REGNO_P (regno))
25189 return regno - CR0_REGNO + 86;
25190 if (regno == XER_REGNO)
25192 if (ALTIVEC_REGNO_P (regno))
25193 return regno - FIRST_ALTIVEC_REGNO + 1124;
25194 if (regno == VRSAVE_REGNO)
25196 if (regno == VSCR_REGNO)
25198 if (regno == SPE_ACC_REGNO)
25200 if (regno == SPEFSCR_REGNO)
25202 /* SPE high reg number. We get these values of regno from
25203 rs6000_dwarf_register_span. */
25204 gcc_assert (regno >= 1200 && regno < 1232);
25208 /* target hook eh_return_filter_mode */
25209 static enum machine_mode
25210 rs6000_eh_return_filter_mode (void)
25212 return TARGET_32BIT ? SImode : word_mode;
25215 /* Target hook for scalar_mode_supported_p. */
25217 rs6000_scalar_mode_supported_p (enum machine_mode mode)
25219 if (DECIMAL_FLOAT_MODE_P (mode))
25222 return default_scalar_mode_supported_p (mode);
25225 /* Target hook for vector_mode_supported_p. */
25227 rs6000_vector_mode_supported_p (enum machine_mode mode)
25230 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
25233 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
25236 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
25243 /* Target hook for invalid_arg_for_unprototyped_fn. */
25244 static const char *
25245 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
25247 return (!rs6000_darwin64_abi
25249 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
25250 && (funcdecl == NULL_TREE
25251 || (TREE_CODE (funcdecl) == FUNCTION_DECL
25252 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
25253 ? N_("AltiVec argument passed to unprototyped function")
25257 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
25258 setup by using __stack_chk_fail_local hidden function instead of
25259 calling __stack_chk_fail directly. Otherwise it is better to call
25260 __stack_chk_fail directly. */
25263 rs6000_stack_protect_fail (void)
25265 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
25266 ? default_hidden_stack_protect_fail ()
25267 : default_external_stack_protect_fail ();
25271 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
25272 int num_operands ATTRIBUTE_UNUSED)
25274 if (rs6000_warn_cell_microcode)
25277 int insn_code_number = recog_memoized (insn);
25278 location_t location = locator_location (INSN_LOCATOR (insn));
25280 /* Punt on insns we cannot recognize. */
25281 if (insn_code_number < 0)
25284 temp = get_insn_template (insn_code_number, insn);
25286 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
25287 warning_at (location, OPT_mwarn_cell_microcode,
25288 "emitting microcode insn %s\t[%s] #%d",
25289 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25290 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
25291 warning_at (location, OPT_mwarn_cell_microcode,
25292 "emitting conditional microcode insn %s\t[%s] #%d",
25293 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
25297 #include "gt-rs6000.h"