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, 2010
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"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-attr.h"
42 #include "basic-block.h"
43 #include "integrate.h"
49 #include "target-def.h"
50 #include "langhooks.h"
52 #include "cfglayout.h"
53 #include "sched-int.h"
55 #include "tree-flow.h"
58 #include "tm-constrs.h"
60 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
63 #include "gstab.h" /* for N_SLINE */
66 #ifndef TARGET_NO_PROTOTYPE
67 #define TARGET_NO_PROTOTYPE 0
70 #define min(A,B) ((A) < (B) ? (A) : (B))
71 #define max(A,B) ((A) > (B) ? (A) : (B))
73 /* Structure used to define the rs6000 stack */
74 typedef struct rs6000_stack {
75 int first_gp_reg_save; /* first callee saved GP register used */
76 int first_fp_reg_save; /* first callee saved FP register used */
77 int first_altivec_reg_save; /* first callee saved AltiVec register used */
78 int lr_save_p; /* true if the link reg needs to be saved */
79 int cr_save_p; /* true if the CR reg needs to be saved */
80 unsigned int vrsave_mask; /* mask of vec registers to save */
81 int push_p; /* true if we need to allocate stack space */
82 int calls_p; /* true if the function makes any calls */
83 int world_save_p; /* true if we're saving *everything*:
84 r13-r31, cr, f14-f31, vrsave, v20-v31 */
85 enum rs6000_abi abi; /* which ABI to use */
86 int gp_save_offset; /* offset to save GP regs from initial SP */
87 int fp_save_offset; /* offset to save FP regs from initial SP */
88 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
89 int lr_save_offset; /* offset to save LR from initial SP */
90 int cr_save_offset; /* offset to save CR from initial SP */
91 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
92 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
93 int varargs_save_offset; /* offset to save the varargs registers */
94 int ehrd_offset; /* offset to EH return data */
95 int reg_size; /* register size (4 or 8) */
96 HOST_WIDE_INT vars_size; /* variable save area size */
97 int parm_size; /* outgoing parameter size */
98 int save_size; /* save area size */
99 int fixed_size; /* fixed size of stack frame */
100 int gp_size; /* size of saved GP registers */
101 int fp_size; /* size of saved FP registers */
102 int altivec_size; /* size of saved AltiVec registers */
103 int cr_size; /* size to hold CR if not in save_size */
104 int vrsave_size; /* size to hold VRSAVE if not in save_size */
105 int altivec_padding_size; /* size of altivec alignment padding if
107 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
108 int spe_padding_size;
109 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
110 int spe_64bit_regs_used;
113 /* A C structure for machine-specific, per-function data.
114 This is added to the cfun structure. */
115 typedef struct GTY(()) machine_function
117 /* Some local-dynamic symbol. */
118 const char *some_ld_name;
119 /* Whether the instruction chain has been scanned already. */
120 int insn_chain_scanned_p;
121 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
122 int ra_needs_full_frame;
123 /* Flags if __builtin_return_address (0) was used. */
125 /* Cache lr_save_p after expansion of builtin_eh_return. */
127 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
128 varargs save area. */
129 HOST_WIDE_INT varargs_save_offset;
130 /* Temporary stack slot to use for SDmode copies. This slot is
131 64-bits wide and is allocated early enough so that the offset
132 does not overflow the 16-bit load/store offset field. */
133 rtx sdmode_stack_slot;
136 /* Target cpu type */
138 enum processor_type rs6000_cpu;
139 struct rs6000_cpu_select rs6000_select[3] =
141 /* switch name, tune arch */
142 { (const char *)0, "--with-cpu=", 1, 1 },
143 { (const char *)0, "-mcpu=", 1, 1 },
144 { (const char *)0, "-mtune=", 1, 0 },
147 /* Always emit branch hint bits. */
148 static GTY(()) bool rs6000_always_hint;
150 /* Schedule instructions for group formation. */
151 static GTY(()) bool rs6000_sched_groups;
153 /* Align branch targets. */
154 static GTY(()) bool rs6000_align_branch_targets;
156 /* Support for -msched-costly-dep option. */
157 const char *rs6000_sched_costly_dep_str;
158 enum rs6000_dependence_cost rs6000_sched_costly_dep;
160 /* Support for -minsert-sched-nops option. */
161 const char *rs6000_sched_insert_nops_str;
162 enum rs6000_nop_insertion rs6000_sched_insert_nops;
164 /* Support targetm.vectorize.builtin_mask_for_load. */
165 static GTY(()) tree altivec_builtin_mask_for_load;
167 /* Size of long double. */
168 int rs6000_long_double_type_size;
170 /* IEEE quad extended precision long double. */
173 /* Nonzero to use AltiVec ABI. */
174 int rs6000_altivec_abi;
176 /* Nonzero if we want SPE SIMD instructions. */
179 /* Nonzero if we want SPE ABI extensions. */
182 /* Nonzero if floating point operations are done in the GPRs. */
183 int rs6000_float_gprs = 0;
185 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
186 int rs6000_darwin64_abi;
188 /* Set to nonzero once AIX common-mode calls have been defined. */
189 static GTY(()) int common_mode_defined;
191 /* Label number of label created for -mrelocatable, to call to so we can
192 get the address of the GOT section */
193 int rs6000_pic_labelno;
196 /* Which abi to adhere to */
197 const char *rs6000_abi_name;
199 /* Semantics of the small data area */
200 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
202 /* Which small data model to use */
203 const char *rs6000_sdata_name = (char *)0;
205 /* Counter for labels which are to be placed in .fixup. */
206 int fixuplabelno = 0;
209 /* Bit size of immediate TLS offsets and string from which it is decoded. */
210 int rs6000_tls_size = 32;
211 const char *rs6000_tls_size_string;
213 /* ABI enumeration available for subtarget to use. */
214 enum rs6000_abi rs6000_current_abi;
216 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
220 const char *rs6000_debug_name;
221 int rs6000_debug_stack; /* debug stack applications */
222 int rs6000_debug_arg; /* debug argument handling */
223 int rs6000_debug_reg; /* debug register classes */
224 int rs6000_debug_addr; /* debug memory addressing */
225 int rs6000_debug_cost; /* debug rtx_costs */
227 /* Specify the machine mode that pointers have. After generation of rtl, the
228 compiler makes no further distinction between pointers and any other objects
229 of this machine mode. The type is unsigned since not all things that
230 include rs6000.h also include machmode.h. */
231 unsigned rs6000_pmode;
233 /* Width in bits of a pointer. */
234 unsigned rs6000_pointer_size;
237 /* Value is TRUE if register/mode pair is acceptable. */
238 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
240 /* Maximum number of registers needed for a given register class and mode. */
241 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
243 /* How many registers are needed for a given register and mode. */
244 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
246 /* Map register number to register class. */
247 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
249 /* Reload functions based on the type and the vector unit. */
250 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
252 /* Built in types. */
253 tree rs6000_builtin_types[RS6000_BTI_MAX];
254 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
256 const char *rs6000_traceback_name;
258 traceback_default = 0,
264 /* Flag to say the TOC is initialized */
266 char toc_label_name[10];
268 /* Cached value of rs6000_variable_issue. This is cached in
269 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
270 static short cached_can_issue_more;
272 static GTY(()) section *read_only_data_section;
273 static GTY(()) section *private_data_section;
274 static GTY(()) section *read_only_private_data_section;
275 static GTY(()) section *sdata2_section;
276 static GTY(()) section *toc_section;
278 /* Control alignment for fields within structures. */
279 /* String from -malign-XXXXX. */
280 int rs6000_alignment_flags;
282 /* Code model for 64-bit linux. */
283 enum rs6000_cmodel cmodel;
285 /* True for any options that were explicitly set. */
287 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
288 bool alignment; /* True if -malign- was used. */
289 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
290 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
291 bool spe; /* True if -mspe= was used. */
292 bool float_gprs; /* True if -mfloat-gprs= was used. */
293 bool long_double; /* True if -mlong-double- was used. */
294 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
295 bool vrsave; /* True if -mvrsave was used. */
296 bool cmodel; /* True if -mcmodel was used. */
297 } rs6000_explicit_options;
299 struct builtin_description
301 /* mask is not const because we're going to alter it below. This
302 nonsense will go away when we rewrite the -march infrastructure
303 to give us more target flag bits. */
305 const enum insn_code icode;
306 const char *const name;
307 const enum rs6000_builtins code;
310 /* Describe the vector unit used for modes. */
311 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
312 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
314 /* Register classes for various constraints that are based on the target
316 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
318 /* Describe the alignment of a vector. */
319 int rs6000_vector_align[NUM_MACHINE_MODES];
321 /* Map selected modes to types for builtins. */
322 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
324 /* What modes to automatically generate reciprocal divide estimate (fre) and
325 reciprocal sqrt (frsqrte) for. */
326 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
328 /* Masks to determine which reciprocal esitmate instructions to generate
330 enum rs6000_recip_mask {
331 RECIP_SF_DIV = 0x001, /* Use divide estimate */
332 RECIP_DF_DIV = 0x002,
333 RECIP_V4SF_DIV = 0x004,
334 RECIP_V2DF_DIV = 0x008,
336 RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */
337 RECIP_DF_RSQRT = 0x020,
338 RECIP_V4SF_RSQRT = 0x040,
339 RECIP_V2DF_RSQRT = 0x080,
341 /* Various combination of flags for -mrecip=xxx. */
343 RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
344 | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
345 | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
347 RECIP_HIGH_PRECISION = RECIP_ALL,
349 /* On low precision machines like the power5, don't enable double precision
350 reciprocal square root estimate, since it isn't accurate enough. */
351 RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
354 static unsigned int rs6000_recip_control;
355 static const char *rs6000_recip_name;
357 /* -mrecip options. */
360 const char *string; /* option name */
361 unsigned int mask; /* mask bits to set */
362 } recip_options[] = {
363 { "all", RECIP_ALL },
364 { "none", RECIP_NONE },
365 { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
367 { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) },
368 { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) },
369 { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
370 | RECIP_V2DF_RSQRT) },
371 { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
372 { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
375 /* 2 argument gen function typedef. */
376 typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
379 /* Target cpu costs. */
381 struct processor_costs {
382 const int mulsi; /* cost of SImode multiplication. */
383 const int mulsi_const; /* cost of SImode multiplication by constant. */
384 const int mulsi_const9; /* cost of SImode mult by short constant. */
385 const int muldi; /* cost of DImode multiplication. */
386 const int divsi; /* cost of SImode division. */
387 const int divdi; /* cost of DImode division. */
388 const int fp; /* cost of simple SFmode and DFmode insns. */
389 const int dmul; /* cost of DFmode multiplication (and fmadd). */
390 const int sdiv; /* cost of SFmode division (fdivs). */
391 const int ddiv; /* cost of DFmode division (fdiv). */
392 const int cache_line_size; /* cache line size in bytes. */
393 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
394 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
395 const int simultaneous_prefetches; /* number of parallel prefetch
399 const struct processor_costs *rs6000_cost;
401 /* Processor costs (relative to an add) */
403 /* Instruction size costs on 32bit processors. */
405 struct processor_costs size32_cost = {
406 COSTS_N_INSNS (1), /* mulsi */
407 COSTS_N_INSNS (1), /* mulsi_const */
408 COSTS_N_INSNS (1), /* mulsi_const9 */
409 COSTS_N_INSNS (1), /* muldi */
410 COSTS_N_INSNS (1), /* divsi */
411 COSTS_N_INSNS (1), /* divdi */
412 COSTS_N_INSNS (1), /* fp */
413 COSTS_N_INSNS (1), /* dmul */
414 COSTS_N_INSNS (1), /* sdiv */
415 COSTS_N_INSNS (1), /* ddiv */
422 /* Instruction size costs on 64bit processors. */
424 struct processor_costs size64_cost = {
425 COSTS_N_INSNS (1), /* mulsi */
426 COSTS_N_INSNS (1), /* mulsi_const */
427 COSTS_N_INSNS (1), /* mulsi_const9 */
428 COSTS_N_INSNS (1), /* muldi */
429 COSTS_N_INSNS (1), /* divsi */
430 COSTS_N_INSNS (1), /* divdi */
431 COSTS_N_INSNS (1), /* fp */
432 COSTS_N_INSNS (1), /* dmul */
433 COSTS_N_INSNS (1), /* sdiv */
434 COSTS_N_INSNS (1), /* ddiv */
441 /* Instruction costs on RIOS1 processors. */
443 struct processor_costs rios1_cost = {
444 COSTS_N_INSNS (5), /* mulsi */
445 COSTS_N_INSNS (4), /* mulsi_const */
446 COSTS_N_INSNS (3), /* mulsi_const9 */
447 COSTS_N_INSNS (5), /* muldi */
448 COSTS_N_INSNS (19), /* divsi */
449 COSTS_N_INSNS (19), /* divdi */
450 COSTS_N_INSNS (2), /* fp */
451 COSTS_N_INSNS (2), /* dmul */
452 COSTS_N_INSNS (19), /* sdiv */
453 COSTS_N_INSNS (19), /* ddiv */
454 128, /* cache line size */
460 /* Instruction costs on RIOS2 processors. */
462 struct processor_costs rios2_cost = {
463 COSTS_N_INSNS (2), /* mulsi */
464 COSTS_N_INSNS (2), /* mulsi_const */
465 COSTS_N_INSNS (2), /* mulsi_const9 */
466 COSTS_N_INSNS (2), /* muldi */
467 COSTS_N_INSNS (13), /* divsi */
468 COSTS_N_INSNS (13), /* divdi */
469 COSTS_N_INSNS (2), /* fp */
470 COSTS_N_INSNS (2), /* dmul */
471 COSTS_N_INSNS (17), /* sdiv */
472 COSTS_N_INSNS (17), /* ddiv */
473 256, /* cache line size */
479 /* Instruction costs on RS64A processors. */
481 struct processor_costs rs64a_cost = {
482 COSTS_N_INSNS (20), /* mulsi */
483 COSTS_N_INSNS (12), /* mulsi_const */
484 COSTS_N_INSNS (8), /* mulsi_const9 */
485 COSTS_N_INSNS (34), /* muldi */
486 COSTS_N_INSNS (65), /* divsi */
487 COSTS_N_INSNS (67), /* divdi */
488 COSTS_N_INSNS (4), /* fp */
489 COSTS_N_INSNS (4), /* dmul */
490 COSTS_N_INSNS (31), /* sdiv */
491 COSTS_N_INSNS (31), /* ddiv */
492 128, /* cache line size */
498 /* Instruction costs on MPCCORE processors. */
500 struct processor_costs mpccore_cost = {
501 COSTS_N_INSNS (2), /* mulsi */
502 COSTS_N_INSNS (2), /* mulsi_const */
503 COSTS_N_INSNS (2), /* mulsi_const9 */
504 COSTS_N_INSNS (2), /* muldi */
505 COSTS_N_INSNS (6), /* divsi */
506 COSTS_N_INSNS (6), /* divdi */
507 COSTS_N_INSNS (4), /* fp */
508 COSTS_N_INSNS (5), /* dmul */
509 COSTS_N_INSNS (10), /* sdiv */
510 COSTS_N_INSNS (17), /* ddiv */
511 32, /* cache line size */
517 /* Instruction costs on PPC403 processors. */
519 struct processor_costs ppc403_cost = {
520 COSTS_N_INSNS (4), /* mulsi */
521 COSTS_N_INSNS (4), /* mulsi_const */
522 COSTS_N_INSNS (4), /* mulsi_const9 */
523 COSTS_N_INSNS (4), /* muldi */
524 COSTS_N_INSNS (33), /* divsi */
525 COSTS_N_INSNS (33), /* divdi */
526 COSTS_N_INSNS (11), /* fp */
527 COSTS_N_INSNS (11), /* dmul */
528 COSTS_N_INSNS (11), /* sdiv */
529 COSTS_N_INSNS (11), /* ddiv */
530 32, /* cache line size */
536 /* Instruction costs on PPC405 processors. */
538 struct processor_costs ppc405_cost = {
539 COSTS_N_INSNS (5), /* mulsi */
540 COSTS_N_INSNS (4), /* mulsi_const */
541 COSTS_N_INSNS (3), /* mulsi_const9 */
542 COSTS_N_INSNS (5), /* muldi */
543 COSTS_N_INSNS (35), /* divsi */
544 COSTS_N_INSNS (35), /* divdi */
545 COSTS_N_INSNS (11), /* fp */
546 COSTS_N_INSNS (11), /* dmul */
547 COSTS_N_INSNS (11), /* sdiv */
548 COSTS_N_INSNS (11), /* ddiv */
549 32, /* cache line size */
555 /* Instruction costs on PPC440 processors. */
557 struct processor_costs ppc440_cost = {
558 COSTS_N_INSNS (3), /* mulsi */
559 COSTS_N_INSNS (2), /* mulsi_const */
560 COSTS_N_INSNS (2), /* mulsi_const9 */
561 COSTS_N_INSNS (3), /* muldi */
562 COSTS_N_INSNS (34), /* divsi */
563 COSTS_N_INSNS (34), /* divdi */
564 COSTS_N_INSNS (5), /* fp */
565 COSTS_N_INSNS (5), /* dmul */
566 COSTS_N_INSNS (19), /* sdiv */
567 COSTS_N_INSNS (33), /* ddiv */
568 32, /* cache line size */
574 /* Instruction costs on PPC476 processors. */
576 struct processor_costs ppc476_cost = {
577 COSTS_N_INSNS (4), /* mulsi */
578 COSTS_N_INSNS (4), /* mulsi_const */
579 COSTS_N_INSNS (4), /* mulsi_const9 */
580 COSTS_N_INSNS (4), /* muldi */
581 COSTS_N_INSNS (11), /* divsi */
582 COSTS_N_INSNS (11), /* divdi */
583 COSTS_N_INSNS (6), /* fp */
584 COSTS_N_INSNS (6), /* dmul */
585 COSTS_N_INSNS (19), /* sdiv */
586 COSTS_N_INSNS (33), /* ddiv */
587 32, /* l1 cache line size */
593 /* Instruction costs on PPC601 processors. */
595 struct processor_costs ppc601_cost = {
596 COSTS_N_INSNS (5), /* mulsi */
597 COSTS_N_INSNS (5), /* mulsi_const */
598 COSTS_N_INSNS (5), /* mulsi_const9 */
599 COSTS_N_INSNS (5), /* muldi */
600 COSTS_N_INSNS (36), /* divsi */
601 COSTS_N_INSNS (36), /* divdi */
602 COSTS_N_INSNS (4), /* fp */
603 COSTS_N_INSNS (5), /* dmul */
604 COSTS_N_INSNS (17), /* sdiv */
605 COSTS_N_INSNS (31), /* ddiv */
606 32, /* cache line size */
612 /* Instruction costs on PPC603 processors. */
614 struct processor_costs ppc603_cost = {
615 COSTS_N_INSNS (5), /* mulsi */
616 COSTS_N_INSNS (3), /* mulsi_const */
617 COSTS_N_INSNS (2), /* mulsi_const9 */
618 COSTS_N_INSNS (5), /* muldi */
619 COSTS_N_INSNS (37), /* divsi */
620 COSTS_N_INSNS (37), /* divdi */
621 COSTS_N_INSNS (3), /* fp */
622 COSTS_N_INSNS (4), /* dmul */
623 COSTS_N_INSNS (18), /* sdiv */
624 COSTS_N_INSNS (33), /* ddiv */
625 32, /* cache line size */
631 /* Instruction costs on PPC604 processors. */
633 struct processor_costs ppc604_cost = {
634 COSTS_N_INSNS (4), /* mulsi */
635 COSTS_N_INSNS (4), /* mulsi_const */
636 COSTS_N_INSNS (4), /* mulsi_const9 */
637 COSTS_N_INSNS (4), /* muldi */
638 COSTS_N_INSNS (20), /* divsi */
639 COSTS_N_INSNS (20), /* divdi */
640 COSTS_N_INSNS (3), /* fp */
641 COSTS_N_INSNS (3), /* dmul */
642 COSTS_N_INSNS (18), /* sdiv */
643 COSTS_N_INSNS (32), /* ddiv */
644 32, /* cache line size */
650 /* Instruction costs on PPC604e processors. */
652 struct processor_costs ppc604e_cost = {
653 COSTS_N_INSNS (2), /* mulsi */
654 COSTS_N_INSNS (2), /* mulsi_const */
655 COSTS_N_INSNS (2), /* mulsi_const9 */
656 COSTS_N_INSNS (2), /* muldi */
657 COSTS_N_INSNS (20), /* divsi */
658 COSTS_N_INSNS (20), /* divdi */
659 COSTS_N_INSNS (3), /* fp */
660 COSTS_N_INSNS (3), /* dmul */
661 COSTS_N_INSNS (18), /* sdiv */
662 COSTS_N_INSNS (32), /* ddiv */
663 32, /* cache line size */
669 /* Instruction costs on PPC620 processors. */
671 struct processor_costs ppc620_cost = {
672 COSTS_N_INSNS (5), /* mulsi */
673 COSTS_N_INSNS (4), /* mulsi_const */
674 COSTS_N_INSNS (3), /* mulsi_const9 */
675 COSTS_N_INSNS (7), /* muldi */
676 COSTS_N_INSNS (21), /* divsi */
677 COSTS_N_INSNS (37), /* divdi */
678 COSTS_N_INSNS (3), /* fp */
679 COSTS_N_INSNS (3), /* dmul */
680 COSTS_N_INSNS (18), /* sdiv */
681 COSTS_N_INSNS (32), /* ddiv */
682 128, /* cache line size */
688 /* Instruction costs on PPC630 processors. */
690 struct processor_costs ppc630_cost = {
691 COSTS_N_INSNS (5), /* mulsi */
692 COSTS_N_INSNS (4), /* mulsi_const */
693 COSTS_N_INSNS (3), /* mulsi_const9 */
694 COSTS_N_INSNS (7), /* muldi */
695 COSTS_N_INSNS (21), /* divsi */
696 COSTS_N_INSNS (37), /* divdi */
697 COSTS_N_INSNS (3), /* fp */
698 COSTS_N_INSNS (3), /* dmul */
699 COSTS_N_INSNS (17), /* sdiv */
700 COSTS_N_INSNS (21), /* ddiv */
701 128, /* cache line size */
707 /* Instruction costs on Cell processor. */
708 /* COSTS_N_INSNS (1) ~ one add. */
710 struct processor_costs ppccell_cost = {
711 COSTS_N_INSNS (9/2)+2, /* mulsi */
712 COSTS_N_INSNS (6/2), /* mulsi_const */
713 COSTS_N_INSNS (6/2), /* mulsi_const9 */
714 COSTS_N_INSNS (15/2)+2, /* muldi */
715 COSTS_N_INSNS (38/2), /* divsi */
716 COSTS_N_INSNS (70/2), /* divdi */
717 COSTS_N_INSNS (10/2), /* fp */
718 COSTS_N_INSNS (10/2), /* dmul */
719 COSTS_N_INSNS (74/2), /* sdiv */
720 COSTS_N_INSNS (74/2), /* ddiv */
721 128, /* cache line size */
727 /* Instruction costs on PPC750 and PPC7400 processors. */
729 struct processor_costs ppc750_cost = {
730 COSTS_N_INSNS (5), /* mulsi */
731 COSTS_N_INSNS (3), /* mulsi_const */
732 COSTS_N_INSNS (2), /* mulsi_const9 */
733 COSTS_N_INSNS (5), /* muldi */
734 COSTS_N_INSNS (17), /* divsi */
735 COSTS_N_INSNS (17), /* divdi */
736 COSTS_N_INSNS (3), /* fp */
737 COSTS_N_INSNS (3), /* dmul */
738 COSTS_N_INSNS (17), /* sdiv */
739 COSTS_N_INSNS (31), /* ddiv */
740 32, /* cache line size */
746 /* Instruction costs on PPC7450 processors. */
748 struct processor_costs ppc7450_cost = {
749 COSTS_N_INSNS (4), /* mulsi */
750 COSTS_N_INSNS (3), /* mulsi_const */
751 COSTS_N_INSNS (3), /* mulsi_const9 */
752 COSTS_N_INSNS (4), /* muldi */
753 COSTS_N_INSNS (23), /* divsi */
754 COSTS_N_INSNS (23), /* divdi */
755 COSTS_N_INSNS (5), /* fp */
756 COSTS_N_INSNS (5), /* dmul */
757 COSTS_N_INSNS (21), /* sdiv */
758 COSTS_N_INSNS (35), /* ddiv */
759 32, /* cache line size */
765 /* Instruction costs on PPC8540 processors. */
767 struct processor_costs ppc8540_cost = {
768 COSTS_N_INSNS (4), /* mulsi */
769 COSTS_N_INSNS (4), /* mulsi_const */
770 COSTS_N_INSNS (4), /* mulsi_const9 */
771 COSTS_N_INSNS (4), /* muldi */
772 COSTS_N_INSNS (19), /* divsi */
773 COSTS_N_INSNS (19), /* divdi */
774 COSTS_N_INSNS (4), /* fp */
775 COSTS_N_INSNS (4), /* dmul */
776 COSTS_N_INSNS (29), /* sdiv */
777 COSTS_N_INSNS (29), /* ddiv */
778 32, /* cache line size */
781 1, /* prefetch streams /*/
784 /* Instruction costs on E300C2 and E300C3 cores. */
786 struct processor_costs ppce300c2c3_cost = {
787 COSTS_N_INSNS (4), /* mulsi */
788 COSTS_N_INSNS (4), /* mulsi_const */
789 COSTS_N_INSNS (4), /* mulsi_const9 */
790 COSTS_N_INSNS (4), /* muldi */
791 COSTS_N_INSNS (19), /* divsi */
792 COSTS_N_INSNS (19), /* divdi */
793 COSTS_N_INSNS (3), /* fp */
794 COSTS_N_INSNS (4), /* dmul */
795 COSTS_N_INSNS (18), /* sdiv */
796 COSTS_N_INSNS (33), /* ddiv */
800 1, /* prefetch streams /*/
803 /* Instruction costs on PPCE500MC processors. */
805 struct processor_costs ppce500mc_cost = {
806 COSTS_N_INSNS (4), /* mulsi */
807 COSTS_N_INSNS (4), /* mulsi_const */
808 COSTS_N_INSNS (4), /* mulsi_const9 */
809 COSTS_N_INSNS (4), /* muldi */
810 COSTS_N_INSNS (14), /* divsi */
811 COSTS_N_INSNS (14), /* divdi */
812 COSTS_N_INSNS (8), /* fp */
813 COSTS_N_INSNS (10), /* dmul */
814 COSTS_N_INSNS (36), /* sdiv */
815 COSTS_N_INSNS (66), /* ddiv */
816 64, /* cache line size */
819 1, /* prefetch streams /*/
822 /* Instruction costs on PPCE500MC64 processors. */
824 struct processor_costs ppce500mc64_cost = {
825 COSTS_N_INSNS (4), /* mulsi */
826 COSTS_N_INSNS (4), /* mulsi_const */
827 COSTS_N_INSNS (4), /* mulsi_const9 */
828 COSTS_N_INSNS (4), /* muldi */
829 COSTS_N_INSNS (14), /* divsi */
830 COSTS_N_INSNS (14), /* divdi */
831 COSTS_N_INSNS (4), /* fp */
832 COSTS_N_INSNS (10), /* dmul */
833 COSTS_N_INSNS (36), /* sdiv */
834 COSTS_N_INSNS (66), /* ddiv */
835 64, /* cache line size */
838 1, /* prefetch streams /*/
841 /* Instruction costs on AppliedMicro Titan processors. */
843 struct processor_costs titan_cost = {
844 COSTS_N_INSNS (5), /* mulsi */
845 COSTS_N_INSNS (5), /* mulsi_const */
846 COSTS_N_INSNS (5), /* mulsi_const9 */
847 COSTS_N_INSNS (5), /* muldi */
848 COSTS_N_INSNS (18), /* divsi */
849 COSTS_N_INSNS (18), /* divdi */
850 COSTS_N_INSNS (10), /* fp */
851 COSTS_N_INSNS (10), /* dmul */
852 COSTS_N_INSNS (46), /* sdiv */
853 COSTS_N_INSNS (72), /* ddiv */
854 32, /* cache line size */
857 1, /* prefetch streams /*/
860 /* Instruction costs on POWER4 and POWER5 processors. */
862 struct processor_costs power4_cost = {
863 COSTS_N_INSNS (3), /* mulsi */
864 COSTS_N_INSNS (2), /* mulsi_const */
865 COSTS_N_INSNS (2), /* mulsi_const9 */
866 COSTS_N_INSNS (4), /* muldi */
867 COSTS_N_INSNS (18), /* divsi */
868 COSTS_N_INSNS (34), /* divdi */
869 COSTS_N_INSNS (3), /* fp */
870 COSTS_N_INSNS (3), /* dmul */
871 COSTS_N_INSNS (17), /* sdiv */
872 COSTS_N_INSNS (17), /* ddiv */
873 128, /* cache line size */
876 8, /* prefetch streams /*/
879 /* Instruction costs on POWER6 processors. */
881 struct processor_costs power6_cost = {
882 COSTS_N_INSNS (8), /* mulsi */
883 COSTS_N_INSNS (8), /* mulsi_const */
884 COSTS_N_INSNS (8), /* mulsi_const9 */
885 COSTS_N_INSNS (8), /* muldi */
886 COSTS_N_INSNS (22), /* divsi */
887 COSTS_N_INSNS (28), /* divdi */
888 COSTS_N_INSNS (3), /* fp */
889 COSTS_N_INSNS (3), /* dmul */
890 COSTS_N_INSNS (13), /* sdiv */
891 COSTS_N_INSNS (16), /* ddiv */
892 128, /* cache line size */
895 16, /* prefetch streams */
898 /* Instruction costs on POWER7 processors. */
900 struct processor_costs power7_cost = {
901 COSTS_N_INSNS (2), /* mulsi */
902 COSTS_N_INSNS (2), /* mulsi_const */
903 COSTS_N_INSNS (2), /* mulsi_const9 */
904 COSTS_N_INSNS (2), /* muldi */
905 COSTS_N_INSNS (18), /* divsi */
906 COSTS_N_INSNS (34), /* divdi */
907 COSTS_N_INSNS (3), /* fp */
908 COSTS_N_INSNS (3), /* dmul */
909 COSTS_N_INSNS (13), /* sdiv */
910 COSTS_N_INSNS (16), /* ddiv */
911 128, /* cache line size */
914 12, /* prefetch streams */
917 /* Instruction costs on POWER A2 processors. */
919 struct processor_costs ppca2_cost = {
920 COSTS_N_INSNS (16), /* mulsi */
921 COSTS_N_INSNS (16), /* mulsi_const */
922 COSTS_N_INSNS (16), /* mulsi_const9 */
923 COSTS_N_INSNS (16), /* muldi */
924 COSTS_N_INSNS (22), /* divsi */
925 COSTS_N_INSNS (28), /* divdi */
926 COSTS_N_INSNS (3), /* fp */
927 COSTS_N_INSNS (3), /* dmul */
928 COSTS_N_INSNS (59), /* sdiv */
929 COSTS_N_INSNS (72), /* ddiv */
933 16, /* prefetch streams */
937 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
938 #undef RS6000_BUILTIN
939 #undef RS6000_BUILTIN_EQUATE
940 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
941 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
943 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
945 #include "rs6000-builtin.def"
948 #undef RS6000_BUILTIN
949 #undef RS6000_BUILTIN_EQUATE
952 static bool rs6000_function_ok_for_sibcall (tree, tree);
953 static const char *rs6000_invalid_within_doloop (const_rtx);
954 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
955 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
956 static rtx rs6000_generate_compare (rtx, enum machine_mode);
957 static void rs6000_emit_stack_tie (void);
958 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
959 static bool spe_func_has_64bit_regs_p (void);
960 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
962 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
963 static unsigned rs6000_hash_constant (rtx);
964 static unsigned toc_hash_function (const void *);
965 static int toc_hash_eq (const void *, const void *);
966 static bool reg_offset_addressing_ok_p (enum machine_mode);
967 static bool virtual_stack_registers_memory_p (rtx);
968 static bool constant_pool_expr_p (rtx);
969 static bool legitimate_small_data_p (enum machine_mode, rtx);
970 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
971 static struct machine_function * rs6000_init_machine_status (void);
972 static bool rs6000_assemble_integer (rtx, unsigned int, int);
973 static bool no_global_regs_above (int, bool);
974 #ifdef HAVE_GAS_HIDDEN
975 static void rs6000_assemble_visibility (tree, int);
977 static int rs6000_ra_ever_killed (void);
978 static bool rs6000_attribute_takes_identifier_p (const_tree);
979 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
980 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
981 static bool rs6000_ms_bitfield_layout_p (const_tree);
982 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
983 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
984 static const char *rs6000_mangle_type (const_tree);
985 static void rs6000_set_default_type_attributes (tree);
986 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
987 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
988 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
989 enum machine_mode, bool, bool, bool);
990 static bool rs6000_reg_live_or_pic_offset_p (int);
991 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
992 static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
993 static void rs6000_restore_saved_cr (rtx, int);
994 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
995 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
996 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
998 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
999 static bool rs6000_return_in_memory (const_tree, const_tree);
1000 static rtx rs6000_function_value (const_tree, const_tree, bool);
1001 static void rs6000_file_start (void);
1003 static int rs6000_elf_reloc_rw_mask (void);
1004 static void rs6000_elf_asm_out_constructor (rtx, int);
1005 static void rs6000_elf_asm_out_destructor (rtx, int);
1006 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
1007 static void rs6000_elf_asm_init_sections (void);
1008 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
1009 unsigned HOST_WIDE_INT);
1010 static void rs6000_elf_encode_section_info (tree, rtx, int)
1013 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
1014 static void rs6000_alloc_sdmode_stack_slot (void);
1015 static void rs6000_instantiate_decls (void);
1017 static void rs6000_xcoff_asm_output_anchor (rtx);
1018 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
1019 static void rs6000_xcoff_asm_init_sections (void);
1020 static int rs6000_xcoff_reloc_rw_mask (void);
1021 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
1022 static section *rs6000_xcoff_select_section (tree, int,
1023 unsigned HOST_WIDE_INT);
1024 static void rs6000_xcoff_unique_section (tree, int);
1025 static section *rs6000_xcoff_select_rtx_section
1026 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
1027 static const char * rs6000_xcoff_strip_name_encoding (const char *);
1028 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
1029 static void rs6000_xcoff_file_start (void);
1030 static void rs6000_xcoff_file_end (void);
1032 static int rs6000_variable_issue (FILE *, int, rtx, int);
1033 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
1034 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
1035 static int rs6000_debug_address_cost (rtx, bool);
1036 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
1037 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
1038 static void rs6000_sched_init (FILE *, int, int);
1039 static bool is_microcoded_insn (rtx);
1040 static bool is_nonpipeline_insn (rtx);
1041 static bool is_cracked_insn (rtx);
1042 static bool is_branch_slot_insn (rtx);
1043 static bool is_load_insn (rtx);
1044 static rtx get_store_dest (rtx pat);
1045 static bool is_store_insn (rtx);
1046 static bool set_to_load_agen (rtx,rtx);
1047 static bool adjacent_mem_locations (rtx,rtx);
1048 static int rs6000_adjust_priority (rtx, int);
1049 static int rs6000_issue_rate (void);
1050 static bool rs6000_is_costly_dependence (dep_t, int, int);
1051 static rtx get_next_active_insn (rtx, rtx);
1052 static bool insn_terminates_group_p (rtx , enum group_termination);
1053 static bool insn_must_be_first_in_group (rtx);
1054 static bool insn_must_be_last_in_group (rtx);
1055 static bool is_costly_group (rtx *, rtx);
1056 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
1057 static int redefine_groups (FILE *, int, rtx, rtx);
1058 static int pad_groups (FILE *, int, rtx, rtx);
1059 static void rs6000_sched_finish (FILE *, int);
1060 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
1061 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
1062 static int rs6000_use_sched_lookahead (void);
1063 static int rs6000_use_sched_lookahead_guard (rtx);
1064 static void * rs6000_alloc_sched_context (void);
1065 static void rs6000_init_sched_context (void *, bool);
1066 static void rs6000_set_sched_context (void *);
1067 static void rs6000_free_sched_context (void *);
1068 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
1069 static tree rs6000_builtin_mask_for_load (void);
1070 static tree rs6000_builtin_mul_widen_even (tree);
1071 static tree rs6000_builtin_mul_widen_odd (tree);
1072 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
1073 static tree rs6000_builtin_vec_perm (tree, tree *);
1074 static bool rs6000_builtin_support_vector_misalignment (enum
1079 static void def_builtin (int, const char *, tree, int);
1080 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1081 static void rs6000_init_builtins (void);
1082 static tree rs6000_builtin_decl (unsigned, bool);
1084 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1085 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1086 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1087 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1088 static void altivec_init_builtins (void);
1089 static unsigned builtin_hash_function (const void *);
1090 static int builtin_hash_eq (const void *, const void *);
1091 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1092 enum machine_mode, enum machine_mode,
1093 enum rs6000_builtins, const char *name);
1094 static void rs6000_common_init_builtins (void);
1095 static void rs6000_init_libfuncs (void);
1097 static void paired_init_builtins (void);
1098 static rtx paired_expand_builtin (tree, rtx, bool *);
1099 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1100 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1101 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1103 static void enable_mask_for_builtins (struct builtin_description *, int,
1104 enum rs6000_builtins,
1105 enum rs6000_builtins);
1106 static void spe_init_builtins (void);
1107 static rtx spe_expand_builtin (tree, rtx, bool *);
1108 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1109 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1110 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1111 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1112 static rs6000_stack_t *rs6000_stack_info (void);
1113 static void debug_stack_info (rs6000_stack_t *);
1115 static rtx altivec_expand_builtin (tree, rtx, bool *);
1116 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1117 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1118 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1119 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1120 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1121 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1122 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1123 static rtx altivec_expand_vec_set_builtin (tree);
1124 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1125 static int get_element_number (tree, tree);
1126 static bool rs6000_handle_option (size_t, const char *, int);
1127 static void rs6000_parse_tls_size_option (void);
1128 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1129 static int first_altivec_reg_to_save (void);
1130 static unsigned int compute_vrsave_mask (void);
1131 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1132 static void is_altivec_return_reg (rtx, void *);
1133 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1134 int easy_vector_constant (rtx, enum machine_mode);
1135 static rtx rs6000_dwarf_register_span (rtx);
1136 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1137 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1138 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1139 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1140 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1141 static rtx rs6000_delegitimize_address (rtx);
1142 static rtx rs6000_tls_get_addr (void);
1143 static rtx rs6000_got_sym (void);
1144 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1145 static const char *rs6000_get_some_local_dynamic_name (void);
1146 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1147 static rtx rs6000_complex_function_value (enum machine_mode);
1148 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
1149 enum machine_mode, tree);
1150 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1152 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1153 tree, HOST_WIDE_INT);
1154 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1157 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1158 const_tree, HOST_WIDE_INT,
1160 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
1161 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
1162 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1163 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1164 enum machine_mode, tree,
1166 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1168 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1170 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1172 static void macho_branch_islands (void);
1173 static int no_previous_def (tree function_name);
1174 static tree get_prev_label (tree function_name);
1175 static void rs6000_darwin_file_start (void);
1178 static tree rs6000_build_builtin_va_list (void);
1179 static void rs6000_va_start (tree, rtx);
1180 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1181 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1182 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1183 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1184 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1185 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1187 static tree rs6000_stack_protect_fail (void);
1189 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1192 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1195 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1197 = rs6000_legitimize_reload_address;
1199 static bool rs6000_mode_dependent_address_p (const_rtx);
1200 static bool rs6000_mode_dependent_address (const_rtx);
1201 static bool rs6000_debug_mode_dependent_address (const_rtx);
1202 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1203 = rs6000_mode_dependent_address;
1205 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1206 enum machine_mode, rtx);
1207 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1210 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1211 enum machine_mode, rtx)
1212 = rs6000_secondary_reload_class;
1214 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1215 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1217 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1218 = rs6000_preferred_reload_class;
1220 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1223 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1227 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1229 = rs6000_secondary_memory_needed;
1231 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1234 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1238 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1241 = rs6000_cannot_change_mode_class;
1243 static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class,
1245 struct secondary_reload_info *);
1247 static const enum reg_class *rs6000_ira_cover_classes (void);
1249 const int INSN_NOT_AVAILABLE = -1;
1250 static enum machine_mode rs6000_eh_return_filter_mode (void);
1251 static bool rs6000_can_eliminate (const int, const int);
1252 static void rs6000_trampoline_init (rtx, tree, rtx);
1254 /* Hash table stuff for keeping track of TOC entries. */
1256 struct GTY(()) toc_hash_struct
1258 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1259 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1261 enum machine_mode key_mode;
1265 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1267 /* Hash table to keep track of the argument types for builtin functions. */
1269 struct GTY(()) builtin_hash_struct
1272 enum machine_mode mode[4]; /* return value + 3 arguments. */
1273 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1276 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1278 /* Default register names. */
1279 char rs6000_reg_names[][8] =
1281 "0", "1", "2", "3", "4", "5", "6", "7",
1282 "8", "9", "10", "11", "12", "13", "14", "15",
1283 "16", "17", "18", "19", "20", "21", "22", "23",
1284 "24", "25", "26", "27", "28", "29", "30", "31",
1285 "0", "1", "2", "3", "4", "5", "6", "7",
1286 "8", "9", "10", "11", "12", "13", "14", "15",
1287 "16", "17", "18", "19", "20", "21", "22", "23",
1288 "24", "25", "26", "27", "28", "29", "30", "31",
1289 "mq", "lr", "ctr","ap",
1290 "0", "1", "2", "3", "4", "5", "6", "7",
1292 /* AltiVec registers. */
1293 "0", "1", "2", "3", "4", "5", "6", "7",
1294 "8", "9", "10", "11", "12", "13", "14", "15",
1295 "16", "17", "18", "19", "20", "21", "22", "23",
1296 "24", "25", "26", "27", "28", "29", "30", "31",
1298 /* SPE registers. */
1299 "spe_acc", "spefscr",
1300 /* Soft frame pointer. */
1304 #ifdef TARGET_REGNAMES
1305 static const char alt_reg_names[][8] =
1307 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1308 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1309 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1310 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1311 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1312 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1313 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1314 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1315 "mq", "lr", "ctr", "ap",
1316 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1318 /* AltiVec registers. */
1319 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1320 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1321 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1322 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1324 /* SPE registers. */
1325 "spe_acc", "spefscr",
1326 /* Soft frame pointer. */
1331 /* Table of valid machine attributes. */
1333 static const struct attribute_spec rs6000_attribute_table[] =
1335 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1336 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1337 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1338 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1339 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1340 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1341 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1342 SUBTARGET_ATTRIBUTE_TABLE,
1344 { NULL, 0, 0, false, false, false, NULL }
1347 #ifndef MASK_STRICT_ALIGN
1348 #define MASK_STRICT_ALIGN 0
1350 #ifndef TARGET_PROFILE_KERNEL
1351 #define TARGET_PROFILE_KERNEL 0
1354 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1355 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1357 /* Initialize the GCC target structure. */
1358 #undef TARGET_ATTRIBUTE_TABLE
1359 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1360 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1361 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1362 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1363 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1365 #undef TARGET_ASM_ALIGNED_DI_OP
1366 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1368 /* Default unaligned ops are only provided for ELF. Find the ops needed
1369 for non-ELF systems. */
1370 #ifndef OBJECT_FORMAT_ELF
1372 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1374 #undef TARGET_ASM_UNALIGNED_HI_OP
1375 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1376 #undef TARGET_ASM_UNALIGNED_SI_OP
1377 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1378 #undef TARGET_ASM_UNALIGNED_DI_OP
1379 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1382 #undef TARGET_ASM_UNALIGNED_HI_OP
1383 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1384 #undef TARGET_ASM_UNALIGNED_SI_OP
1385 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1386 #undef TARGET_ASM_UNALIGNED_DI_OP
1387 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1388 #undef TARGET_ASM_ALIGNED_DI_OP
1389 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1393 /* This hook deals with fixups for relocatable code and DI-mode objects
1395 #undef TARGET_ASM_INTEGER
1396 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1398 #ifdef HAVE_GAS_HIDDEN
1399 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1400 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1403 #undef TARGET_HAVE_TLS
1404 #define TARGET_HAVE_TLS HAVE_AS_TLS
1406 #undef TARGET_CANNOT_FORCE_CONST_MEM
1407 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1409 #undef TARGET_DELEGITIMIZE_ADDRESS
1410 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1412 #undef TARGET_ASM_FUNCTION_PROLOGUE
1413 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1414 #undef TARGET_ASM_FUNCTION_EPILOGUE
1415 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1417 #undef TARGET_LEGITIMIZE_ADDRESS
1418 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1420 #undef TARGET_SCHED_VARIABLE_ISSUE
1421 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1423 #undef TARGET_SCHED_ISSUE_RATE
1424 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1425 #undef TARGET_SCHED_ADJUST_COST
1426 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1427 #undef TARGET_SCHED_ADJUST_PRIORITY
1428 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1429 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1430 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1431 #undef TARGET_SCHED_INIT
1432 #define TARGET_SCHED_INIT rs6000_sched_init
1433 #undef TARGET_SCHED_FINISH
1434 #define TARGET_SCHED_FINISH rs6000_sched_finish
1435 #undef TARGET_SCHED_REORDER
1436 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1437 #undef TARGET_SCHED_REORDER2
1438 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1440 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1441 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1443 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1444 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1446 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1447 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1448 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1449 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1450 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1451 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1452 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1453 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1455 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1456 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1457 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1458 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1459 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1460 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1461 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1462 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1463 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1464 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1465 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1466 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1467 rs6000_builtin_support_vector_misalignment
1468 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1469 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1471 #undef TARGET_INIT_BUILTINS
1472 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1473 #undef TARGET_BUILTIN_DECL
1474 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1476 #undef TARGET_EXPAND_BUILTIN
1477 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1479 #undef TARGET_MANGLE_TYPE
1480 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1482 #undef TARGET_INIT_LIBFUNCS
1483 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1486 #undef TARGET_BINDS_LOCAL_P
1487 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1490 #undef TARGET_MS_BITFIELD_LAYOUT_P
1491 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1493 #undef TARGET_ASM_OUTPUT_MI_THUNK
1494 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1496 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1497 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1499 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1500 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1502 #undef TARGET_INVALID_WITHIN_DOLOOP
1503 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1505 #undef TARGET_RTX_COSTS
1506 #define TARGET_RTX_COSTS rs6000_rtx_costs
1507 #undef TARGET_ADDRESS_COST
1508 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1510 #undef TARGET_DWARF_REGISTER_SPAN
1511 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1513 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1514 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1516 /* On rs6000, function arguments are promoted, as are function return
1518 #undef TARGET_PROMOTE_FUNCTION_MODE
1519 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1521 #undef TARGET_RETURN_IN_MEMORY
1522 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1524 #undef TARGET_SETUP_INCOMING_VARARGS
1525 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1527 /* Always strict argument naming on rs6000. */
1528 #undef TARGET_STRICT_ARGUMENT_NAMING
1529 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1530 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1531 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1532 #undef TARGET_SPLIT_COMPLEX_ARG
1533 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1534 #undef TARGET_MUST_PASS_IN_STACK
1535 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1536 #undef TARGET_PASS_BY_REFERENCE
1537 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1538 #undef TARGET_ARG_PARTIAL_BYTES
1539 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1541 #undef TARGET_BUILD_BUILTIN_VA_LIST
1542 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1544 #undef TARGET_EXPAND_BUILTIN_VA_START
1545 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1547 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1548 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1550 #undef TARGET_EH_RETURN_FILTER_MODE
1551 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1553 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1554 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1556 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1557 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1559 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1560 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1562 #undef TARGET_HANDLE_OPTION
1563 #define TARGET_HANDLE_OPTION rs6000_handle_option
1565 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1566 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1567 rs6000_builtin_vectorized_function
1569 #undef TARGET_DEFAULT_TARGET_FLAGS
1570 #define TARGET_DEFAULT_TARGET_FLAGS \
1573 #undef TARGET_STACK_PROTECT_FAIL
1574 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1576 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1577 The PowerPC architecture requires only weak consistency among
1578 processors--that is, memory accesses between processors need not be
1579 sequentially consistent and memory accesses among processors can occur
1580 in any order. The ability to order memory accesses weakly provides
1581 opportunities for more efficient use of the system bus. Unless a
1582 dependency exists, the 604e allows read operations to precede store
1584 #undef TARGET_RELAXED_ORDERING
1585 #define TARGET_RELAXED_ORDERING true
1588 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1589 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1592 /* Use a 32-bit anchor range. This leads to sequences like:
1594 addis tmp,anchor,high
1597 where tmp itself acts as an anchor, and can be shared between
1598 accesses to the same 64k page. */
1599 #undef TARGET_MIN_ANCHOR_OFFSET
1600 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1601 #undef TARGET_MAX_ANCHOR_OFFSET
1602 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1603 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1604 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1606 #undef TARGET_BUILTIN_RECIPROCAL
1607 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1609 #undef TARGET_EXPAND_TO_RTL_HOOK
1610 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1612 #undef TARGET_INSTANTIATE_DECLS
1613 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1615 #undef TARGET_SECONDARY_RELOAD
1616 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1618 #undef TARGET_IRA_COVER_CLASSES
1619 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1621 #undef TARGET_LEGITIMATE_ADDRESS_P
1622 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1624 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1625 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1627 #undef TARGET_CAN_ELIMINATE
1628 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1630 #undef TARGET_TRAMPOLINE_INIT
1631 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1633 #undef TARGET_FUNCTION_VALUE
1634 #define TARGET_FUNCTION_VALUE rs6000_function_value
1636 struct gcc_target targetm = TARGET_INITIALIZER;
1638 /* Return number of consecutive hard regs needed starting at reg REGNO
1639 to hold something of mode MODE.
1640 This is ordinarily the length in words of a value of mode MODE
1641 but can be less for certain modes in special long registers.
1643 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1644 scalar instructions. The upper 32 bits are only available to the
1647 POWER and PowerPC GPRs hold 32 bits worth;
1648 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1651 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1653 unsigned HOST_WIDE_INT reg_size;
1655 if (FP_REGNO_P (regno))
1656 reg_size = (VECTOR_MEM_VSX_P (mode)
1657 ? UNITS_PER_VSX_WORD
1658 : UNITS_PER_FP_WORD);
1660 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1661 reg_size = UNITS_PER_SPE_WORD;
1663 else if (ALTIVEC_REGNO_P (regno))
1664 reg_size = UNITS_PER_ALTIVEC_WORD;
1666 /* The value returned for SCmode in the E500 double case is 2 for
1667 ABI compatibility; storing an SCmode value in a single register
1668 would require function_arg and rs6000_spe_function_arg to handle
1669 SCmode so as to pass the value correctly in a pair of
1671 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1672 && !DECIMAL_FLOAT_MODE_P (mode))
1673 reg_size = UNITS_PER_FP_WORD;
1676 reg_size = UNITS_PER_WORD;
1678 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1681 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1684 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1686 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1688 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1689 implementations. Don't allow an item to be split between a FP register
1690 and an Altivec register. */
1691 if (VECTOR_MEM_VSX_P (mode))
1693 if (FP_REGNO_P (regno))
1694 return FP_REGNO_P (last_regno);
1696 if (ALTIVEC_REGNO_P (regno))
1697 return ALTIVEC_REGNO_P (last_regno);
1700 /* The GPRs can hold any mode, but values bigger than one register
1701 cannot go past R31. */
1702 if (INT_REGNO_P (regno))
1703 return INT_REGNO_P (last_regno);
1705 /* The float registers (except for VSX vector modes) can only hold floating
1706 modes and DImode. This excludes the 32-bit decimal float mode for
1708 if (FP_REGNO_P (regno))
1710 if (SCALAR_FLOAT_MODE_P (mode)
1711 && (mode != TDmode || (regno % 2) == 0)
1712 && FP_REGNO_P (last_regno))
1715 if (GET_MODE_CLASS (mode) == MODE_INT
1716 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1719 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1720 && PAIRED_VECTOR_MODE (mode))
1726 /* The CR register can only hold CC modes. */
1727 if (CR_REGNO_P (regno))
1728 return GET_MODE_CLASS (mode) == MODE_CC;
1730 if (CA_REGNO_P (regno))
1731 return mode == BImode;
1733 /* AltiVec only in AldyVec registers. */
1734 if (ALTIVEC_REGNO_P (regno))
1735 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1737 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1738 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1741 /* We cannot put TImode anywhere except general register and it must be able
1742 to fit within the register set. In the future, allow TImode in the
1743 Altivec or VSX registers. */
1745 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1748 /* Print interesting facts about registers. */
1750 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1754 for (r = first_regno; r <= last_regno; ++r)
1756 const char *comma = "";
1759 if (first_regno == last_regno)
1760 fprintf (stderr, "%s:\t", reg_name);
1762 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1765 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1766 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1770 fprintf (stderr, ",\n\t");
1775 if (rs6000_hard_regno_nregs[m][r] > 1)
1776 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1777 rs6000_hard_regno_nregs[m][r]);
1779 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1784 if (call_used_regs[r])
1788 fprintf (stderr, ",\n\t");
1793 len += fprintf (stderr, "%s%s", comma, "call-used");
1801 fprintf (stderr, ",\n\t");
1806 len += fprintf (stderr, "%s%s", comma, "fixed");
1812 fprintf (stderr, ",\n\t");
1816 fprintf (stderr, "%sregno = %d\n", comma, r);
1820 /* Print various interesting information with -mdebug=reg. */
1822 rs6000_debug_reg_global (void)
1824 const char *nl = (const char *)0;
1826 char costly_num[20];
1828 const char *costly_str;
1829 const char *nop_str;
1831 /* Map enum rs6000_vector to string. */
1832 static const char *rs6000_debug_vector_unit[] = {
1841 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1842 LAST_VIRTUAL_REGISTER);
1843 rs6000_debug_reg_print (0, 31, "gr");
1844 rs6000_debug_reg_print (32, 63, "fp");
1845 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1848 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1849 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1850 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1851 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1852 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
1853 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1854 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1855 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1856 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1860 "d reg_class = %s\n"
1861 "f reg_class = %s\n"
1862 "v reg_class = %s\n"
1863 "wa reg_class = %s\n"
1864 "wd reg_class = %s\n"
1865 "wf reg_class = %s\n"
1866 "ws reg_class = %s\n\n",
1867 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1868 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1869 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1870 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1871 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1872 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1873 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1875 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1876 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1879 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1881 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1882 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1888 if (rs6000_recip_control)
1890 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
1892 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1893 if (rs6000_recip_bits[m])
1896 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1898 (RS6000_RECIP_AUTO_RE_P (m)
1900 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
1901 (RS6000_RECIP_AUTO_RSQRTE_P (m)
1903 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
1906 fputs ("\n", stderr);
1909 switch (rs6000_sched_costly_dep)
1911 case max_dep_latency:
1912 costly_str = "max_dep_latency";
1916 costly_str = "no_dep_costly";
1919 case all_deps_costly:
1920 costly_str = "all_deps_costly";
1923 case true_store_to_load_dep_costly:
1924 costly_str = "true_store_to_load_dep_costly";
1927 case store_to_load_dep_costly:
1928 costly_str = "store_to_load_dep_costly";
1932 costly_str = costly_num;
1933 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1937 switch (rs6000_sched_insert_nops)
1939 case sched_finish_regroup_exact:
1940 nop_str = "sched_finish_regroup_exact";
1943 case sched_finish_pad_groups:
1944 nop_str = "sched_finish_pad_groups";
1947 case sched_finish_none:
1948 nop_str = "sched_finish_none";
1953 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1958 "always_hint = %s\n"
1959 "align_branch_targets = %s\n"
1960 "sched_restricted_insns_priority = %d\n"
1961 "sched_costly_dep = %s\n"
1962 "sched_insert_nops = %s\n\n",
1963 rs6000_always_hint ? "true" : "false",
1964 rs6000_align_branch_targets ? "true" : "false",
1965 (int)rs6000_sched_restricted_insns_priority,
1966 costly_str, nop_str);
1969 /* Initialize the various global tables that are based on register size. */
1971 rs6000_init_hard_regno_mode_ok (void)
1977 /* Precalculate REGNO_REG_CLASS. */
1978 rs6000_regno_regclass[0] = GENERAL_REGS;
1979 for (r = 1; r < 32; ++r)
1980 rs6000_regno_regclass[r] = BASE_REGS;
1982 for (r = 32; r < 64; ++r)
1983 rs6000_regno_regclass[r] = FLOAT_REGS;
1985 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1986 rs6000_regno_regclass[r] = NO_REGS;
1988 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
1989 rs6000_regno_regclass[r] = ALTIVEC_REGS;
1991 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
1992 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
1993 rs6000_regno_regclass[r] = CR_REGS;
1995 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
1996 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
1997 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
1998 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
1999 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2000 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2001 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2002 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2003 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2004 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2006 /* Precalculate vector information, this must be set up before the
2007 rs6000_hard_regno_nregs_internal below. */
2008 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2010 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2011 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2012 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2015 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2016 rs6000_constraints[c] = NO_REGS;
2018 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2019 believes it can use native alignment or still uses 128-bit alignment. */
2020 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2031 /* V2DF mode, VSX only. */
2034 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2035 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2036 rs6000_vector_align[V2DFmode] = align64;
2039 /* V4SF mode, either VSX or Altivec. */
2042 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2043 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2044 rs6000_vector_align[V4SFmode] = align32;
2046 else if (TARGET_ALTIVEC)
2048 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2049 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2050 rs6000_vector_align[V4SFmode] = align32;
2053 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2057 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2058 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2059 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2060 rs6000_vector_align[V4SImode] = align32;
2061 rs6000_vector_align[V8HImode] = align32;
2062 rs6000_vector_align[V16QImode] = align32;
2066 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2067 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2068 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2072 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2073 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2074 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2078 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2079 Altivec doesn't have 64-bit support. */
2082 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2083 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2084 rs6000_vector_align[V2DImode] = align64;
2087 /* DFmode, see if we want to use the VSX unit. */
2088 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2090 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2091 rs6000_vector_mem[DFmode]
2092 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2093 rs6000_vector_align[DFmode] = align64;
2096 /* TODO add SPE and paired floating point vector support. */
2098 /* Register class constaints for the constraints that depend on compile
2100 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2101 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2103 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2104 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2108 /* At present, we just use VSX_REGS, but we have different constraints
2109 based on the use, in case we want to fine tune the default register
2110 class used. wa = any VSX register, wf = register class to use for
2111 V4SF, wd = register class to use for V2DF, and ws = register classs to
2112 use for DF scalars. */
2113 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2114 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2115 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2116 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2122 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2124 /* Set up the reload helper functions. */
2125 if (TARGET_VSX || TARGET_ALTIVEC)
2129 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2130 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2131 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2132 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2133 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2134 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2135 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2136 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2137 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2138 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2139 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2140 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2144 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2145 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2146 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2147 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2148 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2149 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2150 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2151 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2152 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2153 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2154 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2155 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2159 /* Precalculate HARD_REGNO_NREGS. */
2160 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2161 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2162 rs6000_hard_regno_nregs[m][r]
2163 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2165 /* Precalculate HARD_REGNO_MODE_OK. */
2166 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2167 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2168 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2169 rs6000_hard_regno_mode_ok_p[m][r] = true;
2171 /* Precalculate CLASS_MAX_NREGS sizes. */
2172 for (c = 0; c < LIM_REG_CLASSES; ++c)
2176 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2177 reg_size = UNITS_PER_VSX_WORD;
2179 else if (c == ALTIVEC_REGS)
2180 reg_size = UNITS_PER_ALTIVEC_WORD;
2182 else if (c == FLOAT_REGS)
2183 reg_size = UNITS_PER_FP_WORD;
2186 reg_size = UNITS_PER_WORD;
2188 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2189 rs6000_class_max_nregs[m][c]
2190 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2193 if (TARGET_E500_DOUBLE)
2194 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2196 /* Calculate which modes to automatically generate code to use a the
2197 reciprocal divide and square root instructions. In the future, possibly
2198 automatically generate the instructions even if the user did not specify
2199 -mrecip. The older machines double precision reciprocal sqrt estimate is
2200 not accurate enough. */
2201 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2203 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2205 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2206 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2207 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2208 if (VECTOR_UNIT_VSX_P (V2DFmode))
2209 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2211 if (TARGET_FRSQRTES)
2212 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2214 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2215 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2216 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2217 if (VECTOR_UNIT_VSX_P (V2DFmode))
2218 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2220 if (rs6000_recip_control)
2222 if (!TARGET_FUSED_MADD)
2223 warning (0, "-mrecip requires -mfused-madd");
2224 if (!flag_finite_math_only)
2225 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2226 if (flag_trapping_math)
2227 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2228 if (!flag_reciprocal_math)
2229 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2230 if (TARGET_FUSED_MADD && flag_finite_math_only && !flag_trapping_math
2231 && flag_reciprocal_math)
2233 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2234 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2235 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2237 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2238 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2239 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2241 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2242 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2243 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2245 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2246 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2247 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2249 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2250 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2251 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2253 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2254 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2255 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2257 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2258 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2259 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2261 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2262 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2263 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2267 if (TARGET_DEBUG_REG)
2268 rs6000_debug_reg_global ();
2270 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2272 "SImode variable mult cost = %d\n"
2273 "SImode constant mult cost = %d\n"
2274 "SImode short constant mult cost = %d\n"
2275 "DImode multipliciation cost = %d\n"
2276 "SImode division cost = %d\n"
2277 "DImode division cost = %d\n"
2278 "Simple fp operation cost = %d\n"
2279 "DFmode multiplication cost = %d\n"
2280 "SFmode division cost = %d\n"
2281 "DFmode division cost = %d\n"
2282 "cache line size = %d\n"
2283 "l1 cache size = %d\n"
2284 "l2 cache size = %d\n"
2285 "simultaneous prefetches = %d\n"
2288 rs6000_cost->mulsi_const,
2289 rs6000_cost->mulsi_const9,
2297 rs6000_cost->cache_line_size,
2298 rs6000_cost->l1_cache_size,
2299 rs6000_cost->l2_cache_size,
2300 rs6000_cost->simultaneous_prefetches);
2304 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2307 darwin_rs6000_override_options (void)
2309 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2311 rs6000_altivec_abi = 1;
2312 TARGET_ALTIVEC_VRSAVE = 1;
2313 if (DEFAULT_ABI == ABI_DARWIN)
2315 if (MACHO_DYNAMIC_NO_PIC_P)
2318 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2321 else if (flag_pic == 1)
2326 if (TARGET_64BIT && ! TARGET_POWERPC64)
2328 target_flags |= MASK_POWERPC64;
2329 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2333 rs6000_default_long_calls = 1;
2334 target_flags |= MASK_SOFT_FLOAT;
2337 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2339 if (!flag_mkernel && !flag_apple_kext
2341 && ! (target_flags_explicit & MASK_ALTIVEC))
2342 target_flags |= MASK_ALTIVEC;
2344 /* Unless the user (not the configurer) has explicitly overridden
2345 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2346 G4 unless targetting the kernel. */
2349 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2350 && ! (target_flags_explicit & MASK_ALTIVEC)
2351 && ! rs6000_select[1].string)
2353 target_flags |= MASK_ALTIVEC;
2358 /* If not otherwise specified by a target, make 'long double' equivalent to
2361 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2362 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2365 /* Override command line options. Mostly we process the processor
2366 type and sometimes adjust other TARGET_ options. */
2369 rs6000_override_options (const char *default_cpu)
2372 struct rs6000_cpu_select *ptr;
2375 /* Simplifications for entries below. */
2378 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2379 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2382 /* This table occasionally claims that a processor does not support
2383 a particular feature even though it does, but the feature is slower
2384 than the alternative. Thus, it shouldn't be relied on as a
2385 complete description of the processor's support.
2387 Please keep this list in order, and don't forget to update the
2388 documentation in invoke.texi when adding a new processor or
2392 const char *const name; /* Canonical processor name. */
2393 const enum processor_type processor; /* Processor type enum value. */
2394 const int target_enable; /* Target flags to enable. */
2395 } const processor_target_table[]
2396 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2397 {"403", PROCESSOR_PPC403,
2398 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2399 {"405", PROCESSOR_PPC405,
2400 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2401 {"405fp", PROCESSOR_PPC405,
2402 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2403 {"440", PROCESSOR_PPC440,
2404 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2405 {"440fp", PROCESSOR_PPC440,
2406 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2407 {"464", PROCESSOR_PPC440,
2408 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2409 {"464fp", PROCESSOR_PPC440,
2410 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2411 {"476", PROCESSOR_PPC476,
2412 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2413 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2414 {"476fp", PROCESSOR_PPC476,
2415 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2416 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2417 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2418 {"601", PROCESSOR_PPC601,
2419 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2420 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2421 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2422 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2423 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2424 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2425 {"620", PROCESSOR_PPC620,
2426 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2427 {"630", PROCESSOR_PPC630,
2428 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2429 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2430 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2431 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2432 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2433 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2434 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2435 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2436 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2438 /* 8548 has a dummy entry for now. */
2439 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2441 {"a2", PROCESSOR_PPCA2,
2442 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2443 | MASK_CMPB | MASK_NO_UPDATE },
2444 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2445 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2446 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2448 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2449 | MASK_PPC_GFXOPT | MASK_ISEL},
2450 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2451 {"970", PROCESSOR_POWER4,
2452 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2453 {"cell", PROCESSOR_CELL,
2454 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2455 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2456 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2457 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2458 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2459 {"G5", PROCESSOR_POWER4,
2460 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2461 {"titan", PROCESSOR_TITAN,
2462 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2463 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2464 {"power2", PROCESSOR_POWER,
2465 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2466 {"power3", PROCESSOR_PPC630,
2467 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2468 {"power4", PROCESSOR_POWER4,
2469 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2471 {"power5", PROCESSOR_POWER5,
2472 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2473 | MASK_MFCRF | MASK_POPCNTB},
2474 {"power5+", PROCESSOR_POWER5,
2475 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2476 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2477 {"power6", PROCESSOR_POWER6,
2478 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2479 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2480 | MASK_RECIP_PRECISION},
2481 {"power6x", PROCESSOR_POWER6,
2482 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2483 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2484 | MASK_MFPGPR | MASK_RECIP_PRECISION},
2485 {"power7", PROCESSOR_POWER7,
2486 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2487 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2488 | MASK_VSX| MASK_RECIP_PRECISION}, /* Don't add MASK_ISEL by default */
2489 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2490 {"powerpc64", PROCESSOR_POWERPC64,
2491 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2492 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2493 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2494 {"rios2", PROCESSOR_RIOS2,
2495 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2496 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2497 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2498 {"rs64", PROCESSOR_RS64A,
2499 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2502 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2504 /* Some OSs don't support saving the high part of 64-bit registers on
2505 context switch. Other OSs don't support saving Altivec registers.
2506 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2507 settings; if the user wants either, the user must explicitly specify
2508 them and we won't interfere with the user's specification. */
2511 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2512 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2513 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2514 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2515 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2516 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
2517 | MASK_RECIP_PRECISION)
2520 /* Masks for instructions set at various powerpc ISAs. */
2522 ISA_2_1_MASKS = MASK_MFCRF,
2523 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB | MASK_FPRND),
2525 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and
2526 don't add ALTIVEC, since in general it isn't a win on power6. */
2527 ISA_2_5_MASKS = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
2530 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
2531 altivec is a win so enable it. */
2532 ISA_2_6_MASKS = (ISA_2_5_MASKS | MASK_ALTIVEC | MASK_POPCNTD
2533 | MASK_VSX | MASK_RECIP_PRECISION)
2536 /* Numerous experiment shows that IRA based loop pressure
2537 calculation works better for RTL loop invariant motion on targets
2538 with enough (>= 32) registers. It is an expensive optimization.
2539 So it is on only for peak performance. */
2541 flag_ira_loop_pressure = 1;
2543 /* Set the pointer size. */
2546 rs6000_pmode = (int)DImode;
2547 rs6000_pointer_size = 64;
2551 rs6000_pmode = (int)SImode;
2552 rs6000_pointer_size = 32;
2555 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2556 #ifdef OS_MISSING_POWERPC64
2557 if (OS_MISSING_POWERPC64)
2558 set_masks &= ~MASK_POWERPC64;
2560 #ifdef OS_MISSING_ALTIVEC
2561 if (OS_MISSING_ALTIVEC)
2562 set_masks &= ~MASK_ALTIVEC;
2565 /* Don't override by the processor default if given explicitly. */
2566 set_masks &= ~target_flags_explicit;
2568 /* Identify the processor type. */
2569 rs6000_select[0].string = default_cpu;
2570 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2572 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2574 ptr = &rs6000_select[i];
2575 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2577 for (j = 0; j < ptt_size; j++)
2578 if (! strcmp (ptr->string, processor_target_table[j].name))
2580 if (ptr->set_tune_p)
2581 rs6000_cpu = processor_target_table[j].processor;
2583 if (ptr->set_arch_p)
2585 target_flags &= ~set_masks;
2586 target_flags |= (processor_target_table[j].target_enable
2593 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2597 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2598 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2601 error ("AltiVec not supported in this target");
2603 error ("Spe not supported in this target");
2606 /* Disable Cell microcode if we are optimizing for the Cell
2607 and not optimizing for size. */
2608 if (rs6000_gen_cell_microcode == -1)
2609 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2612 /* If we are optimizing big endian systems for space and it's OK to
2613 use instructions that would be microcoded on the Cell, use the
2614 load/store multiple and string instructions. */
2615 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2616 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2618 /* Don't allow -mmultiple or -mstring on little endian systems
2619 unless the cpu is a 750, because the hardware doesn't support the
2620 instructions used in little endian mode, and causes an alignment
2621 trap. The 750 does not cause an alignment trap (except when the
2622 target is unaligned). */
2624 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2626 if (TARGET_MULTIPLE)
2628 target_flags &= ~MASK_MULTIPLE;
2629 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2630 warning (0, "-mmultiple is not supported on little endian systems");
2635 target_flags &= ~MASK_STRING;
2636 if ((target_flags_explicit & MASK_STRING) != 0)
2637 warning (0, "-mstring is not supported on little endian systems");
2641 /* Add some warnings for VSX. */
2644 const char *msg = NULL;
2645 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2646 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2648 if (target_flags_explicit & MASK_VSX)
2649 msg = N_("-mvsx requires hardware floating point");
2651 target_flags &= ~ MASK_VSX;
2653 else if (TARGET_PAIRED_FLOAT)
2654 msg = N_("-mvsx and -mpaired are incompatible");
2655 /* The hardware will allow VSX and little endian, but until we make sure
2656 things like vector select, etc. work don't allow VSX on little endian
2657 systems at this point. */
2658 else if (!BYTES_BIG_ENDIAN)
2659 msg = N_("-mvsx used with little endian code");
2660 else if (TARGET_AVOID_XFORM > 0)
2661 msg = N_("-mvsx needs indexed addressing");
2662 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2664 if (target_flags_explicit & MASK_VSX)
2665 msg = N_("-mvsx and -mno-altivec are incompatible");
2667 msg = N_("-mno-altivec disables vsx");
2673 target_flags &= ~ MASK_VSX;
2677 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2678 unless the user explicitly used the -mno-<option> to disable the code. */
2680 target_flags |= (ISA_2_6_MASKS & (target_flags_explicit & ~ISA_2_6_MASKS));
2681 else if (TARGET_DFP)
2682 target_flags |= (ISA_2_5_MASKS & (target_flags_explicit & ~ISA_2_5_MASKS));
2683 else if (TARGET_ALTIVEC)
2684 target_flags |= (MASK_PPC_GFXOPT & (target_flags_explicit & ~MASK_PPC_GFXOPT));
2686 /* Set debug flags */
2687 if (rs6000_debug_name)
2689 if (! strcmp (rs6000_debug_name, "all"))
2690 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2691 = rs6000_debug_addr = rs6000_debug_cost = 1;
2692 else if (! strcmp (rs6000_debug_name, "stack"))
2693 rs6000_debug_stack = 1;
2694 else if (! strcmp (rs6000_debug_name, "arg"))
2695 rs6000_debug_arg = 1;
2696 else if (! strcmp (rs6000_debug_name, "reg"))
2697 rs6000_debug_reg = 1;
2698 else if (! strcmp (rs6000_debug_name, "addr"))
2699 rs6000_debug_addr = 1;
2700 else if (! strcmp (rs6000_debug_name, "cost"))
2701 rs6000_debug_cost = 1;
2703 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2705 /* If the appropriate debug option is enabled, replace the target hooks
2706 with debug versions that call the real version and then prints
2707 debugging information. */
2708 if (TARGET_DEBUG_COST)
2710 targetm.rtx_costs = rs6000_debug_rtx_costs;
2711 targetm.address_cost = rs6000_debug_address_cost;
2712 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2715 if (TARGET_DEBUG_ADDR)
2717 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2718 targetm.legitimize_address = rs6000_debug_legitimize_address;
2719 rs6000_secondary_reload_class_ptr
2720 = rs6000_debug_secondary_reload_class;
2721 rs6000_secondary_memory_needed_ptr
2722 = rs6000_debug_secondary_memory_needed;
2723 rs6000_cannot_change_mode_class_ptr
2724 = rs6000_debug_cannot_change_mode_class;
2725 rs6000_preferred_reload_class_ptr
2726 = rs6000_debug_preferred_reload_class;
2727 rs6000_legitimize_reload_address_ptr
2728 = rs6000_debug_legitimize_reload_address;
2729 rs6000_mode_dependent_address_ptr
2730 = rs6000_debug_mode_dependent_address;
2734 if (rs6000_traceback_name)
2736 if (! strncmp (rs6000_traceback_name, "full", 4))
2737 rs6000_traceback = traceback_full;
2738 else if (! strncmp (rs6000_traceback_name, "part", 4))
2739 rs6000_traceback = traceback_part;
2740 else if (! strncmp (rs6000_traceback_name, "no", 2))
2741 rs6000_traceback = traceback_none;
2743 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2744 rs6000_traceback_name);
2747 if (!rs6000_explicit_options.long_double)
2748 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2750 #ifndef POWERPC_LINUX
2751 if (!rs6000_explicit_options.ieee)
2752 rs6000_ieeequad = 1;
2755 /* Enable Altivec ABI for AIX -maltivec. */
2756 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2757 rs6000_altivec_abi = 1;
2759 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2760 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2761 be explicitly overridden in either case. */
2764 if (!rs6000_explicit_options.altivec_abi
2765 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2766 rs6000_altivec_abi = 1;
2768 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2769 if (!rs6000_explicit_options.vrsave)
2770 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2773 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2774 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2776 rs6000_darwin64_abi = 1;
2778 darwin_one_byte_bool = 1;
2780 /* Default to natural alignment, for better performance. */
2781 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2784 /* Place FP constants in the constant pool instead of TOC
2785 if section anchors enabled. */
2786 if (flag_section_anchors)
2787 TARGET_NO_FP_IN_TOC = 1;
2789 /* Handle -mtls-size option. */
2790 rs6000_parse_tls_size_option ();
2792 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2793 SUBTARGET_OVERRIDE_OPTIONS;
2795 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2796 SUBSUBTARGET_OVERRIDE_OPTIONS;
2798 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2799 SUB3TARGET_OVERRIDE_OPTIONS;
2802 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2803 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2805 /* The e500 and e500mc do not have string instructions, and we set
2806 MASK_STRING above when optimizing for size. */
2807 if ((target_flags & MASK_STRING) != 0)
2808 target_flags = target_flags & ~MASK_STRING;
2810 else if (rs6000_select[1].string != NULL)
2812 /* For the powerpc-eabispe configuration, we set all these by
2813 default, so let's unset them if we manually set another
2814 CPU that is not the E500. */
2815 if (!rs6000_explicit_options.spe_abi)
2817 if (!rs6000_explicit_options.spe)
2819 if (!rs6000_explicit_options.float_gprs)
2820 rs6000_float_gprs = 0;
2821 if (!(target_flags_explicit & MASK_ISEL))
2822 target_flags &= ~MASK_ISEL;
2825 /* Detect invalid option combinations with E500. */
2828 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2829 && rs6000_cpu != PROCESSOR_POWER5
2830 && rs6000_cpu != PROCESSOR_POWER6
2831 && rs6000_cpu != PROCESSOR_POWER7
2832 && rs6000_cpu != PROCESSOR_PPCA2
2833 && rs6000_cpu != PROCESSOR_CELL);
2834 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2835 || rs6000_cpu == PROCESSOR_POWER5
2836 || rs6000_cpu == PROCESSOR_POWER7);
2837 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2838 || rs6000_cpu == PROCESSOR_POWER5
2839 || rs6000_cpu == PROCESSOR_POWER6
2840 || rs6000_cpu == PROCESSOR_POWER7
2841 || rs6000_cpu == PROCESSOR_PPCE500MC
2842 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2844 /* Allow debug switches to override the above settings. */
2845 if (TARGET_ALWAYS_HINT > 0)
2846 rs6000_always_hint = TARGET_ALWAYS_HINT;
2848 if (TARGET_SCHED_GROUPS > 0)
2849 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2851 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2852 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2854 rs6000_sched_restricted_insns_priority
2855 = (rs6000_sched_groups ? 1 : 0);
2857 /* Handle -msched-costly-dep option. */
2858 rs6000_sched_costly_dep
2859 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2861 if (rs6000_sched_costly_dep_str)
2863 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2864 rs6000_sched_costly_dep = no_dep_costly;
2865 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2866 rs6000_sched_costly_dep = all_deps_costly;
2867 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2868 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2869 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2870 rs6000_sched_costly_dep = store_to_load_dep_costly;
2872 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2873 atoi (rs6000_sched_costly_dep_str));
2876 /* Handle -minsert-sched-nops option. */
2877 rs6000_sched_insert_nops
2878 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2880 if (rs6000_sched_insert_nops_str)
2882 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2883 rs6000_sched_insert_nops = sched_finish_none;
2884 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2885 rs6000_sched_insert_nops = sched_finish_pad_groups;
2886 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2887 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2889 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2890 atoi (rs6000_sched_insert_nops_str));
2893 #ifdef TARGET_REGNAMES
2894 /* If the user desires alternate register names, copy in the
2895 alternate names now. */
2896 if (TARGET_REGNAMES)
2897 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2900 /* Set aix_struct_return last, after the ABI is determined.
2901 If -maix-struct-return or -msvr4-struct-return was explicitly
2902 used, don't override with the ABI default. */
2903 if (!rs6000_explicit_options.aix_struct_ret)
2904 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2907 /* IBM XL compiler defaults to unsigned bitfields. */
2908 if (TARGET_XL_COMPAT)
2909 flag_signed_bitfields = 0;
2912 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2913 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2916 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2918 /* We can only guarantee the availability of DI pseudo-ops when
2919 assembling for 64-bit targets. */
2922 targetm.asm_out.aligned_op.di = NULL;
2923 targetm.asm_out.unaligned_op.di = NULL;
2926 /* Set branch target alignment, if not optimizing for size. */
2929 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
2930 aligned 8byte to avoid misprediction by the branch predictor. */
2931 if (rs6000_cpu == PROCESSOR_TITAN
2932 || rs6000_cpu == PROCESSOR_CELL)
2934 if (align_functions <= 0)
2935 align_functions = 8;
2936 if (align_jumps <= 0)
2938 if (align_loops <= 0)
2941 if (rs6000_align_branch_targets)
2943 if (align_functions <= 0)
2944 align_functions = 16;
2945 if (align_jumps <= 0)
2947 if (align_loops <= 0)
2950 if (align_jumps_max_skip <= 0)
2951 align_jumps_max_skip = 15;
2952 if (align_loops_max_skip <= 0)
2953 align_loops_max_skip = 15;
2956 /* Arrange to save and restore machine status around nested functions. */
2957 init_machine_status = rs6000_init_machine_status;
2959 /* We should always be splitting complex arguments, but we can't break
2960 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2961 if (DEFAULT_ABI != ABI_AIX)
2962 targetm.calls.split_complex_arg = NULL;
2964 /* Initialize rs6000_cost with the appropriate target costs. */
2966 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2970 case PROCESSOR_RIOS1:
2971 rs6000_cost = &rios1_cost;
2974 case PROCESSOR_RIOS2:
2975 rs6000_cost = &rios2_cost;
2978 case PROCESSOR_RS64A:
2979 rs6000_cost = &rs64a_cost;
2982 case PROCESSOR_MPCCORE:
2983 rs6000_cost = &mpccore_cost;
2986 case PROCESSOR_PPC403:
2987 rs6000_cost = &ppc403_cost;
2990 case PROCESSOR_PPC405:
2991 rs6000_cost = &ppc405_cost;
2994 case PROCESSOR_PPC440:
2995 rs6000_cost = &ppc440_cost;
2998 case PROCESSOR_PPC476:
2999 rs6000_cost = &ppc476_cost;
3002 case PROCESSOR_PPC601:
3003 rs6000_cost = &ppc601_cost;
3006 case PROCESSOR_PPC603:
3007 rs6000_cost = &ppc603_cost;
3010 case PROCESSOR_PPC604:
3011 rs6000_cost = &ppc604_cost;
3014 case PROCESSOR_PPC604e:
3015 rs6000_cost = &ppc604e_cost;
3018 case PROCESSOR_PPC620:
3019 rs6000_cost = &ppc620_cost;
3022 case PROCESSOR_PPC630:
3023 rs6000_cost = &ppc630_cost;
3026 case PROCESSOR_CELL:
3027 rs6000_cost = &ppccell_cost;
3030 case PROCESSOR_PPC750:
3031 case PROCESSOR_PPC7400:
3032 rs6000_cost = &ppc750_cost;
3035 case PROCESSOR_PPC7450:
3036 rs6000_cost = &ppc7450_cost;
3039 case PROCESSOR_PPC8540:
3040 rs6000_cost = &ppc8540_cost;
3043 case PROCESSOR_PPCE300C2:
3044 case PROCESSOR_PPCE300C3:
3045 rs6000_cost = &ppce300c2c3_cost;
3048 case PROCESSOR_PPCE500MC:
3049 rs6000_cost = &ppce500mc_cost;
3052 case PROCESSOR_PPCE500MC64:
3053 rs6000_cost = &ppce500mc64_cost;
3056 case PROCESSOR_TITAN:
3057 rs6000_cost = &titan_cost;
3060 case PROCESSOR_POWER4:
3061 case PROCESSOR_POWER5:
3062 rs6000_cost = &power4_cost;
3065 case PROCESSOR_POWER6:
3066 rs6000_cost = &power6_cost;
3069 case PROCESSOR_POWER7:
3070 rs6000_cost = &power7_cost;
3073 case PROCESSOR_PPCA2:
3074 rs6000_cost = &ppca2_cost;
3081 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
3082 set_param_value ("simultaneous-prefetches",
3083 rs6000_cost->simultaneous_prefetches);
3084 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
3085 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
3086 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
3087 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
3088 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
3089 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
3091 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
3092 can be optimized to ap = __builtin_next_arg (0). */
3093 if (DEFAULT_ABI != ABI_V4)
3094 targetm.expand_builtin_va_start = NULL;
3096 /* Set up single/double float flags.
3097 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3098 then set both flags. */
3099 if (TARGET_HARD_FLOAT && TARGET_FPRS
3100 && rs6000_single_float == 0 && rs6000_double_float == 0)
3101 rs6000_single_float = rs6000_double_float = 1;
3103 /* Reset single and double FP flags if target is E500. */
3106 rs6000_single_float = rs6000_double_float = 0;
3107 if (TARGET_E500_SINGLE)
3108 rs6000_single_float = 1;
3109 if (TARGET_E500_DOUBLE)
3110 rs6000_single_float = rs6000_double_float = 1;
3113 /* If not explicitly specified via option, decide whether to generate indexed
3114 load/store instructions. */
3115 if (TARGET_AVOID_XFORM == -1)
3116 /* Avoid indexed addressing when targeting Power6 in order to avoid
3117 the DERAT mispredict penalty. */
3118 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
3120 /* Set the -mrecip options. */
3121 if (rs6000_recip_name)
3123 char *p = ASTRDUP (rs6000_recip_name);
3125 unsigned int mask, i;
3128 while ((q = strtok (p, ",")) != NULL)
3139 if (!strcmp (q, "default"))
3140 mask = ((TARGET_RECIP_PRECISION)
3141 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3144 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3145 if (!strcmp (q, recip_options[i].string))
3147 mask = recip_options[i].mask;
3151 if (i == ARRAY_SIZE (recip_options))
3153 error ("Unknown option for -mrecip=%s", q);
3160 rs6000_recip_control &= ~mask;
3162 rs6000_recip_control |= mask;
3166 rs6000_init_hard_regno_mode_ok ();
3169 /* Implement targetm.vectorize.builtin_mask_for_load. */
3171 rs6000_builtin_mask_for_load (void)
3173 if (TARGET_ALTIVEC || TARGET_VSX)
3174 return altivec_builtin_mask_for_load;
3179 /* Implement targetm.vectorize.builtin_conversion.
3180 Returns a decl of a function that implements conversion of an integer vector
3181 into a floating-point vector, or vice-versa. DEST_TYPE is the
3182 destination type and SRC_TYPE the source type of the conversion.
3183 Return NULL_TREE if it is not available. */
3185 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3187 enum tree_code code = (enum tree_code) tcode;
3191 case FIX_TRUNC_EXPR:
3192 switch (TYPE_MODE (dest_type))
3195 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3198 return TYPE_UNSIGNED (dest_type)
3199 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3200 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3203 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3206 return TYPE_UNSIGNED (dest_type)
3207 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3208 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3215 switch (TYPE_MODE (src_type))
3218 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3221 return TYPE_UNSIGNED (src_type)
3222 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3223 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3226 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3229 return TYPE_UNSIGNED (src_type)
3230 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3231 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3242 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3244 rs6000_builtin_mul_widen_even (tree type)
3246 if (!TARGET_ALTIVEC)
3249 switch (TYPE_MODE (type))
3252 return TYPE_UNSIGNED (type)
3253 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3254 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3257 return TYPE_UNSIGNED (type)
3258 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3259 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3265 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3267 rs6000_builtin_mul_widen_odd (tree type)
3269 if (!TARGET_ALTIVEC)
3272 switch (TYPE_MODE (type))
3275 return TYPE_UNSIGNED (type)
3276 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3277 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3280 return TYPE_UNSIGNED (type)
3281 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3282 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3289 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3290 after applying N number of iterations. This routine does not determine
3291 how may iterations are required to reach desired alignment. */
3294 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3301 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3304 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3314 /* Assuming that all other types are naturally aligned. CHECKME! */
3319 /* Return true if the vector misalignment factor is supported by the
3322 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3329 /* Return if movmisalign pattern is not supported for this mode. */
3330 if (optab_handler (movmisalign_optab, mode)->insn_code ==
3334 if (misalignment == -1)
3336 /* misalignment factor is unknown at compile time but we know
3337 it's word aligned. */
3338 if (rs6000_vector_alignment_reachable (type, is_packed))
3342 /* VSX supports word-aligned vector. */
3343 if (misalignment % 4 == 0)
3349 /* Implement targetm.vectorize.builtin_vec_perm. */
3351 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3353 tree inner_type = TREE_TYPE (type);
3354 bool uns_p = TYPE_UNSIGNED (inner_type);
3357 *mask_element_type = unsigned_char_type_node;
3359 switch (TYPE_MODE (type))
3363 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3364 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3369 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3370 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3375 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3376 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3380 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3384 if (!TARGET_ALLOW_DF_PERMUTE)
3387 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3391 if (!TARGET_ALLOW_DF_PERMUTE)
3395 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3396 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3407 /* Handle generic options of the form -mfoo=yes/no.
3408 NAME is the option name.
3409 VALUE is the option value.
3410 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3411 whether the option value is 'yes' or 'no' respectively. */
3413 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3417 else if (!strcmp (value, "yes"))
3419 else if (!strcmp (value, "no"))
3422 error ("unknown -m%s= option specified: '%s'", name, value);
3425 /* Validate and record the size specified with the -mtls-size option. */
3428 rs6000_parse_tls_size_option (void)
3430 if (rs6000_tls_size_string == 0)
3432 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3433 rs6000_tls_size = 16;
3434 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3435 rs6000_tls_size = 32;
3436 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3437 rs6000_tls_size = 64;
3439 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3443 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3445 if (DEFAULT_ABI == ABI_DARWIN)
3446 /* The Darwin libraries never set errno, so we might as well
3447 avoid calling them when that's the only reason we would. */
3448 flag_errno_math = 0;
3450 /* Double growth factor to counter reduced min jump length. */
3451 set_param_value ("max-grow-copy-bb-insns", 16);
3453 /* Enable section anchors by default.
3454 Skip section anchors for Objective C and Objective C++
3455 until front-ends fixed. */
3456 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3457 flag_section_anchors = 2;
3460 static enum fpu_type_t
3461 rs6000_parse_fpu_option (const char *option)
3463 if (!strcmp("none", option)) return FPU_NONE;
3464 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3465 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3466 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3467 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3468 error("unknown value %s for -mfpu", option);
3472 /* Returns a function decl for a vectorized version of the builtin function
3473 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3474 if it is not available. */
3477 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3480 enum machine_mode in_mode, out_mode;
3483 if (TREE_CODE (type_out) != VECTOR_TYPE
3484 || TREE_CODE (type_in) != VECTOR_TYPE
3485 || !TARGET_VECTORIZE_BUILTINS)
3488 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3489 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3490 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3491 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3493 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3495 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3498 case BUILT_IN_COPYSIGN:
3499 if (VECTOR_UNIT_VSX_P (V2DFmode)
3500 && out_mode == DFmode && out_n == 2
3501 && in_mode == DFmode && in_n == 2)
3502 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3504 case BUILT_IN_COPYSIGNF:
3505 if (out_mode != SFmode || out_n != 4
3506 || in_mode != SFmode || in_n != 4)
3508 if (VECTOR_UNIT_VSX_P (V4SFmode))
3509 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3510 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3511 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3514 if (VECTOR_UNIT_VSX_P (V2DFmode)
3515 && out_mode == DFmode && out_n == 2
3516 && in_mode == DFmode && in_n == 2)
3517 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3519 case BUILT_IN_SQRTF:
3520 if (VECTOR_UNIT_VSX_P (V4SFmode)
3521 && out_mode == SFmode && out_n == 4
3522 && in_mode == SFmode && in_n == 4)
3523 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3526 if (VECTOR_UNIT_VSX_P (V2DFmode)
3527 && out_mode == DFmode && out_n == 2
3528 && in_mode == DFmode && in_n == 2)
3529 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3531 case BUILT_IN_CEILF:
3532 if (out_mode != SFmode || out_n != 4
3533 || in_mode != SFmode || in_n != 4)
3535 if (VECTOR_UNIT_VSX_P (V4SFmode))
3536 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3537 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3538 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3540 case BUILT_IN_FLOOR:
3541 if (VECTOR_UNIT_VSX_P (V2DFmode)
3542 && out_mode == DFmode && out_n == 2
3543 && in_mode == DFmode && in_n == 2)
3544 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3546 case BUILT_IN_FLOORF:
3547 if (out_mode != SFmode || out_n != 4
3548 || in_mode != SFmode || in_n != 4)
3550 if (VECTOR_UNIT_VSX_P (V4SFmode))
3551 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3552 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3553 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3555 case BUILT_IN_TRUNC:
3556 if (VECTOR_UNIT_VSX_P (V2DFmode)
3557 && out_mode == DFmode && out_n == 2
3558 && in_mode == DFmode && in_n == 2)
3559 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3561 case BUILT_IN_TRUNCF:
3562 if (out_mode != SFmode || out_n != 4
3563 || in_mode != SFmode || in_n != 4)
3565 if (VECTOR_UNIT_VSX_P (V4SFmode))
3566 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3567 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3568 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3570 case BUILT_IN_NEARBYINT:
3571 if (VECTOR_UNIT_VSX_P (V2DFmode)
3572 && flag_unsafe_math_optimizations
3573 && out_mode == DFmode && out_n == 2
3574 && in_mode == DFmode && in_n == 2)
3575 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3577 case BUILT_IN_NEARBYINTF:
3578 if (VECTOR_UNIT_VSX_P (V4SFmode)
3579 && flag_unsafe_math_optimizations
3580 && out_mode == SFmode && out_n == 4
3581 && in_mode == SFmode && in_n == 4)
3582 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3585 if (VECTOR_UNIT_VSX_P (V2DFmode)
3586 && !flag_trapping_math
3587 && out_mode == DFmode && out_n == 2
3588 && in_mode == DFmode && in_n == 2)
3589 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3591 case BUILT_IN_RINTF:
3592 if (VECTOR_UNIT_VSX_P (V4SFmode)
3593 && !flag_trapping_math
3594 && out_mode == SFmode && out_n == 4
3595 && in_mode == SFmode && in_n == 4)
3596 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3603 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3605 enum rs6000_builtins fn
3606 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
3609 case RS6000_BUILTIN_RSQRTF:
3610 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3611 && out_mode == SFmode && out_n == 4
3612 && in_mode == SFmode && in_n == 4)
3613 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
3615 case RS6000_BUILTIN_RSQRT:
3616 if (VECTOR_UNIT_VSX_P (V2DFmode)
3617 && out_mode == DFmode && out_n == 2
3618 && in_mode == DFmode && in_n == 2)
3619 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
3621 case RS6000_BUILTIN_RECIPF:
3622 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3623 && out_mode == SFmode && out_n == 4
3624 && in_mode == SFmode && in_n == 4)
3625 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
3627 case RS6000_BUILTIN_RECIP:
3628 if (VECTOR_UNIT_VSX_P (V2DFmode)
3629 && out_mode == DFmode && out_n == 2
3630 && in_mode == DFmode && in_n == 2)
3631 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
3642 /* Implement TARGET_HANDLE_OPTION. */
3645 rs6000_handle_option (size_t code, const char *arg, int value)
3647 enum fpu_type_t fpu_type = FPU_NONE;
3653 target_flags &= ~(MASK_POWER | MASK_POWER2
3654 | MASK_MULTIPLE | MASK_STRING);
3655 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3656 | MASK_MULTIPLE | MASK_STRING);
3658 case OPT_mno_powerpc:
3659 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3660 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3661 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3662 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3665 target_flags &= ~MASK_MINIMAL_TOC;
3666 TARGET_NO_FP_IN_TOC = 0;
3667 TARGET_NO_SUM_IN_TOC = 0;
3668 target_flags_explicit |= MASK_MINIMAL_TOC;
3669 #ifdef TARGET_USES_SYSV4_OPT
3670 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3671 just the same as -mminimal-toc. */
3672 target_flags |= MASK_MINIMAL_TOC;
3673 target_flags_explicit |= MASK_MINIMAL_TOC;
3677 #ifdef TARGET_USES_SYSV4_OPT
3679 /* Make -mtoc behave like -mminimal-toc. */
3680 target_flags |= MASK_MINIMAL_TOC;
3681 target_flags_explicit |= MASK_MINIMAL_TOC;
3685 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
3687 if (strcmp (arg, "small") == 0)
3688 cmodel = CMODEL_SMALL;
3689 else if (strcmp (arg, "large") == 0)
3690 cmodel = CMODEL_LARGE;
3693 error ("invalid option for -mcmodel: '%s'", arg);
3696 rs6000_explicit_options.cmodel = true;
3699 #ifdef TARGET_USES_AIX64_OPT
3704 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3705 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3706 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3709 #ifdef TARGET_USES_AIX64_OPT
3714 target_flags &= ~MASK_POWERPC64;
3715 target_flags_explicit |= MASK_POWERPC64;
3718 case OPT_minsert_sched_nops_:
3719 rs6000_sched_insert_nops_str = arg;
3722 case OPT_mminimal_toc:
3725 TARGET_NO_FP_IN_TOC = 0;
3726 TARGET_NO_SUM_IN_TOC = 0;
3733 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3734 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3741 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3742 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3746 case OPT_mpowerpc_gpopt:
3747 case OPT_mpowerpc_gfxopt:
3750 target_flags |= MASK_POWERPC;
3751 target_flags_explicit |= MASK_POWERPC;
3755 case OPT_maix_struct_return:
3756 case OPT_msvr4_struct_return:
3757 rs6000_explicit_options.aix_struct_ret = true;
3761 rs6000_explicit_options.vrsave = true;
3762 TARGET_ALTIVEC_VRSAVE = value;
3766 rs6000_explicit_options.vrsave = true;
3767 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3771 target_flags_explicit |= MASK_ISEL;
3773 rs6000_parse_yes_no_option ("isel", arg, &isel);
3775 target_flags |= MASK_ISEL;
3777 target_flags &= ~MASK_ISEL;
3781 rs6000_explicit_options.spe = true;
3786 rs6000_explicit_options.spe = true;
3787 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3791 rs6000_debug_name = arg;
3794 #ifdef TARGET_USES_SYSV4_OPT
3796 rs6000_abi_name = arg;
3800 rs6000_sdata_name = arg;
3803 case OPT_mtls_size_:
3804 rs6000_tls_size_string = arg;
3807 case OPT_mrelocatable:
3810 target_flags |= MASK_MINIMAL_TOC;
3811 target_flags_explicit |= MASK_MINIMAL_TOC;
3812 TARGET_NO_FP_IN_TOC = 1;
3816 case OPT_mrelocatable_lib:
3819 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3820 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3821 TARGET_NO_FP_IN_TOC = 1;
3825 target_flags &= ~MASK_RELOCATABLE;
3826 target_flags_explicit |= MASK_RELOCATABLE;
3832 if (!strcmp (arg, "altivec"))
3834 rs6000_explicit_options.altivec_abi = true;
3835 rs6000_altivec_abi = 1;
3837 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3840 else if (! strcmp (arg, "no-altivec"))
3842 rs6000_explicit_options.altivec_abi = true;
3843 rs6000_altivec_abi = 0;
3845 else if (! strcmp (arg, "spe"))
3847 rs6000_explicit_options.spe_abi = true;
3849 rs6000_altivec_abi = 0;
3850 if (!TARGET_SPE_ABI)
3851 error ("not configured for ABI: '%s'", arg);
3853 else if (! strcmp (arg, "no-spe"))
3855 rs6000_explicit_options.spe_abi = true;
3859 /* These are here for testing during development only, do not
3860 document in the manual please. */
3861 else if (! strcmp (arg, "d64"))
3863 rs6000_darwin64_abi = 1;
3864 warning (0, "Using darwin64 ABI");
3866 else if (! strcmp (arg, "d32"))
3868 rs6000_darwin64_abi = 0;
3869 warning (0, "Using old darwin ABI");
3872 else if (! strcmp (arg, "ibmlongdouble"))
3874 rs6000_explicit_options.ieee = true;
3875 rs6000_ieeequad = 0;
3876 warning (0, "Using IBM extended precision long double");
3878 else if (! strcmp (arg, "ieeelongdouble"))
3880 rs6000_explicit_options.ieee = true;
3881 rs6000_ieeequad = 1;
3882 warning (0, "Using IEEE extended precision long double");
3887 error ("unknown ABI specified: '%s'", arg);
3893 rs6000_select[1].string = arg;
3897 rs6000_select[2].string = arg;
3900 case OPT_mtraceback_:
3901 rs6000_traceback_name = arg;
3904 case OPT_mfloat_gprs_:
3905 rs6000_explicit_options.float_gprs = true;
3906 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3907 rs6000_float_gprs = 1;
3908 else if (! strcmp (arg, "double"))
3909 rs6000_float_gprs = 2;
3910 else if (! strcmp (arg, "no"))
3911 rs6000_float_gprs = 0;
3914 error ("invalid option for -mfloat-gprs: '%s'", arg);
3919 case OPT_mlong_double_:
3920 rs6000_explicit_options.long_double = true;
3921 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3922 if (value != 64 && value != 128)
3924 error ("Unknown switch -mlong-double-%s", arg);
3925 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3929 rs6000_long_double_type_size = value;
3932 case OPT_msched_costly_dep_:
3933 rs6000_sched_costly_dep_str = arg;
3937 rs6000_explicit_options.alignment = true;
3938 if (! strcmp (arg, "power"))
3940 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3941 some C library functions, so warn about it. The flag may be
3942 useful for performance studies from time to time though, so
3943 don't disable it entirely. */
3944 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3945 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3946 " it is incompatible with the installed C and C++ libraries");
3947 rs6000_alignment_flags = MASK_ALIGN_POWER;
3949 else if (! strcmp (arg, "natural"))
3950 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3953 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3958 case OPT_msingle_float:
3959 if (!TARGET_SINGLE_FPU)
3960 warning (0, "-msingle-float option equivalent to -mhard-float");
3961 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3962 rs6000_double_float = 0;
3963 target_flags &= ~MASK_SOFT_FLOAT;
3964 target_flags_explicit |= MASK_SOFT_FLOAT;
3967 case OPT_mdouble_float:
3968 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3969 rs6000_single_float = 1;
3970 target_flags &= ~MASK_SOFT_FLOAT;
3971 target_flags_explicit |= MASK_SOFT_FLOAT;
3974 case OPT_msimple_fpu:
3975 if (!TARGET_SINGLE_FPU)
3976 warning (0, "-msimple-fpu option ignored");
3979 case OPT_mhard_float:
3980 /* -mhard_float implies -msingle-float and -mdouble-float. */
3981 rs6000_single_float = rs6000_double_float = 1;
3984 case OPT_msoft_float:
3985 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3986 rs6000_single_float = rs6000_double_float = 0;
3990 fpu_type = rs6000_parse_fpu_option(arg);
3991 if (fpu_type != FPU_NONE)
3992 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3994 target_flags &= ~MASK_SOFT_FLOAT;
3995 target_flags_explicit |= MASK_SOFT_FLOAT;
3996 rs6000_xilinx_fpu = 1;
3997 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3998 rs6000_single_float = 1;
3999 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4000 rs6000_single_float = rs6000_double_float = 1;
4001 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4002 rs6000_simple_fpu = 1;
4006 /* -mfpu=none is equivalent to -msoft-float */
4007 target_flags |= MASK_SOFT_FLOAT;
4008 target_flags_explicit |= MASK_SOFT_FLOAT;
4009 rs6000_single_float = rs6000_double_float = 0;
4013 rs6000_recip_name = (value) ? "default" : "none";
4017 rs6000_recip_name = arg;
4023 /* Do anything needed at the start of the asm file. */
4026 rs6000_file_start (void)
4030 const char *start = buffer;
4031 struct rs6000_cpu_select *ptr;
4032 const char *default_cpu = TARGET_CPU_DEFAULT;
4033 FILE *file = asm_out_file;
4035 default_file_start ();
4037 #ifdef TARGET_BI_ARCH
4038 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4042 if (flag_verbose_asm)
4044 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4045 rs6000_select[0].string = default_cpu;
4047 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4049 ptr = &rs6000_select[i];
4050 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4052 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4057 if (PPC405_ERRATUM77)
4059 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4063 #ifdef USING_ELFOS_H
4064 switch (rs6000_sdata)
4066 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4067 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4068 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4069 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4072 if (rs6000_sdata && g_switch_value)
4074 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
4084 #ifdef HAVE_AS_GNU_ATTRIBUTE
4085 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
4087 fprintf (file, "\t.gnu_attribute 4, %d\n",
4088 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
4089 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
4091 fprintf (file, "\t.gnu_attribute 8, %d\n",
4092 (TARGET_ALTIVEC_ABI ? 2
4093 : TARGET_SPE_ABI ? 3
4095 fprintf (file, "\t.gnu_attribute 12, %d\n",
4096 aix_struct_return ? 2 : 1);
4101 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4103 switch_to_section (toc_section);
4104 switch_to_section (text_section);
4109 /* Return nonzero if this function is known to have a null epilogue. */
4112 direct_return (void)
4114 if (reload_completed)
4116 rs6000_stack_t *info = rs6000_stack_info ();
4118 if (info->first_gp_reg_save == 32
4119 && info->first_fp_reg_save == 64
4120 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4121 && ! info->lr_save_p
4122 && ! info->cr_save_p
4123 && info->vrsave_mask == 0
4131 /* Return the number of instructions it takes to form a constant in an
4132 integer register. */
4135 num_insns_constant_wide (HOST_WIDE_INT value)
4137 /* signed constant loadable with {cal|addi} */
4138 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4141 /* constant loadable with {cau|addis} */
4142 else if ((value & 0xffff) == 0
4143 && (value >> 31 == -1 || value >> 31 == 0))
4146 #if HOST_BITS_PER_WIDE_INT == 64
4147 else if (TARGET_POWERPC64)
4149 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4150 HOST_WIDE_INT high = value >> 31;
4152 if (high == 0 || high == -1)
4158 return num_insns_constant_wide (high) + 1;
4160 return num_insns_constant_wide (low) + 1;
4162 return (num_insns_constant_wide (high)
4163 + num_insns_constant_wide (low) + 1);
4172 num_insns_constant (rtx op, enum machine_mode mode)
4174 HOST_WIDE_INT low, high;
4176 switch (GET_CODE (op))
4179 #if HOST_BITS_PER_WIDE_INT == 64
4180 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4181 && mask64_operand (op, mode))
4185 return num_insns_constant_wide (INTVAL (op));
4188 if (mode == SFmode || mode == SDmode)
4193 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4194 if (DECIMAL_FLOAT_MODE_P (mode))
4195 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4197 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4198 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4201 if (mode == VOIDmode || mode == DImode)
4203 high = CONST_DOUBLE_HIGH (op);
4204 low = CONST_DOUBLE_LOW (op);
4211 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4212 if (DECIMAL_FLOAT_MODE_P (mode))
4213 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4215 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4216 high = l[WORDS_BIG_ENDIAN == 0];
4217 low = l[WORDS_BIG_ENDIAN != 0];
4221 return (num_insns_constant_wide (low)
4222 + num_insns_constant_wide (high));
4225 if ((high == 0 && low >= 0)
4226 || (high == -1 && low < 0))
4227 return num_insns_constant_wide (low);
4229 else if (mask64_operand (op, mode))
4233 return num_insns_constant_wide (high) + 1;
4236 return (num_insns_constant_wide (high)
4237 + num_insns_constant_wide (low) + 1);
4245 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4246 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4247 corresponding element of the vector, but for V4SFmode and V2SFmode,
4248 the corresponding "float" is interpreted as an SImode integer. */
4251 const_vector_elt_as_int (rtx op, unsigned int elt)
4253 rtx tmp = CONST_VECTOR_ELT (op, elt);
4254 if (GET_MODE (op) == V4SFmode
4255 || GET_MODE (op) == V2SFmode)
4256 tmp = gen_lowpart (SImode, tmp);
4257 return INTVAL (tmp);
4260 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4261 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4262 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4263 all items are set to the same value and contain COPIES replicas of the
4264 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4265 operand and the others are set to the value of the operand's msb. */
4268 vspltis_constant (rtx op, unsigned step, unsigned copies)
4270 enum machine_mode mode = GET_MODE (op);
4271 enum machine_mode inner = GET_MODE_INNER (mode);
4274 unsigned nunits = GET_MODE_NUNITS (mode);
4275 unsigned bitsize = GET_MODE_BITSIZE (inner);
4276 unsigned mask = GET_MODE_MASK (inner);
4278 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
4279 HOST_WIDE_INT splat_val = val;
4280 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
4282 /* Construct the value to be splatted, if possible. If not, return 0. */
4283 for (i = 2; i <= copies; i *= 2)
4285 HOST_WIDE_INT small_val;
4287 small_val = splat_val >> bitsize;
4289 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4291 splat_val = small_val;
4294 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4295 if (EASY_VECTOR_15 (splat_val))
4298 /* Also check if we can splat, and then add the result to itself. Do so if
4299 the value is positive, of if the splat instruction is using OP's mode;
4300 for splat_val < 0, the splat and the add should use the same mode. */
4301 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4302 && (splat_val >= 0 || (step == 1 && copies == 1)))
4305 /* Also check if are loading up the most significant bit which can be done by
4306 loading up -1 and shifting the value left by -1. */
4307 else if (EASY_VECTOR_MSB (splat_val, inner))
4313 /* Check if VAL is present in every STEP-th element, and the
4314 other elements are filled with its most significant bit. */
4315 for (i = 0; i < nunits - 1; ++i)
4317 HOST_WIDE_INT desired_val;
4318 if (((i + 1) & (step - 1)) == 0)
4321 desired_val = msb_val;
4323 if (desired_val != const_vector_elt_as_int (op, i))
4331 /* Return true if OP is of the given MODE and can be synthesized
4332 with a vspltisb, vspltish or vspltisw. */
4335 easy_altivec_constant (rtx op, enum machine_mode mode)
4337 unsigned step, copies;
4339 if (mode == VOIDmode)
4340 mode = GET_MODE (op);
4341 else if (mode != GET_MODE (op))
4344 /* Start with a vspltisw. */
4345 step = GET_MODE_NUNITS (mode) / 4;
4348 if (vspltis_constant (op, step, copies))
4351 /* Then try with a vspltish. */
4357 if (vspltis_constant (op, step, copies))
4360 /* And finally a vspltisb. */
4366 if (vspltis_constant (op, step, copies))
4372 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4373 result is OP. Abort if it is not possible. */
4376 gen_easy_altivec_constant (rtx op)
4378 enum machine_mode mode = GET_MODE (op);
4379 int nunits = GET_MODE_NUNITS (mode);
4380 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4381 unsigned step = nunits / 4;
4382 unsigned copies = 1;
4384 /* Start with a vspltisw. */
4385 if (vspltis_constant (op, step, copies))
4386 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4388 /* Then try with a vspltish. */
4394 if (vspltis_constant (op, step, copies))
4395 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4397 /* And finally a vspltisb. */
4403 if (vspltis_constant (op, step, copies))
4404 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4410 output_vec_const_move (rtx *operands)
4413 enum machine_mode mode;
4418 mode = GET_MODE (dest);
4420 if (TARGET_VSX && zero_constant (vec, mode))
4421 return "xxlxor %x0,%x0,%x0";
4426 if (zero_constant (vec, mode))
4427 return "vxor %0,%0,%0";
4429 splat_vec = gen_easy_altivec_constant (vec);
4430 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4431 operands[1] = XEXP (splat_vec, 0);
4432 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4435 switch (GET_MODE (splat_vec))
4438 return "vspltisw %0,%1";
4441 return "vspltish %0,%1";
4444 return "vspltisb %0,%1";
4451 gcc_assert (TARGET_SPE);
4453 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4454 pattern of V1DI, V4HI, and V2SF.
4456 FIXME: We should probably return # and add post reload
4457 splitters for these, but this way is so easy ;-). */
4458 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4459 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4460 operands[1] = CONST_VECTOR_ELT (vec, 0);
4461 operands[2] = CONST_VECTOR_ELT (vec, 1);
4463 return "li %0,%1\n\tevmergelo %0,%0,%0";
4465 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4468 /* Initialize TARGET of vector PAIRED to VALS. */
4471 paired_expand_vector_init (rtx target, rtx vals)
4473 enum machine_mode mode = GET_MODE (target);
4474 int n_elts = GET_MODE_NUNITS (mode);
4476 rtx x, new_rtx, tmp, constant_op, op1, op2;
4479 for (i = 0; i < n_elts; ++i)
4481 x = XVECEXP (vals, 0, i);
4482 if (!CONSTANT_P (x))
4487 /* Load from constant pool. */
4488 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4494 /* The vector is initialized only with non-constants. */
4495 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4496 XVECEXP (vals, 0, 1));
4498 emit_move_insn (target, new_rtx);
4502 /* One field is non-constant and the other one is a constant. Load the
4503 constant from the constant pool and use ps_merge instruction to
4504 construct the whole vector. */
4505 op1 = XVECEXP (vals, 0, 0);
4506 op2 = XVECEXP (vals, 0, 1);
4508 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4510 tmp = gen_reg_rtx (GET_MODE (constant_op));
4511 emit_move_insn (tmp, constant_op);
4513 if (CONSTANT_P (op1))
4514 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4516 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4518 emit_move_insn (target, new_rtx);
4522 paired_expand_vector_move (rtx operands[])
4524 rtx op0 = operands[0], op1 = operands[1];
4526 emit_move_insn (op0, op1);
4529 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4530 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4531 operands for the relation operation COND. This is a recursive
4535 paired_emit_vector_compare (enum rtx_code rcode,
4536 rtx dest, rtx op0, rtx op1,
4537 rtx cc_op0, rtx cc_op1)
4539 rtx tmp = gen_reg_rtx (V2SFmode);
4542 gcc_assert (TARGET_PAIRED_FLOAT);
4543 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4549 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4553 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4554 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4558 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4561 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4564 tmp1 = gen_reg_rtx (V2SFmode);
4565 max = gen_reg_rtx (V2SFmode);
4566 min = gen_reg_rtx (V2SFmode);
4567 gen_reg_rtx (V2SFmode);
4569 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4570 emit_insn (gen_selv2sf4
4571 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4572 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4573 emit_insn (gen_selv2sf4
4574 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4575 emit_insn (gen_subv2sf3 (tmp1, min, max));
4576 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4579 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4582 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4585 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4588 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4591 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4600 /* Emit vector conditional expression.
4601 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4602 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4605 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4606 rtx cond, rtx cc_op0, rtx cc_op1)
4608 enum rtx_code rcode = GET_CODE (cond);
4610 if (!TARGET_PAIRED_FLOAT)
4613 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4618 /* Initialize vector TARGET to VALS. */
4621 rs6000_expand_vector_init (rtx target, rtx vals)
4623 enum machine_mode mode = GET_MODE (target);
4624 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4625 int n_elts = GET_MODE_NUNITS (mode);
4626 int n_var = 0, one_var = -1;
4627 bool all_same = true, all_const_zero = true;
4631 for (i = 0; i < n_elts; ++i)
4633 x = XVECEXP (vals, 0, i);
4634 if (!CONSTANT_P (x))
4635 ++n_var, one_var = i;
4636 else if (x != CONST0_RTX (inner_mode))
4637 all_const_zero = false;
4639 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4645 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4646 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4647 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4649 /* Zero register. */
4650 emit_insn (gen_rtx_SET (VOIDmode, target,
4651 gen_rtx_XOR (mode, target, target)));
4654 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4656 /* Splat immediate. */
4657 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4662 /* Load from constant pool. */
4663 emit_move_insn (target, const_vec);
4668 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4669 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4673 rtx element = XVECEXP (vals, 0, 0);
4674 if (mode == V2DFmode)
4675 emit_insn (gen_vsx_splat_v2df (target, element));
4677 emit_insn (gen_vsx_splat_v2di (target, element));
4681 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4682 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4683 if (mode == V2DFmode)
4684 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4686 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4691 /* With single precision floating point on VSX, know that internally single
4692 precision is actually represented as a double, and either make 2 V2DF
4693 vectors, and convert these vectors to single precision, or do one
4694 conversion, and splat the result to the other elements. */
4695 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4699 rtx freg = gen_reg_rtx (V4SFmode);
4700 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4702 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4703 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4707 rtx dbl_even = gen_reg_rtx (V2DFmode);
4708 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4709 rtx flt_even = gen_reg_rtx (V4SFmode);
4710 rtx flt_odd = gen_reg_rtx (V4SFmode);
4712 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4713 copy_to_reg (XVECEXP (vals, 0, 0)),
4714 copy_to_reg (XVECEXP (vals, 0, 1))));
4715 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4716 copy_to_reg (XVECEXP (vals, 0, 2)),
4717 copy_to_reg (XVECEXP (vals, 0, 3))));
4718 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4719 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4720 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4725 /* Store value to stack temp. Load vector element. Splat. However, splat
4726 of 64-bit items is not supported on Altivec. */
4727 if (all_same && GET_MODE_SIZE (mode) <= 4)
4729 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4730 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4731 XVECEXP (vals, 0, 0));
4732 x = gen_rtx_UNSPEC (VOIDmode,
4733 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4734 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4736 gen_rtx_SET (VOIDmode,
4739 x = gen_rtx_VEC_SELECT (inner_mode, target,
4740 gen_rtx_PARALLEL (VOIDmode,
4741 gen_rtvec (1, const0_rtx)));
4742 emit_insn (gen_rtx_SET (VOIDmode, target,
4743 gen_rtx_VEC_DUPLICATE (mode, x)));
4747 /* One field is non-constant. Load constant then overwrite
4751 rtx copy = copy_rtx (vals);
4753 /* Load constant part of vector, substitute neighboring value for
4755 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4756 rs6000_expand_vector_init (target, copy);
4758 /* Insert variable. */
4759 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4763 /* Construct the vector in memory one field at a time
4764 and load the whole vector. */
4765 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4766 for (i = 0; i < n_elts; i++)
4767 emit_move_insn (adjust_address_nv (mem, inner_mode,
4768 i * GET_MODE_SIZE (inner_mode)),
4769 XVECEXP (vals, 0, i));
4770 emit_move_insn (target, mem);
4773 /* Set field ELT of TARGET to VAL. */
4776 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4778 enum machine_mode mode = GET_MODE (target);
4779 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4780 rtx reg = gen_reg_rtx (mode);
4782 int width = GET_MODE_SIZE (inner_mode);
4785 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4787 rtx (*set_func) (rtx, rtx, rtx, rtx)
4788 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4789 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4793 /* Load single variable value. */
4794 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4795 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4796 x = gen_rtx_UNSPEC (VOIDmode,
4797 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4798 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4800 gen_rtx_SET (VOIDmode,
4804 /* Linear sequence. */
4805 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4806 for (i = 0; i < 16; ++i)
4807 XVECEXP (mask, 0, i) = GEN_INT (i);
4809 /* Set permute mask to insert element into target. */
4810 for (i = 0; i < width; ++i)
4811 XVECEXP (mask, 0, elt*width + i)
4812 = GEN_INT (i + 0x10);
4813 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4814 x = gen_rtx_UNSPEC (mode,
4815 gen_rtvec (3, target, reg,
4816 force_reg (V16QImode, x)),
4818 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4821 /* Extract field ELT from VEC into TARGET. */
4824 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4826 enum machine_mode mode = GET_MODE (vec);
4827 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4830 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4832 rtx (*extract_func) (rtx, rtx, rtx)
4833 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4834 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4838 /* Allocate mode-sized buffer. */
4839 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4841 /* Add offset to field within buffer matching vector element. */
4842 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4844 /* Store single field into mode-sized buffer. */
4845 x = gen_rtx_UNSPEC (VOIDmode,
4846 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4847 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4849 gen_rtx_SET (VOIDmode,
4852 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4855 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4856 implement ANDing by the mask IN. */
4858 build_mask64_2_operands (rtx in, rtx *out)
4860 #if HOST_BITS_PER_WIDE_INT >= 64
4861 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4864 gcc_assert (GET_CODE (in) == CONST_INT);
4869 /* Assume c initially something like 0x00fff000000fffff. The idea
4870 is to rotate the word so that the middle ^^^^^^ group of zeros
4871 is at the MS end and can be cleared with an rldicl mask. We then
4872 rotate back and clear off the MS ^^ group of zeros with a
4874 c = ~c; /* c == 0xff000ffffff00000 */
4875 lsb = c & -c; /* lsb == 0x0000000000100000 */
4876 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4877 c = ~c; /* c == 0x00fff000000fffff */
4878 c &= -lsb; /* c == 0x00fff00000000000 */
4879 lsb = c & -c; /* lsb == 0x0000100000000000 */
4880 c = ~c; /* c == 0xff000fffffffffff */
4881 c &= -lsb; /* c == 0xff00000000000000 */
4883 while ((lsb >>= 1) != 0)
4884 shift++; /* shift == 44 on exit from loop */
4885 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4886 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4887 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4891 /* Assume c initially something like 0xff000f0000000000. The idea
4892 is to rotate the word so that the ^^^ middle group of zeros
4893 is at the LS end and can be cleared with an rldicr mask. We then
4894 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4896 lsb = c & -c; /* lsb == 0x0000010000000000 */
4897 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4898 c = ~c; /* c == 0x00fff0ffffffffff */
4899 c &= -lsb; /* c == 0x00fff00000000000 */
4900 lsb = c & -c; /* lsb == 0x0000100000000000 */
4901 c = ~c; /* c == 0xff000fffffffffff */
4902 c &= -lsb; /* c == 0xff00000000000000 */
4904 while ((lsb >>= 1) != 0)
4905 shift++; /* shift == 44 on exit from loop */
4906 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4907 m1 >>= shift; /* m1 == 0x0000000000000fff */
4908 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4911 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4912 masks will be all 1's. We are guaranteed more than one transition. */
4913 out[0] = GEN_INT (64 - shift);
4914 out[1] = GEN_INT (m1);
4915 out[2] = GEN_INT (shift);
4916 out[3] = GEN_INT (m2);
4924 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4927 invalid_e500_subreg (rtx op, enum machine_mode mode)
4929 if (TARGET_E500_DOUBLE)
4931 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4932 subreg:TI and reg:TF. Decimal float modes are like integer
4933 modes (only low part of each register used) for this
4935 if (GET_CODE (op) == SUBREG
4936 && (mode == SImode || mode == DImode || mode == TImode
4937 || mode == DDmode || mode == TDmode)
4938 && REG_P (SUBREG_REG (op))
4939 && (GET_MODE (SUBREG_REG (op)) == DFmode
4940 || GET_MODE (SUBREG_REG (op)) == TFmode))
4943 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4945 if (GET_CODE (op) == SUBREG
4946 && (mode == DFmode || mode == TFmode)
4947 && REG_P (SUBREG_REG (op))
4948 && (GET_MODE (SUBREG_REG (op)) == DImode
4949 || GET_MODE (SUBREG_REG (op)) == TImode
4950 || GET_MODE (SUBREG_REG (op)) == DDmode
4951 || GET_MODE (SUBREG_REG (op)) == TDmode))
4956 && GET_CODE (op) == SUBREG
4958 && REG_P (SUBREG_REG (op))
4959 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4965 /* AIX increases natural record alignment to doubleword if the first
4966 field is an FP double while the FP fields remain word aligned. */
4969 rs6000_special_round_type_align (tree type, unsigned int computed,
4970 unsigned int specified)
4972 unsigned int align = MAX (computed, specified);
4973 tree field = TYPE_FIELDS (type);
4975 /* Skip all non field decls */
4976 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4977 field = TREE_CHAIN (field);
4979 if (field != NULL && field != type)
4981 type = TREE_TYPE (field);
4982 while (TREE_CODE (type) == ARRAY_TYPE)
4983 type = TREE_TYPE (type);
4985 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4986 align = MAX (align, 64);
4992 /* Darwin increases record alignment to the natural alignment of
4996 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4997 unsigned int specified)
4999 unsigned int align = MAX (computed, specified);
5001 if (TYPE_PACKED (type))
5004 /* Find the first field, looking down into aggregates. */
5006 tree field = TYPE_FIELDS (type);
5007 /* Skip all non field decls */
5008 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5009 field = TREE_CHAIN (field);
5012 /* A packed field does not contribute any extra alignment. */
5013 if (DECL_PACKED (field))
5015 type = TREE_TYPE (field);
5016 while (TREE_CODE (type) == ARRAY_TYPE)
5017 type = TREE_TYPE (type);
5018 } while (AGGREGATE_TYPE_P (type));
5020 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5021 align = MAX (align, TYPE_ALIGN (type));
5026 /* Return 1 for an operand in small memory on V.4/eabi. */
5029 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5030 enum machine_mode mode ATTRIBUTE_UNUSED)
5035 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5038 if (DEFAULT_ABI != ABI_V4)
5041 /* Vector and float memory instructions have a limited offset on the
5042 SPE, so using a vector or float variable directly as an operand is
5045 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5048 if (GET_CODE (op) == SYMBOL_REF)
5051 else if (GET_CODE (op) != CONST
5052 || GET_CODE (XEXP (op, 0)) != PLUS
5053 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5054 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5059 rtx sum = XEXP (op, 0);
5060 HOST_WIDE_INT summand;
5062 /* We have to be careful here, because it is the referenced address
5063 that must be 32k from _SDA_BASE_, not just the symbol. */
5064 summand = INTVAL (XEXP (sum, 1));
5065 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
5068 sym_ref = XEXP (sum, 0);
5071 return SYMBOL_REF_SMALL_P (sym_ref);
5077 /* Return true if either operand is a general purpose register. */
5080 gpr_or_gpr_p (rtx op0, rtx op1)
5082 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5083 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5087 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5090 reg_offset_addressing_ok_p (enum machine_mode mode)
5100 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5101 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5109 /* Paired vector modes. Only reg+reg addressing is valid. */
5110 if (TARGET_PAIRED_FLOAT)
5122 virtual_stack_registers_memory_p (rtx op)
5126 if (GET_CODE (op) == REG)
5127 regnum = REGNO (op);
5129 else if (GET_CODE (op) == PLUS
5130 && GET_CODE (XEXP (op, 0)) == REG
5131 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5132 regnum = REGNO (XEXP (op, 0));
5137 return (regnum >= FIRST_VIRTUAL_REGISTER
5138 && regnum <= LAST_VIRTUAL_REGISTER);
5142 constant_pool_expr_p (rtx op)
5146 split_const (op, &base, &offset);
5147 return (GET_CODE (base) == SYMBOL_REF
5148 && CONSTANT_POOL_ADDRESS_P (base)
5149 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5152 static rtx tocrel_base, tocrel_offset;
5155 toc_relative_expr_p (rtx op)
5157 if (GET_CODE (op) != CONST)
5160 split_const (op, &tocrel_base, &tocrel_offset);
5161 return (GET_CODE (tocrel_base) == UNSPEC
5162 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5166 legitimate_constant_pool_address_p (const_rtx x, bool strict)
5169 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5170 && GET_CODE (XEXP (x, 0)) == REG
5171 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5172 || ((TARGET_MINIMAL_TOC
5173 || TARGET_CMODEL != CMODEL_SMALL)
5174 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5175 && toc_relative_expr_p (XEXP (x, 1)));
5179 legitimate_small_data_p (enum machine_mode mode, rtx x)
5181 return (DEFAULT_ABI == ABI_V4
5182 && !flag_pic && !TARGET_TOC
5183 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5184 && small_data_operand (x, mode));
5187 /* SPE offset addressing is limited to 5-bits worth of double words. */
5188 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5191 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5193 unsigned HOST_WIDE_INT offset, extra;
5195 if (GET_CODE (x) != PLUS)
5197 if (GET_CODE (XEXP (x, 0)) != REG)
5199 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5201 if (!reg_offset_addressing_ok_p (mode))
5202 return virtual_stack_registers_memory_p (x);
5203 if (legitimate_constant_pool_address_p (x, strict))
5205 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5208 offset = INTVAL (XEXP (x, 1));
5216 /* SPE vector modes. */
5217 return SPE_CONST_OFFSET_OK (offset);
5220 if (TARGET_E500_DOUBLE)
5221 return SPE_CONST_OFFSET_OK (offset);
5223 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5225 if (VECTOR_MEM_VSX_P (DFmode))
5230 /* On e500v2, we may have:
5232 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5234 Which gets addressed with evldd instructions. */
5235 if (TARGET_E500_DOUBLE)
5236 return SPE_CONST_OFFSET_OK (offset);
5238 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5240 else if (offset & 3)
5245 if (TARGET_E500_DOUBLE)
5246 return (SPE_CONST_OFFSET_OK (offset)
5247 && SPE_CONST_OFFSET_OK (offset + 8));
5251 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5253 else if (offset & 3)
5264 return (offset < 0x10000) && (offset + extra < 0x10000);
5268 legitimate_indexed_address_p (rtx x, int strict)
5272 if (GET_CODE (x) != PLUS)
5278 /* Recognize the rtl generated by reload which we know will later be
5279 replaced with proper base and index regs. */
5281 && reload_in_progress
5282 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5286 return (REG_P (op0) && REG_P (op1)
5287 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5288 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5289 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5290 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5294 avoiding_indexed_address_p (enum machine_mode mode)
5296 /* Avoid indexed addressing for modes that have non-indexed
5297 load/store instruction forms. */
5298 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5302 legitimate_indirect_address_p (rtx x, int strict)
5304 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5308 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5310 if (!TARGET_MACHO || !flag_pic
5311 || mode != SImode || GET_CODE (x) != MEM)
5315 if (GET_CODE (x) != LO_SUM)
5317 if (GET_CODE (XEXP (x, 0)) != REG)
5319 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5323 return CONSTANT_P (x);
5327 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5329 if (GET_CODE (x) != LO_SUM)
5331 if (GET_CODE (XEXP (x, 0)) != REG)
5333 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5335 /* Restrict addressing for DI because of our SUBREG hackery. */
5336 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5337 || mode == DDmode || mode == TDmode
5342 if (TARGET_ELF || TARGET_MACHO)
5344 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5348 if (GET_MODE_NUNITS (mode) != 1)
5350 if (GET_MODE_BITSIZE (mode) > 64
5351 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5352 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5353 && (mode == DFmode || mode == DDmode))))
5356 return CONSTANT_P (x);
5363 /* Try machine-dependent ways of modifying an illegitimate address
5364 to be legitimate. If we find one, return the new, valid address.
5365 This is used from only one place: `memory_address' in explow.c.
5367 OLDX is the address as it was before break_out_memory_refs was
5368 called. In some cases it is useful to look at this to decide what
5371 It is always safe for this function to do nothing. It exists to
5372 recognize opportunities to optimize the output.
5374 On RS/6000, first check for the sum of a register with a constant
5375 integer that is out of range. If so, generate code to add the
5376 constant with the low-order 16 bits masked to the register and force
5377 this result into another register (this can be done with `cau').
5378 Then generate an address of REG+(CONST&0xffff), allowing for the
5379 possibility of bit 16 being a one.
5381 Then check for the sum of a register and something not constant, try to
5382 load the other things into a register and return the sum. */
5385 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5386 enum machine_mode mode)
5388 unsigned int extra = 0;
5390 if (!reg_offset_addressing_ok_p (mode))
5392 if (virtual_stack_registers_memory_p (x))
5395 /* In theory we should not be seeing addresses of the form reg+0,
5396 but just in case it is generated, optimize it away. */
5397 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5398 return force_reg (Pmode, XEXP (x, 0));
5400 /* Make sure both operands are registers. */
5401 else if (GET_CODE (x) == PLUS)
5402 return gen_rtx_PLUS (Pmode,
5403 force_reg (Pmode, XEXP (x, 0)),
5404 force_reg (Pmode, XEXP (x, 1)));
5406 return force_reg (Pmode, x);
5408 if (GET_CODE (x) == SYMBOL_REF)
5410 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5412 return rs6000_legitimize_tls_address (x, model);
5422 if (!TARGET_POWERPC64)
5430 extra = TARGET_POWERPC64 ? 8 : 12;
5436 if (GET_CODE (x) == PLUS
5437 && GET_CODE (XEXP (x, 0)) == REG
5438 && GET_CODE (XEXP (x, 1)) == CONST_INT
5439 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5441 && !((TARGET_POWERPC64
5442 && (mode == DImode || mode == TImode)
5443 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5444 || SPE_VECTOR_MODE (mode)
5445 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5446 || mode == DImode || mode == DDmode
5447 || mode == TDmode))))
5449 HOST_WIDE_INT high_int, low_int;
5451 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5452 if (low_int >= 0x8000 - extra)
5454 high_int = INTVAL (XEXP (x, 1)) - low_int;
5455 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5456 GEN_INT (high_int)), 0);
5457 return plus_constant (sum, low_int);
5459 else if (GET_CODE (x) == PLUS
5460 && GET_CODE (XEXP (x, 0)) == REG
5461 && GET_CODE (XEXP (x, 1)) != CONST_INT
5462 && GET_MODE_NUNITS (mode) == 1
5463 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5465 || ((mode != DImode && mode != DFmode && mode != DDmode)
5466 || (TARGET_E500_DOUBLE && mode != DDmode)))
5467 && (TARGET_POWERPC64 || mode != DImode)
5468 && !avoiding_indexed_address_p (mode)
5473 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5474 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5476 else if (SPE_VECTOR_MODE (mode)
5477 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5478 || mode == DDmode || mode == TDmode
5479 || mode == DImode)))
5483 /* We accept [reg + reg] and [reg + OFFSET]. */
5485 if (GET_CODE (x) == PLUS)
5487 rtx op1 = XEXP (x, 0);
5488 rtx op2 = XEXP (x, 1);
5491 op1 = force_reg (Pmode, op1);
5493 if (GET_CODE (op2) != REG
5494 && (GET_CODE (op2) != CONST_INT
5495 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5496 || (GET_MODE_SIZE (mode) > 8
5497 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5498 op2 = force_reg (Pmode, op2);
5500 /* We can't always do [reg + reg] for these, because [reg +
5501 reg + offset] is not a legitimate addressing mode. */
5502 y = gen_rtx_PLUS (Pmode, op1, op2);
5504 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5505 return force_reg (Pmode, y);
5510 return force_reg (Pmode, x);
5516 && GET_CODE (x) != CONST_INT
5517 && GET_CODE (x) != CONST_DOUBLE
5519 && GET_MODE_NUNITS (mode) == 1
5520 && (GET_MODE_BITSIZE (mode) <= 32
5521 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5522 && (mode == DFmode || mode == DDmode))))
5524 rtx reg = gen_reg_rtx (Pmode);
5525 emit_insn (gen_elf_high (reg, x));
5526 return gen_rtx_LO_SUM (Pmode, reg, x);
5528 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5531 && ! MACHO_DYNAMIC_NO_PIC_P
5533 && GET_CODE (x) != CONST_INT
5534 && GET_CODE (x) != CONST_DOUBLE
5536 && GET_MODE_NUNITS (mode) == 1
5537 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5538 || (mode != DFmode && mode != DDmode))
5542 rtx reg = gen_reg_rtx (Pmode);
5543 emit_insn (gen_macho_high (reg, x));
5544 return gen_rtx_LO_SUM (Pmode, reg, x);
5547 && GET_CODE (x) == SYMBOL_REF
5548 && constant_pool_expr_p (x)
5549 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5551 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5552 return create_TOC_reference (x, reg);
5558 /* Debug version of rs6000_legitimize_address. */
5560 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5566 ret = rs6000_legitimize_address (x, oldx, mode);
5567 insns = get_insns ();
5573 "\nrs6000_legitimize_address: mode %s, old code %s, "
5574 "new code %s, modified\n",
5575 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5576 GET_RTX_NAME (GET_CODE (ret)));
5578 fprintf (stderr, "Original address:\n");
5581 fprintf (stderr, "oldx:\n");
5584 fprintf (stderr, "New address:\n");
5589 fprintf (stderr, "Insns added:\n");
5590 debug_rtx_list (insns, 20);
5596 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5597 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5608 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5609 We need to emit DTP-relative relocations. */
5612 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5617 fputs ("\t.long\t", file);
5620 fputs (DOUBLE_INT_ASM_OP, file);
5625 output_addr_const (file, x);
5626 fputs ("@dtprel+0x8000", file);
5629 /* In the name of slightly smaller debug output, and to cater to
5630 general assembler lossage, recognize various UNSPEC sequences
5631 and turn them back into a direct symbol reference. */
5634 rs6000_delegitimize_address (rtx orig_x)
5638 orig_x = delegitimize_mem_from_attrs (orig_x);
5643 if ((GET_CODE (x) == PLUS
5644 || GET_CODE (x) == LO_SUM)
5645 && GET_CODE (XEXP (x, 0)) == REG
5646 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5647 || TARGET_MINIMAL_TOC
5648 || TARGET_CMODEL != CMODEL_SMALL)
5649 && GET_CODE (XEXP (x, 1)) == CONST)
5651 y = XEXP (XEXP (x, 1), 0);
5652 if (GET_CODE (y) == UNSPEC
5653 && XINT (y, 1) == UNSPEC_TOCREL)
5655 y = XVECEXP (y, 0, 0);
5656 if (!MEM_P (orig_x))
5659 return replace_equiv_address_nv (orig_x, y);
5664 && GET_CODE (orig_x) == LO_SUM
5665 && GET_CODE (XEXP (x, 1)) == CONST)
5667 y = XEXP (XEXP (x, 1), 0);
5668 if (GET_CODE (y) == UNSPEC
5669 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5670 return XVECEXP (y, 0, 0);
5676 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5678 static GTY(()) rtx rs6000_tls_symbol;
5680 rs6000_tls_get_addr (void)
5682 if (!rs6000_tls_symbol)
5683 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5685 return rs6000_tls_symbol;
5688 /* Construct the SYMBOL_REF for TLS GOT references. */
5690 static GTY(()) rtx rs6000_got_symbol;
5692 rs6000_got_sym (void)
5694 if (!rs6000_got_symbol)
5696 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5697 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5698 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5701 return rs6000_got_symbol;
5704 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5705 this (thread-local) address. */
5708 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5712 dest = gen_reg_rtx (Pmode);
5713 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5719 tlsreg = gen_rtx_REG (Pmode, 13);
5720 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5724 tlsreg = gen_rtx_REG (Pmode, 2);
5725 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5729 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5733 tmp = gen_reg_rtx (Pmode);
5736 tlsreg = gen_rtx_REG (Pmode, 13);
5737 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5741 tlsreg = gen_rtx_REG (Pmode, 2);
5742 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5746 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5748 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5753 rtx r3, got, tga, tmp1, tmp2, call_insn;
5755 /* We currently use relocations like @got@tlsgd for tls, which
5756 means the linker will handle allocation of tls entries, placing
5757 them in the .got section. So use a pointer to the .got section,
5758 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5759 or to secondary GOT sections used by 32-bit -fPIC. */
5761 got = gen_rtx_REG (Pmode, 2);
5765 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5768 rtx gsym = rs6000_got_sym ();
5769 got = gen_reg_rtx (Pmode);
5771 rs6000_emit_move (got, gsym, Pmode);
5776 tmp1 = gen_reg_rtx (Pmode);
5777 tmp2 = gen_reg_rtx (Pmode);
5778 mem = gen_const_mem (Pmode, tmp1);
5779 lab = gen_label_rtx ();
5780 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
5781 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
5782 emit_move_insn (tmp2, mem);
5783 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
5784 set_unique_reg_note (last, REG_EQUAL, gsym);
5789 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5791 r3 = gen_rtx_REG (Pmode, 3);
5792 tga = rs6000_tls_get_addr ();
5793 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
5795 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5796 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5797 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5798 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5799 else if (DEFAULT_ABI == ABI_V4)
5800 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5803 call_insn = last_call_insn ();
5804 PATTERN (call_insn) = insn;
5805 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5806 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5807 pic_offset_table_rtx);
5809 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5811 r3 = gen_rtx_REG (Pmode, 3);
5812 tga = rs6000_tls_get_addr ();
5813 tmp1 = gen_reg_rtx (Pmode);
5814 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
5816 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5817 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5818 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5819 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5820 else if (DEFAULT_ABI == ABI_V4)
5821 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5824 call_insn = last_call_insn ();
5825 PATTERN (call_insn) = insn;
5826 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5827 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5828 pic_offset_table_rtx);
5830 if (rs6000_tls_size == 16)
5833 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5835 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5837 else if (rs6000_tls_size == 32)
5839 tmp2 = gen_reg_rtx (Pmode);
5841 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5843 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5846 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5848 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5852 tmp2 = gen_reg_rtx (Pmode);
5854 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5856 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5858 insn = gen_rtx_SET (Pmode, dest,
5859 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5865 /* IE, or 64-bit offset LE. */
5866 tmp2 = gen_reg_rtx (Pmode);
5868 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5870 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5873 insn = gen_tls_tls_64 (dest, tmp2, addr);
5875 insn = gen_tls_tls_32 (dest, tmp2, addr);
5883 /* Return 1 if X contains a thread-local symbol. */
5886 rs6000_tls_referenced_p (rtx x)
5888 if (! TARGET_HAVE_TLS)
5891 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5894 /* Return 1 if *X is a thread-local symbol. This is the same as
5895 rs6000_tls_symbol_ref except for the type of the unused argument. */
5898 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5900 return RS6000_SYMBOL_REF_TLS_P (*x);
5903 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5904 replace the input X, or the original X if no replacement is called for.
5905 The output parameter *WIN is 1 if the calling macro should goto WIN,
5908 For RS/6000, we wish to handle large displacements off a base
5909 register by splitting the addend across an addiu/addis and the mem insn.
5910 This cuts number of extra insns needed from 3 to 1.
5912 On Darwin, we use this to generate code for floating point constants.
5913 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5914 The Darwin code is inside #if TARGET_MACHO because only then are the
5915 machopic_* functions defined. */
5917 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5918 int opnum, int type,
5919 int ind_levels ATTRIBUTE_UNUSED, int *win)
5921 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5923 /* We must recognize output that we have already generated ourselves. */
5924 if (GET_CODE (x) == PLUS
5925 && GET_CODE (XEXP (x, 0)) == PLUS
5926 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5927 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5928 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5930 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5931 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5932 opnum, (enum reload_type)type);
5938 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5939 && GET_CODE (x) == LO_SUM
5940 && GET_CODE (XEXP (x, 0)) == PLUS
5941 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5942 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5943 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5944 && machopic_operand_p (XEXP (x, 1)))
5946 /* Result of previous invocation of this function on Darwin
5947 floating point constant. */
5948 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5949 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5950 opnum, (enum reload_type)type);
5956 if (TARGET_CMODEL != CMODEL_SMALL
5957 && GET_CODE (x) == LO_SUM
5958 && GET_CODE (XEXP (x, 0)) == PLUS
5959 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5960 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
5961 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5962 && GET_CODE (XEXP (x, 1)) == CONST
5963 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
5964 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
5965 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
5967 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5968 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5969 opnum, (enum reload_type) type);
5974 /* Force ld/std non-word aligned offset into base register by wrapping
5976 if (GET_CODE (x) == PLUS
5977 && GET_CODE (XEXP (x, 0)) == REG
5978 && REGNO (XEXP (x, 0)) < 32
5979 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5980 && GET_CODE (XEXP (x, 1)) == CONST_INT
5982 && (INTVAL (XEXP (x, 1)) & 3) != 0
5983 && VECTOR_MEM_NONE_P (mode)
5984 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5985 && TARGET_POWERPC64)
5987 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5988 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5989 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5990 opnum, (enum reload_type) type);
5995 if (GET_CODE (x) == PLUS
5996 && GET_CODE (XEXP (x, 0)) == REG
5997 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5998 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5999 && GET_CODE (XEXP (x, 1)) == CONST_INT
6001 && !SPE_VECTOR_MODE (mode)
6002 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6003 || mode == DDmode || mode == TDmode
6005 && VECTOR_MEM_NONE_P (mode))
6007 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6008 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6010 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6012 /* Check for 32-bit overflow. */
6013 if (high + low != val)
6019 /* Reload the high part into a base reg; leave the low part
6020 in the mem directly. */
6022 x = gen_rtx_PLUS (GET_MODE (x),
6023 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6027 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6028 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6029 opnum, (enum reload_type)type);
6034 if (GET_CODE (x) == SYMBOL_REF
6036 && VECTOR_MEM_NONE_P (mode)
6037 && !SPE_VECTOR_MODE (mode)
6039 && DEFAULT_ABI == ABI_DARWIN
6040 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6042 && DEFAULT_ABI == ABI_V4
6045 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6046 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6050 && (mode != DImode || TARGET_POWERPC64)
6051 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6052 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6057 rtx offset = machopic_gen_offset (x);
6058 x = gen_rtx_LO_SUM (GET_MODE (x),
6059 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6060 gen_rtx_HIGH (Pmode, offset)), offset);
6064 x = gen_rtx_LO_SUM (GET_MODE (x),
6065 gen_rtx_HIGH (Pmode, x), x);
6067 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6068 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6069 opnum, (enum reload_type)type);
6074 /* Reload an offset address wrapped by an AND that represents the
6075 masking of the lower bits. Strip the outer AND and let reload
6076 convert the offset address into an indirect address. For VSX,
6077 force reload to create the address with an AND in a separate
6078 register, because we can't guarantee an altivec register will
6080 if (VECTOR_MEM_ALTIVEC_P (mode)
6081 && GET_CODE (x) == AND
6082 && GET_CODE (XEXP (x, 0)) == PLUS
6083 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6084 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6085 && GET_CODE (XEXP (x, 1)) == CONST_INT
6086 && INTVAL (XEXP (x, 1)) == -16)
6095 && GET_CODE (x) == SYMBOL_REF
6096 && constant_pool_expr_p (x)
6097 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6099 x = create_TOC_reference (x, NULL_RTX);
6100 if (TARGET_CMODEL != CMODEL_SMALL)
6101 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6102 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6103 opnum, (enum reload_type) type);
6111 /* Debug version of rs6000_legitimize_reload_address. */
6113 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6114 int opnum, int type,
6115 int ind_levels, int *win)
6117 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6120 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6121 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6122 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6126 fprintf (stderr, "Same address returned\n");
6128 fprintf (stderr, "NULL returned\n");
6131 fprintf (stderr, "New address:\n");
6138 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6139 that is a valid memory address for an instruction.
6140 The MODE argument is the machine mode for the MEM expression
6141 that wants to use this address.
6143 On the RS/6000, there are four valid address: a SYMBOL_REF that
6144 refers to a constant pool entry of an address (or the sum of it
6145 plus a constant), a short (16-bit signed) constant plus a register,
6146 the sum of two registers, or a register indirect, possibly with an
6147 auto-increment. For DFmode, DDmode and DImode with a constant plus
6148 register, we must ensure that both words are addressable or PowerPC64
6149 with offset word aligned.
6151 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6152 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6153 because adjacent memory cells are accessed by adding word-sized offsets
6154 during assembly output. */
6156 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6158 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6160 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6161 if (VECTOR_MEM_ALTIVEC_P (mode)
6162 && GET_CODE (x) == AND
6163 && GET_CODE (XEXP (x, 1)) == CONST_INT
6164 && INTVAL (XEXP (x, 1)) == -16)
6167 if (RS6000_SYMBOL_REF_TLS_P (x))
6169 if (legitimate_indirect_address_p (x, reg_ok_strict))
6171 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6172 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6173 && !SPE_VECTOR_MODE (mode)
6176 /* Restrict addressing for DI because of our SUBREG hackery. */
6177 && !(TARGET_E500_DOUBLE
6178 && (mode == DFmode || mode == DDmode || mode == DImode))
6180 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6182 if (virtual_stack_registers_memory_p (x))
6184 if (reg_offset_p && legitimate_small_data_p (mode, x))
6186 if (reg_offset_p && legitimate_constant_pool_address_p (x, reg_ok_strict))
6188 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6191 && GET_CODE (x) == PLUS
6192 && GET_CODE (XEXP (x, 0)) == REG
6193 && (XEXP (x, 0) == virtual_stack_vars_rtx
6194 || XEXP (x, 0) == arg_pointer_rtx)
6195 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6197 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6202 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6204 || (mode != DFmode && mode != DDmode)
6205 || (TARGET_E500_DOUBLE && mode != DDmode))
6206 && (TARGET_POWERPC64 || mode != DImode)
6207 && !avoiding_indexed_address_p (mode)
6208 && legitimate_indexed_address_p (x, reg_ok_strict))
6210 if (GET_CODE (x) == PRE_MODIFY
6214 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6216 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6217 && (TARGET_POWERPC64 || mode != DImode)
6218 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6219 && !SPE_VECTOR_MODE (mode)
6220 /* Restrict addressing for DI because of our SUBREG hackery. */
6221 && !(TARGET_E500_DOUBLE
6222 && (mode == DFmode || mode == DDmode || mode == DImode))
6224 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6225 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6226 || (!avoiding_indexed_address_p (mode)
6227 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6228 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6230 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6235 /* Debug version of rs6000_legitimate_address_p. */
6237 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6240 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6242 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6243 "strict = %d, code = %s\n",
6244 ret ? "true" : "false",
6245 GET_MODE_NAME (mode),
6247 GET_RTX_NAME (GET_CODE (x)));
6253 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6256 rs6000_mode_dependent_address_p (const_rtx addr)
6258 return rs6000_mode_dependent_address_ptr (addr);
6261 /* Go to LABEL if ADDR (a legitimate address expression)
6262 has an effect that depends on the machine mode it is used for.
6264 On the RS/6000 this is true of all integral offsets (since AltiVec
6265 and VSX modes don't allow them) or is a pre-increment or decrement.
6267 ??? Except that due to conceptual problems in offsettable_address_p
6268 we can't really report the problems of integral offsets. So leave
6269 this assuming that the adjustable offset must be valid for the
6270 sub-words of a TFmode operand, which is what we had before. */
6273 rs6000_mode_dependent_address (const_rtx addr)
6275 switch (GET_CODE (addr))
6278 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6279 is considered a legitimate address before reload, so there
6280 are no offset restrictions in that case. Note that this
6281 condition is safe in strict mode because any address involving
6282 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6283 been rejected as illegitimate. */
6284 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6285 && XEXP (addr, 0) != arg_pointer_rtx
6286 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6288 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6289 return val + 12 + 0x8000 >= 0x10000;
6294 /* Anything in the constant pool is sufficiently aligned that
6295 all bytes have the same high part address. */
6296 return !legitimate_constant_pool_address_p (addr, false);
6298 /* Auto-increment cases are now treated generically in recog.c. */
6300 return TARGET_UPDATE;
6302 /* AND is only allowed in Altivec loads. */
6313 /* Debug version of rs6000_mode_dependent_address. */
6315 rs6000_debug_mode_dependent_address (const_rtx addr)
6317 bool ret = rs6000_mode_dependent_address (addr);
6319 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6320 ret ? "true" : "false");
6326 /* Implement FIND_BASE_TERM. */
6329 rs6000_find_base_term (rtx op)
6333 split_const (op, &base, &offset);
6334 if (GET_CODE (base) == UNSPEC)
6335 switch (XINT (base, 1))
6338 case UNSPEC_MACHOPIC_OFFSET:
6339 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6340 for aliasing purposes. */
6341 return XVECEXP (base, 0, 0);
6347 /* More elaborate version of recog's offsettable_memref_p predicate
6348 that works around the ??? note of rs6000_mode_dependent_address.
6349 In particular it accepts
6351 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6353 in 32-bit mode, that the recog predicate rejects. */
6356 rs6000_offsettable_memref_p (rtx op)
6361 /* First mimic offsettable_memref_p. */
6362 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6365 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6366 the latter predicate knows nothing about the mode of the memory
6367 reference and, therefore, assumes that it is the largest supported
6368 mode (TFmode). As a consequence, legitimate offsettable memory
6369 references are rejected. rs6000_legitimate_offset_address_p contains
6370 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6371 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6374 /* Change register usage conditional on target flags. */
6376 rs6000_conditional_register_usage (void)
6380 /* Set MQ register fixed (already call_used) if not POWER
6381 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6386 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6388 fixed_regs[13] = call_used_regs[13]
6389 = call_really_used_regs[13] = 1;
6391 /* Conditionally disable FPRs. */
6392 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6393 for (i = 32; i < 64; i++)
6394 fixed_regs[i] = call_used_regs[i]
6395 = call_really_used_regs[i] = 1;
6397 /* The TOC register is not killed across calls in a way that is
6398 visible to the compiler. */
6399 if (DEFAULT_ABI == ABI_AIX)
6400 call_really_used_regs[2] = 0;
6402 if (DEFAULT_ABI == ABI_V4
6403 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6405 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6407 if (DEFAULT_ABI == ABI_V4
6408 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6410 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6411 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6412 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6414 if (DEFAULT_ABI == ABI_DARWIN
6415 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6416 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6417 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6418 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6420 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6421 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6422 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6426 global_regs[SPEFSCR_REGNO] = 1;
6427 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6428 registers in prologues and epilogues. We no longer use r14
6429 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6430 pool for link-compatibility with older versions of GCC. Once
6431 "old" code has died out, we can return r14 to the allocation
6434 = call_used_regs[14]
6435 = call_really_used_regs[14] = 1;
6438 if (!TARGET_ALTIVEC && !TARGET_VSX)
6440 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6441 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6442 call_really_used_regs[VRSAVE_REGNO] = 1;
6445 if (TARGET_ALTIVEC || TARGET_VSX)
6446 global_regs[VSCR_REGNO] = 1;
6448 if (TARGET_ALTIVEC_ABI)
6450 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6451 call_used_regs[i] = call_really_used_regs[i] = 1;
6453 /* AIX reserves VR20:31 in non-extended ABI mode. */
6455 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6456 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6460 /* Try to output insns to set TARGET equal to the constant C if it can
6461 be done in less than N insns. Do all computations in MODE.
6462 Returns the place where the output has been placed if it can be
6463 done and the insns have been emitted. If it would take more than N
6464 insns, zero is returned and no insns and emitted. */
6467 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6468 rtx source, int n ATTRIBUTE_UNUSED)
6470 rtx result, insn, set;
6471 HOST_WIDE_INT c0, c1;
6478 dest = gen_reg_rtx (mode);
6479 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6483 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6485 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6486 GEN_INT (INTVAL (source)
6487 & (~ (HOST_WIDE_INT) 0xffff))));
6488 emit_insn (gen_rtx_SET (VOIDmode, dest,
6489 gen_rtx_IOR (SImode, copy_rtx (result),
6490 GEN_INT (INTVAL (source) & 0xffff))));
6495 switch (GET_CODE (source))
6498 c0 = INTVAL (source);
6503 #if HOST_BITS_PER_WIDE_INT >= 64
6504 c0 = CONST_DOUBLE_LOW (source);
6507 c0 = CONST_DOUBLE_LOW (source);
6508 c1 = CONST_DOUBLE_HIGH (source);
6516 result = rs6000_emit_set_long_const (dest, c0, c1);
6523 insn = get_last_insn ();
6524 set = single_set (insn);
6525 if (! CONSTANT_P (SET_SRC (set)))
6526 set_unique_reg_note (insn, REG_EQUAL, source);
6531 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6532 fall back to a straight forward decomposition. We do this to avoid
6533 exponential run times encountered when looking for longer sequences
6534 with rs6000_emit_set_const. */
6536 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6538 if (!TARGET_POWERPC64)
6540 rtx operand1, operand2;
6542 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6544 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6546 emit_move_insn (operand1, GEN_INT (c1));
6547 emit_move_insn (operand2, GEN_INT (c2));
6551 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6554 ud2 = (c1 & 0xffff0000) >> 16;
6555 #if HOST_BITS_PER_WIDE_INT >= 64
6559 ud4 = (c2 & 0xffff0000) >> 16;
6561 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6562 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6565 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6567 emit_move_insn (dest, GEN_INT (ud1));
6570 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6571 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6574 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6577 emit_move_insn (dest, GEN_INT (ud2 << 16));
6579 emit_move_insn (copy_rtx (dest),
6580 gen_rtx_IOR (DImode, copy_rtx (dest),
6583 else if (ud3 == 0 && ud4 == 0)
6585 gcc_assert (ud2 & 0x8000);
6586 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6589 emit_move_insn (copy_rtx (dest),
6590 gen_rtx_IOR (DImode, copy_rtx (dest),
6592 emit_move_insn (copy_rtx (dest),
6593 gen_rtx_ZERO_EXTEND (DImode,
6594 gen_lowpart (SImode,
6597 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6598 || (ud4 == 0 && ! (ud3 & 0x8000)))
6601 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6604 emit_move_insn (dest, GEN_INT (ud3 << 16));
6607 emit_move_insn (copy_rtx (dest),
6608 gen_rtx_IOR (DImode, copy_rtx (dest),
6610 emit_move_insn (copy_rtx (dest),
6611 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6614 emit_move_insn (copy_rtx (dest),
6615 gen_rtx_IOR (DImode, copy_rtx (dest),
6621 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6624 emit_move_insn (dest, GEN_INT (ud4 << 16));
6627 emit_move_insn (copy_rtx (dest),
6628 gen_rtx_IOR (DImode, copy_rtx (dest),
6631 emit_move_insn (copy_rtx (dest),
6632 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6635 emit_move_insn (copy_rtx (dest),
6636 gen_rtx_IOR (DImode, copy_rtx (dest),
6637 GEN_INT (ud2 << 16)));
6639 emit_move_insn (copy_rtx (dest),
6640 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6646 /* Helper for the following. Get rid of [r+r] memory refs
6647 in cases where it won't work (TImode, TFmode, TDmode). */
6650 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6652 if (reload_in_progress)
6655 if (GET_CODE (operands[0]) == MEM
6656 && GET_CODE (XEXP (operands[0], 0)) != REG
6657 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), false))
6659 = replace_equiv_address (operands[0],
6660 copy_addr_to_reg (XEXP (operands[0], 0)));
6662 if (GET_CODE (operands[1]) == MEM
6663 && GET_CODE (XEXP (operands[1], 0)) != REG
6664 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), false))
6666 = replace_equiv_address (operands[1],
6667 copy_addr_to_reg (XEXP (operands[1], 0)));
6670 /* Emit a move from SOURCE to DEST in mode MODE. */
6672 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6676 operands[1] = source;
6678 if (TARGET_DEBUG_ADDR)
6681 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6682 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6683 GET_MODE_NAME (mode),
6686 can_create_pseudo_p ());
6688 fprintf (stderr, "source:\n");
6692 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6693 if (GET_CODE (operands[1]) == CONST_DOUBLE
6694 && ! FLOAT_MODE_P (mode)
6695 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6697 /* FIXME. This should never happen. */
6698 /* Since it seems that it does, do the safe thing and convert
6700 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6702 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6703 || FLOAT_MODE_P (mode)
6704 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6705 || CONST_DOUBLE_LOW (operands[1]) < 0)
6706 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6707 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6709 /* Check if GCC is setting up a block move that will end up using FP
6710 registers as temporaries. We must make sure this is acceptable. */
6711 if (GET_CODE (operands[0]) == MEM
6712 && GET_CODE (operands[1]) == MEM
6714 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6715 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6716 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6717 ? 32 : MEM_ALIGN (operands[0])))
6718 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6720 : MEM_ALIGN (operands[1]))))
6721 && ! MEM_VOLATILE_P (operands [0])
6722 && ! MEM_VOLATILE_P (operands [1]))
6724 emit_move_insn (adjust_address (operands[0], SImode, 0),
6725 adjust_address (operands[1], SImode, 0));
6726 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6727 adjust_address (copy_rtx (operands[1]), SImode, 4));
6731 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6732 && !gpc_reg_operand (operands[1], mode))
6733 operands[1] = force_reg (mode, operands[1]);
6735 if (mode == SFmode && ! TARGET_POWERPC
6736 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6737 && GET_CODE (operands[0]) == MEM)
6741 if (reload_in_progress || reload_completed)
6742 regnum = true_regnum (operands[1]);
6743 else if (GET_CODE (operands[1]) == REG)
6744 regnum = REGNO (operands[1]);
6748 /* If operands[1] is a register, on POWER it may have
6749 double-precision data in it, so truncate it to single
6751 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6754 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6755 : gen_reg_rtx (mode));
6756 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6757 operands[1] = newreg;
6761 /* Recognize the case where operand[1] is a reference to thread-local
6762 data and load its address to a register. */
6763 if (rs6000_tls_referenced_p (operands[1]))
6765 enum tls_model model;
6766 rtx tmp = operands[1];
6769 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6771 addend = XEXP (XEXP (tmp, 0), 1);
6772 tmp = XEXP (XEXP (tmp, 0), 0);
6775 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6776 model = SYMBOL_REF_TLS_MODEL (tmp);
6777 gcc_assert (model != 0);
6779 tmp = rs6000_legitimize_tls_address (tmp, model);
6782 tmp = gen_rtx_PLUS (mode, tmp, addend);
6783 tmp = force_operand (tmp, operands[0]);
6788 /* Handle the case where reload calls us with an invalid address. */
6789 if (reload_in_progress && mode == Pmode
6790 && (! general_operand (operands[1], mode)
6791 || ! nonimmediate_operand (operands[0], mode)))
6794 /* 128-bit constant floating-point values on Darwin should really be
6795 loaded as two parts. */
6796 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6797 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6799 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6800 know how to get a DFmode SUBREG of a TFmode. */
6801 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6802 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6803 simplify_gen_subreg (imode, operands[1], mode, 0),
6805 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6806 GET_MODE_SIZE (imode)),
6807 simplify_gen_subreg (imode, operands[1], mode,
6808 GET_MODE_SIZE (imode)),
6813 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6814 cfun->machine->sdmode_stack_slot =
6815 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6817 if (reload_in_progress
6819 && MEM_P (operands[0])
6820 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6821 && REG_P (operands[1]))
6823 if (FP_REGNO_P (REGNO (operands[1])))
6825 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6826 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6827 emit_insn (gen_movsd_store (mem, operands[1]));
6829 else if (INT_REGNO_P (REGNO (operands[1])))
6831 rtx mem = adjust_address_nv (operands[0], mode, 4);
6832 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6833 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6839 if (reload_in_progress
6841 && REG_P (operands[0])
6842 && MEM_P (operands[1])
6843 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6845 if (FP_REGNO_P (REGNO (operands[0])))
6847 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6848 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6849 emit_insn (gen_movsd_load (operands[0], mem));
6851 else if (INT_REGNO_P (REGNO (operands[0])))
6853 rtx mem = adjust_address_nv (operands[1], mode, 4);
6854 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6855 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6862 /* FIXME: In the long term, this switch statement should go away
6863 and be replaced by a sequence of tests based on things like
6869 if (CONSTANT_P (operands[1])
6870 && GET_CODE (operands[1]) != CONST_INT)
6871 operands[1] = force_const_mem (mode, operands[1]);
6876 rs6000_eliminate_indexed_memrefs (operands);
6883 if (CONSTANT_P (operands[1])
6884 && ! easy_fp_constant (operands[1], mode))
6885 operands[1] = force_const_mem (mode, operands[1]);
6898 if (CONSTANT_P (operands[1])
6899 && !easy_vector_constant (operands[1], mode))
6900 operands[1] = force_const_mem (mode, operands[1]);
6905 /* Use default pattern for address of ELF small data */
6908 && DEFAULT_ABI == ABI_V4
6909 && (GET_CODE (operands[1]) == SYMBOL_REF
6910 || GET_CODE (operands[1]) == CONST)
6911 && small_data_operand (operands[1], mode))
6913 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6917 if (DEFAULT_ABI == ABI_V4
6918 && mode == Pmode && mode == SImode
6919 && flag_pic == 1 && got_operand (operands[1], mode))
6921 emit_insn (gen_movsi_got (operands[0], operands[1]));
6925 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6929 && CONSTANT_P (operands[1])
6930 && GET_CODE (operands[1]) != HIGH
6931 && GET_CODE (operands[1]) != CONST_INT)
6933 rtx target = (!can_create_pseudo_p ()
6935 : gen_reg_rtx (mode));
6937 /* If this is a function address on -mcall-aixdesc,
6938 convert it to the address of the descriptor. */
6939 if (DEFAULT_ABI == ABI_AIX
6940 && GET_CODE (operands[1]) == SYMBOL_REF
6941 && XSTR (operands[1], 0)[0] == '.')
6943 const char *name = XSTR (operands[1], 0);
6945 while (*name == '.')
6947 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6948 CONSTANT_POOL_ADDRESS_P (new_ref)
6949 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6950 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6951 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6952 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6953 operands[1] = new_ref;
6956 if (DEFAULT_ABI == ABI_DARWIN)
6959 if (MACHO_DYNAMIC_NO_PIC_P)
6961 /* Take care of any required data indirection. */
6962 operands[1] = rs6000_machopic_legitimize_pic_address (
6963 operands[1], mode, operands[0]);
6964 if (operands[0] != operands[1])
6965 emit_insn (gen_rtx_SET (VOIDmode,
6966 operands[0], operands[1]));
6970 emit_insn (gen_macho_high (target, operands[1]));
6971 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6975 emit_insn (gen_elf_high (target, operands[1]));
6976 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6980 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6981 and we have put it in the TOC, we just need to make a TOC-relative
6984 && GET_CODE (operands[1]) == SYMBOL_REF
6985 && constant_pool_expr_p (operands[1])
6986 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6987 get_pool_mode (operands[1])))
6990 if (TARGET_CMODEL != CMODEL_SMALL)
6992 if (can_create_pseudo_p ())
6993 reg = gen_reg_rtx (Pmode);
6997 operands[1] = create_TOC_reference (operands[1], reg);
6999 else if (mode == Pmode
7000 && CONSTANT_P (operands[1])
7001 && ((GET_CODE (operands[1]) != CONST_INT
7002 && ! easy_fp_constant (operands[1], mode))
7003 || (GET_CODE (operands[1]) == CONST_INT
7004 && (num_insns_constant (operands[1], mode)
7005 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7006 || (GET_CODE (operands[0]) == REG
7007 && FP_REGNO_P (REGNO (operands[0]))))
7008 && GET_CODE (operands[1]) != HIGH
7009 && ! legitimate_constant_pool_address_p (operands[1], false)
7010 && ! toc_relative_expr_p (operands[1])
7011 && (TARGET_CMODEL == CMODEL_SMALL
7012 || can_create_pseudo_p ()
7013 || (REG_P (operands[0])
7014 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7018 /* Darwin uses a special PIC legitimizer. */
7019 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7022 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7024 if (operands[0] != operands[1])
7025 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7030 /* If we are to limit the number of things we put in the TOC and
7031 this is a symbol plus a constant we can add in one insn,
7032 just put the symbol in the TOC and add the constant. Don't do
7033 this if reload is in progress. */
7034 if (GET_CODE (operands[1]) == CONST
7035 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7036 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7037 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7038 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7039 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7040 && ! side_effects_p (operands[0]))
7043 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7044 rtx other = XEXP (XEXP (operands[1], 0), 1);
7046 sym = force_reg (mode, sym);
7047 emit_insn (gen_add3_insn (operands[0], sym, other));
7051 operands[1] = force_const_mem (mode, operands[1]);
7054 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7055 && constant_pool_expr_p (XEXP (operands[1], 0))
7056 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7057 get_pool_constant (XEXP (operands[1], 0)),
7058 get_pool_mode (XEXP (operands[1], 0))))
7062 if (TARGET_CMODEL != CMODEL_SMALL)
7064 if (can_create_pseudo_p ())
7065 reg = gen_reg_rtx (Pmode);
7069 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7070 operands[1] = gen_const_mem (mode, tocref);
7071 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7077 rs6000_eliminate_indexed_memrefs (operands);
7081 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7083 gen_rtx_SET (VOIDmode,
7084 operands[0], operands[1]),
7085 gen_rtx_CLOBBER (VOIDmode,
7086 gen_rtx_SCRATCH (SImode)))));
7092 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7095 /* Above, we may have called force_const_mem which may have returned
7096 an invalid address. If we can, fix this up; otherwise, reload will
7097 have to deal with it. */
7098 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7099 operands[1] = validize_mem (operands[1]);
7102 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7105 /* Nonzero if we can use a floating-point register to pass this arg. */
7106 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7107 (SCALAR_FLOAT_MODE_P (MODE) \
7108 && (CUM)->fregno <= FP_ARG_MAX_REG \
7109 && TARGET_HARD_FLOAT && TARGET_FPRS)
7111 /* Nonzero if we can use an AltiVec register to pass this arg. */
7112 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7113 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7114 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7115 && TARGET_ALTIVEC_ABI \
7118 /* Return a nonzero value to say to return the function value in
7119 memory, just as large structures are always returned. TYPE will be
7120 the data type of the value, and FNTYPE will be the type of the
7121 function doing the returning, or @code{NULL} for libcalls.
7123 The AIX ABI for the RS/6000 specifies that all structures are
7124 returned in memory. The Darwin ABI does the same. The SVR4 ABI
7125 specifies that structures <= 8 bytes are returned in r3/r4, but a
7126 draft put them in memory, and GCC used to implement the draft
7127 instead of the final standard. Therefore, aix_struct_return
7128 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7129 compatibility can change DRAFT_V4_STRUCT_RET to override the
7130 default, and -m switches get the final word. See
7131 rs6000_override_options for more details.
7133 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7134 long double support is enabled. These values are returned in memory.
7136 int_size_in_bytes returns -1 for variable size objects, which go in
7137 memory always. The cast to unsigned makes -1 > 8. */
7140 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7142 /* In the darwin64 abi, try to use registers for larger structs
7144 if (rs6000_darwin64_abi
7145 && TREE_CODE (type) == RECORD_TYPE
7146 && int_size_in_bytes (type) > 0)
7148 CUMULATIVE_ARGS valcum;
7152 valcum.fregno = FP_ARG_MIN_REG;
7153 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7154 /* Do a trial code generation as if this were going to be passed
7155 as an argument; if any part goes in memory, we return NULL. */
7156 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
7159 /* Otherwise fall through to more conventional ABI rules. */
7162 if (AGGREGATE_TYPE_P (type)
7163 && (aix_struct_return
7164 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7167 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7168 modes only exist for GCC vector types if -maltivec. */
7169 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7170 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7173 /* Return synthetic vectors in memory. */
7174 if (TREE_CODE (type) == VECTOR_TYPE
7175 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7177 static bool warned_for_return_big_vectors = false;
7178 if (!warned_for_return_big_vectors)
7180 warning (0, "GCC vector returned by reference: "
7181 "non-standard ABI extension with no compatibility guarantee");
7182 warned_for_return_big_vectors = true;
7187 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7193 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7194 for a call to a function whose data type is FNTYPE.
7195 For a library call, FNTYPE is 0.
7197 For incoming args we set the number of arguments in the prototype large
7198 so we never return a PARALLEL. */
7201 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7202 rtx libname ATTRIBUTE_UNUSED, int incoming,
7203 int libcall, int n_named_args)
7205 static CUMULATIVE_ARGS zero_cumulative;
7207 *cum = zero_cumulative;
7209 cum->fregno = FP_ARG_MIN_REG;
7210 cum->vregno = ALTIVEC_ARG_MIN_REG;
7211 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7212 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7213 ? CALL_LIBCALL : CALL_NORMAL);
7214 cum->sysv_gregno = GP_ARG_MIN_REG;
7215 cum->stdarg = fntype
7216 && (TYPE_ARG_TYPES (fntype) != 0
7217 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
7218 != void_type_node));
7220 cum->nargs_prototype = 0;
7221 if (incoming || cum->prototype)
7222 cum->nargs_prototype = n_named_args;
7224 /* Check for a longcall attribute. */
7225 if ((!fntype && rs6000_default_long_calls)
7227 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7228 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7229 cum->call_cookie |= CALL_LONG;
7231 if (TARGET_DEBUG_ARG)
7233 fprintf (stderr, "\ninit_cumulative_args:");
7236 tree ret_type = TREE_TYPE (fntype);
7237 fprintf (stderr, " ret code = %s,",
7238 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7241 if (cum->call_cookie & CALL_LONG)
7242 fprintf (stderr, " longcall,");
7244 fprintf (stderr, " proto = %d, nargs = %d\n",
7245 cum->prototype, cum->nargs_prototype);
7250 && TARGET_ALTIVEC_ABI
7251 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7253 error ("cannot return value in vector register because"
7254 " altivec instructions are disabled, use -maltivec"
7259 /* Return true if TYPE must be passed on the stack and not in registers. */
7262 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7264 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7265 return must_pass_in_stack_var_size (mode, type);
7267 return must_pass_in_stack_var_size_or_pad (mode, type);
7270 /* If defined, a C expression which determines whether, and in which
7271 direction, to pad out an argument with extra space. The value
7272 should be of type `enum direction': either `upward' to pad above
7273 the argument, `downward' to pad below, or `none' to inhibit
7276 For the AIX ABI structs are always stored left shifted in their
7280 function_arg_padding (enum machine_mode mode, const_tree type)
7282 #ifndef AGGREGATE_PADDING_FIXED
7283 #define AGGREGATE_PADDING_FIXED 0
7285 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7286 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7289 if (!AGGREGATE_PADDING_FIXED)
7291 /* GCC used to pass structures of the same size as integer types as
7292 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7293 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7294 passed padded downward, except that -mstrict-align further
7295 muddied the water in that multi-component structures of 2 and 4
7296 bytes in size were passed padded upward.
7298 The following arranges for best compatibility with previous
7299 versions of gcc, but removes the -mstrict-align dependency. */
7300 if (BYTES_BIG_ENDIAN)
7302 HOST_WIDE_INT size = 0;
7304 if (mode == BLKmode)
7306 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7307 size = int_size_in_bytes (type);
7310 size = GET_MODE_SIZE (mode);
7312 if (size == 1 || size == 2 || size == 4)
7318 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7320 if (type != 0 && AGGREGATE_TYPE_P (type))
7324 /* Fall back to the default. */
7325 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7328 /* If defined, a C expression that gives the alignment boundary, in bits,
7329 of an argument with the specified mode and type. If it is not defined,
7330 PARM_BOUNDARY is used for all arguments.
7332 V.4 wants long longs and doubles to be double word aligned. Just
7333 testing the mode size is a boneheaded way to do this as it means
7334 that other types such as complex int are also double word aligned.
7335 However, we're stuck with this because changing the ABI might break
7336 existing library interfaces.
7338 Doubleword align SPE vectors.
7339 Quadword align Altivec vectors.
7340 Quadword align large synthetic vector types. */
7343 function_arg_boundary (enum machine_mode mode, tree type)
7345 if (DEFAULT_ABI == ABI_V4
7346 && (GET_MODE_SIZE (mode) == 8
7347 || (TARGET_HARD_FLOAT
7349 && (mode == TFmode || mode == TDmode))))
7351 else if (SPE_VECTOR_MODE (mode)
7352 || (type && TREE_CODE (type) == VECTOR_TYPE
7353 && int_size_in_bytes (type) >= 8
7354 && int_size_in_bytes (type) < 16))
7356 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
7357 || (type && TREE_CODE (type) == VECTOR_TYPE
7358 && int_size_in_bytes (type) >= 16))
7360 else if (rs6000_darwin64_abi && mode == BLKmode
7361 && type && TYPE_ALIGN (type) > 64)
7364 return PARM_BOUNDARY;
7367 /* For a function parm of MODE and TYPE, return the starting word in
7368 the parameter area. NWORDS of the parameter area are already used. */
7371 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
7374 unsigned int parm_offset;
7376 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7377 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7378 return nwords + (-(parm_offset + nwords) & align);
7381 /* Compute the size (in words) of a function argument. */
7383 static unsigned long
7384 rs6000_arg_size (enum machine_mode mode, tree type)
7388 if (mode != BLKmode)
7389 size = GET_MODE_SIZE (mode);
7391 size = int_size_in_bytes (type);
7394 return (size + 3) >> 2;
7396 return (size + 7) >> 3;
7399 /* Use this to flush pending int fields. */
7402 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7403 HOST_WIDE_INT bitpos)
7405 unsigned int startbit, endbit;
7406 int intregs, intoffset;
7407 enum machine_mode mode;
7409 if (cum->intoffset == -1)
7412 intoffset = cum->intoffset;
7413 cum->intoffset = -1;
7415 if (intoffset % BITS_PER_WORD != 0)
7417 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7419 if (mode == BLKmode)
7421 /* We couldn't find an appropriate mode, which happens,
7422 e.g., in packed structs when there are 3 bytes to load.
7423 Back intoffset back to the beginning of the word in this
7425 intoffset = intoffset & -BITS_PER_WORD;
7429 startbit = intoffset & -BITS_PER_WORD;
7430 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7431 intregs = (endbit - startbit) / BITS_PER_WORD;
7432 cum->words += intregs;
7435 /* The darwin64 ABI calls for us to recurse down through structs,
7436 looking for elements passed in registers. Unfortunately, we have
7437 to track int register count here also because of misalignments
7438 in powerpc alignment mode. */
7441 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7443 HOST_WIDE_INT startbitpos)
7447 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7448 if (TREE_CODE (f) == FIELD_DECL)
7450 HOST_WIDE_INT bitpos = startbitpos;
7451 tree ftype = TREE_TYPE (f);
7452 enum machine_mode mode;
7453 if (ftype == error_mark_node)
7455 mode = TYPE_MODE (ftype);
7457 if (DECL_SIZE (f) != 0
7458 && host_integerp (bit_position (f), 1))
7459 bitpos += int_bit_position (f);
7461 /* ??? FIXME: else assume zero offset. */
7463 if (TREE_CODE (ftype) == RECORD_TYPE)
7464 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7465 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7467 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7468 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7469 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7471 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7473 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7477 else if (cum->intoffset == -1)
7478 cum->intoffset = bitpos;
7482 /* Update the data in CUM to advance over an argument
7483 of mode MODE and data type TYPE.
7484 (TYPE is null for libcalls where that information may not be available.)
7486 Note that for args passed by reference, function_arg will be called
7487 with MODE and TYPE set to that of the pointer to the arg, not the arg
7491 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7492 tree type, int named, int depth)
7496 /* Only tick off an argument if we're not recursing. */
7498 cum->nargs_prototype--;
7500 if (TARGET_ALTIVEC_ABI
7501 && (ALTIVEC_VECTOR_MODE (mode)
7502 || VSX_VECTOR_MODE (mode)
7503 || (type && TREE_CODE (type) == VECTOR_TYPE
7504 && int_size_in_bytes (type) == 16)))
7508 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7511 if (!TARGET_ALTIVEC)
7512 error ("cannot pass argument in vector register because"
7513 " altivec instructions are disabled, use -maltivec"
7516 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7517 even if it is going to be passed in a vector register.
7518 Darwin does the same for variable-argument functions. */
7519 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7520 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7530 /* Vector parameters must be 16-byte aligned. This places
7531 them at 2 mod 4 in terms of words in 32-bit mode, since
7532 the parameter save area starts at offset 24 from the
7533 stack. In 64-bit mode, they just have to start on an
7534 even word, since the parameter save area is 16-byte
7535 aligned. Space for GPRs is reserved even if the argument
7536 will be passed in memory. */
7538 align = (2 - cum->words) & 3;
7540 align = cum->words & 1;
7541 cum->words += align + rs6000_arg_size (mode, type);
7543 if (TARGET_DEBUG_ARG)
7545 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7547 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7548 cum->nargs_prototype, cum->prototype,
7549 GET_MODE_NAME (mode));
7553 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7555 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7558 else if (rs6000_darwin64_abi
7560 && TREE_CODE (type) == RECORD_TYPE
7561 && (size = int_size_in_bytes (type)) > 0)
7563 /* Variable sized types have size == -1 and are
7564 treated as if consisting entirely of ints.
7565 Pad to 16 byte boundary if needed. */
7566 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7567 && (cum->words % 2) != 0)
7569 /* For varargs, we can just go up by the size of the struct. */
7571 cum->words += (size + 7) / 8;
7574 /* It is tempting to say int register count just goes up by
7575 sizeof(type)/8, but this is wrong in a case such as
7576 { int; double; int; } [powerpc alignment]. We have to
7577 grovel through the fields for these too. */
7579 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7580 rs6000_darwin64_record_arg_advance_flush (cum,
7581 size * BITS_PER_UNIT);
7584 else if (DEFAULT_ABI == ABI_V4)
7586 if (TARGET_HARD_FLOAT && TARGET_FPRS
7587 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7588 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7589 || (mode == TFmode && !TARGET_IEEEQUAD)
7590 || mode == SDmode || mode == DDmode || mode == TDmode))
7592 /* _Decimal128 must use an even/odd register pair. This assumes
7593 that the register number is odd when fregno is odd. */
7594 if (mode == TDmode && (cum->fregno % 2) == 1)
7597 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7598 <= FP_ARG_V4_MAX_REG)
7599 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7602 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7603 if (mode == DFmode || mode == TFmode
7604 || mode == DDmode || mode == TDmode)
7605 cum->words += cum->words & 1;
7606 cum->words += rs6000_arg_size (mode, type);
7611 int n_words = rs6000_arg_size (mode, type);
7612 int gregno = cum->sysv_gregno;
7614 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7615 (r7,r8) or (r9,r10). As does any other 2 word item such
7616 as complex int due to a historical mistake. */
7618 gregno += (1 - gregno) & 1;
7620 /* Multi-reg args are not split between registers and stack. */
7621 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7623 /* Long long and SPE vectors are aligned on the stack.
7624 So are other 2 word items such as complex int due to
7625 a historical mistake. */
7627 cum->words += cum->words & 1;
7628 cum->words += n_words;
7631 /* Note: continuing to accumulate gregno past when we've started
7632 spilling to the stack indicates the fact that we've started
7633 spilling to the stack to expand_builtin_saveregs. */
7634 cum->sysv_gregno = gregno + n_words;
7637 if (TARGET_DEBUG_ARG)
7639 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7640 cum->words, cum->fregno);
7641 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7642 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7643 fprintf (stderr, "mode = %4s, named = %d\n",
7644 GET_MODE_NAME (mode), named);
7649 int n_words = rs6000_arg_size (mode, type);
7650 int start_words = cum->words;
7651 int align_words = rs6000_parm_start (mode, type, start_words);
7653 cum->words = align_words + n_words;
7655 if (SCALAR_FLOAT_MODE_P (mode)
7656 && TARGET_HARD_FLOAT && TARGET_FPRS)
7658 /* _Decimal128 must be passed in an even/odd float register pair.
7659 This assumes that the register number is odd when fregno is
7661 if (mode == TDmode && (cum->fregno % 2) == 1)
7663 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7666 if (TARGET_DEBUG_ARG)
7668 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7669 cum->words, cum->fregno);
7670 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7671 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7672 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7673 named, align_words - start_words, depth);
7679 spe_build_register_parallel (enum machine_mode mode, int gregno)
7686 r1 = gen_rtx_REG (DImode, gregno);
7687 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7688 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7692 r1 = gen_rtx_REG (DImode, gregno);
7693 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7694 r3 = gen_rtx_REG (DImode, gregno + 2);
7695 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7696 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7699 r1 = gen_rtx_REG (DImode, gregno);
7700 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7701 r3 = gen_rtx_REG (DImode, gregno + 2);
7702 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7703 r5 = gen_rtx_REG (DImode, gregno + 4);
7704 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7705 r7 = gen_rtx_REG (DImode, gregno + 6);
7706 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7707 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7714 /* Determine where to put a SIMD argument on the SPE. */
7716 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7719 int gregno = cum->sysv_gregno;
7721 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7722 are passed and returned in a pair of GPRs for ABI compatibility. */
7723 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7724 || mode == DCmode || mode == TCmode))
7726 int n_words = rs6000_arg_size (mode, type);
7728 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7730 gregno += (1 - gregno) & 1;
7732 /* Multi-reg args are not split between registers and stack. */
7733 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7736 return spe_build_register_parallel (mode, gregno);
7740 int n_words = rs6000_arg_size (mode, type);
7742 /* SPE vectors are put in odd registers. */
7743 if (n_words == 2 && (gregno & 1) == 0)
7746 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7749 enum machine_mode m = SImode;
7751 r1 = gen_rtx_REG (m, gregno);
7752 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7753 r2 = gen_rtx_REG (m, gregno + 1);
7754 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7755 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7762 if (gregno <= GP_ARG_MAX_REG)
7763 return gen_rtx_REG (mode, gregno);
7769 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7770 structure between cum->intoffset and bitpos to integer registers. */
7773 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7774 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7776 enum machine_mode mode;
7778 unsigned int startbit, endbit;
7779 int this_regno, intregs, intoffset;
7782 if (cum->intoffset == -1)
7785 intoffset = cum->intoffset;
7786 cum->intoffset = -1;
7788 /* If this is the trailing part of a word, try to only load that
7789 much into the register. Otherwise load the whole register. Note
7790 that in the latter case we may pick up unwanted bits. It's not a
7791 problem at the moment but may wish to revisit. */
7793 if (intoffset % BITS_PER_WORD != 0)
7795 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7797 if (mode == BLKmode)
7799 /* We couldn't find an appropriate mode, which happens,
7800 e.g., in packed structs when there are 3 bytes to load.
7801 Back intoffset back to the beginning of the word in this
7803 intoffset = intoffset & -BITS_PER_WORD;
7810 startbit = intoffset & -BITS_PER_WORD;
7811 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7812 intregs = (endbit - startbit) / BITS_PER_WORD;
7813 this_regno = cum->words + intoffset / BITS_PER_WORD;
7815 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7818 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7822 intoffset /= BITS_PER_UNIT;
7825 regno = GP_ARG_MIN_REG + this_regno;
7826 reg = gen_rtx_REG (mode, regno);
7828 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7831 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7835 while (intregs > 0);
7838 /* Recursive workhorse for the following. */
7841 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7842 HOST_WIDE_INT startbitpos, rtx rvec[],
7847 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7848 if (TREE_CODE (f) == FIELD_DECL)
7850 HOST_WIDE_INT bitpos = startbitpos;
7851 tree ftype = TREE_TYPE (f);
7852 enum machine_mode mode;
7853 if (ftype == error_mark_node)
7855 mode = TYPE_MODE (ftype);
7857 if (DECL_SIZE (f) != 0
7858 && host_integerp (bit_position (f), 1))
7859 bitpos += int_bit_position (f);
7861 /* ??? FIXME: else assume zero offset. */
7863 if (TREE_CODE (ftype) == RECORD_TYPE)
7864 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7865 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7870 case SCmode: mode = SFmode; break;
7871 case DCmode: mode = DFmode; break;
7872 case TCmode: mode = TFmode; break;
7876 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7878 = gen_rtx_EXPR_LIST (VOIDmode,
7879 gen_rtx_REG (mode, cum->fregno++),
7880 GEN_INT (bitpos / BITS_PER_UNIT));
7881 if (mode == TFmode || mode == TDmode)
7884 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7886 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7888 = gen_rtx_EXPR_LIST (VOIDmode,
7889 gen_rtx_REG (mode, cum->vregno++),
7890 GEN_INT (bitpos / BITS_PER_UNIT));
7892 else if (cum->intoffset == -1)
7893 cum->intoffset = bitpos;
7897 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7898 the register(s) to be used for each field and subfield of a struct
7899 being passed by value, along with the offset of where the
7900 register's value may be found in the block. FP fields go in FP
7901 register, vector fields go in vector registers, and everything
7902 else goes in int registers, packed as in memory.
7904 This code is also used for function return values. RETVAL indicates
7905 whether this is the case.
7907 Much of this is taken from the SPARC V9 port, which has a similar
7908 calling convention. */
7911 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7912 int named, bool retval)
7914 rtx rvec[FIRST_PSEUDO_REGISTER];
7915 int k = 1, kbase = 1;
7916 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7917 /* This is a copy; modifications are not visible to our caller. */
7918 CUMULATIVE_ARGS copy_cum = *orig_cum;
7919 CUMULATIVE_ARGS *cum = ©_cum;
7921 /* Pad to 16 byte boundary if needed. */
7922 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7923 && (cum->words % 2) != 0)
7930 /* Put entries into rvec[] for individual FP and vector fields, and
7931 for the chunks of memory that go in int regs. Note we start at
7932 element 1; 0 is reserved for an indication of using memory, and
7933 may or may not be filled in below. */
7934 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7935 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7937 /* If any part of the struct went on the stack put all of it there.
7938 This hack is because the generic code for
7939 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7940 parts of the struct are not at the beginning. */
7944 return NULL_RTX; /* doesn't go in registers at all */
7946 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7948 if (k > 1 || cum->use_stack)
7949 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7954 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7957 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7961 rtx rvec[GP_ARG_NUM_REG + 1];
7963 if (align_words >= GP_ARG_NUM_REG)
7966 n_units = rs6000_arg_size (mode, type);
7968 /* Optimize the simple case where the arg fits in one gpr, except in
7969 the case of BLKmode due to assign_parms assuming that registers are
7970 BITS_PER_WORD wide. */
7972 || (n_units == 1 && mode != BLKmode))
7973 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7976 if (align_words + n_units > GP_ARG_NUM_REG)
7977 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7978 using a magic NULL_RTX component.
7979 This is not strictly correct. Only some of the arg belongs in
7980 memory, not all of it. However, the normal scheme using
7981 function_arg_partial_nregs can result in unusual subregs, eg.
7982 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7983 store the whole arg to memory is often more efficient than code
7984 to store pieces, and we know that space is available in the right
7985 place for the whole arg. */
7986 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7991 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7992 rtx off = GEN_INT (i++ * 4);
7993 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7995 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7997 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8000 /* Determine where to put an argument to a function.
8001 Value is zero to push the argument on the stack,
8002 or a hard register in which to store the argument.
8004 MODE is the argument's machine mode.
8005 TYPE is the data type of the argument (as a tree).
8006 This is null for libcalls where that information may
8008 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8009 the preceding args and about the function being called. It is
8010 not modified in this routine.
8011 NAMED is nonzero if this argument is a named parameter
8012 (otherwise it is an extra parameter matching an ellipsis).
8014 On RS/6000 the first eight words of non-FP are normally in registers
8015 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8016 Under V.4, the first 8 FP args are in registers.
8018 If this is floating-point and no prototype is specified, we use
8019 both an FP and integer register (or possibly FP reg and stack). Library
8020 functions (when CALL_LIBCALL is set) always have the proper types for args,
8021 so we can pass the FP value just in one register. emit_library_function
8022 doesn't support PARALLEL anyway.
8024 Note that for args passed by reference, function_arg will be called
8025 with MODE and TYPE set to that of the pointer to the arg, not the arg
8029 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8030 tree type, int named)
8032 enum rs6000_abi abi = DEFAULT_ABI;
8034 /* Return a marker to indicate whether CR1 needs to set or clear the
8035 bit that V.4 uses to say fp args were passed in registers.
8036 Assume that we don't need the marker for software floating point,
8037 or compiler generated library calls. */
8038 if (mode == VOIDmode)
8041 && (cum->call_cookie & CALL_LIBCALL) == 0
8043 || (cum->nargs_prototype < 0
8044 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8046 /* For the SPE, we need to crxor CR6 always. */
8048 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8049 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8050 return GEN_INT (cum->call_cookie
8051 | ((cum->fregno == FP_ARG_MIN_REG)
8052 ? CALL_V4_SET_FP_ARGS
8053 : CALL_V4_CLEAR_FP_ARGS));
8056 return GEN_INT (cum->call_cookie);
8059 if (rs6000_darwin64_abi && mode == BLKmode
8060 && TREE_CODE (type) == RECORD_TYPE)
8062 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
8063 if (rslt != NULL_RTX)
8065 /* Else fall through to usual handling. */
8068 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8069 if (TARGET_64BIT && ! cum->prototype)
8071 /* Vector parameters get passed in vector register
8072 and also in GPRs or memory, in absence of prototype. */
8075 align_words = (cum->words + 1) & ~1;
8077 if (align_words >= GP_ARG_NUM_REG)
8083 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8085 return gen_rtx_PARALLEL (mode,
8087 gen_rtx_EXPR_LIST (VOIDmode,
8089 gen_rtx_EXPR_LIST (VOIDmode,
8090 gen_rtx_REG (mode, cum->vregno),
8094 return gen_rtx_REG (mode, cum->vregno);
8095 else if (TARGET_ALTIVEC_ABI
8096 && (ALTIVEC_VECTOR_MODE (mode)
8097 || VSX_VECTOR_MODE (mode)
8098 || (type && TREE_CODE (type) == VECTOR_TYPE
8099 && int_size_in_bytes (type) == 16)))
8101 if (named || abi == ABI_V4)
8105 /* Vector parameters to varargs functions under AIX or Darwin
8106 get passed in memory and possibly also in GPRs. */
8107 int align, align_words, n_words;
8108 enum machine_mode part_mode;
8110 /* Vector parameters must be 16-byte aligned. This places them at
8111 2 mod 4 in terms of words in 32-bit mode, since the parameter
8112 save area starts at offset 24 from the stack. In 64-bit mode,
8113 they just have to start on an even word, since the parameter
8114 save area is 16-byte aligned. */
8116 align = (2 - cum->words) & 3;
8118 align = cum->words & 1;
8119 align_words = cum->words + align;
8121 /* Out of registers? Memory, then. */
8122 if (align_words >= GP_ARG_NUM_REG)
8125 if (TARGET_32BIT && TARGET_POWERPC64)
8126 return rs6000_mixed_function_arg (mode, type, align_words);
8128 /* The vector value goes in GPRs. Only the part of the
8129 value in GPRs is reported here. */
8131 n_words = rs6000_arg_size (mode, type);
8132 if (align_words + n_words > GP_ARG_NUM_REG)
8133 /* Fortunately, there are only two possibilities, the value
8134 is either wholly in GPRs or half in GPRs and half not. */
8137 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8140 else if (TARGET_SPE_ABI && TARGET_SPE
8141 && (SPE_VECTOR_MODE (mode)
8142 || (TARGET_E500_DOUBLE && (mode == DFmode
8145 || mode == TCmode))))
8146 return rs6000_spe_function_arg (cum, mode, type);
8148 else if (abi == ABI_V4)
8150 if (TARGET_HARD_FLOAT && TARGET_FPRS
8151 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8152 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8153 || (mode == TFmode && !TARGET_IEEEQUAD)
8154 || mode == SDmode || mode == DDmode || mode == TDmode))
8156 /* _Decimal128 must use an even/odd register pair. This assumes
8157 that the register number is odd when fregno is odd. */
8158 if (mode == TDmode && (cum->fregno % 2) == 1)
8161 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8162 <= FP_ARG_V4_MAX_REG)
8163 return gen_rtx_REG (mode, cum->fregno);
8169 int n_words = rs6000_arg_size (mode, type);
8170 int gregno = cum->sysv_gregno;
8172 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8173 (r7,r8) or (r9,r10). As does any other 2 word item such
8174 as complex int due to a historical mistake. */
8176 gregno += (1 - gregno) & 1;
8178 /* Multi-reg args are not split between registers and stack. */
8179 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8182 if (TARGET_32BIT && TARGET_POWERPC64)
8183 return rs6000_mixed_function_arg (mode, type,
8184 gregno - GP_ARG_MIN_REG);
8185 return gen_rtx_REG (mode, gregno);
8190 int align_words = rs6000_parm_start (mode, type, cum->words);
8192 /* _Decimal128 must be passed in an even/odd float register pair.
8193 This assumes that the register number is odd when fregno is odd. */
8194 if (mode == TDmode && (cum->fregno % 2) == 1)
8197 if (USE_FP_FOR_ARG_P (cum, mode, type))
8199 rtx rvec[GP_ARG_NUM_REG + 1];
8203 enum machine_mode fmode = mode;
8204 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8206 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8208 /* Currently, we only ever need one reg here because complex
8209 doubles are split. */
8210 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8211 && (fmode == TFmode || fmode == TDmode));
8213 /* Long double or _Decimal128 split over regs and memory. */
8214 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8217 /* Do we also need to pass this arg in the parameter save
8220 && (cum->nargs_prototype <= 0
8221 || (DEFAULT_ABI == ABI_AIX
8223 && align_words >= GP_ARG_NUM_REG)));
8225 if (!needs_psave && mode == fmode)
8226 return gen_rtx_REG (fmode, cum->fregno);
8231 /* Describe the part that goes in gprs or the stack.
8232 This piece must come first, before the fprs. */
8233 if (align_words < GP_ARG_NUM_REG)
8235 unsigned long n_words = rs6000_arg_size (mode, type);
8237 if (align_words + n_words > GP_ARG_NUM_REG
8238 || (TARGET_32BIT && TARGET_POWERPC64))
8240 /* If this is partially on the stack, then we only
8241 include the portion actually in registers here. */
8242 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8245 if (align_words + n_words > GP_ARG_NUM_REG)
8246 /* Not all of the arg fits in gprs. Say that it
8247 goes in memory too, using a magic NULL_RTX
8248 component. Also see comment in
8249 rs6000_mixed_function_arg for why the normal
8250 function_arg_partial_nregs scheme doesn't work
8252 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8256 r = gen_rtx_REG (rmode,
8257 GP_ARG_MIN_REG + align_words);
8258 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8259 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8261 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8265 /* The whole arg fits in gprs. */
8266 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8267 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8271 /* It's entirely in memory. */
8272 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8275 /* Describe where this piece goes in the fprs. */
8276 r = gen_rtx_REG (fmode, cum->fregno);
8277 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8279 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8281 else if (align_words < GP_ARG_NUM_REG)
8283 if (TARGET_32BIT && TARGET_POWERPC64)
8284 return rs6000_mixed_function_arg (mode, type, align_words);
8286 if (mode == BLKmode)
8289 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8296 /* For an arg passed partly in registers and partly in memory, this is
8297 the number of bytes passed in registers. For args passed entirely in
8298 registers or entirely in memory, zero. When an arg is described by a
8299 PARALLEL, perhaps using more than one register type, this function
8300 returns the number of bytes used by the first element of the PARALLEL. */
8303 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8304 tree type, bool named)
8309 if (DEFAULT_ABI == ABI_V4)
8312 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8313 && cum->nargs_prototype >= 0)
8316 /* In this complicated case we just disable the partial_nregs code. */
8317 if (rs6000_darwin64_abi && mode == BLKmode
8318 && TREE_CODE (type) == RECORD_TYPE
8319 && int_size_in_bytes (type) > 0)
8322 align_words = rs6000_parm_start (mode, type, cum->words);
8324 if (USE_FP_FOR_ARG_P (cum, mode, type))
8326 /* If we are passing this arg in the fixed parameter save area
8327 (gprs or memory) as well as fprs, then this function should
8328 return the number of partial bytes passed in the parameter
8329 save area rather than partial bytes passed in fprs. */
8331 && (cum->nargs_prototype <= 0
8332 || (DEFAULT_ABI == ABI_AIX
8334 && align_words >= GP_ARG_NUM_REG)))
8336 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8337 > FP_ARG_MAX_REG + 1)
8338 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8339 else if (cum->nargs_prototype >= 0)
8343 if (align_words < GP_ARG_NUM_REG
8344 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8345 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8347 if (ret != 0 && TARGET_DEBUG_ARG)
8348 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8353 /* A C expression that indicates when an argument must be passed by
8354 reference. If nonzero for an argument, a copy of that argument is
8355 made in memory and a pointer to the argument is passed instead of
8356 the argument itself. The pointer is passed in whatever way is
8357 appropriate for passing a pointer to that type.
8359 Under V.4, aggregates and long double are passed by reference.
8361 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8362 reference unless the AltiVec vector extension ABI is in force.
8364 As an extension to all ABIs, variable sized types are passed by
8368 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
8369 enum machine_mode mode, const_tree type,
8370 bool named ATTRIBUTE_UNUSED)
8372 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8374 if (TARGET_DEBUG_ARG)
8375 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8382 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8384 if (TARGET_DEBUG_ARG)
8385 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8389 if (int_size_in_bytes (type) < 0)
8391 if (TARGET_DEBUG_ARG)
8392 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8396 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8397 modes only exist for GCC vector types if -maltivec. */
8398 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8400 if (TARGET_DEBUG_ARG)
8401 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8405 /* Pass synthetic vectors in memory. */
8406 if (TREE_CODE (type) == VECTOR_TYPE
8407 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8409 static bool warned_for_pass_big_vectors = false;
8410 if (TARGET_DEBUG_ARG)
8411 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8412 if (!warned_for_pass_big_vectors)
8414 warning (0, "GCC vector passed by reference: "
8415 "non-standard ABI extension with no compatibility guarantee");
8416 warned_for_pass_big_vectors = true;
8425 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8428 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8433 for (i = 0; i < nregs; i++)
8435 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8436 if (reload_completed)
8438 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8441 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8442 i * GET_MODE_SIZE (reg_mode));
8445 tem = replace_equiv_address (tem, XEXP (tem, 0));
8449 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8453 /* Perform any needed actions needed for a function that is receiving a
8454 variable number of arguments.
8458 MODE and TYPE are the mode and type of the current parameter.
8460 PRETEND_SIZE is a variable that should be set to the amount of stack
8461 that must be pushed by the prolog to pretend that our caller pushed
8464 Normally, this macro will push all remaining incoming registers on the
8465 stack and set PRETEND_SIZE to the length of the registers pushed. */
8468 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8469 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8472 CUMULATIVE_ARGS next_cum;
8473 int reg_size = TARGET_32BIT ? 4 : 8;
8474 rtx save_area = NULL_RTX, mem;
8475 int first_reg_offset;
8478 /* Skip the last named argument. */
8480 function_arg_advance (&next_cum, mode, type, 1, 0);
8482 if (DEFAULT_ABI == ABI_V4)
8484 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8488 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8489 HOST_WIDE_INT offset = 0;
8491 /* Try to optimize the size of the varargs save area.
8492 The ABI requires that ap.reg_save_area is doubleword
8493 aligned, but we don't need to allocate space for all
8494 the bytes, only those to which we actually will save
8496 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8497 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8498 if (TARGET_HARD_FLOAT && TARGET_FPRS
8499 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8500 && cfun->va_list_fpr_size)
8503 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8504 * UNITS_PER_FP_WORD;
8505 if (cfun->va_list_fpr_size
8506 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8507 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8509 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8510 * UNITS_PER_FP_WORD;
8514 offset = -((first_reg_offset * reg_size) & ~7);
8515 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8517 gpr_reg_num = cfun->va_list_gpr_size;
8518 if (reg_size == 4 && (first_reg_offset & 1))
8521 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8524 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8526 - (int) (GP_ARG_NUM_REG * reg_size);
8528 if (gpr_size + fpr_size)
8531 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8532 gcc_assert (GET_CODE (reg_save_area) == MEM);
8533 reg_save_area = XEXP (reg_save_area, 0);
8534 if (GET_CODE (reg_save_area) == PLUS)
8536 gcc_assert (XEXP (reg_save_area, 0)
8537 == virtual_stack_vars_rtx);
8538 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8539 offset += INTVAL (XEXP (reg_save_area, 1));
8542 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8545 cfun->machine->varargs_save_offset = offset;
8546 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8551 first_reg_offset = next_cum.words;
8552 save_area = virtual_incoming_args_rtx;
8554 if (targetm.calls.must_pass_in_stack (mode, type))
8555 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8558 set = get_varargs_alias_set ();
8559 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8560 && cfun->va_list_gpr_size)
8562 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8564 if (va_list_gpr_counter_field)
8566 /* V4 va_list_gpr_size counts number of registers needed. */
8567 if (nregs > cfun->va_list_gpr_size)
8568 nregs = cfun->va_list_gpr_size;
8572 /* char * va_list instead counts number of bytes needed. */
8573 if (nregs > cfun->va_list_gpr_size / reg_size)
8574 nregs = cfun->va_list_gpr_size / reg_size;
8577 mem = gen_rtx_MEM (BLKmode,
8578 plus_constant (save_area,
8579 first_reg_offset * reg_size));
8580 MEM_NOTRAP_P (mem) = 1;
8581 set_mem_alias_set (mem, set);
8582 set_mem_align (mem, BITS_PER_WORD);
8584 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8588 /* Save FP registers if needed. */
8589 if (DEFAULT_ABI == ABI_V4
8590 && TARGET_HARD_FLOAT && TARGET_FPRS
8592 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8593 && cfun->va_list_fpr_size)
8595 int fregno = next_cum.fregno, nregs;
8596 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8597 rtx lab = gen_label_rtx ();
8598 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8599 * UNITS_PER_FP_WORD);
8602 (gen_rtx_SET (VOIDmode,
8604 gen_rtx_IF_THEN_ELSE (VOIDmode,
8605 gen_rtx_NE (VOIDmode, cr1,
8607 gen_rtx_LABEL_REF (VOIDmode, lab),
8611 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8612 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8614 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8616 plus_constant (save_area, off));
8617 MEM_NOTRAP_P (mem) = 1;
8618 set_mem_alias_set (mem, set);
8619 set_mem_align (mem, GET_MODE_ALIGNMENT (
8620 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8621 ? DFmode : SFmode));
8622 emit_move_insn (mem, gen_rtx_REG (
8623 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8624 ? DFmode : SFmode, fregno));
8631 /* Create the va_list data type. */
8634 rs6000_build_builtin_va_list (void)
8636 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8638 /* For AIX, prefer 'char *' because that's what the system
8639 header files like. */
8640 if (DEFAULT_ABI != ABI_V4)
8641 return build_pointer_type (char_type_node);
8643 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8644 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8645 get_identifier ("__va_list_tag"), record);
8647 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8648 unsigned_char_type_node);
8649 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8650 unsigned_char_type_node);
8651 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8653 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8654 get_identifier ("reserved"), short_unsigned_type_node);
8655 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8656 get_identifier ("overflow_arg_area"),
8658 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8659 get_identifier ("reg_save_area"),
8662 va_list_gpr_counter_field = f_gpr;
8663 va_list_fpr_counter_field = f_fpr;
8665 DECL_FIELD_CONTEXT (f_gpr) = record;
8666 DECL_FIELD_CONTEXT (f_fpr) = record;
8667 DECL_FIELD_CONTEXT (f_res) = record;
8668 DECL_FIELD_CONTEXT (f_ovf) = record;
8669 DECL_FIELD_CONTEXT (f_sav) = record;
8671 TREE_CHAIN (record) = type_decl;
8672 TYPE_NAME (record) = type_decl;
8673 TYPE_FIELDS (record) = f_gpr;
8674 TREE_CHAIN (f_gpr) = f_fpr;
8675 TREE_CHAIN (f_fpr) = f_res;
8676 TREE_CHAIN (f_res) = f_ovf;
8677 TREE_CHAIN (f_ovf) = f_sav;
8679 layout_type (record);
8681 /* The correct type is an array type of one element. */
8682 return build_array_type (record, build_index_type (size_zero_node));
8685 /* Implement va_start. */
8688 rs6000_va_start (tree valist, rtx nextarg)
8690 HOST_WIDE_INT words, n_gpr, n_fpr;
8691 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8692 tree gpr, fpr, ovf, sav, t;
8694 /* Only SVR4 needs something special. */
8695 if (DEFAULT_ABI != ABI_V4)
8697 std_expand_builtin_va_start (valist, nextarg);
8701 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8702 f_fpr = TREE_CHAIN (f_gpr);
8703 f_res = TREE_CHAIN (f_fpr);
8704 f_ovf = TREE_CHAIN (f_res);
8705 f_sav = TREE_CHAIN (f_ovf);
8707 valist = build_va_arg_indirect_ref (valist);
8708 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8709 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8711 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8713 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8716 /* Count number of gp and fp argument registers used. */
8717 words = crtl->args.info.words;
8718 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8720 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8723 if (TARGET_DEBUG_ARG)
8724 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8725 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8726 words, n_gpr, n_fpr);
8728 if (cfun->va_list_gpr_size)
8730 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8731 build_int_cst (NULL_TREE, n_gpr));
8732 TREE_SIDE_EFFECTS (t) = 1;
8733 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8736 if (cfun->va_list_fpr_size)
8738 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8739 build_int_cst (NULL_TREE, n_fpr));
8740 TREE_SIDE_EFFECTS (t) = 1;
8741 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8744 /* Find the overflow area. */
8745 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8747 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8748 size_int (words * UNITS_PER_WORD));
8749 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8750 TREE_SIDE_EFFECTS (t) = 1;
8751 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8753 /* If there were no va_arg invocations, don't set up the register
8755 if (!cfun->va_list_gpr_size
8756 && !cfun->va_list_fpr_size
8757 && n_gpr < GP_ARG_NUM_REG
8758 && n_fpr < FP_ARG_V4_MAX_REG)
8761 /* Find the register save area. */
8762 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8763 if (cfun->machine->varargs_save_offset)
8764 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8765 size_int (cfun->machine->varargs_save_offset));
8766 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8767 TREE_SIDE_EFFECTS (t) = 1;
8768 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8771 /* Implement va_arg. */
8774 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8777 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8778 tree gpr, fpr, ovf, sav, reg, t, u;
8779 int size, rsize, n_reg, sav_ofs, sav_scale;
8780 tree lab_false, lab_over, addr;
8782 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8786 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8788 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8789 return build_va_arg_indirect_ref (t);
8792 if (DEFAULT_ABI != ABI_V4)
8794 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8796 tree elem_type = TREE_TYPE (type);
8797 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8798 int elem_size = GET_MODE_SIZE (elem_mode);
8800 if (elem_size < UNITS_PER_WORD)
8802 tree real_part, imag_part;
8803 gimple_seq post = NULL;
8805 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8807 /* Copy the value into a temporary, lest the formal temporary
8808 be reused out from under us. */
8809 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8810 gimple_seq_add_seq (pre_p, post);
8812 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8815 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8819 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8822 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8823 f_fpr = TREE_CHAIN (f_gpr);
8824 f_res = TREE_CHAIN (f_fpr);
8825 f_ovf = TREE_CHAIN (f_res);
8826 f_sav = TREE_CHAIN (f_ovf);
8828 valist = build_va_arg_indirect_ref (valist);
8829 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8830 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8832 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8834 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8837 size = int_size_in_bytes (type);
8838 rsize = (size + 3) / 4;
8841 if (TARGET_HARD_FLOAT && TARGET_FPRS
8842 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8843 || (TARGET_DOUBLE_FLOAT
8844 && (TYPE_MODE (type) == DFmode
8845 || TYPE_MODE (type) == TFmode
8846 || TYPE_MODE (type) == SDmode
8847 || TYPE_MODE (type) == DDmode
8848 || TYPE_MODE (type) == TDmode))))
8850 /* FP args go in FP registers, if present. */
8852 n_reg = (size + 7) / 8;
8853 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8854 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8855 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8860 /* Otherwise into GP registers. */
8869 /* Pull the value out of the saved registers.... */
8872 addr = create_tmp_var (ptr_type_node, "addr");
8874 /* AltiVec vectors never go in registers when -mabi=altivec. */
8875 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8879 lab_false = create_artificial_label (input_location);
8880 lab_over = create_artificial_label (input_location);
8882 /* Long long and SPE vectors are aligned in the registers.
8883 As are any other 2 gpr item such as complex int due to a
8884 historical mistake. */
8886 if (n_reg == 2 && reg == gpr)
8889 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8890 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8891 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8892 unshare_expr (reg), u);
8894 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8895 reg number is 0 for f1, so we want to make it odd. */
8896 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8898 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8899 build_int_cst (TREE_TYPE (reg), 1));
8900 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8903 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8904 t = build2 (GE_EXPR, boolean_type_node, u, t);
8905 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8906 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8907 gimplify_and_add (t, pre_p);
8911 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8913 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8914 build_int_cst (TREE_TYPE (reg), n_reg));
8915 u = fold_convert (sizetype, u);
8916 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8917 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8919 /* _Decimal32 varargs are located in the second word of the 64-bit
8920 FP register for 32-bit binaries. */
8921 if (!TARGET_POWERPC64
8922 && TARGET_HARD_FLOAT && TARGET_FPRS
8923 && TYPE_MODE (type) == SDmode)
8924 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8926 gimplify_assign (addr, t, pre_p);
8928 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8930 stmt = gimple_build_label (lab_false);
8931 gimple_seq_add_stmt (pre_p, stmt);
8933 if ((n_reg == 2 && !regalign) || n_reg > 2)
8935 /* Ensure that we don't find any more args in regs.
8936 Alignment has taken care of for special cases. */
8937 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8941 /* ... otherwise out of the overflow area. */
8943 /* Care for on-stack alignment if needed. */
8947 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8948 t = fold_convert (sizetype, t);
8949 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8951 t = fold_convert (TREE_TYPE (ovf), t);
8953 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8955 gimplify_assign (unshare_expr (addr), t, pre_p);
8957 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8958 gimplify_assign (unshare_expr (ovf), t, pre_p);
8962 stmt = gimple_build_label (lab_over);
8963 gimple_seq_add_stmt (pre_p, stmt);
8966 if (STRICT_ALIGNMENT
8967 && (TYPE_ALIGN (type)
8968 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8970 /* The value (of type complex double, for example) may not be
8971 aligned in memory in the saved registers, so copy via a
8972 temporary. (This is the same code as used for SPARC.) */
8973 tree tmp = create_tmp_var (type, "va_arg_tmp");
8974 tree dest_addr = build_fold_addr_expr (tmp);
8976 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8977 3, dest_addr, addr, size_int (rsize * 4));
8979 gimplify_and_add (copy, pre_p);
8983 addr = fold_convert (ptrtype, addr);
8984 return build_va_arg_indirect_ref (addr);
8990 def_builtin (int mask, const char *name, tree type, int code)
8992 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8995 if (rs6000_builtin_decls[code])
8996 fatal_error ("internal error: builtin function to %s already processed.",
8999 rs6000_builtin_decls[code] = t =
9000 add_builtin_function (name, type, code, BUILT_IN_MD,
9003 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9004 switch (builtin_classify[code])
9009 /* assume builtin can do anything. */
9010 case RS6000_BTC_MISC:
9013 /* const function, function only depends on the inputs. */
9014 case RS6000_BTC_CONST:
9015 TREE_READONLY (t) = 1;
9016 TREE_NOTHROW (t) = 1;
9019 /* pure function, function can read global memory. */
9020 case RS6000_BTC_PURE:
9021 DECL_PURE_P (t) = 1;
9022 TREE_NOTHROW (t) = 1;
9025 /* Function is a math function. If rounding mode is on, then treat
9026 the function as not reading global memory, but it can have
9027 arbitrary side effects. If it is off, then assume the function is
9028 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9029 attribute in builtin-attribute.def that is used for the math
9031 case RS6000_BTC_FP_PURE:
9032 TREE_NOTHROW (t) = 1;
9033 if (flag_rounding_math)
9035 DECL_PURE_P (t) = 1;
9036 DECL_IS_NOVOPS (t) = 1;
9039 TREE_READONLY (t) = 1;
9045 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9047 static const struct builtin_description bdesc_3arg[] =
9049 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9050 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9051 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9052 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9053 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9054 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9055 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9056 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9057 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9058 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9059 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9060 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9061 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9062 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9063 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9064 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9065 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9066 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9067 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9068 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9069 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9070 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9071 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9072 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9073 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9074 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9075 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9076 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9077 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9078 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9079 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9080 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9081 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9082 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9083 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9085 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9086 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9087 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9088 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9089 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9090 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9091 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9092 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9093 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9094 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9095 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9096 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9097 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9098 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9099 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9101 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9102 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9103 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9104 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9106 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9107 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9108 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9109 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9111 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9112 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9114 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9115 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9116 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9117 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9118 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9119 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9120 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9121 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9122 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9123 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9125 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9126 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9127 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9128 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9129 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9130 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9131 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9132 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9133 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9134 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9136 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9137 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9138 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9139 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9140 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9141 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9142 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9143 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9144 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9146 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9147 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9148 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9149 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9150 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9151 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9152 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9154 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9155 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9156 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9157 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9158 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9159 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9160 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9161 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9162 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9165 /* DST operations: void foo (void *, const int, const char). */
9167 static const struct builtin_description bdesc_dst[] =
9169 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9170 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9171 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9172 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9174 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9175 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9176 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9177 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9180 /* Simple binary operations: VECc = foo (VECa, VECb). */
9182 static struct builtin_description bdesc_2arg[] =
9184 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9185 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9186 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9187 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9188 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9189 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9190 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9191 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9192 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9193 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9194 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9195 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9196 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9197 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9198 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9199 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9200 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9201 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9202 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9203 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9204 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9205 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9206 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9207 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9208 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9209 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9210 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9211 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9212 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9213 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9214 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9215 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9216 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9217 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9218 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9219 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9220 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9221 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9222 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9223 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9224 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9225 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9226 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9227 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9228 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9229 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9230 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9231 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9232 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9233 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9234 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9235 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9236 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9237 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9238 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9239 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9240 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9241 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9242 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9243 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9244 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9245 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9246 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9247 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9248 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9249 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9250 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9251 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9252 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9253 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9254 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9255 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9256 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9257 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9258 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9259 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9260 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9261 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9262 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9263 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9264 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9265 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9266 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9267 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9268 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9269 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9270 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9271 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9272 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9273 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9274 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9275 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9276 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9277 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9278 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9279 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9280 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9281 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9282 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9283 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9284 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9285 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9286 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9287 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9288 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9289 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9290 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9291 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9292 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9293 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9294 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9295 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9296 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9297 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9298 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9299 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9300 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9302 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9303 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9304 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9305 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9306 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9307 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9308 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9309 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9310 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9311 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9312 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9313 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9315 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9316 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9317 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9318 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9319 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9320 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9321 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9322 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9323 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9324 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9325 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9326 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9328 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9329 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9330 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9331 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9332 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9333 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9335 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9336 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9337 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9338 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9339 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9340 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9341 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9342 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9343 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9344 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9345 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9346 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9348 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9349 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9350 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9351 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9352 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9353 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9354 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9355 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9356 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9357 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9358 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9359 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9360 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9361 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9362 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9363 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9364 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9365 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9366 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9367 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9368 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9369 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9370 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9371 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9372 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9373 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9374 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9375 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9376 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9377 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9378 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9379 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9380 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9381 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9382 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9383 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9384 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9385 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9386 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9387 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9388 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9389 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9390 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9391 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9392 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9393 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9394 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9395 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9396 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9397 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9398 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9399 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9400 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9401 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9402 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9403 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9404 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9405 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9406 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9407 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9408 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9409 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9410 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9411 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9412 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9413 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9414 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9415 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9416 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9417 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9418 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9419 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9420 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9421 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9422 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9423 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9424 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9425 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9426 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9427 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9428 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9429 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9430 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9431 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9432 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9433 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9434 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9435 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9436 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
9437 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9438 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9439 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9440 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9441 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9442 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9443 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9444 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9445 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9446 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9447 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9448 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9449 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9450 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9453 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9454 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9455 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9456 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9457 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9458 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9459 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9460 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9461 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9462 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9463 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9464 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9465 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9466 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9467 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9468 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9469 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9470 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9471 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9472 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9473 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9474 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9475 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9476 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9478 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9479 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9481 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9482 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9483 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9484 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9485 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9486 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9487 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9488 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9489 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9490 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9492 /* Place holder, leave as first spe builtin. */
9493 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9494 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9495 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9496 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9497 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9498 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9499 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9500 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9501 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9502 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9503 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9504 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9505 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9506 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9507 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9508 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9509 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9510 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9511 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9512 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9513 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9514 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9515 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9516 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9517 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9518 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9519 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9520 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9521 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9522 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9523 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9524 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9525 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9526 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9527 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9528 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9529 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9530 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9531 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9532 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9533 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9534 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9535 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9536 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9537 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9538 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9539 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9540 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9541 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9542 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9543 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9544 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9545 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9546 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9547 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9548 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9549 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9550 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9551 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9552 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9553 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9554 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9555 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9556 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9557 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9558 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9559 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9560 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9561 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9562 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9563 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9564 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9565 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9566 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9567 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9568 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9569 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9570 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9571 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9572 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9573 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9574 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9575 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9576 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9577 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9578 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9579 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9580 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9581 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9582 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9583 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9584 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9585 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9586 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9587 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9588 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9589 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9590 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9591 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9592 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9593 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9594 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9595 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9596 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9597 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9598 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9599 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9600 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9601 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9603 /* SPE binary operations expecting a 5-bit unsigned literal. */
9604 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9606 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9607 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9608 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9609 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9610 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9611 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9612 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9613 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9614 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9615 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9616 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9617 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9618 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9619 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9620 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9621 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9622 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9623 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9624 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9625 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9626 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9627 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9628 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9629 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9630 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9631 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9633 /* Place-holder. Leave as last binary SPE builtin. */
9634 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9637 /* AltiVec predicates. */
9639 struct builtin_description_predicates
9641 const unsigned int mask;
9642 const enum insn_code icode;
9643 const char *const name;
9644 const enum rs6000_builtins code;
9647 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9649 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9650 ALTIVEC_BUILTIN_VCMPBFP_P },
9651 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9652 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9653 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9654 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9655 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9656 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9657 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9658 ALTIVEC_BUILTIN_VCMPEQUW_P },
9659 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9660 ALTIVEC_BUILTIN_VCMPGTSW_P },
9661 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9662 ALTIVEC_BUILTIN_VCMPGTUW_P },
9663 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9664 ALTIVEC_BUILTIN_VCMPEQUH_P },
9665 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9666 ALTIVEC_BUILTIN_VCMPGTSH_P },
9667 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9668 ALTIVEC_BUILTIN_VCMPGTUH_P },
9669 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9670 ALTIVEC_BUILTIN_VCMPEQUB_P },
9671 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9672 ALTIVEC_BUILTIN_VCMPGTSB_P },
9673 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9674 ALTIVEC_BUILTIN_VCMPGTUB_P },
9676 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9677 VSX_BUILTIN_XVCMPEQSP_P },
9678 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9679 VSX_BUILTIN_XVCMPGESP_P },
9680 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9681 VSX_BUILTIN_XVCMPGTSP_P },
9682 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9683 VSX_BUILTIN_XVCMPEQDP_P },
9684 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9685 VSX_BUILTIN_XVCMPGEDP_P },
9686 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9687 VSX_BUILTIN_XVCMPGTDP_P },
9689 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9690 ALTIVEC_BUILTIN_VCMPEQ_P },
9691 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9692 ALTIVEC_BUILTIN_VCMPGT_P },
9693 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9694 ALTIVEC_BUILTIN_VCMPGE_P }
9697 /* SPE predicates. */
9698 static struct builtin_description bdesc_spe_predicates[] =
9700 /* Place-holder. Leave as first. */
9701 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9702 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9703 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9704 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9705 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9706 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9707 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9708 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9709 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9710 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9711 /* Place-holder. Leave as last. */
9712 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9715 /* SPE evsel predicates. */
9716 static struct builtin_description bdesc_spe_evsel[] =
9718 /* Place-holder. Leave as first. */
9719 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9720 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9721 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9722 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9723 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9724 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9725 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9726 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9727 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9728 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9729 /* Place-holder. Leave as last. */
9730 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9733 /* PAIRED predicates. */
9734 static const struct builtin_description bdesc_paired_preds[] =
9736 /* Place-holder. Leave as first. */
9737 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9738 /* Place-holder. Leave as last. */
9739 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9742 /* ABS* operations. */
9744 static const struct builtin_description bdesc_abs[] =
9746 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9747 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9748 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9749 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9750 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9751 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9752 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9753 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9754 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9755 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9756 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9759 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9762 static struct builtin_description bdesc_1arg[] =
9764 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9765 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9766 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9767 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9768 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9769 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9770 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9771 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
9772 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9773 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9774 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9775 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9776 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9777 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9778 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9779 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9780 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9781 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9783 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9784 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9785 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
9786 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9787 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9788 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9789 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9791 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9792 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9793 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
9794 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9795 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9796 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9797 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9799 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9800 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9801 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9802 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9803 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9804 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9806 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9807 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9808 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9809 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9810 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9811 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9813 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9814 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9815 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9816 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9818 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9819 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9820 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9821 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9822 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9823 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9824 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9825 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9826 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9828 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9829 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9830 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9831 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9832 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9833 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9834 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9835 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9836 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9838 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9839 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9840 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9841 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9842 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9844 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9845 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9846 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9847 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9848 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9849 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9850 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9851 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9852 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9853 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
9854 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9855 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9856 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9857 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9858 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9859 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9860 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9861 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9862 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9863 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9865 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9866 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9867 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9869 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9870 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9871 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9872 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9874 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9875 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9876 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9877 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9878 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9879 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9880 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9881 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9882 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9883 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9884 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9885 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9886 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9887 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9888 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9889 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9890 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9891 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9892 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9893 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9894 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9895 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9896 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9897 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9898 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9899 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9900 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9901 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9902 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9903 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9905 /* Place-holder. Leave as last unary SPE builtin. */
9906 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9908 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9909 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9910 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9911 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9912 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9916 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9919 tree arg0 = CALL_EXPR_ARG (exp, 0);
9920 rtx op0 = expand_normal (arg0);
9921 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9922 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9924 if (icode == CODE_FOR_nothing)
9925 /* Builtin not supported on this processor. */
9928 /* If we got invalid arguments bail out before generating bad rtl. */
9929 if (arg0 == error_mark_node)
9932 if (icode == CODE_FOR_altivec_vspltisb
9933 || icode == CODE_FOR_altivec_vspltish
9934 || icode == CODE_FOR_altivec_vspltisw
9935 || icode == CODE_FOR_spe_evsplatfi
9936 || icode == CODE_FOR_spe_evsplati)
9938 /* Only allow 5-bit *signed* literals. */
9939 if (GET_CODE (op0) != CONST_INT
9940 || INTVAL (op0) > 15
9941 || INTVAL (op0) < -16)
9943 error ("argument 1 must be a 5-bit signed literal");
9949 || GET_MODE (target) != tmode
9950 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9951 target = gen_reg_rtx (tmode);
9953 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9954 op0 = copy_to_mode_reg (mode0, op0);
9956 pat = GEN_FCN (icode) (target, op0);
9965 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9967 rtx pat, scratch1, scratch2;
9968 tree arg0 = CALL_EXPR_ARG (exp, 0);
9969 rtx op0 = expand_normal (arg0);
9970 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9971 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9973 /* If we have invalid arguments, bail out before generating bad rtl. */
9974 if (arg0 == error_mark_node)
9978 || GET_MODE (target) != tmode
9979 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9980 target = gen_reg_rtx (tmode);
9982 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9983 op0 = copy_to_mode_reg (mode0, op0);
9985 scratch1 = gen_reg_rtx (mode0);
9986 scratch2 = gen_reg_rtx (mode0);
9988 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9997 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10000 tree arg0 = CALL_EXPR_ARG (exp, 0);
10001 tree arg1 = CALL_EXPR_ARG (exp, 1);
10002 rtx op0 = expand_normal (arg0);
10003 rtx op1 = expand_normal (arg1);
10004 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10005 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10006 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10008 if (icode == CODE_FOR_nothing)
10009 /* Builtin not supported on this processor. */
10012 /* If we got invalid arguments bail out before generating bad rtl. */
10013 if (arg0 == error_mark_node || arg1 == error_mark_node)
10016 if (icode == CODE_FOR_altivec_vcfux
10017 || icode == CODE_FOR_altivec_vcfsx
10018 || icode == CODE_FOR_altivec_vctsxs
10019 || icode == CODE_FOR_altivec_vctuxs
10020 || icode == CODE_FOR_altivec_vspltb
10021 || icode == CODE_FOR_altivec_vsplth
10022 || icode == CODE_FOR_altivec_vspltw
10023 || icode == CODE_FOR_spe_evaddiw
10024 || icode == CODE_FOR_spe_evldd
10025 || icode == CODE_FOR_spe_evldh
10026 || icode == CODE_FOR_spe_evldw
10027 || icode == CODE_FOR_spe_evlhhesplat
10028 || icode == CODE_FOR_spe_evlhhossplat
10029 || icode == CODE_FOR_spe_evlhhousplat
10030 || icode == CODE_FOR_spe_evlwhe
10031 || icode == CODE_FOR_spe_evlwhos
10032 || icode == CODE_FOR_spe_evlwhou
10033 || icode == CODE_FOR_spe_evlwhsplat
10034 || icode == CODE_FOR_spe_evlwwsplat
10035 || icode == CODE_FOR_spe_evrlwi
10036 || icode == CODE_FOR_spe_evslwi
10037 || icode == CODE_FOR_spe_evsrwis
10038 || icode == CODE_FOR_spe_evsubifw
10039 || icode == CODE_FOR_spe_evsrwiu)
10041 /* Only allow 5-bit unsigned literals. */
10043 if (TREE_CODE (arg1) != INTEGER_CST
10044 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10046 error ("argument 2 must be a 5-bit unsigned literal");
10052 || GET_MODE (target) != tmode
10053 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10054 target = gen_reg_rtx (tmode);
10056 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10057 op0 = copy_to_mode_reg (mode0, op0);
10058 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10059 op1 = copy_to_mode_reg (mode1, op1);
10061 pat = GEN_FCN (icode) (target, op0, op1);
10070 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10073 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10074 tree arg0 = CALL_EXPR_ARG (exp, 1);
10075 tree arg1 = CALL_EXPR_ARG (exp, 2);
10076 rtx op0 = expand_normal (arg0);
10077 rtx op1 = expand_normal (arg1);
10078 enum machine_mode tmode = SImode;
10079 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10080 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10083 if (TREE_CODE (cr6_form) != INTEGER_CST)
10085 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10089 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10091 gcc_assert (mode0 == mode1);
10093 /* If we have invalid arguments, bail out before generating bad rtl. */
10094 if (arg0 == error_mark_node || arg1 == error_mark_node)
10098 || GET_MODE (target) != tmode
10099 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10100 target = gen_reg_rtx (tmode);
10102 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10103 op0 = copy_to_mode_reg (mode0, op0);
10104 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10105 op1 = copy_to_mode_reg (mode1, op1);
10107 scratch = gen_reg_rtx (mode0);
10109 pat = GEN_FCN (icode) (scratch, op0, op1);
10114 /* The vec_any* and vec_all* predicates use the same opcodes for two
10115 different operations, but the bits in CR6 will be different
10116 depending on what information we want. So we have to play tricks
10117 with CR6 to get the right bits out.
10119 If you think this is disgusting, look at the specs for the
10120 AltiVec predicates. */
10122 switch (cr6_form_int)
10125 emit_insn (gen_cr6_test_for_zero (target));
10128 emit_insn (gen_cr6_test_for_zero_reverse (target));
10131 emit_insn (gen_cr6_test_for_lt (target));
10134 emit_insn (gen_cr6_test_for_lt_reverse (target));
10137 error ("argument 1 of __builtin_altivec_predicate is out of range");
10145 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10148 tree arg0 = CALL_EXPR_ARG (exp, 0);
10149 tree arg1 = CALL_EXPR_ARG (exp, 1);
10150 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10151 enum machine_mode mode0 = Pmode;
10152 enum machine_mode mode1 = Pmode;
10153 rtx op0 = expand_normal (arg0);
10154 rtx op1 = expand_normal (arg1);
10156 if (icode == CODE_FOR_nothing)
10157 /* Builtin not supported on this processor. */
10160 /* If we got invalid arguments bail out before generating bad rtl. */
10161 if (arg0 == error_mark_node || arg1 == error_mark_node)
10165 || GET_MODE (target) != tmode
10166 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10167 target = gen_reg_rtx (tmode);
10169 op1 = copy_to_mode_reg (mode1, op1);
10171 if (op0 == const0_rtx)
10173 addr = gen_rtx_MEM (tmode, op1);
10177 op0 = copy_to_mode_reg (mode0, op0);
10178 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10181 pat = GEN_FCN (icode) (target, addr);
10191 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10194 tree arg0 = CALL_EXPR_ARG (exp, 0);
10195 tree arg1 = CALL_EXPR_ARG (exp, 1);
10196 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10197 enum machine_mode mode0 = Pmode;
10198 enum machine_mode mode1 = Pmode;
10199 rtx op0 = expand_normal (arg0);
10200 rtx op1 = expand_normal (arg1);
10202 if (icode == CODE_FOR_nothing)
10203 /* Builtin not supported on this processor. */
10206 /* If we got invalid arguments bail out before generating bad rtl. */
10207 if (arg0 == error_mark_node || arg1 == error_mark_node)
10211 || GET_MODE (target) != tmode
10212 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10213 target = gen_reg_rtx (tmode);
10215 op1 = copy_to_mode_reg (mode1, op1);
10217 if (op0 == const0_rtx)
10219 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10223 op0 = copy_to_mode_reg (mode0, op0);
10224 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10227 pat = GEN_FCN (icode) (target, addr);
10237 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10239 tree arg0 = CALL_EXPR_ARG (exp, 0);
10240 tree arg1 = CALL_EXPR_ARG (exp, 1);
10241 tree arg2 = CALL_EXPR_ARG (exp, 2);
10242 rtx op0 = expand_normal (arg0);
10243 rtx op1 = expand_normal (arg1);
10244 rtx op2 = expand_normal (arg2);
10246 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10247 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10248 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10250 /* Invalid arguments. Bail before doing anything stoopid! */
10251 if (arg0 == error_mark_node
10252 || arg1 == error_mark_node
10253 || arg2 == error_mark_node)
10256 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10257 op0 = copy_to_mode_reg (mode2, op0);
10258 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10259 op1 = copy_to_mode_reg (mode0, op1);
10260 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10261 op2 = copy_to_mode_reg (mode1, op2);
10263 pat = GEN_FCN (icode) (op1, op2, op0);
10270 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10272 tree arg0 = CALL_EXPR_ARG (exp, 0);
10273 tree arg1 = CALL_EXPR_ARG (exp, 1);
10274 tree arg2 = CALL_EXPR_ARG (exp, 2);
10275 rtx op0 = expand_normal (arg0);
10276 rtx op1 = expand_normal (arg1);
10277 rtx op2 = expand_normal (arg2);
10279 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10280 enum machine_mode mode1 = Pmode;
10281 enum machine_mode mode2 = Pmode;
10283 /* Invalid arguments. Bail before doing anything stoopid! */
10284 if (arg0 == error_mark_node
10285 || arg1 == error_mark_node
10286 || arg2 == error_mark_node)
10289 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10290 op0 = copy_to_mode_reg (tmode, op0);
10292 op2 = copy_to_mode_reg (mode2, op2);
10294 if (op1 == const0_rtx)
10296 addr = gen_rtx_MEM (tmode, op2);
10300 op1 = copy_to_mode_reg (mode1, op1);
10301 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10304 pat = GEN_FCN (icode) (addr, op0);
10311 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10313 tree arg0 = CALL_EXPR_ARG (exp, 0);
10314 tree arg1 = CALL_EXPR_ARG (exp, 1);
10315 tree arg2 = CALL_EXPR_ARG (exp, 2);
10316 rtx op0 = expand_normal (arg0);
10317 rtx op1 = expand_normal (arg1);
10318 rtx op2 = expand_normal (arg2);
10320 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10321 enum machine_mode mode1 = Pmode;
10322 enum machine_mode mode2 = Pmode;
10324 /* Invalid arguments. Bail before doing anything stoopid! */
10325 if (arg0 == error_mark_node
10326 || arg1 == error_mark_node
10327 || arg2 == error_mark_node)
10330 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10331 op0 = copy_to_mode_reg (tmode, op0);
10333 op2 = copy_to_mode_reg (mode2, op2);
10335 if (op1 == const0_rtx)
10337 addr = gen_rtx_MEM (tmode, op2);
10341 op1 = copy_to_mode_reg (mode1, op1);
10342 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10345 pat = GEN_FCN (icode) (addr, op0);
10352 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10355 tree arg0 = CALL_EXPR_ARG (exp, 0);
10356 tree arg1 = CALL_EXPR_ARG (exp, 1);
10357 tree arg2 = CALL_EXPR_ARG (exp, 2);
10358 rtx op0 = expand_normal (arg0);
10359 rtx op1 = expand_normal (arg1);
10360 rtx op2 = expand_normal (arg2);
10361 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10362 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10363 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10364 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10366 if (icode == CODE_FOR_nothing)
10367 /* Builtin not supported on this processor. */
10370 /* If we got invalid arguments bail out before generating bad rtl. */
10371 if (arg0 == error_mark_node
10372 || arg1 == error_mark_node
10373 || arg2 == error_mark_node)
10378 case CODE_FOR_altivec_vsldoi_v4sf:
10379 case CODE_FOR_altivec_vsldoi_v4si:
10380 case CODE_FOR_altivec_vsldoi_v8hi:
10381 case CODE_FOR_altivec_vsldoi_v16qi:
10382 /* Only allow 4-bit unsigned literals. */
10384 if (TREE_CODE (arg2) != INTEGER_CST
10385 || TREE_INT_CST_LOW (arg2) & ~0xf)
10387 error ("argument 3 must be a 4-bit unsigned literal");
10392 case CODE_FOR_vsx_xxpermdi_v2df:
10393 case CODE_FOR_vsx_xxpermdi_v2di:
10394 case CODE_FOR_vsx_xxsldwi_v16qi:
10395 case CODE_FOR_vsx_xxsldwi_v8hi:
10396 case CODE_FOR_vsx_xxsldwi_v4si:
10397 case CODE_FOR_vsx_xxsldwi_v4sf:
10398 case CODE_FOR_vsx_xxsldwi_v2di:
10399 case CODE_FOR_vsx_xxsldwi_v2df:
10400 /* Only allow 2-bit unsigned literals. */
10402 if (TREE_CODE (arg2) != INTEGER_CST
10403 || TREE_INT_CST_LOW (arg2) & ~0x3)
10405 error ("argument 3 must be a 2-bit unsigned literal");
10410 case CODE_FOR_vsx_set_v2df:
10411 case CODE_FOR_vsx_set_v2di:
10412 /* Only allow 1-bit unsigned literals. */
10414 if (TREE_CODE (arg2) != INTEGER_CST
10415 || TREE_INT_CST_LOW (arg2) & ~0x1)
10417 error ("argument 3 must be a 1-bit unsigned literal");
10427 || GET_MODE (target) != tmode
10428 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10429 target = gen_reg_rtx (tmode);
10431 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10432 op0 = copy_to_mode_reg (mode0, op0);
10433 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10434 op1 = copy_to_mode_reg (mode1, op1);
10435 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10436 op2 = copy_to_mode_reg (mode2, op2);
10438 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10439 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10441 pat = GEN_FCN (icode) (target, op0, op1, op2);
10449 /* Expand the lvx builtins. */
10451 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10453 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10454 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10456 enum machine_mode tmode, mode0;
10458 enum insn_code icode;
10462 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10463 icode = CODE_FOR_vector_load_v16qi;
10465 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10466 icode = CODE_FOR_vector_load_v8hi;
10468 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10469 icode = CODE_FOR_vector_load_v4si;
10471 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10472 icode = CODE_FOR_vector_load_v4sf;
10475 *expandedp = false;
10481 arg0 = CALL_EXPR_ARG (exp, 0);
10482 op0 = expand_normal (arg0);
10483 tmode = insn_data[icode].operand[0].mode;
10484 mode0 = insn_data[icode].operand[1].mode;
10487 || GET_MODE (target) != tmode
10488 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10489 target = gen_reg_rtx (tmode);
10491 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10492 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10494 pat = GEN_FCN (icode) (target, op0);
10501 /* Expand the stvx builtins. */
10503 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10506 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10507 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10509 enum machine_mode mode0, mode1;
10511 enum insn_code icode;
10515 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10516 icode = CODE_FOR_vector_store_v16qi;
10518 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10519 icode = CODE_FOR_vector_store_v8hi;
10521 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10522 icode = CODE_FOR_vector_store_v4si;
10524 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10525 icode = CODE_FOR_vector_store_v4sf;
10528 *expandedp = false;
10532 arg0 = CALL_EXPR_ARG (exp, 0);
10533 arg1 = CALL_EXPR_ARG (exp, 1);
10534 op0 = expand_normal (arg0);
10535 op1 = expand_normal (arg1);
10536 mode0 = insn_data[icode].operand[0].mode;
10537 mode1 = insn_data[icode].operand[1].mode;
10539 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10540 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10541 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10542 op1 = copy_to_mode_reg (mode1, op1);
10544 pat = GEN_FCN (icode) (op0, op1);
10552 /* Expand the dst builtins. */
10554 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10557 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10558 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10559 tree arg0, arg1, arg2;
10560 enum machine_mode mode0, mode1;
10561 rtx pat, op0, op1, op2;
10562 const struct builtin_description *d;
10565 *expandedp = false;
10567 /* Handle DST variants. */
10569 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10570 if (d->code == fcode)
10572 arg0 = CALL_EXPR_ARG (exp, 0);
10573 arg1 = CALL_EXPR_ARG (exp, 1);
10574 arg2 = CALL_EXPR_ARG (exp, 2);
10575 op0 = expand_normal (arg0);
10576 op1 = expand_normal (arg1);
10577 op2 = expand_normal (arg2);
10578 mode0 = insn_data[d->icode].operand[0].mode;
10579 mode1 = insn_data[d->icode].operand[1].mode;
10581 /* Invalid arguments, bail out before generating bad rtl. */
10582 if (arg0 == error_mark_node
10583 || arg1 == error_mark_node
10584 || arg2 == error_mark_node)
10589 if (TREE_CODE (arg2) != INTEGER_CST
10590 || TREE_INT_CST_LOW (arg2) & ~0x3)
10592 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10596 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10597 op0 = copy_to_mode_reg (Pmode, op0);
10598 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10599 op1 = copy_to_mode_reg (mode1, op1);
10601 pat = GEN_FCN (d->icode) (op0, op1, op2);
10611 /* Expand vec_init builtin. */
10613 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10615 enum machine_mode tmode = TYPE_MODE (type);
10616 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10617 int i, n_elt = GET_MODE_NUNITS (tmode);
10618 rtvec v = rtvec_alloc (n_elt);
10620 gcc_assert (VECTOR_MODE_P (tmode));
10621 gcc_assert (n_elt == call_expr_nargs (exp));
10623 for (i = 0; i < n_elt; ++i)
10625 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10626 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10629 if (!target || !register_operand (target, tmode))
10630 target = gen_reg_rtx (tmode);
10632 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10636 /* Return the integer constant in ARG. Constrain it to be in the range
10637 of the subparts of VEC_TYPE; issue an error if not. */
10640 get_element_number (tree vec_type, tree arg)
10642 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10644 if (!host_integerp (arg, 1)
10645 || (elt = tree_low_cst (arg, 1), elt > max))
10647 error ("selector must be an integer constant in the range 0..%wi", max);
10654 /* Expand vec_set builtin. */
10656 altivec_expand_vec_set_builtin (tree exp)
10658 enum machine_mode tmode, mode1;
10659 tree arg0, arg1, arg2;
10663 arg0 = CALL_EXPR_ARG (exp, 0);
10664 arg1 = CALL_EXPR_ARG (exp, 1);
10665 arg2 = CALL_EXPR_ARG (exp, 2);
10667 tmode = TYPE_MODE (TREE_TYPE (arg0));
10668 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10669 gcc_assert (VECTOR_MODE_P (tmode));
10671 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10672 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10673 elt = get_element_number (TREE_TYPE (arg0), arg2);
10675 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10676 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10678 op0 = force_reg (tmode, op0);
10679 op1 = force_reg (mode1, op1);
10681 rs6000_expand_vector_set (op0, op1, elt);
10686 /* Expand vec_ext builtin. */
10688 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10690 enum machine_mode tmode, mode0;
10695 arg0 = CALL_EXPR_ARG (exp, 0);
10696 arg1 = CALL_EXPR_ARG (exp, 1);
10698 op0 = expand_normal (arg0);
10699 elt = get_element_number (TREE_TYPE (arg0), arg1);
10701 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10702 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10703 gcc_assert (VECTOR_MODE_P (mode0));
10705 op0 = force_reg (mode0, op0);
10707 if (optimize || !target || !register_operand (target, tmode))
10708 target = gen_reg_rtx (tmode);
10710 rs6000_expand_vector_extract (target, op0, elt);
10715 /* Expand the builtin in EXP and store the result in TARGET. Store
10716 true in *EXPANDEDP if we found a builtin to expand. */
10718 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10720 const struct builtin_description *d;
10721 const struct builtin_description_predicates *dp;
10723 enum insn_code icode;
10724 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10727 enum machine_mode tmode, mode0;
10728 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10730 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10731 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10732 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10733 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10736 error ("unresolved overload for Altivec builtin %qF", fndecl);
10740 target = altivec_expand_ld_builtin (exp, target, expandedp);
10744 target = altivec_expand_st_builtin (exp, target, expandedp);
10748 target = altivec_expand_dst_builtin (exp, target, expandedp);
10756 case ALTIVEC_BUILTIN_STVX:
10757 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10758 case ALTIVEC_BUILTIN_STVEBX:
10759 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10760 case ALTIVEC_BUILTIN_STVEHX:
10761 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10762 case ALTIVEC_BUILTIN_STVEWX:
10763 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10764 case ALTIVEC_BUILTIN_STVXL:
10765 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10767 case ALTIVEC_BUILTIN_STVLX:
10768 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10769 case ALTIVEC_BUILTIN_STVLXL:
10770 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10771 case ALTIVEC_BUILTIN_STVRX:
10772 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10773 case ALTIVEC_BUILTIN_STVRXL:
10774 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10776 case ALTIVEC_BUILTIN_MFVSCR:
10777 icode = CODE_FOR_altivec_mfvscr;
10778 tmode = insn_data[icode].operand[0].mode;
10781 || GET_MODE (target) != tmode
10782 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10783 target = gen_reg_rtx (tmode);
10785 pat = GEN_FCN (icode) (target);
10791 case ALTIVEC_BUILTIN_MTVSCR:
10792 icode = CODE_FOR_altivec_mtvscr;
10793 arg0 = CALL_EXPR_ARG (exp, 0);
10794 op0 = expand_normal (arg0);
10795 mode0 = insn_data[icode].operand[0].mode;
10797 /* If we got invalid arguments bail out before generating bad rtl. */
10798 if (arg0 == error_mark_node)
10801 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10802 op0 = copy_to_mode_reg (mode0, op0);
10804 pat = GEN_FCN (icode) (op0);
10809 case ALTIVEC_BUILTIN_DSSALL:
10810 emit_insn (gen_altivec_dssall ());
10813 case ALTIVEC_BUILTIN_DSS:
10814 icode = CODE_FOR_altivec_dss;
10815 arg0 = CALL_EXPR_ARG (exp, 0);
10817 op0 = expand_normal (arg0);
10818 mode0 = insn_data[icode].operand[0].mode;
10820 /* If we got invalid arguments bail out before generating bad rtl. */
10821 if (arg0 == error_mark_node)
10824 if (TREE_CODE (arg0) != INTEGER_CST
10825 || TREE_INT_CST_LOW (arg0) & ~0x3)
10827 error ("argument to dss must be a 2-bit unsigned literal");
10831 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10832 op0 = copy_to_mode_reg (mode0, op0);
10834 emit_insn (gen_altivec_dss (op0));
10837 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10838 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10839 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10840 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10841 case VSX_BUILTIN_VEC_INIT_V2DF:
10842 case VSX_BUILTIN_VEC_INIT_V2DI:
10843 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10845 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10846 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10847 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10848 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10849 case VSX_BUILTIN_VEC_SET_V2DF:
10850 case VSX_BUILTIN_VEC_SET_V2DI:
10851 return altivec_expand_vec_set_builtin (exp);
10853 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10854 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10855 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10856 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10857 case VSX_BUILTIN_VEC_EXT_V2DF:
10858 case VSX_BUILTIN_VEC_EXT_V2DI:
10859 return altivec_expand_vec_ext_builtin (exp, target);
10863 /* Fall through. */
10866 /* Expand abs* operations. */
10868 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10869 if (d->code == fcode)
10870 return altivec_expand_abs_builtin (d->icode, exp, target);
10872 /* Expand the AltiVec predicates. */
10873 dp = bdesc_altivec_preds;
10874 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10875 if (dp->code == fcode)
10876 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10878 /* LV* are funky. We initialized them differently. */
10881 case ALTIVEC_BUILTIN_LVSL:
10882 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10883 exp, target, false);
10884 case ALTIVEC_BUILTIN_LVSR:
10885 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10886 exp, target, false);
10887 case ALTIVEC_BUILTIN_LVEBX:
10888 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10889 exp, target, false);
10890 case ALTIVEC_BUILTIN_LVEHX:
10891 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10892 exp, target, false);
10893 case ALTIVEC_BUILTIN_LVEWX:
10894 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10895 exp, target, false);
10896 case ALTIVEC_BUILTIN_LVXL:
10897 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10898 exp, target, false);
10899 case ALTIVEC_BUILTIN_LVX:
10900 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10901 exp, target, false);
10902 case ALTIVEC_BUILTIN_LVLX:
10903 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10904 exp, target, true);
10905 case ALTIVEC_BUILTIN_LVLXL:
10906 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10907 exp, target, true);
10908 case ALTIVEC_BUILTIN_LVRX:
10909 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10910 exp, target, true);
10911 case ALTIVEC_BUILTIN_LVRXL:
10912 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10913 exp, target, true);
10916 /* Fall through. */
10919 *expandedp = false;
10923 /* Expand the builtin in EXP and store the result in TARGET. Store
10924 true in *EXPANDEDP if we found a builtin to expand. */
10926 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10928 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10929 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10930 const struct builtin_description *d;
10937 case PAIRED_BUILTIN_STX:
10938 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10939 case PAIRED_BUILTIN_LX:
10940 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10943 /* Fall through. */
10946 /* Expand the paired predicates. */
10947 d = bdesc_paired_preds;
10948 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10949 if (d->code == fcode)
10950 return paired_expand_predicate_builtin (d->icode, exp, target);
10952 *expandedp = false;
10956 /* Binops that need to be initialized manually, but can be expanded
10957 automagically by rs6000_expand_binop_builtin. */
10958 static struct builtin_description bdesc_2arg_spe[] =
10960 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10961 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10962 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10963 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10964 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10965 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10966 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10967 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10968 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10969 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10970 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10971 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10972 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10973 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10974 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10975 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10976 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10977 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10978 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10979 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10980 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10981 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10984 /* Expand the builtin in EXP and store the result in TARGET. Store
10985 true in *EXPANDEDP if we found a builtin to expand.
10987 This expands the SPE builtins that are not simple unary and binary
10990 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10992 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10994 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10995 enum insn_code icode;
10996 enum machine_mode tmode, mode0;
10998 struct builtin_description *d;
11003 /* Syntax check for a 5-bit unsigned immediate. */
11006 case SPE_BUILTIN_EVSTDD:
11007 case SPE_BUILTIN_EVSTDH:
11008 case SPE_BUILTIN_EVSTDW:
11009 case SPE_BUILTIN_EVSTWHE:
11010 case SPE_BUILTIN_EVSTWHO:
11011 case SPE_BUILTIN_EVSTWWE:
11012 case SPE_BUILTIN_EVSTWWO:
11013 arg1 = CALL_EXPR_ARG (exp, 2);
11014 if (TREE_CODE (arg1) != INTEGER_CST
11015 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11017 error ("argument 2 must be a 5-bit unsigned literal");
11025 /* The evsplat*i instructions are not quite generic. */
11028 case SPE_BUILTIN_EVSPLATFI:
11029 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11031 case SPE_BUILTIN_EVSPLATI:
11032 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11038 d = (struct builtin_description *) bdesc_2arg_spe;
11039 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11040 if (d->code == fcode)
11041 return rs6000_expand_binop_builtin (d->icode, exp, target);
11043 d = (struct builtin_description *) bdesc_spe_predicates;
11044 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11045 if (d->code == fcode)
11046 return spe_expand_predicate_builtin (d->icode, exp, target);
11048 d = (struct builtin_description *) bdesc_spe_evsel;
11049 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11050 if (d->code == fcode)
11051 return spe_expand_evsel_builtin (d->icode, exp, target);
11055 case SPE_BUILTIN_EVSTDDX:
11056 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11057 case SPE_BUILTIN_EVSTDHX:
11058 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11059 case SPE_BUILTIN_EVSTDWX:
11060 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11061 case SPE_BUILTIN_EVSTWHEX:
11062 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11063 case SPE_BUILTIN_EVSTWHOX:
11064 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11065 case SPE_BUILTIN_EVSTWWEX:
11066 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11067 case SPE_BUILTIN_EVSTWWOX:
11068 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11069 case SPE_BUILTIN_EVSTDD:
11070 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11071 case SPE_BUILTIN_EVSTDH:
11072 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11073 case SPE_BUILTIN_EVSTDW:
11074 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11075 case SPE_BUILTIN_EVSTWHE:
11076 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11077 case SPE_BUILTIN_EVSTWHO:
11078 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11079 case SPE_BUILTIN_EVSTWWE:
11080 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11081 case SPE_BUILTIN_EVSTWWO:
11082 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11083 case SPE_BUILTIN_MFSPEFSCR:
11084 icode = CODE_FOR_spe_mfspefscr;
11085 tmode = insn_data[icode].operand[0].mode;
11088 || GET_MODE (target) != tmode
11089 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11090 target = gen_reg_rtx (tmode);
11092 pat = GEN_FCN (icode) (target);
11097 case SPE_BUILTIN_MTSPEFSCR:
11098 icode = CODE_FOR_spe_mtspefscr;
11099 arg0 = CALL_EXPR_ARG (exp, 0);
11100 op0 = expand_normal (arg0);
11101 mode0 = insn_data[icode].operand[0].mode;
11103 if (arg0 == error_mark_node)
11106 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11107 op0 = copy_to_mode_reg (mode0, op0);
11109 pat = GEN_FCN (icode) (op0);
11117 *expandedp = false;
11122 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11124 rtx pat, scratch, tmp;
11125 tree form = CALL_EXPR_ARG (exp, 0);
11126 tree arg0 = CALL_EXPR_ARG (exp, 1);
11127 tree arg1 = CALL_EXPR_ARG (exp, 2);
11128 rtx op0 = expand_normal (arg0);
11129 rtx op1 = expand_normal (arg1);
11130 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11131 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11133 enum rtx_code code;
11135 if (TREE_CODE (form) != INTEGER_CST)
11137 error ("argument 1 of __builtin_paired_predicate must be a constant");
11141 form_int = TREE_INT_CST_LOW (form);
11143 gcc_assert (mode0 == mode1);
11145 if (arg0 == error_mark_node || arg1 == error_mark_node)
11149 || GET_MODE (target) != SImode
11150 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11151 target = gen_reg_rtx (SImode);
11152 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11153 op0 = copy_to_mode_reg (mode0, op0);
11154 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11155 op1 = copy_to_mode_reg (mode1, op1);
11157 scratch = gen_reg_rtx (CCFPmode);
11159 pat = GEN_FCN (icode) (scratch, op0, op1);
11181 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11184 error ("argument 1 of __builtin_paired_predicate is out of range");
11188 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11189 emit_move_insn (target, tmp);
11194 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11196 rtx pat, scratch, tmp;
11197 tree form = CALL_EXPR_ARG (exp, 0);
11198 tree arg0 = CALL_EXPR_ARG (exp, 1);
11199 tree arg1 = CALL_EXPR_ARG (exp, 2);
11200 rtx op0 = expand_normal (arg0);
11201 rtx op1 = expand_normal (arg1);
11202 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11203 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11205 enum rtx_code code;
11207 if (TREE_CODE (form) != INTEGER_CST)
11209 error ("argument 1 of __builtin_spe_predicate must be a constant");
11213 form_int = TREE_INT_CST_LOW (form);
11215 gcc_assert (mode0 == mode1);
11217 if (arg0 == error_mark_node || arg1 == error_mark_node)
11221 || GET_MODE (target) != SImode
11222 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11223 target = gen_reg_rtx (SImode);
11225 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11226 op0 = copy_to_mode_reg (mode0, op0);
11227 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11228 op1 = copy_to_mode_reg (mode1, op1);
11230 scratch = gen_reg_rtx (CCmode);
11232 pat = GEN_FCN (icode) (scratch, op0, op1);
11237 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11238 _lower_. We use one compare, but look in different bits of the
11239 CR for each variant.
11241 There are 2 elements in each SPE simd type (upper/lower). The CR
11242 bits are set as follows:
11244 BIT0 | BIT 1 | BIT 2 | BIT 3
11245 U | L | (U | L) | (U & L)
11247 So, for an "all" relationship, BIT 3 would be set.
11248 For an "any" relationship, BIT 2 would be set. Etc.
11250 Following traditional nomenclature, these bits map to:
11252 BIT0 | BIT 1 | BIT 2 | BIT 3
11255 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11260 /* All variant. OV bit. */
11262 /* We need to get to the OV bit, which is the ORDERED bit. We
11263 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11264 that's ugly and will make validate_condition_mode die.
11265 So let's just use another pattern. */
11266 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11268 /* Any variant. EQ bit. */
11272 /* Upper variant. LT bit. */
11276 /* Lower variant. GT bit. */
11281 error ("argument 1 of __builtin_spe_predicate is out of range");
11285 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11286 emit_move_insn (target, tmp);
11291 /* The evsel builtins look like this:
11293 e = __builtin_spe_evsel_OP (a, b, c, d);
11295 and work like this:
11297 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11298 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11302 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11305 tree arg0 = CALL_EXPR_ARG (exp, 0);
11306 tree arg1 = CALL_EXPR_ARG (exp, 1);
11307 tree arg2 = CALL_EXPR_ARG (exp, 2);
11308 tree arg3 = CALL_EXPR_ARG (exp, 3);
11309 rtx op0 = expand_normal (arg0);
11310 rtx op1 = expand_normal (arg1);
11311 rtx op2 = expand_normal (arg2);
11312 rtx op3 = expand_normal (arg3);
11313 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11314 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11316 gcc_assert (mode0 == mode1);
11318 if (arg0 == error_mark_node || arg1 == error_mark_node
11319 || arg2 == error_mark_node || arg3 == error_mark_node)
11323 || GET_MODE (target) != mode0
11324 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11325 target = gen_reg_rtx (mode0);
11327 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11328 op0 = copy_to_mode_reg (mode0, op0);
11329 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11330 op1 = copy_to_mode_reg (mode0, op1);
11331 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11332 op2 = copy_to_mode_reg (mode0, op2);
11333 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11334 op3 = copy_to_mode_reg (mode0, op3);
11336 /* Generate the compare. */
11337 scratch = gen_reg_rtx (CCmode);
11338 pat = GEN_FCN (icode) (scratch, op0, op1);
11343 if (mode0 == V2SImode)
11344 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11346 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11351 /* Expand an expression EXP that calls a built-in function,
11352 with result going to TARGET if that's convenient
11353 (and in mode MODE if that's convenient).
11354 SUBTARGET may be used as the target for computing one of EXP's operands.
11355 IGNORE is nonzero if the value is to be ignored. */
11358 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11359 enum machine_mode mode ATTRIBUTE_UNUSED,
11360 int ignore ATTRIBUTE_UNUSED)
11362 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11363 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11364 const struct builtin_description *d;
11371 case RS6000_BUILTIN_RECIP:
11372 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11374 case RS6000_BUILTIN_RECIPF:
11375 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11377 case RS6000_BUILTIN_RSQRTF:
11378 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11380 case RS6000_BUILTIN_RSQRT:
11381 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11383 case RS6000_BUILTIN_BSWAP_HI:
11384 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11386 case POWER7_BUILTIN_BPERMD:
11387 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11388 ? CODE_FOR_bpermd_di
11389 : CODE_FOR_bpermd_si), exp, target);
11391 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11392 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11394 int icode = (int) CODE_FOR_altivec_lvsr;
11395 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11396 enum machine_mode mode = insn_data[icode].operand[1].mode;
11400 gcc_assert (TARGET_ALTIVEC);
11402 arg = CALL_EXPR_ARG (exp, 0);
11403 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
11404 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11405 addr = memory_address (mode, op);
11406 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11410 /* For the load case need to negate the address. */
11411 op = gen_reg_rtx (GET_MODE (addr));
11412 emit_insn (gen_rtx_SET (VOIDmode, op,
11413 gen_rtx_NEG (GET_MODE (addr), addr)));
11415 op = gen_rtx_MEM (mode, op);
11418 || GET_MODE (target) != tmode
11419 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11420 target = gen_reg_rtx (tmode);
11422 /*pat = gen_altivec_lvsr (target, op);*/
11423 pat = GEN_FCN (icode) (target, op);
11431 case ALTIVEC_BUILTIN_VCFUX:
11432 case ALTIVEC_BUILTIN_VCFSX:
11433 case ALTIVEC_BUILTIN_VCTUXS:
11434 case ALTIVEC_BUILTIN_VCTSXS:
11435 /* FIXME: There's got to be a nicer way to handle this case than
11436 constructing a new CALL_EXPR. */
11437 if (call_expr_nargs (exp) == 1)
11439 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11440 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11448 if (TARGET_ALTIVEC)
11450 ret = altivec_expand_builtin (exp, target, &success);
11457 ret = spe_expand_builtin (exp, target, &success);
11462 if (TARGET_PAIRED_FLOAT)
11464 ret = paired_expand_builtin (exp, target, &success);
11470 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11472 /* Handle simple unary operations. */
11473 d = (struct builtin_description *) bdesc_1arg;
11474 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11475 if (d->code == fcode)
11476 return rs6000_expand_unop_builtin (d->icode, exp, target);
11478 /* Handle simple binary operations. */
11479 d = (struct builtin_description *) bdesc_2arg;
11480 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11481 if (d->code == fcode)
11482 return rs6000_expand_binop_builtin (d->icode, exp, target);
11484 /* Handle simple ternary operations. */
11486 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11487 if (d->code == fcode)
11488 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11490 gcc_unreachable ();
11494 rs6000_init_builtins (void)
11499 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11500 V2SF_type_node = build_vector_type (float_type_node, 2);
11501 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11502 V2DF_type_node = build_vector_type (double_type_node, 2);
11503 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11504 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11505 V4SF_type_node = build_vector_type (float_type_node, 4);
11506 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11507 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11509 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11510 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11511 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11512 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11514 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11515 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11516 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11517 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11519 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11520 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11521 'vector unsigned short'. */
11523 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11524 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11525 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11526 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11527 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11529 long_integer_type_internal_node = long_integer_type_node;
11530 long_unsigned_type_internal_node = long_unsigned_type_node;
11531 intQI_type_internal_node = intQI_type_node;
11532 uintQI_type_internal_node = unsigned_intQI_type_node;
11533 intHI_type_internal_node = intHI_type_node;
11534 uintHI_type_internal_node = unsigned_intHI_type_node;
11535 intSI_type_internal_node = intSI_type_node;
11536 uintSI_type_internal_node = unsigned_intSI_type_node;
11537 intDI_type_internal_node = intDI_type_node;
11538 uintDI_type_internal_node = unsigned_intDI_type_node;
11539 float_type_internal_node = float_type_node;
11540 double_type_internal_node = float_type_node;
11541 void_type_internal_node = void_type_node;
11543 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11545 builtin_mode_to_type[QImode][0] = integer_type_node;
11546 builtin_mode_to_type[HImode][0] = integer_type_node;
11547 builtin_mode_to_type[SImode][0] = intSI_type_node;
11548 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
11549 builtin_mode_to_type[DImode][0] = intDI_type_node;
11550 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
11551 builtin_mode_to_type[SFmode][0] = float_type_node;
11552 builtin_mode_to_type[DFmode][0] = double_type_node;
11553 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
11554 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
11555 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
11556 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
11557 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
11558 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
11559 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11560 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11561 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11562 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11563 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11564 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11565 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11567 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11568 get_identifier ("__bool char"),
11569 bool_char_type_node);
11570 TYPE_NAME (bool_char_type_node) = tdecl;
11571 (*lang_hooks.decls.pushdecl) (tdecl);
11572 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11573 get_identifier ("__bool short"),
11574 bool_short_type_node);
11575 TYPE_NAME (bool_short_type_node) = tdecl;
11576 (*lang_hooks.decls.pushdecl) (tdecl);
11577 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11578 get_identifier ("__bool int"),
11579 bool_int_type_node);
11580 TYPE_NAME (bool_int_type_node) = tdecl;
11581 (*lang_hooks.decls.pushdecl) (tdecl);
11582 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
11584 TYPE_NAME (pixel_type_node) = tdecl;
11585 (*lang_hooks.decls.pushdecl) (tdecl);
11587 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
11588 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11589 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11590 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11591 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11593 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11594 get_identifier ("__vector unsigned char"),
11595 unsigned_V16QI_type_node);
11596 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11597 (*lang_hooks.decls.pushdecl) (tdecl);
11598 tdecl = build_decl (BUILTINS_LOCATION,
11599 TYPE_DECL, get_identifier ("__vector signed char"),
11601 TYPE_NAME (V16QI_type_node) = tdecl;
11602 (*lang_hooks.decls.pushdecl) (tdecl);
11603 tdecl = build_decl (BUILTINS_LOCATION,
11604 TYPE_DECL, get_identifier ("__vector __bool char"),
11605 bool_V16QI_type_node);
11606 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11607 (*lang_hooks.decls.pushdecl) (tdecl);
11609 tdecl = build_decl (BUILTINS_LOCATION,
11610 TYPE_DECL, get_identifier ("__vector unsigned short"),
11611 unsigned_V8HI_type_node);
11612 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11613 (*lang_hooks.decls.pushdecl) (tdecl);
11614 tdecl = build_decl (BUILTINS_LOCATION,
11615 TYPE_DECL, get_identifier ("__vector signed short"),
11617 TYPE_NAME (V8HI_type_node) = tdecl;
11618 (*lang_hooks.decls.pushdecl) (tdecl);
11619 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11620 get_identifier ("__vector __bool short"),
11621 bool_V8HI_type_node);
11622 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11623 (*lang_hooks.decls.pushdecl) (tdecl);
11625 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11626 get_identifier ("__vector unsigned int"),
11627 unsigned_V4SI_type_node);
11628 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11629 (*lang_hooks.decls.pushdecl) (tdecl);
11630 tdecl = build_decl (BUILTINS_LOCATION,
11631 TYPE_DECL, get_identifier ("__vector signed int"),
11633 TYPE_NAME (V4SI_type_node) = tdecl;
11634 (*lang_hooks.decls.pushdecl) (tdecl);
11635 tdecl = build_decl (BUILTINS_LOCATION,
11636 TYPE_DECL, get_identifier ("__vector __bool int"),
11637 bool_V4SI_type_node);
11638 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11639 (*lang_hooks.decls.pushdecl) (tdecl);
11641 tdecl = build_decl (BUILTINS_LOCATION,
11642 TYPE_DECL, get_identifier ("__vector float"),
11644 TYPE_NAME (V4SF_type_node) = tdecl;
11645 (*lang_hooks.decls.pushdecl) (tdecl);
11646 tdecl = build_decl (BUILTINS_LOCATION,
11647 TYPE_DECL, get_identifier ("__vector __pixel"),
11648 pixel_V8HI_type_node);
11649 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11650 (*lang_hooks.decls.pushdecl) (tdecl);
11654 tdecl = build_decl (BUILTINS_LOCATION,
11655 TYPE_DECL, get_identifier ("__vector double"),
11657 TYPE_NAME (V2DF_type_node) = tdecl;
11658 (*lang_hooks.decls.pushdecl) (tdecl);
11660 tdecl = build_decl (BUILTINS_LOCATION,
11661 TYPE_DECL, get_identifier ("__vector long"),
11663 TYPE_NAME (V2DI_type_node) = tdecl;
11664 (*lang_hooks.decls.pushdecl) (tdecl);
11666 tdecl = build_decl (BUILTINS_LOCATION,
11667 TYPE_DECL, get_identifier ("__vector unsigned long"),
11668 unsigned_V2DI_type_node);
11669 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11670 (*lang_hooks.decls.pushdecl) (tdecl);
11672 tdecl = build_decl (BUILTINS_LOCATION,
11673 TYPE_DECL, get_identifier ("__vector __bool long"),
11674 bool_V2DI_type_node);
11675 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11676 (*lang_hooks.decls.pushdecl) (tdecl);
11679 if (TARGET_PAIRED_FLOAT)
11680 paired_init_builtins ();
11682 spe_init_builtins ();
11683 if (TARGET_ALTIVEC)
11684 altivec_init_builtins ();
11685 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11686 rs6000_common_init_builtins ();
11689 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11690 RS6000_BUILTIN_RECIP,
11691 "__builtin_recipdiv");
11692 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11693 RS6000_BUILTIN_RECIP);
11697 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11698 RS6000_BUILTIN_RECIPF,
11699 "__builtin_recipdivf");
11700 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11701 RS6000_BUILTIN_RECIPF);
11703 if (TARGET_FRSQRTE)
11705 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
11706 RS6000_BUILTIN_RSQRT,
11707 "__builtin_rsqrt");
11708 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
11709 RS6000_BUILTIN_RSQRT);
11711 if (TARGET_FRSQRTES)
11713 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11714 RS6000_BUILTIN_RSQRTF,
11715 "__builtin_rsqrtf");
11716 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11717 RS6000_BUILTIN_RSQRTF);
11719 if (TARGET_POPCNTD)
11721 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11722 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11723 POWER7_BUILTIN_BPERMD,
11724 "__builtin_bpermd");
11725 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11726 POWER7_BUILTIN_BPERMD);
11728 if (TARGET_POWERPC)
11730 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11731 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11732 unsigned_intHI_type_node,
11734 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11735 RS6000_BUILTIN_BSWAP_HI);
11739 /* AIX libm provides clog as __clog. */
11740 if (built_in_decls [BUILT_IN_CLOG])
11741 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11744 #ifdef SUBTARGET_INIT_BUILTINS
11745 SUBTARGET_INIT_BUILTINS;
11749 /* Returns the rs6000 builtin decl for CODE. */
11752 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
11754 if (code >= RS6000_BUILTIN_COUNT)
11755 return error_mark_node;
11757 return rs6000_builtin_decls[code];
11760 /* Search through a set of builtins and enable the mask bits.
11761 DESC is an array of builtins.
11762 SIZE is the total number of builtins.
11763 START is the builtin enum at which to start.
11764 END is the builtin enum at which to end. */
11766 enable_mask_for_builtins (struct builtin_description *desc, int size,
11767 enum rs6000_builtins start,
11768 enum rs6000_builtins end)
11772 for (i = 0; i < size; ++i)
11773 if (desc[i].code == start)
11779 for (; i < size; ++i)
11781 /* Flip all the bits on. */
11782 desc[i].mask = target_flags;
11783 if (desc[i].code == end)
11789 spe_init_builtins (void)
11791 tree endlink = void_list_node;
11792 tree puint_type_node = build_pointer_type (unsigned_type_node);
11793 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11794 struct builtin_description *d;
11797 tree v2si_ftype_4_v2si
11798 = build_function_type
11799 (opaque_V2SI_type_node,
11800 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11801 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11802 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11803 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11806 tree v2sf_ftype_4_v2sf
11807 = build_function_type
11808 (opaque_V2SF_type_node,
11809 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11810 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11811 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11812 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11815 tree int_ftype_int_v2si_v2si
11816 = build_function_type
11817 (integer_type_node,
11818 tree_cons (NULL_TREE, integer_type_node,
11819 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11820 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11823 tree int_ftype_int_v2sf_v2sf
11824 = build_function_type
11825 (integer_type_node,
11826 tree_cons (NULL_TREE, integer_type_node,
11827 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11828 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11831 tree void_ftype_v2si_puint_int
11832 = build_function_type (void_type_node,
11833 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11834 tree_cons (NULL_TREE, puint_type_node,
11835 tree_cons (NULL_TREE,
11839 tree void_ftype_v2si_puint_char
11840 = build_function_type (void_type_node,
11841 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11842 tree_cons (NULL_TREE, puint_type_node,
11843 tree_cons (NULL_TREE,
11847 tree void_ftype_v2si_pv2si_int
11848 = build_function_type (void_type_node,
11849 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11850 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11851 tree_cons (NULL_TREE,
11855 tree void_ftype_v2si_pv2si_char
11856 = build_function_type (void_type_node,
11857 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11858 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11859 tree_cons (NULL_TREE,
11863 tree void_ftype_int
11864 = build_function_type (void_type_node,
11865 tree_cons (NULL_TREE, integer_type_node, endlink));
11867 tree int_ftype_void
11868 = build_function_type (integer_type_node, endlink);
11870 tree v2si_ftype_pv2si_int
11871 = build_function_type (opaque_V2SI_type_node,
11872 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11873 tree_cons (NULL_TREE, integer_type_node,
11876 tree v2si_ftype_puint_int
11877 = build_function_type (opaque_V2SI_type_node,
11878 tree_cons (NULL_TREE, puint_type_node,
11879 tree_cons (NULL_TREE, integer_type_node,
11882 tree v2si_ftype_pushort_int
11883 = build_function_type (opaque_V2SI_type_node,
11884 tree_cons (NULL_TREE, pushort_type_node,
11885 tree_cons (NULL_TREE, integer_type_node,
11888 tree v2si_ftype_signed_char
11889 = build_function_type (opaque_V2SI_type_node,
11890 tree_cons (NULL_TREE, signed_char_type_node,
11893 /* The initialization of the simple binary and unary builtins is
11894 done in rs6000_common_init_builtins, but we have to enable the
11895 mask bits here manually because we have run out of `target_flags'
11896 bits. We really need to redesign this mask business. */
11898 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11899 ARRAY_SIZE (bdesc_2arg),
11900 SPE_BUILTIN_EVADDW,
11901 SPE_BUILTIN_EVXOR);
11902 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11903 ARRAY_SIZE (bdesc_1arg),
11905 SPE_BUILTIN_EVSUBFUSIAAW);
11906 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11907 ARRAY_SIZE (bdesc_spe_predicates),
11908 SPE_BUILTIN_EVCMPEQ,
11909 SPE_BUILTIN_EVFSTSTLT);
11910 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11911 ARRAY_SIZE (bdesc_spe_evsel),
11912 SPE_BUILTIN_EVSEL_CMPGTS,
11913 SPE_BUILTIN_EVSEL_FSTSTEQ);
11915 (*lang_hooks.decls.pushdecl)
11916 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11917 get_identifier ("__ev64_opaque__"),
11918 opaque_V2SI_type_node));
11920 /* Initialize irregular SPE builtins. */
11922 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11923 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11924 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11925 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11926 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11927 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11928 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11929 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11930 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11931 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11932 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11933 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11934 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11935 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11936 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11937 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11938 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11939 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11942 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11943 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11944 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11945 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11946 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11947 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11948 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11949 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11950 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11951 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11952 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11953 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11954 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11955 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11956 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11957 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11958 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11959 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11960 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11961 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11962 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11963 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11966 d = (struct builtin_description *) bdesc_spe_predicates;
11967 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11971 switch (insn_data[d->icode].operand[1].mode)
11974 type = int_ftype_int_v2si_v2si;
11977 type = int_ftype_int_v2sf_v2sf;
11980 gcc_unreachable ();
11983 def_builtin (d->mask, d->name, type, d->code);
11986 /* Evsel predicates. */
11987 d = (struct builtin_description *) bdesc_spe_evsel;
11988 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11992 switch (insn_data[d->icode].operand[1].mode)
11995 type = v2si_ftype_4_v2si;
11998 type = v2sf_ftype_4_v2sf;
12001 gcc_unreachable ();
12004 def_builtin (d->mask, d->name, type, d->code);
12009 paired_init_builtins (void)
12011 const struct builtin_description *d;
12013 tree endlink = void_list_node;
12015 tree int_ftype_int_v2sf_v2sf
12016 = build_function_type
12017 (integer_type_node,
12018 tree_cons (NULL_TREE, integer_type_node,
12019 tree_cons (NULL_TREE, V2SF_type_node,
12020 tree_cons (NULL_TREE, V2SF_type_node,
12022 tree pcfloat_type_node =
12023 build_pointer_type (build_qualified_type
12024 (float_type_node, TYPE_QUAL_CONST));
12026 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12027 long_integer_type_node,
12030 tree void_ftype_v2sf_long_pcfloat =
12031 build_function_type_list (void_type_node,
12033 long_integer_type_node,
12038 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12039 PAIRED_BUILTIN_LX);
12042 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12043 PAIRED_BUILTIN_STX);
12046 d = bdesc_paired_preds;
12047 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12051 switch (insn_data[d->icode].operand[1].mode)
12054 type = int_ftype_int_v2sf_v2sf;
12057 gcc_unreachable ();
12060 def_builtin (d->mask, d->name, type, d->code);
12065 altivec_init_builtins (void)
12067 const struct builtin_description *d;
12068 const struct builtin_description_predicates *dp;
12072 tree pfloat_type_node = build_pointer_type (float_type_node);
12073 tree pint_type_node = build_pointer_type (integer_type_node);
12074 tree pshort_type_node = build_pointer_type (short_integer_type_node);
12075 tree pchar_type_node = build_pointer_type (char_type_node);
12077 tree pvoid_type_node = build_pointer_type (void_type_node);
12079 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
12080 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
12081 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
12082 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
12084 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
12086 tree int_ftype_opaque
12087 = build_function_type_list (integer_type_node,
12088 opaque_V4SI_type_node, NULL_TREE);
12089 tree opaque_ftype_opaque
12090 = build_function_type (integer_type_node,
12092 tree opaque_ftype_opaque_int
12093 = build_function_type_list (opaque_V4SI_type_node,
12094 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12095 tree opaque_ftype_opaque_opaque_int
12096 = build_function_type_list (opaque_V4SI_type_node,
12097 opaque_V4SI_type_node, opaque_V4SI_type_node,
12098 integer_type_node, NULL_TREE);
12099 tree int_ftype_int_opaque_opaque
12100 = build_function_type_list (integer_type_node,
12101 integer_type_node, opaque_V4SI_type_node,
12102 opaque_V4SI_type_node, NULL_TREE);
12103 tree int_ftype_int_v4si_v4si
12104 = build_function_type_list (integer_type_node,
12105 integer_type_node, V4SI_type_node,
12106 V4SI_type_node, NULL_TREE);
12107 tree v4sf_ftype_pcfloat
12108 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
12109 tree void_ftype_pfloat_v4sf
12110 = build_function_type_list (void_type_node,
12111 pfloat_type_node, V4SF_type_node, NULL_TREE);
12112 tree v4si_ftype_pcint
12113 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
12114 tree void_ftype_pint_v4si
12115 = build_function_type_list (void_type_node,
12116 pint_type_node, V4SI_type_node, NULL_TREE);
12117 tree v8hi_ftype_pcshort
12118 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
12119 tree void_ftype_pshort_v8hi
12120 = build_function_type_list (void_type_node,
12121 pshort_type_node, V8HI_type_node, NULL_TREE);
12122 tree v16qi_ftype_pcchar
12123 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
12124 tree void_ftype_pchar_v16qi
12125 = build_function_type_list (void_type_node,
12126 pchar_type_node, V16QI_type_node, NULL_TREE);
12127 tree void_ftype_v4si
12128 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12129 tree v8hi_ftype_void
12130 = build_function_type (V8HI_type_node, void_list_node);
12131 tree void_ftype_void
12132 = build_function_type (void_type_node, void_list_node);
12133 tree void_ftype_int
12134 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12136 tree opaque_ftype_long_pcvoid
12137 = build_function_type_list (opaque_V4SI_type_node,
12138 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12139 tree v16qi_ftype_long_pcvoid
12140 = build_function_type_list (V16QI_type_node,
12141 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12142 tree v8hi_ftype_long_pcvoid
12143 = build_function_type_list (V8HI_type_node,
12144 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12145 tree v4si_ftype_long_pcvoid
12146 = build_function_type_list (V4SI_type_node,
12147 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12149 tree void_ftype_opaque_long_pvoid
12150 = build_function_type_list (void_type_node,
12151 opaque_V4SI_type_node, long_integer_type_node,
12152 pvoid_type_node, NULL_TREE);
12153 tree void_ftype_v4si_long_pvoid
12154 = build_function_type_list (void_type_node,
12155 V4SI_type_node, long_integer_type_node,
12156 pvoid_type_node, NULL_TREE);
12157 tree void_ftype_v16qi_long_pvoid
12158 = build_function_type_list (void_type_node,
12159 V16QI_type_node, long_integer_type_node,
12160 pvoid_type_node, NULL_TREE);
12161 tree void_ftype_v8hi_long_pvoid
12162 = build_function_type_list (void_type_node,
12163 V8HI_type_node, long_integer_type_node,
12164 pvoid_type_node, NULL_TREE);
12165 tree int_ftype_int_v8hi_v8hi
12166 = build_function_type_list (integer_type_node,
12167 integer_type_node, V8HI_type_node,
12168 V8HI_type_node, NULL_TREE);
12169 tree int_ftype_int_v16qi_v16qi
12170 = build_function_type_list (integer_type_node,
12171 integer_type_node, V16QI_type_node,
12172 V16QI_type_node, NULL_TREE);
12173 tree int_ftype_int_v4sf_v4sf
12174 = build_function_type_list (integer_type_node,
12175 integer_type_node, V4SF_type_node,
12176 V4SF_type_node, NULL_TREE);
12177 tree int_ftype_int_v2df_v2df
12178 = build_function_type_list (integer_type_node,
12179 integer_type_node, V2DF_type_node,
12180 V2DF_type_node, NULL_TREE);
12181 tree v4si_ftype_v4si
12182 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12183 tree v8hi_ftype_v8hi
12184 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12185 tree v16qi_ftype_v16qi
12186 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12187 tree v4sf_ftype_v4sf
12188 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12189 tree v2df_ftype_v2df
12190 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12191 tree void_ftype_pcvoid_int_int
12192 = build_function_type_list (void_type_node,
12193 pcvoid_type_node, integer_type_node,
12194 integer_type_node, NULL_TREE);
12196 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
12197 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
12198 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
12199 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
12200 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
12201 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
12202 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
12203 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
12204 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
12205 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
12206 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
12207 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
12208 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
12209 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
12210 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
12211 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
12212 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12213 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12214 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12215 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12216 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12217 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12218 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12219 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12220 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12221 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12222 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12223 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12224 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12225 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12226 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12227 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12228 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12229 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12230 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12231 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12232 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12233 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12234 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12235 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12236 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12237 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12238 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12239 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12240 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12241 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12243 if (rs6000_cpu == PROCESSOR_CELL)
12245 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12246 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12247 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12248 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12250 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12251 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12252 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12253 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12255 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12256 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12257 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12258 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12260 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12261 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12262 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12263 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12265 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12266 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12267 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12269 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12270 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12271 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12272 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12273 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12274 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12275 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12276 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12277 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12278 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12279 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12280 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12282 /* Add the DST variants. */
12284 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12285 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12287 /* Initialize the predicates. */
12288 dp = bdesc_altivec_preds;
12289 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12291 enum machine_mode mode1;
12293 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12294 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12295 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12296 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12301 mode1 = insn_data[dp->icode].operand[1].mode;
12306 type = int_ftype_int_opaque_opaque;
12309 type = int_ftype_int_v4si_v4si;
12312 type = int_ftype_int_v8hi_v8hi;
12315 type = int_ftype_int_v16qi_v16qi;
12318 type = int_ftype_int_v4sf_v4sf;
12321 type = int_ftype_int_v2df_v2df;
12324 gcc_unreachable ();
12327 def_builtin (dp->mask, dp->name, type, dp->code);
12330 /* Initialize the abs* operators. */
12332 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12334 enum machine_mode mode0;
12337 mode0 = insn_data[d->icode].operand[0].mode;
12342 type = v4si_ftype_v4si;
12345 type = v8hi_ftype_v8hi;
12348 type = v16qi_ftype_v16qi;
12351 type = v4sf_ftype_v4sf;
12354 type = v2df_ftype_v2df;
12357 gcc_unreachable ();
12360 def_builtin (d->mask, d->name, type, d->code);
12363 if (TARGET_ALTIVEC)
12367 /* Initialize target builtin that implements
12368 targetm.vectorize.builtin_mask_for_load. */
12370 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12371 v16qi_ftype_long_pcvoid,
12372 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12373 BUILT_IN_MD, NULL, NULL_TREE);
12374 TREE_READONLY (decl) = 1;
12375 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12376 altivec_builtin_mask_for_load = decl;
12379 /* Access to the vec_init patterns. */
12380 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12381 integer_type_node, integer_type_node,
12382 integer_type_node, NULL_TREE);
12383 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12384 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12386 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12387 short_integer_type_node,
12388 short_integer_type_node,
12389 short_integer_type_node,
12390 short_integer_type_node,
12391 short_integer_type_node,
12392 short_integer_type_node,
12393 short_integer_type_node, NULL_TREE);
12394 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12395 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12397 ftype = build_function_type_list (V16QI_type_node, char_type_node,
12398 char_type_node, char_type_node,
12399 char_type_node, char_type_node,
12400 char_type_node, char_type_node,
12401 char_type_node, char_type_node,
12402 char_type_node, char_type_node,
12403 char_type_node, char_type_node,
12404 char_type_node, char_type_node,
12405 char_type_node, NULL_TREE);
12406 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
12407 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
12409 ftype = build_function_type_list (V4SF_type_node, float_type_node,
12410 float_type_node, float_type_node,
12411 float_type_node, NULL_TREE);
12412 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
12413 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12417 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12418 double_type_node, NULL_TREE);
12419 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12420 VSX_BUILTIN_VEC_INIT_V2DF);
12422 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12423 intDI_type_node, NULL_TREE);
12424 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12425 VSX_BUILTIN_VEC_INIT_V2DI);
12428 /* Access to the vec_set patterns. */
12429 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12431 integer_type_node, NULL_TREE);
12432 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12433 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12435 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12437 integer_type_node, NULL_TREE);
12438 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12439 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12441 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12443 integer_type_node, NULL_TREE);
12444 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12445 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12447 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12449 integer_type_node, NULL_TREE);
12450 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12451 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12455 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12457 integer_type_node, NULL_TREE);
12458 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12459 VSX_BUILTIN_VEC_SET_V2DF);
12461 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12463 integer_type_node, NULL_TREE);
12464 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12465 VSX_BUILTIN_VEC_SET_V2DI);
12468 /* Access to the vec_extract patterns. */
12469 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12470 integer_type_node, NULL_TREE);
12471 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12472 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12474 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12475 integer_type_node, NULL_TREE);
12476 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12477 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12479 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12480 integer_type_node, NULL_TREE);
12481 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12482 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12484 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12485 integer_type_node, NULL_TREE);
12486 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12487 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12491 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12492 integer_type_node, NULL_TREE);
12493 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12494 VSX_BUILTIN_VEC_EXT_V2DF);
12496 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12497 integer_type_node, NULL_TREE);
12498 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12499 VSX_BUILTIN_VEC_EXT_V2DI);
12503 /* Hash function for builtin functions with up to 3 arguments and a return
12506 builtin_hash_function (const void *hash_entry)
12510 const struct builtin_hash_struct *bh =
12511 (const struct builtin_hash_struct *) hash_entry;
12513 for (i = 0; i < 4; i++)
12515 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12516 ret = (ret * 2) + bh->uns_p[i];
12522 /* Compare builtin hash entries H1 and H2 for equivalence. */
12524 builtin_hash_eq (const void *h1, const void *h2)
12526 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12527 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
12529 return ((p1->mode[0] == p2->mode[0])
12530 && (p1->mode[1] == p2->mode[1])
12531 && (p1->mode[2] == p2->mode[2])
12532 && (p1->mode[3] == p2->mode[3])
12533 && (p1->uns_p[0] == p2->uns_p[0])
12534 && (p1->uns_p[1] == p2->uns_p[1])
12535 && (p1->uns_p[2] == p2->uns_p[2])
12536 && (p1->uns_p[3] == p2->uns_p[3]));
12539 /* Map types for builtin functions with an explicit return type and up to 3
12540 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12541 of the argument. */
12543 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
12544 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
12545 enum rs6000_builtins builtin, const char *name)
12547 struct builtin_hash_struct h;
12548 struct builtin_hash_struct *h2;
12552 tree ret_type = NULL_TREE;
12553 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
12556 /* Create builtin_hash_table. */
12557 if (builtin_hash_table == NULL)
12558 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
12559 builtin_hash_eq, NULL);
12561 h.type = NULL_TREE;
12562 h.mode[0] = mode_ret;
12563 h.mode[1] = mode_arg0;
12564 h.mode[2] = mode_arg1;
12565 h.mode[3] = mode_arg2;
12571 /* If the builtin is a type that produces unsigned results or takes unsigned
12572 arguments, and it is returned as a decl for the vectorizer (such as
12573 widening multiplies, permute), make sure the arguments and return value
12574 are type correct. */
12577 /* unsigned 2 argument functions. */
12578 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12579 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12580 case ALTIVEC_BUILTIN_VMULOUB_UNS:
12581 case ALTIVEC_BUILTIN_VMULOUH_UNS:
12587 /* unsigned 3 argument functions. */
12588 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
12589 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
12590 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
12591 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
12592 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
12593 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
12594 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
12595 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
12596 case VSX_BUILTIN_VPERM_16QI_UNS:
12597 case VSX_BUILTIN_VPERM_8HI_UNS:
12598 case VSX_BUILTIN_VPERM_4SI_UNS:
12599 case VSX_BUILTIN_VPERM_2DI_UNS:
12600 case VSX_BUILTIN_XXSEL_16QI_UNS:
12601 case VSX_BUILTIN_XXSEL_8HI_UNS:
12602 case VSX_BUILTIN_XXSEL_4SI_UNS:
12603 case VSX_BUILTIN_XXSEL_2DI_UNS:
12610 /* signed permute functions with unsigned char mask. */
12611 case ALTIVEC_BUILTIN_VPERM_16QI:
12612 case ALTIVEC_BUILTIN_VPERM_8HI:
12613 case ALTIVEC_BUILTIN_VPERM_4SI:
12614 case ALTIVEC_BUILTIN_VPERM_4SF:
12615 case ALTIVEC_BUILTIN_VPERM_2DI:
12616 case ALTIVEC_BUILTIN_VPERM_2DF:
12617 case VSX_BUILTIN_VPERM_16QI:
12618 case VSX_BUILTIN_VPERM_8HI:
12619 case VSX_BUILTIN_VPERM_4SI:
12620 case VSX_BUILTIN_VPERM_4SF:
12621 case VSX_BUILTIN_VPERM_2DI:
12622 case VSX_BUILTIN_VPERM_2DF:
12626 /* unsigned args, signed return. */
12627 case VSX_BUILTIN_XVCVUXDDP_UNS:
12628 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12632 /* signed args, unsigned return. */
12633 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12634 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12642 /* Figure out how many args are present. */
12643 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12647 fatal_error ("internal error: builtin function %s had no type", name);
12649 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12650 if (!ret_type && h.uns_p[0])
12651 ret_type = builtin_mode_to_type[h.mode[0]][0];
12654 fatal_error ("internal error: builtin function %s had an unexpected "
12655 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12657 for (i = 0; i < num_args; i++)
12659 int m = (int) h.mode[i+1];
12660 int uns_p = h.uns_p[i+1];
12662 arg_type[i] = builtin_mode_to_type[m][uns_p];
12663 if (!arg_type[i] && uns_p)
12664 arg_type[i] = builtin_mode_to_type[m][0];
12667 fatal_error ("internal error: builtin function %s, argument %d "
12668 "had unexpected argument type %s", name, i,
12669 GET_MODE_NAME (m));
12672 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12673 if (*found == NULL)
12675 h2 = ggc_alloc_builtin_hash_struct ();
12677 *found = (void *)h2;
12678 args = void_list_node;
12680 for (i = num_args - 1; i >= 0; i--)
12681 args = tree_cons (NULL_TREE, arg_type[i], args);
12683 h2->type = build_function_type (ret_type, args);
12686 return ((struct builtin_hash_struct *)(*found))->type;
12690 rs6000_common_init_builtins (void)
12692 const struct builtin_description *d;
12695 tree opaque_ftype_opaque = NULL_TREE;
12696 tree opaque_ftype_opaque_opaque = NULL_TREE;
12697 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12698 tree v2si_ftype_qi = NULL_TREE;
12699 tree v2si_ftype_v2si_qi = NULL_TREE;
12700 tree v2si_ftype_int_qi = NULL_TREE;
12702 if (!TARGET_PAIRED_FLOAT)
12704 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12705 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12708 /* Add the ternary operators. */
12710 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12713 int mask = d->mask;
12715 if ((mask != 0 && (mask & target_flags) == 0)
12716 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12719 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12720 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12721 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12722 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12724 if (! (type = opaque_ftype_opaque_opaque_opaque))
12725 type = opaque_ftype_opaque_opaque_opaque
12726 = build_function_type_list (opaque_V4SI_type_node,
12727 opaque_V4SI_type_node,
12728 opaque_V4SI_type_node,
12729 opaque_V4SI_type_node,
12734 enum insn_code icode = d->icode;
12735 if (d->name == 0 || icode == CODE_FOR_nothing)
12738 type = builtin_function_type (insn_data[icode].operand[0].mode,
12739 insn_data[icode].operand[1].mode,
12740 insn_data[icode].operand[2].mode,
12741 insn_data[icode].operand[3].mode,
12745 def_builtin (d->mask, d->name, type, d->code);
12748 /* Add the binary operators. */
12750 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12752 enum machine_mode mode0, mode1, mode2;
12754 int mask = d->mask;
12756 if ((mask != 0 && (mask & target_flags) == 0)
12757 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12760 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12761 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12762 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12763 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12765 if (! (type = opaque_ftype_opaque_opaque))
12766 type = opaque_ftype_opaque_opaque
12767 = build_function_type_list (opaque_V4SI_type_node,
12768 opaque_V4SI_type_node,
12769 opaque_V4SI_type_node,
12774 enum insn_code icode = d->icode;
12775 if (d->name == 0 || icode == CODE_FOR_nothing)
12778 mode0 = insn_data[icode].operand[0].mode;
12779 mode1 = insn_data[icode].operand[1].mode;
12780 mode2 = insn_data[icode].operand[2].mode;
12782 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12784 if (! (type = v2si_ftype_v2si_qi))
12785 type = v2si_ftype_v2si_qi
12786 = build_function_type_list (opaque_V2SI_type_node,
12787 opaque_V2SI_type_node,
12792 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12793 && mode2 == QImode)
12795 if (! (type = v2si_ftype_int_qi))
12796 type = v2si_ftype_int_qi
12797 = build_function_type_list (opaque_V2SI_type_node,
12804 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12808 def_builtin (d->mask, d->name, type, d->code);
12811 /* Add the simple unary operators. */
12812 d = (struct builtin_description *) bdesc_1arg;
12813 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12815 enum machine_mode mode0, mode1;
12817 int mask = d->mask;
12819 if ((mask != 0 && (mask & target_flags) == 0)
12820 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12823 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12824 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12825 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12826 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12828 if (! (type = opaque_ftype_opaque))
12829 type = opaque_ftype_opaque
12830 = build_function_type_list (opaque_V4SI_type_node,
12831 opaque_V4SI_type_node,
12836 enum insn_code icode = d->icode;
12837 if (d->name == 0 || icode == CODE_FOR_nothing)
12840 mode0 = insn_data[icode].operand[0].mode;
12841 mode1 = insn_data[icode].operand[1].mode;
12843 if (mode0 == V2SImode && mode1 == QImode)
12845 if (! (type = v2si_ftype_qi))
12846 type = v2si_ftype_qi
12847 = build_function_type_list (opaque_V2SI_type_node,
12853 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12857 def_builtin (d->mask, d->name, type, d->code);
12862 rs6000_init_libfuncs (void)
12864 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12865 && !TARGET_POWER2 && !TARGET_POWERPC)
12867 /* AIX library routines for float->int conversion. */
12868 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12869 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12870 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12871 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12874 if (!TARGET_IEEEQUAD)
12875 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12876 if (!TARGET_XL_COMPAT)
12878 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12879 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12880 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12881 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12883 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12885 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12886 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12887 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12888 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12889 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12890 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12891 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12893 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12894 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12895 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12896 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12897 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12898 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12899 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12900 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12903 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12904 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12908 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12909 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12910 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12911 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12915 /* 32-bit SVR4 quad floating point routines. */
12917 set_optab_libfunc (add_optab, TFmode, "_q_add");
12918 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12919 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12920 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12921 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12922 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12923 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12925 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12926 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12927 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12928 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12929 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12930 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12932 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12933 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12934 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12935 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12936 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12937 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12938 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12939 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12944 /* Expand a block clear operation, and return 1 if successful. Return 0
12945 if we should let the compiler generate normal code.
12947 operands[0] is the destination
12948 operands[1] is the length
12949 operands[3] is the alignment */
12952 expand_block_clear (rtx operands[])
12954 rtx orig_dest = operands[0];
12955 rtx bytes_rtx = operands[1];
12956 rtx align_rtx = operands[3];
12957 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12958 HOST_WIDE_INT align;
12959 HOST_WIDE_INT bytes;
12964 /* If this is not a fixed size move, just call memcpy */
12968 /* This must be a fixed size alignment */
12969 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12970 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12972 /* Anything to clear? */
12973 bytes = INTVAL (bytes_rtx);
12977 /* Use the builtin memset after a point, to avoid huge code bloat.
12978 When optimize_size, avoid any significant code bloat; calling
12979 memset is about 4 instructions, so allow for one instruction to
12980 load zero and three to do clearing. */
12981 if (TARGET_ALTIVEC && align >= 128)
12983 else if (TARGET_POWERPC64 && align >= 32)
12985 else if (TARGET_SPE && align >= 64)
12990 if (optimize_size && bytes > 3 * clear_step)
12992 if (! optimize_size && bytes > 8 * clear_step)
12995 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12997 enum machine_mode mode = BLKmode;
13000 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13005 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13010 else if (bytes >= 8 && TARGET_POWERPC64
13011 /* 64-bit loads and stores require word-aligned
13013 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13018 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13019 { /* move 4 bytes */
13023 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13024 { /* move 2 bytes */
13028 else /* move 1 byte at a time */
13034 dest = adjust_address (orig_dest, mode, offset);
13036 emit_move_insn (dest, CONST0_RTX (mode));
13043 /* Expand a block move operation, and return 1 if successful. Return 0
13044 if we should let the compiler generate normal code.
13046 operands[0] is the destination
13047 operands[1] is the source
13048 operands[2] is the length
13049 operands[3] is the alignment */
13051 #define MAX_MOVE_REG 4
13054 expand_block_move (rtx operands[])
13056 rtx orig_dest = operands[0];
13057 rtx orig_src = operands[1];
13058 rtx bytes_rtx = operands[2];
13059 rtx align_rtx = operands[3];
13060 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13065 rtx stores[MAX_MOVE_REG];
13068 /* If this is not a fixed size move, just call memcpy */
13072 /* This must be a fixed size alignment */
13073 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13074 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13076 /* Anything to move? */
13077 bytes = INTVAL (bytes_rtx);
13081 /* store_one_arg depends on expand_block_move to handle at least the size of
13082 reg_parm_stack_space. */
13083 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
13086 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13089 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13090 rtx (*mov) (rtx, rtx);
13092 enum machine_mode mode = BLKmode;
13095 /* Altivec first, since it will be faster than a string move
13096 when it applies, and usually not significantly larger. */
13097 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13101 gen_func.mov = gen_movv4si;
13103 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13107 gen_func.mov = gen_movv2si;
13109 else if (TARGET_STRING
13110 && bytes > 24 /* move up to 32 bytes at a time */
13116 && ! fixed_regs[10]
13117 && ! fixed_regs[11]
13118 && ! fixed_regs[12])
13120 move_bytes = (bytes > 32) ? 32 : bytes;
13121 gen_func.movmemsi = gen_movmemsi_8reg;
13123 else if (TARGET_STRING
13124 && bytes > 16 /* move up to 24 bytes at a time */
13130 && ! fixed_regs[10])
13132 move_bytes = (bytes > 24) ? 24 : bytes;
13133 gen_func.movmemsi = gen_movmemsi_6reg;
13135 else if (TARGET_STRING
13136 && bytes > 8 /* move up to 16 bytes at a time */
13140 && ! fixed_regs[8])
13142 move_bytes = (bytes > 16) ? 16 : bytes;
13143 gen_func.movmemsi = gen_movmemsi_4reg;
13145 else if (bytes >= 8 && TARGET_POWERPC64
13146 /* 64-bit loads and stores require word-aligned
13148 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13152 gen_func.mov = gen_movdi;
13154 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13155 { /* move up to 8 bytes at a time */
13156 move_bytes = (bytes > 8) ? 8 : bytes;
13157 gen_func.movmemsi = gen_movmemsi_2reg;
13159 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13160 { /* move 4 bytes */
13163 gen_func.mov = gen_movsi;
13165 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13166 { /* move 2 bytes */
13169 gen_func.mov = gen_movhi;
13171 else if (TARGET_STRING && bytes > 1)
13172 { /* move up to 4 bytes at a time */
13173 move_bytes = (bytes > 4) ? 4 : bytes;
13174 gen_func.movmemsi = gen_movmemsi_1reg;
13176 else /* move 1 byte at a time */
13180 gen_func.mov = gen_movqi;
13183 src = adjust_address (orig_src, mode, offset);
13184 dest = adjust_address (orig_dest, mode, offset);
13186 if (mode != BLKmode)
13188 rtx tmp_reg = gen_reg_rtx (mode);
13190 emit_insn ((*gen_func.mov) (tmp_reg, src));
13191 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13194 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13197 for (i = 0; i < num_reg; i++)
13198 emit_insn (stores[i]);
13202 if (mode == BLKmode)
13204 /* Move the address into scratch registers. The movmemsi
13205 patterns require zero offset. */
13206 if (!REG_P (XEXP (src, 0)))
13208 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13209 src = replace_equiv_address (src, src_reg);
13211 set_mem_size (src, GEN_INT (move_bytes));
13213 if (!REG_P (XEXP (dest, 0)))
13215 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13216 dest = replace_equiv_address (dest, dest_reg);
13218 set_mem_size (dest, GEN_INT (move_bytes));
13220 emit_insn ((*gen_func.movmemsi) (dest, src,
13221 GEN_INT (move_bytes & 31),
13230 /* Return a string to perform a load_multiple operation.
13231 operands[0] is the vector.
13232 operands[1] is the source address.
13233 operands[2] is the first destination register. */
13236 rs6000_output_load_multiple (rtx operands[3])
13238 /* We have to handle the case where the pseudo used to contain the address
13239 is assigned to one of the output registers. */
13241 int words = XVECLEN (operands[0], 0);
13244 if (XVECLEN (operands[0], 0) == 1)
13245 return "{l|lwz} %2,0(%1)";
13247 for (i = 0; i < words; i++)
13248 if (refers_to_regno_p (REGNO (operands[2]) + i,
13249 REGNO (operands[2]) + i + 1, operands[1], 0))
13253 xop[0] = GEN_INT (4 * (words-1));
13254 xop[1] = operands[1];
13255 xop[2] = operands[2];
13256 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13261 xop[0] = GEN_INT (4 * (words-1));
13262 xop[1] = operands[1];
13263 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13264 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);
13269 for (j = 0; j < words; j++)
13272 xop[0] = GEN_INT (j * 4);
13273 xop[1] = operands[1];
13274 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13275 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13277 xop[0] = GEN_INT (i * 4);
13278 xop[1] = operands[1];
13279 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13284 return "{lsi|lswi} %2,%1,%N0";
13288 /* A validation routine: say whether CODE, a condition code, and MODE
13289 match. The other alternatives either don't make sense or should
13290 never be generated. */
13293 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13295 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13296 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13297 && GET_MODE_CLASS (mode) == MODE_CC);
13299 /* These don't make sense. */
13300 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13301 || mode != CCUNSmode);
13303 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13304 || mode == CCUNSmode);
13306 gcc_assert (mode == CCFPmode
13307 || (code != ORDERED && code != UNORDERED
13308 && code != UNEQ && code != LTGT
13309 && code != UNGT && code != UNLT
13310 && code != UNGE && code != UNLE));
13312 /* These should never be generated except for
13313 flag_finite_math_only. */
13314 gcc_assert (mode != CCFPmode
13315 || flag_finite_math_only
13316 || (code != LE && code != GE
13317 && code != UNEQ && code != LTGT
13318 && code != UNGT && code != UNLT));
13320 /* These are invalid; the information is not there. */
13321 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13325 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13326 mask required to convert the result of a rotate insn into a shift
13327 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13330 includes_lshift_p (rtx shiftop, rtx andop)
13332 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13334 shift_mask <<= INTVAL (shiftop);
13336 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13339 /* Similar, but for right shift. */
13342 includes_rshift_p (rtx shiftop, rtx andop)
13344 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13346 shift_mask >>= INTVAL (shiftop);
13348 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13351 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13352 to perform a left shift. It must have exactly SHIFTOP least
13353 significant 0's, then one or more 1's, then zero or more 0's. */
13356 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13358 if (GET_CODE (andop) == CONST_INT)
13360 HOST_WIDE_INT c, lsb, shift_mask;
13362 c = INTVAL (andop);
13363 if (c == 0 || c == ~0)
13367 shift_mask <<= INTVAL (shiftop);
13369 /* Find the least significant one bit. */
13372 /* It must coincide with the LSB of the shift mask. */
13373 if (-lsb != shift_mask)
13376 /* Invert to look for the next transition (if any). */
13379 /* Remove the low group of ones (originally low group of zeros). */
13382 /* Again find the lsb, and check we have all 1's above. */
13386 else if (GET_CODE (andop) == CONST_DOUBLE
13387 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13389 HOST_WIDE_INT low, high, lsb;
13390 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13392 low = CONST_DOUBLE_LOW (andop);
13393 if (HOST_BITS_PER_WIDE_INT < 64)
13394 high = CONST_DOUBLE_HIGH (andop);
13396 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13397 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13400 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13402 shift_mask_high = ~0;
13403 if (INTVAL (shiftop) > 32)
13404 shift_mask_high <<= INTVAL (shiftop) - 32;
13406 lsb = high & -high;
13408 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13414 lsb = high & -high;
13415 return high == -lsb;
13418 shift_mask_low = ~0;
13419 shift_mask_low <<= INTVAL (shiftop);
13423 if (-lsb != shift_mask_low)
13426 if (HOST_BITS_PER_WIDE_INT < 64)
13431 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13433 lsb = high & -high;
13434 return high == -lsb;
13438 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13444 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13445 to perform a left shift. It must have SHIFTOP or more least
13446 significant 0's, with the remainder of the word 1's. */
13449 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13451 if (GET_CODE (andop) == CONST_INT)
13453 HOST_WIDE_INT c, lsb, shift_mask;
13456 shift_mask <<= INTVAL (shiftop);
13457 c = INTVAL (andop);
13459 /* Find the least significant one bit. */
13462 /* It must be covered by the shift mask.
13463 This test also rejects c == 0. */
13464 if ((lsb & shift_mask) == 0)
13467 /* Check we have all 1's above the transition, and reject all 1's. */
13468 return c == -lsb && lsb != 1;
13470 else if (GET_CODE (andop) == CONST_DOUBLE
13471 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13473 HOST_WIDE_INT low, lsb, shift_mask_low;
13475 low = CONST_DOUBLE_LOW (andop);
13477 if (HOST_BITS_PER_WIDE_INT < 64)
13479 HOST_WIDE_INT high, shift_mask_high;
13481 high = CONST_DOUBLE_HIGH (andop);
13485 shift_mask_high = ~0;
13486 if (INTVAL (shiftop) > 32)
13487 shift_mask_high <<= INTVAL (shiftop) - 32;
13489 lsb = high & -high;
13491 if ((lsb & shift_mask_high) == 0)
13494 return high == -lsb;
13500 shift_mask_low = ~0;
13501 shift_mask_low <<= INTVAL (shiftop);
13505 if ((lsb & shift_mask_low) == 0)
13508 return low == -lsb && lsb != 1;
13514 /* Return 1 if operands will generate a valid arguments to rlwimi
13515 instruction for insert with right shift in 64-bit mode. The mask may
13516 not start on the first bit or stop on the last bit because wrap-around
13517 effects of instruction do not correspond to semantics of RTL insn. */
13520 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13522 if (INTVAL (startop) > 32
13523 && INTVAL (startop) < 64
13524 && INTVAL (sizeop) > 1
13525 && INTVAL (sizeop) + INTVAL (startop) < 64
13526 && INTVAL (shiftop) > 0
13527 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13528 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
13534 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13535 for lfq and stfq insns iff the registers are hard registers. */
13538 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
13540 /* We might have been passed a SUBREG. */
13541 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
13544 /* We might have been passed non floating point registers. */
13545 if (!FP_REGNO_P (REGNO (reg1))
13546 || !FP_REGNO_P (REGNO (reg2)))
13549 return (REGNO (reg1) == REGNO (reg2) - 1);
13552 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13553 addr1 and addr2 must be in consecutive memory locations
13554 (addr2 == addr1 + 8). */
13557 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
13560 unsigned int reg1, reg2;
13561 int offset1, offset2;
13563 /* The mems cannot be volatile. */
13564 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
13567 addr1 = XEXP (mem1, 0);
13568 addr2 = XEXP (mem2, 0);
13570 /* Extract an offset (if used) from the first addr. */
13571 if (GET_CODE (addr1) == PLUS)
13573 /* If not a REG, return zero. */
13574 if (GET_CODE (XEXP (addr1, 0)) != REG)
13578 reg1 = REGNO (XEXP (addr1, 0));
13579 /* The offset must be constant! */
13580 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13582 offset1 = INTVAL (XEXP (addr1, 1));
13585 else if (GET_CODE (addr1) != REG)
13589 reg1 = REGNO (addr1);
13590 /* This was a simple (mem (reg)) expression. Offset is 0. */
13594 /* And now for the second addr. */
13595 if (GET_CODE (addr2) == PLUS)
13597 /* If not a REG, return zero. */
13598 if (GET_CODE (XEXP (addr2, 0)) != REG)
13602 reg2 = REGNO (XEXP (addr2, 0));
13603 /* The offset must be constant. */
13604 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
13606 offset2 = INTVAL (XEXP (addr2, 1));
13609 else if (GET_CODE (addr2) != REG)
13613 reg2 = REGNO (addr2);
13614 /* This was a simple (mem (reg)) expression. Offset is 0. */
13618 /* Both of these must have the same base register. */
13622 /* The offset for the second addr must be 8 more than the first addr. */
13623 if (offset2 != offset1 + 8)
13626 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13633 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13635 static bool eliminated = false;
13638 if (mode != SDmode)
13639 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13642 rtx mem = cfun->machine->sdmode_stack_slot;
13643 gcc_assert (mem != NULL_RTX);
13647 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13648 cfun->machine->sdmode_stack_slot = mem;
13654 if (TARGET_DEBUG_ADDR)
13656 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13657 GET_MODE_NAME (mode));
13659 fprintf (stderr, "\tNULL_RTX\n");
13668 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13670 /* Don't walk into types. */
13671 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13673 *walk_subtrees = 0;
13677 switch (TREE_CODE (*tp))
13686 case ALIGN_INDIRECT_REF:
13687 case MISALIGNED_INDIRECT_REF:
13688 case VIEW_CONVERT_EXPR:
13689 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13699 enum reload_reg_type {
13701 VECTOR_REGISTER_TYPE,
13702 OTHER_REGISTER_TYPE
13705 static enum reload_reg_type
13706 rs6000_reload_register_type (enum reg_class rclass)
13712 return GPR_REGISTER_TYPE;
13717 return VECTOR_REGISTER_TYPE;
13720 return OTHER_REGISTER_TYPE;
13724 /* Inform reload about cases where moving X with a mode MODE to a register in
13725 RCLASS requires an extra scratch or immediate register. Return the class
13726 needed for the immediate register.
13728 For VSX and Altivec, we may need a register to convert sp+offset into
13731 static enum reg_class
13732 rs6000_secondary_reload (bool in_p,
13734 enum reg_class rclass,
13735 enum machine_mode mode,
13736 secondary_reload_info *sri)
13738 enum reg_class ret = ALL_REGS;
13739 enum insn_code icode;
13740 bool default_p = false;
13742 sri->icode = CODE_FOR_nothing;
13744 /* Convert vector loads and stores into gprs to use an additional base
13746 icode = rs6000_vector_reload[mode][in_p != false];
13747 if (icode != CODE_FOR_nothing)
13750 sri->icode = CODE_FOR_nothing;
13751 sri->extra_cost = 0;
13753 if (GET_CODE (x) == MEM)
13755 rtx addr = XEXP (x, 0);
13757 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13758 an extra register in that case, but it would need an extra
13759 register if the addressing is reg+reg or (reg+reg)&(-16). */
13760 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13762 if (!legitimate_indirect_address_p (addr, false)
13763 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13765 sri->icode = icode;
13766 /* account for splitting the loads, and converting the
13767 address from reg+reg to reg. */
13768 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13769 + ((GET_CODE (addr) == AND) ? 1 : 0));
13772 /* Loads to and stores from vector registers can only do reg+reg
13773 addressing. Altivec registers can also do (reg+reg)&(-16). */
13774 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13775 || rclass == FLOAT_REGS || rclass == NO_REGS)
13777 if (!VECTOR_MEM_ALTIVEC_P (mode)
13778 && GET_CODE (addr) == AND
13779 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13780 && INTVAL (XEXP (addr, 1)) == -16
13781 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13782 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13784 sri->icode = icode;
13785 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13788 else if (!legitimate_indirect_address_p (addr, false)
13789 && (rclass == NO_REGS
13790 || !legitimate_indexed_address_p (addr, false)))
13792 sri->icode = icode;
13793 sri->extra_cost = 1;
13796 icode = CODE_FOR_nothing;
13798 /* Any other loads, including to pseudo registers which haven't been
13799 assigned to a register yet, default to require a scratch
13803 sri->icode = icode;
13804 sri->extra_cost = 2;
13807 else if (REG_P (x))
13809 int regno = true_regnum (x);
13811 icode = CODE_FOR_nothing;
13812 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13816 enum reg_class xclass = REGNO_REG_CLASS (regno);
13817 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13818 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13820 /* If memory is needed, use default_secondary_reload to create the
13822 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13835 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13837 gcc_assert (ret != ALL_REGS);
13839 if (TARGET_DEBUG_ADDR)
13842 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13844 reg_class_names[ret],
13845 in_p ? "true" : "false",
13846 reg_class_names[rclass],
13847 GET_MODE_NAME (mode));
13850 fprintf (stderr, ", default secondary reload");
13852 if (sri->icode != CODE_FOR_nothing)
13853 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13854 insn_data[sri->icode].name, sri->extra_cost);
13856 fprintf (stderr, "\n");
13864 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13865 to SP+reg addressing. */
13868 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13870 int regno = true_regnum (reg);
13871 enum machine_mode mode = GET_MODE (reg);
13872 enum reg_class rclass;
13874 rtx and_op2 = NULL_RTX;
13877 rtx scratch_or_premodify = scratch;
13881 if (TARGET_DEBUG_ADDR)
13883 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13884 store_p ? "store" : "load");
13885 fprintf (stderr, "reg:\n");
13887 fprintf (stderr, "mem:\n");
13889 fprintf (stderr, "scratch:\n");
13890 debug_rtx (scratch);
13893 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13894 gcc_assert (GET_CODE (mem) == MEM);
13895 rclass = REGNO_REG_CLASS (regno);
13896 addr = XEXP (mem, 0);
13900 /* GPRs can handle reg + small constant, all other addresses need to use
13901 the scratch register. */
13904 if (GET_CODE (addr) == AND)
13906 and_op2 = XEXP (addr, 1);
13907 addr = XEXP (addr, 0);
13910 if (GET_CODE (addr) == PRE_MODIFY)
13912 scratch_or_premodify = XEXP (addr, 0);
13913 gcc_assert (REG_P (scratch_or_premodify));
13914 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13915 addr = XEXP (addr, 1);
13918 if (GET_CODE (addr) == PLUS
13919 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13920 || and_op2 != NULL_RTX))
13922 addr_op1 = XEXP (addr, 0);
13923 addr_op2 = XEXP (addr, 1);
13924 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13926 if (!REG_P (addr_op2)
13927 && (GET_CODE (addr_op2) != CONST_INT
13928 || !satisfies_constraint_I (addr_op2)))
13930 if (TARGET_DEBUG_ADDR)
13933 "\nMove plus addr to register %s, mode = %s: ",
13934 rs6000_reg_names[REGNO (scratch)],
13935 GET_MODE_NAME (mode));
13936 debug_rtx (addr_op2);
13938 rs6000_emit_move (scratch, addr_op2, Pmode);
13939 addr_op2 = scratch;
13942 emit_insn (gen_rtx_SET (VOIDmode,
13943 scratch_or_premodify,
13944 gen_rtx_PLUS (Pmode,
13948 addr = scratch_or_premodify;
13949 scratch_or_premodify = scratch;
13951 else if (!legitimate_indirect_address_p (addr, false)
13952 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13954 if (TARGET_DEBUG_ADDR)
13956 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13957 rs6000_reg_names[REGNO (scratch_or_premodify)],
13958 GET_MODE_NAME (mode));
13961 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13962 addr = scratch_or_premodify;
13963 scratch_or_premodify = scratch;
13967 /* Float/Altivec registers can only handle reg+reg addressing. Move
13968 other addresses into a scratch register. */
13973 /* With float regs, we need to handle the AND ourselves, since we can't
13974 use the Altivec instruction with an implicit AND -16. Allow scalar
13975 loads to float registers to use reg+offset even if VSX. */
13976 if (GET_CODE (addr) == AND
13977 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13978 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13979 || INTVAL (XEXP (addr, 1)) != -16
13980 || !VECTOR_MEM_ALTIVEC_P (mode)))
13982 and_op2 = XEXP (addr, 1);
13983 addr = XEXP (addr, 0);
13986 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13987 as the address later. */
13988 if (GET_CODE (addr) == PRE_MODIFY
13989 && (!VECTOR_MEM_VSX_P (mode)
13990 || and_op2 != NULL_RTX
13991 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13993 scratch_or_premodify = XEXP (addr, 0);
13994 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13996 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13997 addr = XEXP (addr, 1);
14000 if (legitimate_indirect_address_p (addr, false) /* reg */
14001 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14002 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14003 || (GET_CODE (addr) == AND /* Altivec memory */
14004 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14005 && INTVAL (XEXP (addr, 1)) == -16
14006 && VECTOR_MEM_ALTIVEC_P (mode))
14007 || (rclass == FLOAT_REGS /* legacy float mem */
14008 && GET_MODE_SIZE (mode) == 8
14009 && and_op2 == NULL_RTX
14010 && scratch_or_premodify == scratch
14011 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14014 else if (GET_CODE (addr) == PLUS)
14016 addr_op1 = XEXP (addr, 0);
14017 addr_op2 = XEXP (addr, 1);
14018 gcc_assert (REG_P (addr_op1));
14020 if (TARGET_DEBUG_ADDR)
14022 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14023 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14024 debug_rtx (addr_op2);
14026 rs6000_emit_move (scratch, addr_op2, Pmode);
14027 emit_insn (gen_rtx_SET (VOIDmode,
14028 scratch_or_premodify,
14029 gen_rtx_PLUS (Pmode,
14032 addr = scratch_or_premodify;
14033 scratch_or_premodify = scratch;
14036 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14037 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14039 if (TARGET_DEBUG_ADDR)
14041 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14042 rs6000_reg_names[REGNO (scratch_or_premodify)],
14043 GET_MODE_NAME (mode));
14047 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14048 addr = scratch_or_premodify;
14049 scratch_or_premodify = scratch;
14053 gcc_unreachable ();
14058 gcc_unreachable ();
14061 /* If the original address involved a pre-modify that we couldn't use the VSX
14062 memory instruction with update, and we haven't taken care of already,
14063 store the address in the pre-modify register and use that as the
14065 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14067 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14068 addr = scratch_or_premodify;
14071 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14072 memory instruction, recreate the AND now, including the clobber which is
14073 generated by the general ANDSI3/ANDDI3 patterns for the
14074 andi. instruction. */
14075 if (and_op2 != NULL_RTX)
14077 if (! legitimate_indirect_address_p (addr, false))
14079 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14083 if (TARGET_DEBUG_ADDR)
14085 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14086 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14087 debug_rtx (and_op2);
14090 and_rtx = gen_rtx_SET (VOIDmode,
14092 gen_rtx_AND (Pmode,
14096 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14097 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14098 gen_rtvec (2, and_rtx, cc_clobber)));
14102 /* Adjust the address if it changed. */
14103 if (addr != XEXP (mem, 0))
14105 mem = change_address (mem, mode, addr);
14106 if (TARGET_DEBUG_ADDR)
14107 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14110 /* Now create the move. */
14112 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14114 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14119 /* Target hook to return the cover classes for Integrated Register Allocator.
14120 Cover classes is a set of non-intersected register classes covering all hard
14121 registers used for register allocation purpose. Any move between two
14122 registers of a cover class should be cheaper than load or store of the
14123 registers. The value is array of register classes with LIM_REG_CLASSES used
14126 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14127 account for the Altivec and Floating registers being subsets of the VSX
14128 register set under VSX, but distinct register sets on pre-VSX machines. */
14130 static const enum reg_class *
14131 rs6000_ira_cover_classes (void)
14133 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
14134 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
14136 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
14139 /* Allocate a 64-bit stack slot to be used for copying SDmode
14140 values through if this function has any SDmode references. */
14143 rs6000_alloc_sdmode_stack_slot (void)
14147 gimple_stmt_iterator gsi;
14149 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14152 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14154 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14157 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14158 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14164 /* Check for any SDmode parameters of the function. */
14165 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
14167 if (TREE_TYPE (t) == error_mark_node)
14170 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14171 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14173 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14174 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14182 rs6000_instantiate_decls (void)
14184 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14185 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14188 /* Given an rtx X being reloaded into a reg required to be
14189 in class CLASS, return the class of reg to actually use.
14190 In general this is just CLASS; but on some machines
14191 in some cases it is preferable to use a more restrictive class.
14193 On the RS/6000, we have to return NO_REGS when we want to reload a
14194 floating-point CONST_DOUBLE to force it to be copied to memory.
14196 We also don't want to reload integer values into floating-point
14197 registers if we can at all help it. In fact, this can
14198 cause reload to die, if it tries to generate a reload of CTR
14199 into a FP register and discovers it doesn't have the memory location
14202 ??? Would it be a good idea to have reload do the converse, that is
14203 try to reload floating modes into FP registers if possible?
14206 static enum reg_class
14207 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14209 enum machine_mode mode = GET_MODE (x);
14211 if (VECTOR_UNIT_VSX_P (mode)
14212 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14215 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14216 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14217 && easy_vector_constant (x, mode))
14218 return ALTIVEC_REGS;
14220 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14223 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14224 return GENERAL_REGS;
14226 /* For VSX, prefer the traditional registers for 64-bit values because we can
14227 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14228 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14229 prefer Altivec loads.. */
14230 if (rclass == VSX_REGS)
14232 if (GET_MODE_SIZE (mode) <= 8)
14235 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14236 return ALTIVEC_REGS;
14244 /* Debug version of rs6000_preferred_reload_class. */
14245 static enum reg_class
14246 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14248 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14251 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14253 reg_class_names[ret], reg_class_names[rclass],
14254 GET_MODE_NAME (GET_MODE (x)));
14260 /* If we are copying between FP or AltiVec registers and anything else, we need
14261 a memory location. The exception is when we are targeting ppc64 and the
14262 move to/from fpr to gpr instructions are available. Also, under VSX, you
14263 can copy vector registers from the FP register set to the Altivec register
14264 set and vice versa. */
14267 rs6000_secondary_memory_needed (enum reg_class class1,
14268 enum reg_class class2,
14269 enum machine_mode mode)
14271 if (class1 == class2)
14274 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14275 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14276 between these classes. But we need memory for other things that can go in
14277 FLOAT_REGS like SFmode. */
14279 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14280 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14281 || class1 == FLOAT_REGS))
14282 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14283 && class2 != FLOAT_REGS);
14285 if (class1 == VSX_REGS || class2 == VSX_REGS)
14288 if (class1 == FLOAT_REGS
14289 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14290 || ((mode != DFmode)
14291 && (mode != DDmode)
14292 && (mode != DImode))))
14295 if (class2 == FLOAT_REGS
14296 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14297 || ((mode != DFmode)
14298 && (mode != DDmode)
14299 && (mode != DImode))))
14302 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14308 /* Debug version of rs6000_secondary_memory_needed. */
14310 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14311 enum reg_class class2,
14312 enum machine_mode mode)
14314 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14317 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14318 "class2 = %s, mode = %s\n",
14319 ret ? "true" : "false", reg_class_names[class1],
14320 reg_class_names[class2], GET_MODE_NAME (mode));
14325 /* Return the register class of a scratch register needed to copy IN into
14326 or out of a register in RCLASS in MODE. If it can be done directly,
14327 NO_REGS is returned. */
14329 static enum reg_class
14330 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14335 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14337 && MACHOPIC_INDIRECT
14341 /* We cannot copy a symbolic operand directly into anything
14342 other than BASE_REGS for TARGET_ELF. So indicate that a
14343 register from BASE_REGS is needed as an intermediate
14346 On Darwin, pic addresses require a load from memory, which
14347 needs a base register. */
14348 if (rclass != BASE_REGS
14349 && (GET_CODE (in) == SYMBOL_REF
14350 || GET_CODE (in) == HIGH
14351 || GET_CODE (in) == LABEL_REF
14352 || GET_CODE (in) == CONST))
14356 if (GET_CODE (in) == REG)
14358 regno = REGNO (in);
14359 if (regno >= FIRST_PSEUDO_REGISTER)
14361 regno = true_regnum (in);
14362 if (regno >= FIRST_PSEUDO_REGISTER)
14366 else if (GET_CODE (in) == SUBREG)
14368 regno = true_regnum (in);
14369 if (regno >= FIRST_PSEUDO_REGISTER)
14375 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14377 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14378 || (regno >= 0 && INT_REGNO_P (regno)))
14381 /* Constants, memory, and FP registers can go into FP registers. */
14382 if ((regno == -1 || FP_REGNO_P (regno))
14383 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14384 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14386 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14389 && (regno == -1 || VSX_REGNO_P (regno))
14390 && VSX_REG_CLASS_P (rclass))
14393 /* Memory, and AltiVec registers can go into AltiVec registers. */
14394 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14395 && rclass == ALTIVEC_REGS)
14398 /* We can copy among the CR registers. */
14399 if ((rclass == CR_REGS || rclass == CR0_REGS)
14400 && regno >= 0 && CR_REGNO_P (regno))
14403 /* Otherwise, we need GENERAL_REGS. */
14404 return GENERAL_REGS;
14407 /* Debug version of rs6000_secondary_reload_class. */
14408 static enum reg_class
14409 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14410 enum machine_mode mode, rtx in)
14412 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14414 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14415 "mode = %s, input rtx:\n",
14416 reg_class_names[ret], reg_class_names[rclass],
14417 GET_MODE_NAME (mode));
14423 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14426 rs6000_cannot_change_mode_class (enum machine_mode from,
14427 enum machine_mode to,
14428 enum reg_class rclass)
14430 unsigned from_size = GET_MODE_SIZE (from);
14431 unsigned to_size = GET_MODE_SIZE (to);
14433 if (from_size != to_size)
14435 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14436 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14437 && reg_classes_intersect_p (xclass, rclass));
14440 if (TARGET_E500_DOUBLE
14441 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14442 || (((to) == TFmode) + ((from) == TFmode)) == 1
14443 || (((to) == DDmode) + ((from) == DDmode)) == 1
14444 || (((to) == TDmode) + ((from) == TDmode)) == 1
14445 || (((to) == DImode) + ((from) == DImode)) == 1))
14448 /* Since the VSX register set includes traditional floating point registers
14449 and altivec registers, just check for the size being different instead of
14450 trying to check whether the modes are vector modes. Otherwise it won't
14451 allow say DF and DI to change classes. */
14452 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14453 return (from_size != 8 && from_size != 16);
14455 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14456 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14459 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14460 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14466 /* Debug version of rs6000_cannot_change_mode_class. */
14468 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14469 enum machine_mode to,
14470 enum reg_class rclass)
14472 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
14475 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14476 "to = %s, rclass = %s\n",
14477 ret ? "true" : "false",
14478 GET_MODE_NAME (from), GET_MODE_NAME (to),
14479 reg_class_names[rclass]);
14484 /* Given a comparison operation, return the bit number in CCR to test. We
14485 know this is a valid comparison.
14487 SCC_P is 1 if this is for an scc. That means that %D will have been
14488 used instead of %C, so the bits will be in different places.
14490 Return -1 if OP isn't a valid comparison for some reason. */
14493 ccr_bit (rtx op, int scc_p)
14495 enum rtx_code code = GET_CODE (op);
14496 enum machine_mode cc_mode;
14501 if (!COMPARISON_P (op))
14504 reg = XEXP (op, 0);
14506 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14508 cc_mode = GET_MODE (reg);
14509 cc_regnum = REGNO (reg);
14510 base_bit = 4 * (cc_regnum - CR0_REGNO);
14512 validate_condition_mode (code, cc_mode);
14514 /* When generating a sCOND operation, only positive conditions are
14517 || code == EQ || code == GT || code == LT || code == UNORDERED
14518 || code == GTU || code == LTU);
14523 return scc_p ? base_bit + 3 : base_bit + 2;
14525 return base_bit + 2;
14526 case GT: case GTU: case UNLE:
14527 return base_bit + 1;
14528 case LT: case LTU: case UNGE:
14530 case ORDERED: case UNORDERED:
14531 return base_bit + 3;
14534 /* If scc, we will have done a cror to put the bit in the
14535 unordered position. So test that bit. For integer, this is ! LT
14536 unless this is an scc insn. */
14537 return scc_p ? base_bit + 3 : base_bit;
14540 return scc_p ? base_bit + 3 : base_bit + 1;
14543 gcc_unreachable ();
14547 /* Return the GOT register. */
14550 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
14552 /* The second flow pass currently (June 1999) can't update
14553 regs_ever_live without disturbing other parts of the compiler, so
14554 update it here to make the prolog/epilogue code happy. */
14555 if (!can_create_pseudo_p ()
14556 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
14557 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
14559 crtl->uses_pic_offset_table = 1;
14561 return pic_offset_table_rtx;
14564 /* Function to init struct machine_function.
14565 This will be called, via a pointer variable,
14566 from push_function_context. */
14568 static struct machine_function *
14569 rs6000_init_machine_status (void)
14571 return ggc_alloc_cleared_machine_function ();
14574 /* These macros test for integers and extract the low-order bits. */
14576 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
14577 && GET_MODE (X) == VOIDmode)
14579 #define INT_LOWPART(X) \
14580 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
14583 extract_MB (rtx op)
14586 unsigned long val = INT_LOWPART (op);
14588 /* If the high bit is zero, the value is the first 1 bit we find
14590 if ((val & 0x80000000) == 0)
14592 gcc_assert (val & 0xffffffff);
14595 while (((val <<= 1) & 0x80000000) == 0)
14600 /* If the high bit is set and the low bit is not, or the mask is all
14601 1's, the value is zero. */
14602 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14605 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14608 while (((val >>= 1) & 1) != 0)
14615 extract_ME (rtx op)
14618 unsigned long val = INT_LOWPART (op);
14620 /* If the low bit is zero, the value is the first 1 bit we find from
14622 if ((val & 1) == 0)
14624 gcc_assert (val & 0xffffffff);
14627 while (((val >>= 1) & 1) == 0)
14633 /* If the low bit is set and the high bit is not, or the mask is all
14634 1's, the value is 31. */
14635 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14638 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14641 while (((val <<= 1) & 0x80000000) != 0)
14647 /* Locate some local-dynamic symbol still in use by this function
14648 so that we can print its name in some tls_ld pattern. */
14650 static const char *
14651 rs6000_get_some_local_dynamic_name (void)
14655 if (cfun->machine->some_ld_name)
14656 return cfun->machine->some_ld_name;
14658 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14660 && for_each_rtx (&PATTERN (insn),
14661 rs6000_get_some_local_dynamic_name_1, 0))
14662 return cfun->machine->some_ld_name;
14664 gcc_unreachable ();
14667 /* Helper function for rs6000_get_some_local_dynamic_name. */
14670 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14674 if (GET_CODE (x) == SYMBOL_REF)
14676 const char *str = XSTR (x, 0);
14677 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14679 cfun->machine->some_ld_name = str;
14687 /* Write out a function code label. */
14690 rs6000_output_function_entry (FILE *file, const char *fname)
14692 if (fname[0] != '.')
14694 switch (DEFAULT_ABI)
14697 gcc_unreachable ();
14703 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14712 RS6000_OUTPUT_BASENAME (file, fname);
14715 /* Print an operand. Recognize special options, documented below. */
14718 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14719 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14721 #define SMALL_DATA_RELOC "sda21"
14722 #define SMALL_DATA_REG 0
14726 print_operand (FILE *file, rtx x, int code)
14730 unsigned HOST_WIDE_INT uval;
14735 /* Write out an instruction after the call which may be replaced
14736 with glue code by the loader. This depends on the AIX version. */
14737 asm_fprintf (file, RS6000_CALL_GLUE);
14740 /* %a is output_address. */
14743 /* If X is a constant integer whose low-order 5 bits are zero,
14744 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14745 in the AIX assembler where "sri" with a zero shift count
14746 writes a trash instruction. */
14747 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14754 /* If constant, low-order 16 bits of constant, unsigned.
14755 Otherwise, write normally. */
14757 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14759 print_operand (file, x, 0);
14763 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14764 for 64-bit mask direction. */
14765 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14768 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14772 /* X is a CR register. Print the number of the GT bit of the CR. */
14773 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14774 output_operand_lossage ("invalid %%c value");
14776 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14780 /* Like 'J' but get to the GT bit only. */
14781 gcc_assert (GET_CODE (x) == REG);
14783 /* Bit 1 is GT bit. */
14784 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14786 /* Add one for shift count in rlinm for scc. */
14787 fprintf (file, "%d", i + 1);
14791 /* X is a CR register. Print the number of the EQ bit of the CR */
14792 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14793 output_operand_lossage ("invalid %%E value");
14795 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14799 /* X is a CR register. Print the shift count needed to move it
14800 to the high-order four bits. */
14801 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14802 output_operand_lossage ("invalid %%f value");
14804 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14808 /* Similar, but print the count for the rotate in the opposite
14810 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14811 output_operand_lossage ("invalid %%F value");
14813 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14817 /* X is a constant integer. If it is negative, print "m",
14818 otherwise print "z". This is to make an aze or ame insn. */
14819 if (GET_CODE (x) != CONST_INT)
14820 output_operand_lossage ("invalid %%G value");
14821 else if (INTVAL (x) >= 0)
14828 /* If constant, output low-order five bits. Otherwise, write
14831 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14833 print_operand (file, x, 0);
14837 /* If constant, output low-order six bits. Otherwise, write
14840 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14842 print_operand (file, x, 0);
14846 /* Print `i' if this is a constant, else nothing. */
14852 /* Write the bit number in CCR for jump. */
14853 i = ccr_bit (x, 0);
14855 output_operand_lossage ("invalid %%j code");
14857 fprintf (file, "%d", i);
14861 /* Similar, but add one for shift count in rlinm for scc and pass
14862 scc flag to `ccr_bit'. */
14863 i = ccr_bit (x, 1);
14865 output_operand_lossage ("invalid %%J code");
14867 /* If we want bit 31, write a shift count of zero, not 32. */
14868 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14872 /* X must be a constant. Write the 1's complement of the
14875 output_operand_lossage ("invalid %%k value");
14877 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14881 /* X must be a symbolic constant on ELF. Write an
14882 expression suitable for an 'addi' that adds in the low 16
14883 bits of the MEM. */
14884 if (GET_CODE (x) == CONST)
14886 if (GET_CODE (XEXP (x, 0)) != PLUS
14887 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14888 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14889 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14890 output_operand_lossage ("invalid %%K value");
14892 print_operand_address (file, x);
14893 fputs ("@l", file);
14896 /* %l is output_asm_label. */
14899 /* Write second word of DImode or DFmode reference. Works on register
14900 or non-indexed memory only. */
14901 if (GET_CODE (x) == REG)
14902 fputs (reg_names[REGNO (x) + 1], file);
14903 else if (GET_CODE (x) == MEM)
14905 /* Handle possible auto-increment. Since it is pre-increment and
14906 we have already done it, we can just use an offset of word. */
14907 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14908 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14909 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14911 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14912 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14915 output_address (XEXP (adjust_address_nv (x, SImode,
14919 if (small_data_operand (x, GET_MODE (x)))
14920 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14921 reg_names[SMALL_DATA_REG]);
14926 /* MB value for a mask operand. */
14927 if (! mask_operand (x, SImode))
14928 output_operand_lossage ("invalid %%m value");
14930 fprintf (file, "%d", extract_MB (x));
14934 /* ME value for a mask operand. */
14935 if (! mask_operand (x, SImode))
14936 output_operand_lossage ("invalid %%M value");
14938 fprintf (file, "%d", extract_ME (x));
14941 /* %n outputs the negative of its operand. */
14944 /* Write the number of elements in the vector times 4. */
14945 if (GET_CODE (x) != PARALLEL)
14946 output_operand_lossage ("invalid %%N value");
14948 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14952 /* Similar, but subtract 1 first. */
14953 if (GET_CODE (x) != PARALLEL)
14954 output_operand_lossage ("invalid %%O value");
14956 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14960 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14962 || INT_LOWPART (x) < 0
14963 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14964 output_operand_lossage ("invalid %%p value");
14966 fprintf (file, "%d", i);
14970 /* The operand must be an indirect memory reference. The result
14971 is the register name. */
14972 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14973 || REGNO (XEXP (x, 0)) >= 32)
14974 output_operand_lossage ("invalid %%P value");
14976 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14980 /* This outputs the logical code corresponding to a boolean
14981 expression. The expression may have one or both operands
14982 negated (if one, only the first one). For condition register
14983 logical operations, it will also treat the negated
14984 CR codes as NOTs, but not handle NOTs of them. */
14986 const char *const *t = 0;
14988 enum rtx_code code = GET_CODE (x);
14989 static const char * const tbl[3][3] = {
14990 { "and", "andc", "nor" },
14991 { "or", "orc", "nand" },
14992 { "xor", "eqv", "xor" } };
14996 else if (code == IOR)
14998 else if (code == XOR)
15001 output_operand_lossage ("invalid %%q value");
15003 if (GET_CODE (XEXP (x, 0)) != NOT)
15007 if (GET_CODE (XEXP (x, 1)) == NOT)
15025 /* X is a CR register. Print the mask for `mtcrf'. */
15026 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15027 output_operand_lossage ("invalid %%R value");
15029 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15033 /* Low 5 bits of 32 - value */
15035 output_operand_lossage ("invalid %%s value");
15037 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15041 /* PowerPC64 mask position. All 0's is excluded.
15042 CONST_INT 32-bit mask is considered sign-extended so any
15043 transition must occur within the CONST_INT, not on the boundary. */
15044 if (! mask64_operand (x, DImode))
15045 output_operand_lossage ("invalid %%S value");
15047 uval = INT_LOWPART (x);
15049 if (uval & 1) /* Clear Left */
15051 #if HOST_BITS_PER_WIDE_INT > 64
15052 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15056 else /* Clear Right */
15059 #if HOST_BITS_PER_WIDE_INT > 64
15060 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15066 gcc_assert (i >= 0);
15067 fprintf (file, "%d", i);
15071 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15072 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15074 /* Bit 3 is OV bit. */
15075 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15077 /* If we want bit 31, write a shift count of zero, not 32. */
15078 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15082 /* Print the symbolic name of a branch target register. */
15083 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15084 && REGNO (x) != CTR_REGNO))
15085 output_operand_lossage ("invalid %%T value");
15086 else if (REGNO (x) == LR_REGNO)
15087 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15089 fputs ("ctr", file);
15093 /* High-order 16 bits of constant for use in unsigned operand. */
15095 output_operand_lossage ("invalid %%u value");
15097 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15098 (INT_LOWPART (x) >> 16) & 0xffff);
15102 /* High-order 16 bits of constant for use in signed operand. */
15104 output_operand_lossage ("invalid %%v value");
15106 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15107 (INT_LOWPART (x) >> 16) & 0xffff);
15111 /* Print `u' if this has an auto-increment or auto-decrement. */
15112 if (GET_CODE (x) == MEM
15113 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15114 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15115 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15120 /* Print the trap code for this operand. */
15121 switch (GET_CODE (x))
15124 fputs ("eq", file); /* 4 */
15127 fputs ("ne", file); /* 24 */
15130 fputs ("lt", file); /* 16 */
15133 fputs ("le", file); /* 20 */
15136 fputs ("gt", file); /* 8 */
15139 fputs ("ge", file); /* 12 */
15142 fputs ("llt", file); /* 2 */
15145 fputs ("lle", file); /* 6 */
15148 fputs ("lgt", file); /* 1 */
15151 fputs ("lge", file); /* 5 */
15154 gcc_unreachable ();
15159 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15162 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15163 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15165 print_operand (file, x, 0);
15169 /* MB value for a PowerPC64 rldic operand. */
15170 val = (GET_CODE (x) == CONST_INT
15171 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15176 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15177 if ((val <<= 1) < 0)
15180 #if HOST_BITS_PER_WIDE_INT == 32
15181 if (GET_CODE (x) == CONST_INT && i >= 0)
15182 i += 32; /* zero-extend high-part was all 0's */
15183 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15185 val = CONST_DOUBLE_LOW (x);
15191 for ( ; i < 64; i++)
15192 if ((val <<= 1) < 0)
15197 fprintf (file, "%d", i + 1);
15201 /* X is a FPR or Altivec register used in a VSX context. */
15202 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15203 output_operand_lossage ("invalid %%x value");
15206 int reg = REGNO (x);
15207 int vsx_reg = (FP_REGNO_P (reg)
15209 : reg - FIRST_ALTIVEC_REGNO + 32);
15211 #ifdef TARGET_REGNAMES
15212 if (TARGET_REGNAMES)
15213 fprintf (file, "%%vs%d", vsx_reg);
15216 fprintf (file, "%d", vsx_reg);
15221 if (GET_CODE (x) == MEM
15222 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15223 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15224 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15229 /* Like 'L', for third word of TImode */
15230 if (GET_CODE (x) == REG)
15231 fputs (reg_names[REGNO (x) + 2], file);
15232 else if (GET_CODE (x) == MEM)
15234 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15235 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15236 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15237 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15238 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15240 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15241 if (small_data_operand (x, GET_MODE (x)))
15242 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15243 reg_names[SMALL_DATA_REG]);
15248 /* X is a SYMBOL_REF. Write out the name preceded by a
15249 period and without any trailing data in brackets. Used for function
15250 names. If we are configured for System V (or the embedded ABI) on
15251 the PowerPC, do not emit the period, since those systems do not use
15252 TOCs and the like. */
15253 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15255 /* Mark the decl as referenced so that cgraph will output the
15257 if (SYMBOL_REF_DECL (x))
15258 mark_decl_referenced (SYMBOL_REF_DECL (x));
15260 /* For macho, check to see if we need a stub. */
15263 const char *name = XSTR (x, 0);
15265 if (MACHOPIC_INDIRECT
15266 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15267 name = machopic_indirection_name (x, /*stub_p=*/true);
15269 assemble_name (file, name);
15271 else if (!DOT_SYMBOLS)
15272 assemble_name (file, XSTR (x, 0));
15274 rs6000_output_function_entry (file, XSTR (x, 0));
15278 /* Like 'L', for last word of TImode. */
15279 if (GET_CODE (x) == REG)
15280 fputs (reg_names[REGNO (x) + 3], file);
15281 else if (GET_CODE (x) == MEM)
15283 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15284 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15285 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15286 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15287 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15289 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15290 if (small_data_operand (x, GET_MODE (x)))
15291 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15292 reg_names[SMALL_DATA_REG]);
15296 /* Print AltiVec or SPE memory operand. */
15301 gcc_assert (GET_CODE (x) == MEM);
15305 /* Ugly hack because %y is overloaded. */
15306 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15307 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15308 || GET_MODE (x) == TFmode
15309 || GET_MODE (x) == TImode))
15311 /* Handle [reg]. */
15312 if (GET_CODE (tmp) == REG)
15314 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15317 /* Handle [reg+UIMM]. */
15318 else if (GET_CODE (tmp) == PLUS &&
15319 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15323 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15325 x = INTVAL (XEXP (tmp, 1));
15326 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15330 /* Fall through. Must be [reg+reg]. */
15332 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15333 && GET_CODE (tmp) == AND
15334 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15335 && INTVAL (XEXP (tmp, 1)) == -16)
15336 tmp = XEXP (tmp, 0);
15337 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15338 && GET_CODE (tmp) == PRE_MODIFY)
15339 tmp = XEXP (tmp, 1);
15340 if (GET_CODE (tmp) == REG)
15341 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15344 if (!GET_CODE (tmp) == PLUS
15345 || !REG_P (XEXP (tmp, 0))
15346 || !REG_P (XEXP (tmp, 1)))
15348 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15352 if (REGNO (XEXP (tmp, 0)) == 0)
15353 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15354 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15356 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15357 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15363 if (GET_CODE (x) == REG)
15364 fprintf (file, "%s", reg_names[REGNO (x)]);
15365 else if (GET_CODE (x) == MEM)
15367 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15368 know the width from the mode. */
15369 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15370 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15371 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15372 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15373 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15374 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15375 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15376 output_address (XEXP (XEXP (x, 0), 1));
15378 output_address (XEXP (x, 0));
15381 output_addr_const (file, x);
15385 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15389 output_operand_lossage ("invalid %%xn code");
15393 /* Print the address of an operand. */
15396 print_operand_address (FILE *file, rtx x)
15398 if (GET_CODE (x) == REG)
15399 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15400 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15401 || GET_CODE (x) == LABEL_REF)
15403 output_addr_const (file, x);
15404 if (small_data_operand (x, GET_MODE (x)))
15405 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15406 reg_names[SMALL_DATA_REG]);
15408 gcc_assert (!TARGET_TOC);
15410 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15412 gcc_assert (REG_P (XEXP (x, 0)));
15413 if (REGNO (XEXP (x, 0)) == 0)
15414 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15415 reg_names[ REGNO (XEXP (x, 0)) ]);
15417 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15418 reg_names[ REGNO (XEXP (x, 1)) ]);
15420 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15421 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15422 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15424 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15425 && CONSTANT_P (XEXP (x, 1)))
15427 fprintf (file, "lo16(");
15428 output_addr_const (file, XEXP (x, 1));
15429 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15432 else if (legitimate_constant_pool_address_p (x, true))
15434 /* This hack along with a corresponding hack in
15435 rs6000_output_addr_const_extra arranges to output addends
15436 where the assembler expects to find them. eg.
15438 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
15439 without this hack would be output as "x@toc+8@l(9)". We
15440 want "x+8@toc@l(9)". */
15441 output_addr_const (file, tocrel_base);
15442 if (GET_CODE (x) == LO_SUM)
15443 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15445 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15448 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15449 && CONSTANT_P (XEXP (x, 1)))
15451 output_addr_const (file, XEXP (x, 1));
15452 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15456 gcc_unreachable ();
15459 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
15462 rs6000_output_addr_const_extra (FILE *file, rtx x)
15464 if (GET_CODE (x) == UNSPEC)
15465 switch (XINT (x, 1))
15467 case UNSPEC_TOCREL:
15468 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
15469 output_addr_const (file, XVECEXP (x, 0, 0));
15470 if (x == tocrel_base && tocrel_offset != const0_rtx)
15472 if (INTVAL (tocrel_offset) >= 0)
15473 fprintf (file, "+");
15474 output_addr_const (file, tocrel_offset);
15476 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
15479 assemble_name (file, toc_label_name);
15481 else if (TARGET_ELF)
15482 fputs ("@toc", file);
15486 case UNSPEC_MACHOPIC_OFFSET:
15487 output_addr_const (file, XVECEXP (x, 0, 0));
15489 machopic_output_function_base_name (file);
15496 /* Target hook for assembling integer objects. The PowerPC version has
15497 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15498 is defined. It also needs to handle DI-mode objects on 64-bit
15502 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15504 #ifdef RELOCATABLE_NEEDS_FIXUP
15505 /* Special handling for SI values. */
15506 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
15508 static int recurse = 0;
15510 /* For -mrelocatable, we mark all addresses that need to be fixed up
15511 in the .fixup section. */
15512 if (TARGET_RELOCATABLE
15513 && in_section != toc_section
15514 && in_section != text_section
15515 && !unlikely_text_section_p (in_section)
15517 && GET_CODE (x) != CONST_INT
15518 && GET_CODE (x) != CONST_DOUBLE
15524 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
15526 ASM_OUTPUT_LABEL (asm_out_file, buf);
15527 fprintf (asm_out_file, "\t.long\t(");
15528 output_addr_const (asm_out_file, x);
15529 fprintf (asm_out_file, ")@fixup\n");
15530 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
15531 ASM_OUTPUT_ALIGN (asm_out_file, 2);
15532 fprintf (asm_out_file, "\t.long\t");
15533 assemble_name (asm_out_file, buf);
15534 fprintf (asm_out_file, "\n\t.previous\n");
15538 /* Remove initial .'s to turn a -mcall-aixdesc function
15539 address into the address of the descriptor, not the function
15541 else if (GET_CODE (x) == SYMBOL_REF
15542 && XSTR (x, 0)[0] == '.'
15543 && DEFAULT_ABI == ABI_AIX)
15545 const char *name = XSTR (x, 0);
15546 while (*name == '.')
15549 fprintf (asm_out_file, "\t.long\t%s\n", name);
15553 #endif /* RELOCATABLE_NEEDS_FIXUP */
15554 return default_assemble_integer (x, size, aligned_p);
15557 #ifdef HAVE_GAS_HIDDEN
15558 /* Emit an assembler directive to set symbol visibility for DECL to
15559 VISIBILITY_TYPE. */
15562 rs6000_assemble_visibility (tree decl, int vis)
15564 /* Functions need to have their entry point symbol visibility set as
15565 well as their descriptor symbol visibility. */
15566 if (DEFAULT_ABI == ABI_AIX
15568 && TREE_CODE (decl) == FUNCTION_DECL)
15570 static const char * const visibility_types[] = {
15571 NULL, "internal", "hidden", "protected"
15574 const char *name, *type;
15576 name = ((* targetm.strip_name_encoding)
15577 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
15578 type = visibility_types[vis];
15580 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
15581 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
15584 default_assemble_visibility (decl, vis);
15589 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15591 /* Reversal of FP compares takes care -- an ordered compare
15592 becomes an unordered compare and vice versa. */
15593 if (mode == CCFPmode
15594 && (!flag_finite_math_only
15595 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15596 || code == UNEQ || code == LTGT))
15597 return reverse_condition_maybe_unordered (code);
15599 return reverse_condition (code);
15602 /* Generate a compare for CODE. Return a brand-new rtx that
15603 represents the result of the compare. */
15606 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15608 enum machine_mode comp_mode;
15609 rtx compare_result;
15610 enum rtx_code code = GET_CODE (cmp);
15611 rtx op0 = XEXP (cmp, 0);
15612 rtx op1 = XEXP (cmp, 1);
15614 if (FLOAT_MODE_P (mode))
15615 comp_mode = CCFPmode;
15616 else if (code == GTU || code == LTU
15617 || code == GEU || code == LEU)
15618 comp_mode = CCUNSmode;
15619 else if ((code == EQ || code == NE)
15620 && GET_CODE (op0) == SUBREG
15621 && GET_CODE (op1) == SUBREG
15622 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15623 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15624 /* These are unsigned values, perhaps there will be a later
15625 ordering compare that can be shared with this one.
15626 Unfortunately we cannot detect the signedness of the operands
15627 for non-subregs. */
15628 comp_mode = CCUNSmode;
15630 comp_mode = CCmode;
15632 /* First, the compare. */
15633 compare_result = gen_reg_rtx (comp_mode);
15635 /* E500 FP compare instructions on the GPRs. Yuck! */
15636 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15637 && FLOAT_MODE_P (mode))
15639 rtx cmp, or_result, compare_result2;
15640 enum machine_mode op_mode = GET_MODE (op0);
15642 if (op_mode == VOIDmode)
15643 op_mode = GET_MODE (op1);
15645 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15646 This explains the following mess. */
15650 case EQ: case UNEQ: case NE: case LTGT:
15654 cmp = (flag_finite_math_only && !flag_trapping_math)
15655 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15656 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15660 cmp = (flag_finite_math_only && !flag_trapping_math)
15661 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15662 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15666 cmp = (flag_finite_math_only && !flag_trapping_math)
15667 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15668 : gen_cmptfeq_gpr (compare_result, op0, op1);
15672 gcc_unreachable ();
15676 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15680 cmp = (flag_finite_math_only && !flag_trapping_math)
15681 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15682 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15686 cmp = (flag_finite_math_only && !flag_trapping_math)
15687 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15688 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15692 cmp = (flag_finite_math_only && !flag_trapping_math)
15693 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15694 : gen_cmptfgt_gpr (compare_result, op0, op1);
15698 gcc_unreachable ();
15702 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15706 cmp = (flag_finite_math_only && !flag_trapping_math)
15707 ? gen_tstsflt_gpr (compare_result, op0, op1)
15708 : gen_cmpsflt_gpr (compare_result, op0, op1);
15712 cmp = (flag_finite_math_only && !flag_trapping_math)
15713 ? gen_tstdflt_gpr (compare_result, op0, op1)
15714 : gen_cmpdflt_gpr (compare_result, op0, op1);
15718 cmp = (flag_finite_math_only && !flag_trapping_math)
15719 ? gen_tsttflt_gpr (compare_result, op0, op1)
15720 : gen_cmptflt_gpr (compare_result, op0, op1);
15724 gcc_unreachable ();
15728 gcc_unreachable ();
15731 /* Synthesize LE and GE from LT/GT || EQ. */
15732 if (code == LE || code == GE || code == LEU || code == GEU)
15738 case LE: code = LT; break;
15739 case GE: code = GT; break;
15740 case LEU: code = LT; break;
15741 case GEU: code = GT; break;
15742 default: gcc_unreachable ();
15745 compare_result2 = gen_reg_rtx (CCFPmode);
15751 cmp = (flag_finite_math_only && !flag_trapping_math)
15752 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15753 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15757 cmp = (flag_finite_math_only && !flag_trapping_math)
15758 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15759 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15763 cmp = (flag_finite_math_only && !flag_trapping_math)
15764 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15765 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15769 gcc_unreachable ();
15773 /* OR them together. */
15774 or_result = gen_reg_rtx (CCFPmode);
15775 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15777 compare_result = or_result;
15782 if (code == NE || code == LTGT)
15792 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15793 CLOBBERs to match cmptf_internal2 pattern. */
15794 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15795 && GET_MODE (op0) == TFmode
15796 && !TARGET_IEEEQUAD
15797 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15798 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15800 gen_rtx_SET (VOIDmode,
15802 gen_rtx_COMPARE (comp_mode, op0, op1)),
15803 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15804 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15805 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15806 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15807 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15808 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15809 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15810 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15811 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
15812 else if (GET_CODE (op1) == UNSPEC
15813 && XINT (op1, 1) == UNSPEC_SP_TEST)
15815 rtx op1b = XVECEXP (op1, 0, 0);
15816 comp_mode = CCEQmode;
15817 compare_result = gen_reg_rtx (CCEQmode);
15819 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15821 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15824 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15825 gen_rtx_COMPARE (comp_mode, op0, op1)));
15828 /* Some kinds of FP comparisons need an OR operation;
15829 under flag_finite_math_only we don't bother. */
15830 if (FLOAT_MODE_P (mode)
15831 && !flag_finite_math_only
15832 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15833 && (code == LE || code == GE
15834 || code == UNEQ || code == LTGT
15835 || code == UNGT || code == UNLT))
15837 enum rtx_code or1, or2;
15838 rtx or1_rtx, or2_rtx, compare2_rtx;
15839 rtx or_result = gen_reg_rtx (CCEQmode);
15843 case LE: or1 = LT; or2 = EQ; break;
15844 case GE: or1 = GT; or2 = EQ; break;
15845 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15846 case LTGT: or1 = LT; or2 = GT; break;
15847 case UNGT: or1 = UNORDERED; or2 = GT; break;
15848 case UNLT: or1 = UNORDERED; or2 = LT; break;
15849 default: gcc_unreachable ();
15851 validate_condition_mode (or1, comp_mode);
15852 validate_condition_mode (or2, comp_mode);
15853 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15854 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15855 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15856 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15858 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15860 compare_result = or_result;
15864 validate_condition_mode (code, GET_MODE (compare_result));
15866 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15870 /* Emit the RTL for an sCOND pattern. */
15873 rs6000_emit_sISEL (enum machine_mode mode, rtx operands[])
15876 enum machine_mode op_mode;
15877 enum rtx_code cond_code;
15878 rtx result = operands[0];
15880 condition_rtx = rs6000_generate_compare (operands[1], mode);
15881 cond_code = GET_CODE (condition_rtx);
15883 op_mode = GET_MODE (XEXP (operands[1], 0));
15884 if (op_mode == VOIDmode)
15885 op_mode = GET_MODE (XEXP (operands[1], 1));
15887 if (TARGET_POWERPC64 && GET_MODE (result) == DImode)
15889 PUT_MODE (condition_rtx, DImode);
15890 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15891 || cond_code == LTU)
15892 emit_insn (gen_isel_unsigned_di (result, condition_rtx,
15893 force_reg (DImode, const1_rtx),
15894 force_reg (DImode, const0_rtx),
15895 XEXP (condition_rtx, 0)));
15897 emit_insn (gen_isel_signed_di (result, condition_rtx,
15898 force_reg (DImode, const1_rtx),
15899 force_reg (DImode, const0_rtx),
15900 XEXP (condition_rtx, 0)));
15904 PUT_MODE (condition_rtx, SImode);
15905 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15906 || cond_code == LTU)
15907 emit_insn (gen_isel_unsigned_si (result, condition_rtx,
15908 force_reg (SImode, const1_rtx),
15909 force_reg (SImode, const0_rtx),
15910 XEXP (condition_rtx, 0)));
15912 emit_insn (gen_isel_signed_si (result, condition_rtx,
15913 force_reg (SImode, const1_rtx),
15914 force_reg (SImode, const0_rtx),
15915 XEXP (condition_rtx, 0)));
15920 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15923 enum machine_mode op_mode;
15924 enum rtx_code cond_code;
15925 rtx result = operands[0];
15927 if (TARGET_ISEL && (mode == SImode || mode == DImode))
15929 rs6000_emit_sISEL (mode, operands);
15933 condition_rtx = rs6000_generate_compare (operands[1], mode);
15934 cond_code = GET_CODE (condition_rtx);
15936 if (FLOAT_MODE_P (mode)
15937 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15941 PUT_MODE (condition_rtx, SImode);
15942 t = XEXP (condition_rtx, 0);
15944 gcc_assert (cond_code == NE || cond_code == EQ);
15946 if (cond_code == NE)
15947 emit_insn (gen_e500_flip_gt_bit (t, t));
15949 emit_insn (gen_move_from_CR_gt_bit (result, t));
15953 if (cond_code == NE
15954 || cond_code == GE || cond_code == LE
15955 || cond_code == GEU || cond_code == LEU
15956 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15958 rtx not_result = gen_reg_rtx (CCEQmode);
15959 rtx not_op, rev_cond_rtx;
15960 enum machine_mode cc_mode;
15962 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15964 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15965 SImode, XEXP (condition_rtx, 0), const0_rtx);
15966 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15967 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15968 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15971 op_mode = GET_MODE (XEXP (operands[1], 0));
15972 if (op_mode == VOIDmode)
15973 op_mode = GET_MODE (XEXP (operands[1], 1));
15975 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15977 PUT_MODE (condition_rtx, DImode);
15978 convert_move (result, condition_rtx, 0);
15982 PUT_MODE (condition_rtx, SImode);
15983 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15987 /* Emit a branch of kind CODE to location LOC. */
15990 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15992 rtx condition_rtx, loc_ref;
15994 condition_rtx = rs6000_generate_compare (operands[0], mode);
15995 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15996 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15997 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15998 loc_ref, pc_rtx)));
16001 /* Return the string to output a conditional branch to LABEL, which is
16002 the operand number of the label, or -1 if the branch is really a
16003 conditional return.
16005 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16006 condition code register and its mode specifies what kind of
16007 comparison we made.
16009 REVERSED is nonzero if we should reverse the sense of the comparison.
16011 INSN is the insn. */
16014 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16016 static char string[64];
16017 enum rtx_code code = GET_CODE (op);
16018 rtx cc_reg = XEXP (op, 0);
16019 enum machine_mode mode = GET_MODE (cc_reg);
16020 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16021 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16022 int really_reversed = reversed ^ need_longbranch;
16028 validate_condition_mode (code, mode);
16030 /* Work out which way this really branches. We could use
16031 reverse_condition_maybe_unordered here always but this
16032 makes the resulting assembler clearer. */
16033 if (really_reversed)
16035 /* Reversal of FP compares takes care -- an ordered compare
16036 becomes an unordered compare and vice versa. */
16037 if (mode == CCFPmode)
16038 code = reverse_condition_maybe_unordered (code);
16040 code = reverse_condition (code);
16043 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16045 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16050 /* Opposite of GT. */
16059 gcc_unreachable ();
16065 /* Not all of these are actually distinct opcodes, but
16066 we distinguish them for clarity of the resulting assembler. */
16067 case NE: case LTGT:
16068 ccode = "ne"; break;
16069 case EQ: case UNEQ:
16070 ccode = "eq"; break;
16072 ccode = "ge"; break;
16073 case GT: case GTU: case UNGT:
16074 ccode = "gt"; break;
16076 ccode = "le"; break;
16077 case LT: case LTU: case UNLT:
16078 ccode = "lt"; break;
16079 case UNORDERED: ccode = "un"; break;
16080 case ORDERED: ccode = "nu"; break;
16081 case UNGE: ccode = "nl"; break;
16082 case UNLE: ccode = "ng"; break;
16084 gcc_unreachable ();
16087 /* Maybe we have a guess as to how likely the branch is.
16088 The old mnemonics don't have a way to specify this information. */
16090 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16091 if (note != NULL_RTX)
16093 /* PROB is the difference from 50%. */
16094 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16096 /* Only hint for highly probable/improbable branches on newer
16097 cpus as static prediction overrides processor dynamic
16098 prediction. For older cpus we may as well always hint, but
16099 assume not taken for branches that are very close to 50% as a
16100 mispredicted taken branch is more expensive than a
16101 mispredicted not-taken branch. */
16102 if (rs6000_always_hint
16103 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16104 && br_prob_note_reliable_p (note)))
16106 if (abs (prob) > REG_BR_PROB_BASE / 20
16107 && ((prob > 0) ^ need_longbranch))
16115 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16117 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16119 /* We need to escape any '%' characters in the reg_names string.
16120 Assume they'd only be the first character.... */
16121 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16123 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16127 /* If the branch distance was too far, we may have to use an
16128 unconditional branch to go the distance. */
16129 if (need_longbranch)
16130 s += sprintf (s, ",$+8\n\tb %s", label);
16132 s += sprintf (s, ",%s", label);
16138 /* Return the string to flip the GT bit on a CR. */
16140 output_e500_flip_gt_bit (rtx dst, rtx src)
16142 static char string[64];
16145 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16146 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16149 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16150 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16152 sprintf (string, "crnot %d,%d", a, b);
16156 /* Return insn for VSX or Altivec comparisons. */
16159 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16162 enum machine_mode mode = GET_MODE (op0);
16170 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16176 mask = gen_reg_rtx (mode);
16177 emit_insn (gen_rtx_SET (VOIDmode,
16179 gen_rtx_fmt_ee (code, mode, op0, op1)));
16186 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16187 DMODE is expected destination mode. This is a recursive function. */
16190 rs6000_emit_vector_compare (enum rtx_code rcode,
16192 enum machine_mode dmode)
16195 bool swap_operands = false;
16196 bool try_again = false;
16198 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16199 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16201 /* See if the comparison works as is. */
16202 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16210 swap_operands = true;
16215 swap_operands = true;
16223 /* Invert condition and try again.
16224 e.g., A != B becomes ~(A==B). */
16226 enum rtx_code rev_code;
16227 enum insn_code nor_code;
16230 rev_code = reverse_condition_maybe_unordered (rcode);
16231 if (rev_code == UNKNOWN)
16234 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
16235 if (nor_code == CODE_FOR_nothing)
16238 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16242 mask = gen_reg_rtx (dmode);
16243 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16251 /* Try GT/GTU/LT/LTU OR EQ */
16254 enum insn_code ior_code;
16255 enum rtx_code new_code;
16276 gcc_unreachable ();
16279 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
16280 if (ior_code == CODE_FOR_nothing)
16283 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16287 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16291 mask = gen_reg_rtx (dmode);
16292 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16310 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16315 /* You only get two chances. */
16319 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16320 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16321 operands for the relation operation COND. */
16324 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16325 rtx cond, rtx cc_op0, rtx cc_op1)
16327 enum machine_mode dest_mode = GET_MODE (dest);
16328 enum rtx_code rcode = GET_CODE (cond);
16329 enum machine_mode cc_mode = CCmode;
16333 bool invert_move = false;
16335 if (VECTOR_UNIT_NONE_P (dest_mode))
16340 /* Swap operands if we can, and fall back to doing the operation as
16341 specified, and doing a NOR to invert the test. */
16347 /* Invert condition and try again.
16348 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16349 invert_move = true;
16350 rcode = reverse_condition_maybe_unordered (rcode);
16351 if (rcode == UNKNOWN)
16355 /* Mark unsigned tests with CCUNSmode. */
16360 cc_mode = CCUNSmode;
16367 /* Get the vector mask for the given relational operations. */
16368 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16376 op_true = op_false;
16380 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
16381 emit_insn (gen_rtx_SET (VOIDmode,
16383 gen_rtx_IF_THEN_ELSE (dest_mode,
16390 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16391 operands of the last comparison is nonzero/true, FALSE_COND if it
16392 is zero/false. Return 0 if the hardware has no such operation. */
16395 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16397 enum rtx_code code = GET_CODE (op);
16398 rtx op0 = XEXP (op, 0);
16399 rtx op1 = XEXP (op, 1);
16400 REAL_VALUE_TYPE c1;
16401 enum machine_mode compare_mode = GET_MODE (op0);
16402 enum machine_mode result_mode = GET_MODE (dest);
16404 bool is_against_zero;
16406 /* These modes should always match. */
16407 if (GET_MODE (op1) != compare_mode
16408 /* In the isel case however, we can use a compare immediate, so
16409 op1 may be a small constant. */
16410 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16412 if (GET_MODE (true_cond) != result_mode)
16414 if (GET_MODE (false_cond) != result_mode)
16417 /* First, work out if the hardware can do this at all, or
16418 if it's too slow.... */
16419 if (!FLOAT_MODE_P (compare_mode))
16422 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16425 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16426 && SCALAR_FLOAT_MODE_P (compare_mode))
16429 is_against_zero = op1 == CONST0_RTX (compare_mode);
16431 /* A floating-point subtract might overflow, underflow, or produce
16432 an inexact result, thus changing the floating-point flags, so it
16433 can't be generated if we care about that. It's safe if one side
16434 of the construct is zero, since then no subtract will be
16436 if (SCALAR_FLOAT_MODE_P (compare_mode)
16437 && flag_trapping_math && ! is_against_zero)
16440 /* Eliminate half of the comparisons by switching operands, this
16441 makes the remaining code simpler. */
16442 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16443 || code == LTGT || code == LT || code == UNLE)
16445 code = reverse_condition_maybe_unordered (code);
16447 true_cond = false_cond;
16451 /* UNEQ and LTGT take four instructions for a comparison with zero,
16452 it'll probably be faster to use a branch here too. */
16453 if (code == UNEQ && HONOR_NANS (compare_mode))
16456 if (GET_CODE (op1) == CONST_DOUBLE)
16457 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16459 /* We're going to try to implement comparisons by performing
16460 a subtract, then comparing against zero. Unfortunately,
16461 Inf - Inf is NaN which is not zero, and so if we don't
16462 know that the operand is finite and the comparison
16463 would treat EQ different to UNORDERED, we can't do it. */
16464 if (HONOR_INFINITIES (compare_mode)
16465 && code != GT && code != UNGE
16466 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16467 /* Constructs of the form (a OP b ? a : b) are safe. */
16468 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16469 || (! rtx_equal_p (op0, true_cond)
16470 && ! rtx_equal_p (op1, true_cond))))
16473 /* At this point we know we can use fsel. */
16475 /* Reduce the comparison to a comparison against zero. */
16476 if (! is_against_zero)
16478 temp = gen_reg_rtx (compare_mode);
16479 emit_insn (gen_rtx_SET (VOIDmode, temp,
16480 gen_rtx_MINUS (compare_mode, op0, op1)));
16482 op1 = CONST0_RTX (compare_mode);
16485 /* If we don't care about NaNs we can reduce some of the comparisons
16486 down to faster ones. */
16487 if (! HONOR_NANS (compare_mode))
16493 true_cond = false_cond;
16506 /* Now, reduce everything down to a GE. */
16513 temp = gen_reg_rtx (compare_mode);
16514 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16519 temp = gen_reg_rtx (compare_mode);
16520 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
16525 temp = gen_reg_rtx (compare_mode);
16526 emit_insn (gen_rtx_SET (VOIDmode, temp,
16527 gen_rtx_NEG (compare_mode,
16528 gen_rtx_ABS (compare_mode, op0))));
16533 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16534 temp = gen_reg_rtx (result_mode);
16535 emit_insn (gen_rtx_SET (VOIDmode, temp,
16536 gen_rtx_IF_THEN_ELSE (result_mode,
16537 gen_rtx_GE (VOIDmode,
16539 true_cond, false_cond)));
16540 false_cond = true_cond;
16543 temp = gen_reg_rtx (compare_mode);
16544 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16549 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
16550 temp = gen_reg_rtx (result_mode);
16551 emit_insn (gen_rtx_SET (VOIDmode, temp,
16552 gen_rtx_IF_THEN_ELSE (result_mode,
16553 gen_rtx_GE (VOIDmode,
16555 true_cond, false_cond)));
16556 true_cond = false_cond;
16559 temp = gen_reg_rtx (compare_mode);
16560 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16565 gcc_unreachable ();
16568 emit_insn (gen_rtx_SET (VOIDmode, dest,
16569 gen_rtx_IF_THEN_ELSE (result_mode,
16570 gen_rtx_GE (VOIDmode,
16572 true_cond, false_cond)));
16576 /* Same as above, but for ints (isel). */
16579 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16581 rtx condition_rtx, cr;
16582 enum machine_mode mode = GET_MODE (dest);
16584 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
16587 /* We still have to do the compare, because isel doesn't do a
16588 compare, it just looks at the CRx bits set by a previous compare
16590 condition_rtx = rs6000_generate_compare (op, mode);
16591 cr = XEXP (condition_rtx, 0);
16593 if (mode == SImode)
16595 if (GET_MODE (cr) == CCmode)
16596 emit_insn (gen_isel_signed_si (dest, condition_rtx,
16597 true_cond, false_cond, cr));
16599 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
16600 true_cond, false_cond, cr));
16604 if (GET_MODE (cr) == CCmode)
16605 emit_insn (gen_isel_signed_di (dest, condition_rtx,
16606 true_cond, false_cond, cr));
16608 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
16609 true_cond, false_cond, cr));
16616 output_isel (rtx *operands)
16618 enum rtx_code code;
16620 code = GET_CODE (operands[1]);
16621 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
16623 PUT_CODE (operands[1], reverse_condition (code));
16624 return "isel %0,%3,%2,%j1";
16627 return "isel %0,%2,%3,%j1";
16631 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
16633 enum machine_mode mode = GET_MODE (op0);
16637 /* VSX/altivec have direct min/max insns. */
16638 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
16640 emit_insn (gen_rtx_SET (VOIDmode,
16642 gen_rtx_fmt_ee (code, mode, op0, op1)));
16646 if (code == SMAX || code == SMIN)
16651 if (code == SMAX || code == UMAX)
16652 target = emit_conditional_move (dest, c, op0, op1, mode,
16653 op0, op1, mode, 0);
16655 target = emit_conditional_move (dest, c, op0, op1, mode,
16656 op1, op0, mode, 0);
16657 gcc_assert (target);
16658 if (target != dest)
16659 emit_move_insn (dest, target);
16662 /* Emit instructions to perform a load-reserved/store-conditional operation.
16663 The operation performed is an atomic
16664 (set M (CODE:MODE M OP))
16665 If not NULL, BEFORE is atomically set to M before the operation, and
16666 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16667 If SYNC_P then a memory barrier is emitted before the operation.
16668 Either OP or M may be wrapped in a NOT operation. */
16671 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16672 rtx m, rtx op, rtx before_param, rtx after_param,
16675 enum machine_mode used_mode;
16676 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16679 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16680 rtx shift = NULL_RTX;
16683 emit_insn (gen_lwsync ());
16687 /* If this is smaller than SImode, we'll have to use SImode with
16689 if (mode == QImode || mode == HImode)
16693 if (MEM_ALIGN (used_m) >= 32)
16696 if (BYTES_BIG_ENDIAN)
16697 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16699 shift = GEN_INT (ishift);
16700 used_m = change_address (used_m, SImode, 0);
16704 rtx addrSI, aligned_addr;
16705 int shift_mask = mode == QImode ? 0x18 : 0x10;
16707 addrSI = gen_lowpart_common (SImode,
16708 force_reg (Pmode, XEXP (used_m, 0)));
16709 addrSI = force_reg (SImode, addrSI);
16710 shift = gen_reg_rtx (SImode);
16712 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16713 GEN_INT (shift_mask)));
16714 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16716 aligned_addr = expand_binop (Pmode, and_optab,
16718 GEN_INT (-4), NULL_RTX,
16719 1, OPTAB_LIB_WIDEN);
16720 used_m = change_address (used_m, SImode, aligned_addr);
16721 set_mem_align (used_m, 32);
16723 /* It's safe to keep the old alias set of USED_M, because
16724 the operation is atomic and only affects the original
16728 if (GET_CODE (op) == NOT)
16730 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16731 oldop = gen_rtx_NOT (SImode, oldop);
16734 oldop = lowpart_subreg (SImode, op, mode);
16740 newop = expand_binop (SImode, and_optab,
16741 oldop, GEN_INT (imask), NULL_RTX,
16742 1, OPTAB_LIB_WIDEN);
16743 emit_insn (gen_ashlsi3 (newop, newop, shift));
16746 case NOT: /* NAND */
16747 newop = expand_binop (SImode, ior_optab,
16748 oldop, GEN_INT (~imask), NULL_RTX,
16749 1, OPTAB_LIB_WIDEN);
16750 emit_insn (gen_rotlsi3 (newop, newop, shift));
16754 newop = expand_binop (SImode, ior_optab,
16755 oldop, GEN_INT (~imask), NULL_RTX,
16756 1, OPTAB_LIB_WIDEN);
16757 emit_insn (gen_rotlsi3 (newop, newop, shift));
16765 newop = expand_binop (SImode, and_optab,
16766 oldop, GEN_INT (imask), NULL_RTX,
16767 1, OPTAB_LIB_WIDEN);
16768 emit_insn (gen_ashlsi3 (newop, newop, shift));
16770 mask = gen_reg_rtx (SImode);
16771 emit_move_insn (mask, GEN_INT (imask));
16772 emit_insn (gen_ashlsi3 (mask, mask, shift));
16775 newop = gen_rtx_PLUS (SImode, m, newop);
16777 newop = gen_rtx_MINUS (SImode, m, newop);
16778 newop = gen_rtx_AND (SImode, newop, mask);
16779 newop = gen_rtx_IOR (SImode, newop,
16780 gen_rtx_AND (SImode,
16781 gen_rtx_NOT (SImode, mask),
16787 gcc_unreachable ();
16791 used_mode = SImode;
16792 before = gen_reg_rtx (used_mode);
16793 after = gen_reg_rtx (used_mode);
16798 before = before_param;
16799 after = after_param;
16801 if (before == NULL_RTX)
16802 before = gen_reg_rtx (used_mode);
16803 if (after == NULL_RTX)
16804 after = gen_reg_rtx (used_mode);
16807 if ((code == PLUS || code == MINUS)
16808 && used_mode != mode)
16809 the_op = op; /* Computed above. */
16810 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16811 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16812 else if (code == NOT)
16813 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16814 gen_rtx_NOT (used_mode, m),
16815 gen_rtx_NOT (used_mode, op));
16817 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16819 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16820 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16821 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16822 gen_rtx_UNSPEC (used_mode,
16823 gen_rtvec (1, the_op),
16825 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16827 if ((code == PLUS || code == MINUS) && used_mode != mode)
16828 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16829 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16831 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16832 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16834 /* Shift and mask the return values properly. */
16835 if (used_mode != mode && before_param)
16837 emit_insn (gen_lshrsi3 (before, before, shift));
16838 convert_move (before_param, before, 1);
16841 if (used_mode != mode && after_param)
16843 emit_insn (gen_lshrsi3 (after, after, shift));
16844 convert_move (after_param, after, 1);
16847 /* The previous sequence will end with a branch that's dependent on
16848 the conditional store, so placing an isync will ensure that no
16849 other instructions (especially, no load or store instructions)
16850 can start before the atomic operation completes. */
16852 emit_insn (gen_isync ());
16855 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16856 COND is true. Mark the jump as unlikely to be taken. */
16859 emit_unlikely_jump (rtx cond, rtx label)
16861 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16864 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16865 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16866 add_reg_note (x, REG_BR_PROB, very_unlikely);
16869 /* A subroutine of the atomic operation splitters. Emit a load-locked
16870 instruction in MODE. */
16873 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16875 rtx (*fn) (rtx, rtx) = NULL;
16876 if (mode == SImode)
16877 fn = gen_load_locked_si;
16878 else if (mode == DImode)
16879 fn = gen_load_locked_di;
16880 emit_insn (fn (reg, mem));
16883 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16884 instruction in MODE. */
16887 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16889 rtx (*fn) (rtx, rtx, rtx) = NULL;
16890 if (mode == SImode)
16891 fn = gen_store_conditional_si;
16892 else if (mode == DImode)
16893 fn = gen_store_conditional_di;
16895 /* Emit sync before stwcx. to address PPC405 Erratum. */
16896 if (PPC405_ERRATUM77)
16897 emit_insn (gen_memory_barrier ());
16899 emit_insn (fn (res, mem, val));
16902 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16903 to perform. MEM is the memory on which to operate. VAL is the second
16904 operand of the binary operator. BEFORE and AFTER are optional locations to
16905 return the value of MEM either before of after the operation. SCRATCH is
16906 a scratch register. */
16909 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16910 rtx before, rtx after, rtx scratch)
16912 enum machine_mode mode = GET_MODE (mem);
16913 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16915 emit_insn (gen_lwsync ());
16917 label = gen_label_rtx ();
16918 emit_label (label);
16919 label = gen_rtx_LABEL_REF (VOIDmode, label);
16921 if (before == NULL_RTX)
16923 emit_load_locked (mode, before, mem);
16926 x = gen_rtx_IOR (mode,
16927 gen_rtx_NOT (mode, before),
16928 gen_rtx_NOT (mode, val));
16929 else if (code == AND)
16930 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16932 x = gen_rtx_fmt_ee (code, mode, before, val);
16934 if (after != NULL_RTX)
16935 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16936 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16938 emit_store_conditional (mode, cond, mem, scratch);
16940 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16941 emit_unlikely_jump (x, label);
16943 emit_insn (gen_isync ());
16946 /* Expand an atomic compare and swap operation. MEM is the memory on which
16947 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16948 value to be stored. SCRATCH is a scratch GPR. */
16951 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16954 enum machine_mode mode = GET_MODE (mem);
16955 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16957 emit_insn (gen_lwsync ());
16959 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16960 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16961 emit_label (XEXP (label1, 0));
16963 emit_load_locked (mode, retval, mem);
16965 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16966 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16968 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16969 emit_unlikely_jump (x, label2);
16971 emit_move_insn (scratch, newval);
16972 emit_store_conditional (mode, cond, mem, scratch);
16974 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16975 emit_unlikely_jump (x, label1);
16977 emit_insn (gen_isync ());
16978 emit_label (XEXP (label2, 0));
16981 /* Expand an atomic test and set operation. MEM is the memory on which
16982 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16985 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16987 enum machine_mode mode = GET_MODE (mem);
16988 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16990 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16991 emit_label (XEXP (label, 0));
16993 emit_load_locked (mode, retval, mem);
16994 emit_move_insn (scratch, val);
16995 emit_store_conditional (mode, cond, mem, scratch);
16997 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16998 emit_unlikely_jump (x, label);
17000 emit_insn (gen_isync ());
17004 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17006 enum machine_mode mode = GET_MODE (mem);
17007 rtx addrSI, align, wdst, shift, mask;
17008 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17009 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17011 /* Shift amount for subword relative to aligned word. */
17012 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17013 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17014 shift = gen_reg_rtx (SImode);
17015 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17016 GEN_INT (shift_mask)));
17017 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17019 /* Shift and mask old value into position within word. */
17020 oldval = convert_modes (SImode, mode, oldval, 1);
17021 oldval = expand_binop (SImode, and_optab,
17022 oldval, GEN_INT (imask), NULL_RTX,
17023 1, OPTAB_LIB_WIDEN);
17024 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17026 /* Shift and mask new value into position within word. */
17027 newval = convert_modes (SImode, mode, newval, 1);
17028 newval = expand_binop (SImode, and_optab,
17029 newval, GEN_INT (imask), NULL_RTX,
17030 1, OPTAB_LIB_WIDEN);
17031 emit_insn (gen_ashlsi3 (newval, newval, shift));
17033 /* Mask for insertion. */
17034 mask = gen_reg_rtx (SImode);
17035 emit_move_insn (mask, GEN_INT (imask));
17036 emit_insn (gen_ashlsi3 (mask, mask, shift));
17038 /* Address of aligned word containing subword. */
17039 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17040 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17041 mem = change_address (mem, SImode, align);
17042 set_mem_align (mem, 32);
17043 MEM_VOLATILE_P (mem) = 1;
17045 wdst = gen_reg_rtx (SImode);
17046 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17047 oldval, newval, mem));
17049 /* Shift the result back. */
17050 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17052 emit_move_insn (dst, gen_lowpart (mode, wdst));
17056 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17057 rtx oldval, rtx newval, rtx mem,
17060 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17062 emit_insn (gen_lwsync ());
17063 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17064 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17065 emit_label (XEXP (label1, 0));
17067 emit_load_locked (SImode, scratch, mem);
17069 /* Mask subword within loaded value for comparison with oldval.
17070 Use UNSPEC_AND to avoid clobber.*/
17071 emit_insn (gen_rtx_SET (SImode, dest,
17072 gen_rtx_UNSPEC (SImode,
17073 gen_rtvec (2, scratch, mask),
17076 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17077 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17079 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17080 emit_unlikely_jump (x, label2);
17082 /* Clear subword within loaded value for insertion of new value. */
17083 emit_insn (gen_rtx_SET (SImode, scratch,
17084 gen_rtx_AND (SImode,
17085 gen_rtx_NOT (SImode, mask), scratch)));
17086 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17087 emit_store_conditional (SImode, cond, mem, scratch);
17089 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17090 emit_unlikely_jump (x, label1);
17092 emit_insn (gen_isync ());
17093 emit_label (XEXP (label2, 0));
17097 /* Emit instructions to move SRC to DST. Called by splitters for
17098 multi-register moves. It will emit at most one instruction for
17099 each register that is accessed; that is, it won't emit li/lis pairs
17100 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17104 rs6000_split_multireg_move (rtx dst, rtx src)
17106 /* The register number of the first register being moved. */
17108 /* The mode that is to be moved. */
17109 enum machine_mode mode;
17110 /* The mode that the move is being done in, and its size. */
17111 enum machine_mode reg_mode;
17113 /* The number of registers that will be moved. */
17116 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17117 mode = GET_MODE (dst);
17118 nregs = hard_regno_nregs[reg][mode];
17119 if (FP_REGNO_P (reg))
17120 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17121 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17122 else if (ALTIVEC_REGNO_P (reg))
17123 reg_mode = V16QImode;
17124 else if (TARGET_E500_DOUBLE && mode == TFmode)
17127 reg_mode = word_mode;
17128 reg_mode_size = GET_MODE_SIZE (reg_mode);
17130 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17132 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17134 /* Move register range backwards, if we might have destructive
17137 for (i = nregs - 1; i >= 0; i--)
17138 emit_insn (gen_rtx_SET (VOIDmode,
17139 simplify_gen_subreg (reg_mode, dst, mode,
17140 i * reg_mode_size),
17141 simplify_gen_subreg (reg_mode, src, mode,
17142 i * reg_mode_size)));
17148 bool used_update = false;
17149 rtx restore_basereg = NULL_RTX;
17151 if (MEM_P (src) && INT_REGNO_P (reg))
17155 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17156 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17159 breg = XEXP (XEXP (src, 0), 0);
17160 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17161 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17162 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17163 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17164 src = replace_equiv_address (src, breg);
17166 else if (! rs6000_offsettable_memref_p (src))
17168 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17170 rtx basereg = XEXP (XEXP (src, 0), 0);
17173 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17174 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17175 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17176 used_update = true;
17179 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17180 XEXP (XEXP (src, 0), 1)));
17181 src = replace_equiv_address (src, basereg);
17185 rtx basereg = gen_rtx_REG (Pmode, reg);
17186 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17187 src = replace_equiv_address (src, basereg);
17191 breg = XEXP (src, 0);
17192 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17193 breg = XEXP (breg, 0);
17195 /* If the base register we are using to address memory is
17196 also a destination reg, then change that register last. */
17198 && REGNO (breg) >= REGNO (dst)
17199 && REGNO (breg) < REGNO (dst) + nregs)
17200 j = REGNO (breg) - REGNO (dst);
17202 else if (MEM_P (dst) && INT_REGNO_P (reg))
17206 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17207 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17210 breg = XEXP (XEXP (dst, 0), 0);
17211 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17212 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17213 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17215 /* We have to update the breg before doing the store.
17216 Use store with update, if available. */
17220 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17221 emit_insn (TARGET_32BIT
17222 ? (TARGET_POWERPC64
17223 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17224 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17225 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17226 used_update = true;
17229 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17230 dst = replace_equiv_address (dst, breg);
17232 else if (!rs6000_offsettable_memref_p (dst)
17233 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17235 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17237 rtx basereg = XEXP (XEXP (dst, 0), 0);
17240 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17241 emit_insn (gen_rtx_SET (VOIDmode,
17242 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17243 used_update = true;
17246 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17247 XEXP (XEXP (dst, 0), 1)));
17248 dst = replace_equiv_address (dst, basereg);
17252 rtx basereg = XEXP (XEXP (dst, 0), 0);
17253 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17254 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17256 && REG_P (offsetreg)
17257 && REGNO (basereg) != REGNO (offsetreg));
17258 if (REGNO (basereg) == 0)
17260 rtx tmp = offsetreg;
17261 offsetreg = basereg;
17264 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17265 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17266 dst = replace_equiv_address (dst, basereg);
17269 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17270 gcc_assert (rs6000_offsettable_memref_p (dst));
17273 for (i = 0; i < nregs; i++)
17275 /* Calculate index to next subword. */
17280 /* If compiler already emitted move of first word by
17281 store with update, no need to do anything. */
17282 if (j == 0 && used_update)
17285 emit_insn (gen_rtx_SET (VOIDmode,
17286 simplify_gen_subreg (reg_mode, dst, mode,
17287 j * reg_mode_size),
17288 simplify_gen_subreg (reg_mode, src, mode,
17289 j * reg_mode_size)));
17291 if (restore_basereg != NULL_RTX)
17292 emit_insn (restore_basereg);
17297 /* This page contains routines that are used to determine what the
17298 function prologue and epilogue code will do and write them out. */
17300 /* Return the first fixed-point register that is required to be
17301 saved. 32 if none. */
17304 first_reg_to_save (void)
17308 /* Find lowest numbered live register. */
17309 for (first_reg = 13; first_reg <= 31; first_reg++)
17310 if (df_regs_ever_live_p (first_reg)
17311 && (! call_used_regs[first_reg]
17312 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17313 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17314 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17315 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17320 && crtl->uses_pic_offset_table
17321 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17322 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17328 /* Similar, for FP regs. */
17331 first_fp_reg_to_save (void)
17335 /* Find lowest numbered live register. */
17336 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17337 if (df_regs_ever_live_p (first_reg))
17343 /* Similar, for AltiVec regs. */
17346 first_altivec_reg_to_save (void)
17350 /* Stack frame remains as is unless we are in AltiVec ABI. */
17351 if (! TARGET_ALTIVEC_ABI)
17352 return LAST_ALTIVEC_REGNO + 1;
17354 /* On Darwin, the unwind routines are compiled without
17355 TARGET_ALTIVEC, and use save_world to save/restore the
17356 altivec registers when necessary. */
17357 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17358 && ! TARGET_ALTIVEC)
17359 return FIRST_ALTIVEC_REGNO + 20;
17361 /* Find lowest numbered live register. */
17362 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17363 if (df_regs_ever_live_p (i))
17369 /* Return a 32-bit mask of the AltiVec registers we need to set in
17370 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17371 the 32-bit word is 0. */
17373 static unsigned int
17374 compute_vrsave_mask (void)
17376 unsigned int i, mask = 0;
17378 /* On Darwin, the unwind routines are compiled without
17379 TARGET_ALTIVEC, and use save_world to save/restore the
17380 call-saved altivec registers when necessary. */
17381 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17382 && ! TARGET_ALTIVEC)
17385 /* First, find out if we use _any_ altivec registers. */
17386 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17387 if (df_regs_ever_live_p (i))
17388 mask |= ALTIVEC_REG_BIT (i);
17393 /* Next, remove the argument registers from the set. These must
17394 be in the VRSAVE mask set by the caller, so we don't need to add
17395 them in again. More importantly, the mask we compute here is
17396 used to generate CLOBBERs in the set_vrsave insn, and we do not
17397 wish the argument registers to die. */
17398 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17399 mask &= ~ALTIVEC_REG_BIT (i);
17401 /* Similarly, remove the return value from the set. */
17404 diddle_return_value (is_altivec_return_reg, &yes);
17406 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17412 /* For a very restricted set of circumstances, we can cut down the
17413 size of prologues/epilogues by calling our own save/restore-the-world
17417 compute_save_world_info (rs6000_stack_t *info_ptr)
17419 info_ptr->world_save_p = 1;
17420 info_ptr->world_save_p
17421 = (WORLD_SAVE_P (info_ptr)
17422 && DEFAULT_ABI == ABI_DARWIN
17423 && ! (cfun->calls_setjmp && flag_exceptions)
17424 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17425 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17426 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17427 && info_ptr->cr_save_p);
17429 /* This will not work in conjunction with sibcalls. Make sure there
17430 are none. (This check is expensive, but seldom executed.) */
17431 if (WORLD_SAVE_P (info_ptr))
17434 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17435 if ( GET_CODE (insn) == CALL_INSN
17436 && SIBLING_CALL_P (insn))
17438 info_ptr->world_save_p = 0;
17443 if (WORLD_SAVE_P (info_ptr))
17445 /* Even if we're not touching VRsave, make sure there's room on the
17446 stack for it, if it looks like we're calling SAVE_WORLD, which
17447 will attempt to save it. */
17448 info_ptr->vrsave_size = 4;
17450 /* If we are going to save the world, we need to save the link register too. */
17451 info_ptr->lr_save_p = 1;
17453 /* "Save" the VRsave register too if we're saving the world. */
17454 if (info_ptr->vrsave_mask == 0)
17455 info_ptr->vrsave_mask = compute_vrsave_mask ();
17457 /* Because the Darwin register save/restore routines only handle
17458 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17460 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17461 && (info_ptr->first_altivec_reg_save
17462 >= FIRST_SAVED_ALTIVEC_REGNO));
17469 is_altivec_return_reg (rtx reg, void *xyes)
17471 bool *yes = (bool *) xyes;
17472 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17477 /* Calculate the stack information for the current function. This is
17478 complicated by having two separate calling sequences, the AIX calling
17479 sequence and the V.4 calling sequence.
17481 AIX (and Darwin/Mac OS X) stack frames look like:
17483 SP----> +---------------------------------------+
17484 | back chain to caller | 0 0
17485 +---------------------------------------+
17486 | saved CR | 4 8 (8-11)
17487 +---------------------------------------+
17489 +---------------------------------------+
17490 | reserved for compilers | 12 24
17491 +---------------------------------------+
17492 | reserved for binders | 16 32
17493 +---------------------------------------+
17494 | saved TOC pointer | 20 40
17495 +---------------------------------------+
17496 | Parameter save area (P) | 24 48
17497 +---------------------------------------+
17498 | Alloca space (A) | 24+P etc.
17499 +---------------------------------------+
17500 | Local variable space (L) | 24+P+A
17501 +---------------------------------------+
17502 | Float/int conversion temporary (X) | 24+P+A+L
17503 +---------------------------------------+
17504 | Save area for AltiVec registers (W) | 24+P+A+L+X
17505 +---------------------------------------+
17506 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
17507 +---------------------------------------+
17508 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
17509 +---------------------------------------+
17510 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
17511 +---------------------------------------+
17512 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
17513 +---------------------------------------+
17514 old SP->| back chain to caller's caller |
17515 +---------------------------------------+
17517 The required alignment for AIX configurations is two words (i.e., 8
17521 V.4 stack frames look like:
17523 SP----> +---------------------------------------+
17524 | back chain to caller | 0
17525 +---------------------------------------+
17526 | caller's saved LR | 4
17527 +---------------------------------------+
17528 | Parameter save area (P) | 8
17529 +---------------------------------------+
17530 | Alloca space (A) | 8+P
17531 +---------------------------------------+
17532 | Varargs save area (V) | 8+P+A
17533 +---------------------------------------+
17534 | Local variable space (L) | 8+P+A+V
17535 +---------------------------------------+
17536 | Float/int conversion temporary (X) | 8+P+A+V+L
17537 +---------------------------------------+
17538 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
17539 +---------------------------------------+
17540 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
17541 +---------------------------------------+
17542 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
17543 +---------------------------------------+
17544 | SPE: area for 64-bit GP registers |
17545 +---------------------------------------+
17546 | SPE alignment padding |
17547 +---------------------------------------+
17548 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
17549 +---------------------------------------+
17550 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
17551 +---------------------------------------+
17552 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
17553 +---------------------------------------+
17554 old SP->| back chain to caller's caller |
17555 +---------------------------------------+
17557 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
17558 given. (But note below and in sysv4.h that we require only 8 and
17559 may round up the size of our stack frame anyways. The historical
17560 reason is early versions of powerpc-linux which didn't properly
17561 align the stack at program startup. A happy side-effect is that
17562 -mno-eabi libraries can be used with -meabi programs.)
17564 The EABI configuration defaults to the V.4 layout. However,
17565 the stack alignment requirements may differ. If -mno-eabi is not
17566 given, the required stack alignment is 8 bytes; if -mno-eabi is
17567 given, the required alignment is 16 bytes. (But see V.4 comment
17570 #ifndef ABI_STACK_BOUNDARY
17571 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
17574 static rs6000_stack_t *
17575 rs6000_stack_info (void)
17577 static rs6000_stack_t info;
17578 rs6000_stack_t *info_ptr = &info;
17579 int reg_size = TARGET_32BIT ? 4 : 8;
17583 HOST_WIDE_INT non_fixed_size;
17585 memset (&info, 0, sizeof (info));
17589 /* Cache value so we don't rescan instruction chain over and over. */
17590 if (cfun->machine->insn_chain_scanned_p == 0)
17591 cfun->machine->insn_chain_scanned_p
17592 = spe_func_has_64bit_regs_p () + 1;
17593 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
17596 /* Select which calling sequence. */
17597 info_ptr->abi = DEFAULT_ABI;
17599 /* Calculate which registers need to be saved & save area size. */
17600 info_ptr->first_gp_reg_save = first_reg_to_save ();
17601 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
17602 even if it currently looks like we won't. Reload may need it to
17603 get at a constant; if so, it will have already created a constant
17604 pool entry for it. */
17605 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
17606 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
17607 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
17608 && crtl->uses_const_pool
17609 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
17610 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
17612 first_gp = info_ptr->first_gp_reg_save;
17614 info_ptr->gp_size = reg_size * (32 - first_gp);
17616 /* For the SPE, we have an additional upper 32-bits on each GPR.
17617 Ideally we should save the entire 64-bits only when the upper
17618 half is used in SIMD instructions. Since we only record
17619 registers live (not the size they are used in), this proves
17620 difficult because we'd have to traverse the instruction chain at
17621 the right time, taking reload into account. This is a real pain,
17622 so we opt to save the GPRs in 64-bits always if but one register
17623 gets used in 64-bits. Otherwise, all the registers in the frame
17624 get saved in 32-bits.
17626 So... since when we save all GPRs (except the SP) in 64-bits, the
17627 traditional GP save area will be empty. */
17628 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17629 info_ptr->gp_size = 0;
17631 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
17632 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
17634 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
17635 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
17636 - info_ptr->first_altivec_reg_save);
17638 /* Does this function call anything? */
17639 info_ptr->calls_p = (! current_function_is_leaf
17640 || cfun->machine->ra_needs_full_frame);
17642 /* Determine if we need to save the link register. */
17643 if ((DEFAULT_ABI == ABI_AIX
17645 && !TARGET_PROFILE_KERNEL)
17646 #ifdef TARGET_RELOCATABLE
17647 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
17649 || (info_ptr->first_fp_reg_save != 64
17650 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
17651 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
17652 || info_ptr->calls_p
17653 || rs6000_ra_ever_killed ())
17655 info_ptr->lr_save_p = 1;
17656 df_set_regs_ever_live (LR_REGNO, true);
17659 /* Determine if we need to save the condition code registers. */
17660 if (df_regs_ever_live_p (CR2_REGNO)
17661 || df_regs_ever_live_p (CR3_REGNO)
17662 || df_regs_ever_live_p (CR4_REGNO))
17664 info_ptr->cr_save_p = 1;
17665 if (DEFAULT_ABI == ABI_V4)
17666 info_ptr->cr_size = reg_size;
17669 /* If the current function calls __builtin_eh_return, then we need
17670 to allocate stack space for registers that will hold data for
17671 the exception handler. */
17672 if (crtl->calls_eh_return)
17675 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
17678 /* SPE saves EH registers in 64-bits. */
17679 ehrd_size = i * (TARGET_SPE_ABI
17680 && info_ptr->spe_64bit_regs_used != 0
17681 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
17686 /* Determine various sizes. */
17687 info_ptr->reg_size = reg_size;
17688 info_ptr->fixed_size = RS6000_SAVE_AREA;
17689 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
17690 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
17691 TARGET_ALTIVEC ? 16 : 8);
17692 if (FRAME_GROWS_DOWNWARD)
17693 info_ptr->vars_size
17694 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
17695 + info_ptr->parm_size,
17696 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
17697 - (info_ptr->fixed_size + info_ptr->vars_size
17698 + info_ptr->parm_size);
17700 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17701 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17703 info_ptr->spe_gp_size = 0;
17705 if (TARGET_ALTIVEC_ABI)
17706 info_ptr->vrsave_mask = compute_vrsave_mask ();
17708 info_ptr->vrsave_mask = 0;
17710 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17711 info_ptr->vrsave_size = 4;
17713 info_ptr->vrsave_size = 0;
17715 compute_save_world_info (info_ptr);
17717 /* Calculate the offsets. */
17718 switch (DEFAULT_ABI)
17722 gcc_unreachable ();
17726 info_ptr->fp_save_offset = - info_ptr->fp_size;
17727 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17729 if (TARGET_ALTIVEC_ABI)
17731 info_ptr->vrsave_save_offset
17732 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17734 /* Align stack so vector save area is on a quadword boundary.
17735 The padding goes above the vectors. */
17736 if (info_ptr->altivec_size != 0)
17737 info_ptr->altivec_padding_size
17738 = info_ptr->vrsave_save_offset & 0xF;
17740 info_ptr->altivec_padding_size = 0;
17742 info_ptr->altivec_save_offset
17743 = info_ptr->vrsave_save_offset
17744 - info_ptr->altivec_padding_size
17745 - info_ptr->altivec_size;
17746 gcc_assert (info_ptr->altivec_size == 0
17747 || info_ptr->altivec_save_offset % 16 == 0);
17749 /* Adjust for AltiVec case. */
17750 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17753 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17754 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17755 info_ptr->lr_save_offset = 2*reg_size;
17759 info_ptr->fp_save_offset = - info_ptr->fp_size;
17760 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17761 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17763 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17765 /* Align stack so SPE GPR save area is aligned on a
17766 double-word boundary. */
17767 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17768 info_ptr->spe_padding_size
17769 = 8 - (-info_ptr->cr_save_offset % 8);
17771 info_ptr->spe_padding_size = 0;
17773 info_ptr->spe_gp_save_offset
17774 = info_ptr->cr_save_offset
17775 - info_ptr->spe_padding_size
17776 - info_ptr->spe_gp_size;
17778 /* Adjust for SPE case. */
17779 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17781 else if (TARGET_ALTIVEC_ABI)
17783 info_ptr->vrsave_save_offset
17784 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17786 /* Align stack so vector save area is on a quadword boundary. */
17787 if (info_ptr->altivec_size != 0)
17788 info_ptr->altivec_padding_size
17789 = 16 - (-info_ptr->vrsave_save_offset % 16);
17791 info_ptr->altivec_padding_size = 0;
17793 info_ptr->altivec_save_offset
17794 = info_ptr->vrsave_save_offset
17795 - info_ptr->altivec_padding_size
17796 - info_ptr->altivec_size;
17798 /* Adjust for AltiVec case. */
17799 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17802 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17803 info_ptr->ehrd_offset -= ehrd_size;
17804 info_ptr->lr_save_offset = reg_size;
17808 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17809 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17810 + info_ptr->gp_size
17811 + info_ptr->altivec_size
17812 + info_ptr->altivec_padding_size
17813 + info_ptr->spe_gp_size
17814 + info_ptr->spe_padding_size
17816 + info_ptr->cr_size
17817 + info_ptr->vrsave_size,
17820 non_fixed_size = (info_ptr->vars_size
17821 + info_ptr->parm_size
17822 + info_ptr->save_size);
17824 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17825 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17827 /* Determine if we need to allocate any stack frame:
17829 For AIX we need to push the stack if a frame pointer is needed
17830 (because the stack might be dynamically adjusted), if we are
17831 debugging, if we make calls, or if the sum of fp_save, gp_save,
17832 and local variables are more than the space needed to save all
17833 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17834 + 18*8 = 288 (GPR13 reserved).
17836 For V.4 we don't have the stack cushion that AIX uses, but assume
17837 that the debugger can handle stackless frames. */
17839 if (info_ptr->calls_p)
17840 info_ptr->push_p = 1;
17842 else if (DEFAULT_ABI == ABI_V4)
17843 info_ptr->push_p = non_fixed_size != 0;
17845 else if (frame_pointer_needed)
17846 info_ptr->push_p = 1;
17848 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17849 info_ptr->push_p = 1;
17852 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17854 /* Zero offsets if we're not saving those registers. */
17855 if (info_ptr->fp_size == 0)
17856 info_ptr->fp_save_offset = 0;
17858 if (info_ptr->gp_size == 0)
17859 info_ptr->gp_save_offset = 0;
17861 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17862 info_ptr->altivec_save_offset = 0;
17864 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17865 info_ptr->vrsave_save_offset = 0;
17867 if (! TARGET_SPE_ABI
17868 || info_ptr->spe_64bit_regs_used == 0
17869 || info_ptr->spe_gp_size == 0)
17870 info_ptr->spe_gp_save_offset = 0;
17872 if (! info_ptr->lr_save_p)
17873 info_ptr->lr_save_offset = 0;
17875 if (! info_ptr->cr_save_p)
17876 info_ptr->cr_save_offset = 0;
17881 /* Return true if the current function uses any GPRs in 64-bit SIMD
17885 spe_func_has_64bit_regs_p (void)
17889 /* Functions that save and restore all the call-saved registers will
17890 need to save/restore the registers in 64-bits. */
17891 if (crtl->calls_eh_return
17892 || cfun->calls_setjmp
17893 || crtl->has_nonlocal_goto)
17896 insns = get_insns ();
17898 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17904 /* FIXME: This should be implemented with attributes...
17906 (set_attr "spe64" "true")....then,
17907 if (get_spe64(insn)) return true;
17909 It's the only reliable way to do the stuff below. */
17911 i = PATTERN (insn);
17912 if (GET_CODE (i) == SET)
17914 enum machine_mode mode = GET_MODE (SET_SRC (i));
17916 if (SPE_VECTOR_MODE (mode))
17918 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17928 debug_stack_info (rs6000_stack_t *info)
17930 const char *abi_string;
17933 info = rs6000_stack_info ();
17935 fprintf (stderr, "\nStack information for function %s:\n",
17936 ((current_function_decl && DECL_NAME (current_function_decl))
17937 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17942 default: abi_string = "Unknown"; break;
17943 case ABI_NONE: abi_string = "NONE"; break;
17944 case ABI_AIX: abi_string = "AIX"; break;
17945 case ABI_DARWIN: abi_string = "Darwin"; break;
17946 case ABI_V4: abi_string = "V.4"; break;
17949 fprintf (stderr, "\tABI = %5s\n", abi_string);
17951 if (TARGET_ALTIVEC_ABI)
17952 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17954 if (TARGET_SPE_ABI)
17955 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17957 if (info->first_gp_reg_save != 32)
17958 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17960 if (info->first_fp_reg_save != 64)
17961 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17963 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17964 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17965 info->first_altivec_reg_save);
17967 if (info->lr_save_p)
17968 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17970 if (info->cr_save_p)
17971 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17973 if (info->vrsave_mask)
17974 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17977 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17980 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17982 if (info->gp_save_offset)
17983 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17985 if (info->fp_save_offset)
17986 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17988 if (info->altivec_save_offset)
17989 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17990 info->altivec_save_offset);
17992 if (info->spe_gp_save_offset)
17993 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17994 info->spe_gp_save_offset);
17996 if (info->vrsave_save_offset)
17997 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17998 info->vrsave_save_offset);
18000 if (info->lr_save_offset)
18001 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18003 if (info->cr_save_offset)
18004 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18006 if (info->varargs_save_offset)
18007 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18009 if (info->total_size)
18010 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18013 if (info->vars_size)
18014 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18017 if (info->parm_size)
18018 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18020 if (info->fixed_size)
18021 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18024 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18026 if (info->spe_gp_size)
18027 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18030 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18032 if (info->altivec_size)
18033 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18035 if (info->vrsave_size)
18036 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18038 if (info->altivec_padding_size)
18039 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18040 info->altivec_padding_size);
18042 if (info->spe_padding_size)
18043 fprintf (stderr, "\tspe_padding_size = %5d\n",
18044 info->spe_padding_size);
18047 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18049 if (info->save_size)
18050 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18052 if (info->reg_size != 4)
18053 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18055 fprintf (stderr, "\n");
18059 rs6000_return_addr (int count, rtx frame)
18061 /* Currently we don't optimize very well between prolog and body
18062 code and for PIC code the code can be actually quite bad, so
18063 don't try to be too clever here. */
18064 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18066 cfun->machine->ra_needs_full_frame = 1;
18073 plus_constant (copy_to_reg
18074 (gen_rtx_MEM (Pmode,
18075 memory_address (Pmode, frame))),
18076 RETURN_ADDRESS_OFFSET)));
18079 cfun->machine->ra_need_lr = 1;
18080 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18083 /* Say whether a function is a candidate for sibcall handling or not.
18084 We do not allow indirect calls to be optimized into sibling calls.
18085 Also, we can't do it if there are any vector parameters; there's
18086 nowhere to put the VRsave code so it works; note that functions with
18087 vector parameters are required to have a prototype, so the argument
18088 type info must be available here. (The tail recursion case can work
18089 with vector parameters, but there's no way to distinguish here.) */
18091 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
18096 if (TARGET_ALTIVEC_VRSAVE)
18098 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
18099 type; type = TREE_CHAIN (type))
18101 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
18105 if (DEFAULT_ABI == ABI_DARWIN
18106 || ((*targetm.binds_local_p) (decl)
18107 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
18109 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
18111 if (!lookup_attribute ("longcall", attr_list)
18112 || lookup_attribute ("shortcall", attr_list))
18119 /* NULL if INSN insn is valid within a low-overhead loop.
18120 Otherwise return why doloop cannot be applied.
18121 PowerPC uses the COUNT register for branch on table instructions. */
18123 static const char *
18124 rs6000_invalid_within_doloop (const_rtx insn)
18127 return "Function call in the loop.";
18130 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18131 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18132 return "Computed branch in the loop.";
18138 rs6000_ra_ever_killed (void)
18144 if (cfun->is_thunk)
18147 if (cfun->machine->lr_save_state)
18148 return cfun->machine->lr_save_state - 1;
18150 /* regs_ever_live has LR marked as used if any sibcalls are present,
18151 but this should not force saving and restoring in the
18152 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18153 clobbers LR, so that is inappropriate. */
18155 /* Also, the prologue can generate a store into LR that
18156 doesn't really count, like this:
18159 bcl to set PIC register
18163 When we're called from the epilogue, we need to avoid counting
18164 this as a store. */
18166 push_topmost_sequence ();
18167 top = get_insns ();
18168 pop_topmost_sequence ();
18169 reg = gen_rtx_REG (Pmode, LR_REGNO);
18171 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18177 if (!SIBLING_CALL_P (insn))
18180 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18182 else if (set_of (reg, insn) != NULL_RTX
18183 && !prologue_epilogue_contains (insn))
18190 /* Emit instructions needed to load the TOC register.
18191 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18192 a constant pool; or for SVR4 -fpic. */
18195 rs6000_emit_load_toc_table (int fromprolog)
18198 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18200 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18203 rtx lab, tmp1, tmp2, got;
18205 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18206 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18208 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18210 got = rs6000_got_sym ();
18211 tmp1 = tmp2 = dest;
18214 tmp1 = gen_reg_rtx (Pmode);
18215 tmp2 = gen_reg_rtx (Pmode);
18217 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18218 emit_move_insn (tmp1,
18219 gen_rtx_REG (Pmode, LR_REGNO));
18220 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18221 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18223 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18225 emit_insn (gen_load_toc_v4_pic_si ());
18226 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18228 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18231 rtx temp0 = (fromprolog
18232 ? gen_rtx_REG (Pmode, 0)
18233 : gen_reg_rtx (Pmode));
18239 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18240 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18242 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18243 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18245 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18246 emit_move_insn (dest,
18247 gen_rtx_REG (Pmode, LR_REGNO));
18248 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18254 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18255 lab = gen_label_rtx ();
18256 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18257 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18258 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18260 emit_insn (gen_addsi3 (dest, temp0, dest));
18262 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18264 /* This is for AIX code running in non-PIC ELF32. */
18267 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18268 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18270 emit_insn (gen_elf_high (dest, realsym));
18271 emit_insn (gen_elf_low (dest, dest, realsym));
18275 gcc_assert (DEFAULT_ABI == ABI_AIX);
18278 emit_insn (gen_load_toc_aix_si (dest));
18280 emit_insn (gen_load_toc_aix_di (dest));
18284 /* Emit instructions to restore the link register after determining where
18285 its value has been stored. */
18288 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18290 rs6000_stack_t *info = rs6000_stack_info ();
18293 operands[0] = source;
18294 operands[1] = scratch;
18296 if (info->lr_save_p)
18298 rtx frame_rtx = stack_pointer_rtx;
18299 HOST_WIDE_INT sp_offset = 0;
18302 if (frame_pointer_needed
18303 || cfun->calls_alloca
18304 || info->total_size > 32767)
18306 tmp = gen_frame_mem (Pmode, frame_rtx);
18307 emit_move_insn (operands[1], tmp);
18308 frame_rtx = operands[1];
18310 else if (info->push_p)
18311 sp_offset = info->total_size;
18313 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18314 tmp = gen_frame_mem (Pmode, tmp);
18315 emit_move_insn (tmp, operands[0]);
18318 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
18320 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18321 state of lr_save_p so any change from here on would be a bug. In
18322 particular, stop rs6000_ra_ever_killed from considering the SET
18323 of lr we may have added just above. */
18324 cfun->machine->lr_save_state = info->lr_save_p + 1;
18327 static GTY(()) alias_set_type set = -1;
18330 get_TOC_alias_set (void)
18333 set = new_alias_set ();
18337 /* This returns nonzero if the current function uses the TOC. This is
18338 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
18339 is generated by the ABI_V4 load_toc_* patterns. */
18346 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
18349 rtx pat = PATTERN (insn);
18352 if (GET_CODE (pat) == PARALLEL)
18353 for (i = 0; i < XVECLEN (pat, 0); i++)
18355 rtx sub = XVECEXP (pat, 0, i);
18356 if (GET_CODE (sub) == USE)
18358 sub = XEXP (sub, 0);
18359 if (GET_CODE (sub) == UNSPEC
18360 && XINT (sub, 1) == UNSPEC_TOC)
18370 create_TOC_reference (rtx symbol, rtx largetoc_reg)
18372 rtx tocrel, tocreg;
18374 if (TARGET_DEBUG_ADDR)
18376 if (GET_CODE (symbol) == SYMBOL_REF)
18377 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
18381 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
18382 GET_RTX_NAME (GET_CODE (symbol)));
18383 debug_rtx (symbol);
18387 if (!can_create_pseudo_p ())
18388 df_set_regs_ever_live (TOC_REGISTER, true);
18390 tocrel = gen_rtx_CONST (Pmode,
18391 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
18393 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
18394 if (TARGET_CMODEL != CMODEL_SMALL)
18396 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
18397 if (largetoc_reg != NULL)
18399 emit_move_insn (largetoc_reg, hi);
18402 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
18405 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
18408 /* Issue assembly directives that create a reference to the given DWARF
18409 FRAME_TABLE_LABEL from the current function section. */
18411 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
18413 fprintf (asm_out_file, "\t.ref %s\n",
18414 TARGET_STRIP_NAME_ENCODING (frame_table_label));
18417 /* If _Unwind_* has been called from within the same module,
18418 toc register is not guaranteed to be saved to 40(1) on function
18419 entry. Save it there in that case. */
18422 rs6000_aix_emit_builtin_unwind_init (void)
18425 rtx stack_top = gen_reg_rtx (Pmode);
18426 rtx opcode_addr = gen_reg_rtx (Pmode);
18427 rtx opcode = gen_reg_rtx (SImode);
18428 rtx tocompare = gen_reg_rtx (SImode);
18429 rtx no_toc_save_needed = gen_label_rtx ();
18431 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
18432 emit_move_insn (stack_top, mem);
18434 mem = gen_frame_mem (Pmode,
18435 gen_rtx_PLUS (Pmode, stack_top,
18436 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
18437 emit_move_insn (opcode_addr, mem);
18438 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
18439 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
18440 : 0xE8410028, SImode));
18442 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
18443 SImode, NULL_RTX, NULL_RTX,
18444 no_toc_save_needed, -1);
18446 mem = gen_frame_mem (Pmode,
18447 gen_rtx_PLUS (Pmode, stack_top,
18448 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
18449 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
18450 emit_label (no_toc_save_needed);
18453 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18454 and the change to the stack pointer. */
18457 rs6000_emit_stack_tie (void)
18459 rtx mem = gen_frame_mem (BLKmode,
18460 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
18462 emit_insn (gen_stack_tie (mem));
18465 /* Emit the correct code for allocating stack space, as insns.
18466 If COPY_REG, make sure a copy of the old frame is left there.
18467 The generated code may use hard register 0 as a temporary. */
18470 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
18473 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18474 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
18475 rtx todec = gen_int_mode (-size, Pmode);
18478 if (INTVAL (todec) != -size)
18480 warning (0, "stack frame too large");
18481 emit_insn (gen_trap ());
18485 if (crtl->limit_stack)
18487 if (REG_P (stack_limit_rtx)
18488 && REGNO (stack_limit_rtx) > 1
18489 && REGNO (stack_limit_rtx) <= 31)
18491 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
18492 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18495 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
18497 && DEFAULT_ABI == ABI_V4)
18499 rtx toload = gen_rtx_CONST (VOIDmode,
18500 gen_rtx_PLUS (Pmode,
18504 emit_insn (gen_elf_high (tmp_reg, toload));
18505 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
18506 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18510 warning (0, "stack limit expression is not supported");
18514 emit_move_insn (copy_reg, stack_reg);
18518 /* Need a note here so that try_split doesn't get confused. */
18519 if (get_last_insn () == NULL_RTX)
18520 emit_note (NOTE_INSN_DELETED);
18521 insn = emit_move_insn (tmp_reg, todec);
18522 try_split (PATTERN (insn), insn, 0);
18526 insn = emit_insn (TARGET_32BIT
18527 ? gen_movsi_update_stack (stack_reg, stack_reg,
18529 : gen_movdi_di_update_stack (stack_reg, stack_reg,
18530 todec, stack_reg));
18531 /* Since we didn't use gen_frame_mem to generate the MEM, grab
18532 it now and set the alias set/attributes. The above gen_*_update
18533 calls will generate a PARALLEL with the MEM set being the first
18535 par = PATTERN (insn);
18536 gcc_assert (GET_CODE (par) == PARALLEL);
18537 set = XVECEXP (par, 0, 0);
18538 gcc_assert (GET_CODE (set) == SET);
18539 mem = SET_DEST (set);
18540 gcc_assert (MEM_P (mem));
18541 MEM_NOTRAP_P (mem) = 1;
18542 set_mem_alias_set (mem, get_frame_alias_set ());
18544 RTX_FRAME_RELATED_P (insn) = 1;
18545 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
18546 gen_rtx_SET (VOIDmode, stack_reg,
18547 gen_rtx_PLUS (Pmode, stack_reg,
18548 GEN_INT (-size))));
18551 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
18552 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
18553 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
18554 deduce these equivalences by itself so it wasn't necessary to hold
18555 its hand so much. */
18558 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
18559 rtx reg2, rtx rreg)
18563 /* copy_rtx will not make unique copies of registers, so we need to
18564 ensure we don't have unwanted sharing here. */
18566 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18569 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18571 real = copy_rtx (PATTERN (insn));
18573 if (reg2 != NULL_RTX)
18574 real = replace_rtx (real, reg2, rreg);
18576 real = replace_rtx (real, reg,
18577 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
18578 STACK_POINTER_REGNUM),
18581 /* We expect that 'real' is either a SET or a PARALLEL containing
18582 SETs (and possibly other stuff). In a PARALLEL, all the SETs
18583 are important so they all have to be marked RTX_FRAME_RELATED_P. */
18585 if (GET_CODE (real) == SET)
18589 temp = simplify_rtx (SET_SRC (set));
18591 SET_SRC (set) = temp;
18592 temp = simplify_rtx (SET_DEST (set));
18594 SET_DEST (set) = temp;
18595 if (GET_CODE (SET_DEST (set)) == MEM)
18597 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18599 XEXP (SET_DEST (set), 0) = temp;
18606 gcc_assert (GET_CODE (real) == PARALLEL);
18607 for (i = 0; i < XVECLEN (real, 0); i++)
18608 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
18610 rtx set = XVECEXP (real, 0, i);
18612 temp = simplify_rtx (SET_SRC (set));
18614 SET_SRC (set) = temp;
18615 temp = simplify_rtx (SET_DEST (set));
18617 SET_DEST (set) = temp;
18618 if (GET_CODE (SET_DEST (set)) == MEM)
18620 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18622 XEXP (SET_DEST (set), 0) = temp;
18624 RTX_FRAME_RELATED_P (set) = 1;
18628 RTX_FRAME_RELATED_P (insn) = 1;
18629 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
18632 /* Returns an insn that has a vrsave set operation with the
18633 appropriate CLOBBERs. */
18636 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
18639 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
18640 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18643 = gen_rtx_SET (VOIDmode,
18645 gen_rtx_UNSPEC_VOLATILE (SImode,
18646 gen_rtvec (2, reg, vrsave),
18647 UNSPECV_SET_VRSAVE));
18651 /* We need to clobber the registers in the mask so the scheduler
18652 does not move sets to VRSAVE before sets of AltiVec registers.
18654 However, if the function receives nonlocal gotos, reload will set
18655 all call saved registers live. We will end up with:
18657 (set (reg 999) (mem))
18658 (parallel [ (set (reg vrsave) (unspec blah))
18659 (clobber (reg 999))])
18661 The clobber will cause the store into reg 999 to be dead, and
18662 flow will attempt to delete an epilogue insn. In this case, we
18663 need an unspec use/set of the register. */
18665 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18666 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18668 if (!epiloguep || call_used_regs [i])
18669 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
18670 gen_rtx_REG (V4SImode, i));
18673 rtx reg = gen_rtx_REG (V4SImode, i);
18676 = gen_rtx_SET (VOIDmode,
18678 gen_rtx_UNSPEC (V4SImode,
18679 gen_rtvec (1, reg), 27));
18683 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
18685 for (i = 0; i < nclobs; ++i)
18686 XVECEXP (insn, 0, i) = clobs[i];
18691 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
18692 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
18695 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
18696 unsigned int regno, int offset, HOST_WIDE_INT total_size)
18698 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
18699 rtx replacea, replaceb;
18701 int_rtx = GEN_INT (offset);
18703 /* Some cases that need register indexed addressing. */
18704 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
18705 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
18706 || (TARGET_E500_DOUBLE && mode == DFmode)
18708 && SPE_VECTOR_MODE (mode)
18709 && !SPE_CONST_OFFSET_OK (offset)))
18711 /* Whomever calls us must make sure r11 is available in the
18712 flow path of instructions in the prologue. */
18713 offset_rtx = gen_rtx_REG (Pmode, 11);
18714 emit_move_insn (offset_rtx, int_rtx);
18716 replacea = offset_rtx;
18717 replaceb = int_rtx;
18721 offset_rtx = int_rtx;
18722 replacea = NULL_RTX;
18723 replaceb = NULL_RTX;
18726 reg = gen_rtx_REG (mode, regno);
18727 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18728 mem = gen_frame_mem (mode, addr);
18730 insn = emit_move_insn (mem, reg);
18732 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18735 /* Emit an offset memory reference suitable for a frame store, while
18736 converting to a valid addressing mode. */
18739 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18741 rtx int_rtx, offset_rtx;
18743 int_rtx = GEN_INT (offset);
18745 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18746 || (TARGET_E500_DOUBLE && mode == DFmode))
18748 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18749 emit_move_insn (offset_rtx, int_rtx);
18752 offset_rtx = int_rtx;
18754 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18757 /* Look for user-defined global regs. We should not save and restore these,
18758 and cannot use stmw/lmw if there are any in its range. */
18761 no_global_regs_above (int first, bool gpr)
18764 int last = gpr ? 32 : 64;
18765 for (i = first; i < last; i++)
18766 if (global_regs[i])
18771 #ifndef TARGET_FIX_AND_CONTINUE
18772 #define TARGET_FIX_AND_CONTINUE 0
18775 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18776 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18777 #define LAST_SAVRES_REGISTER 31
18778 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18780 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18782 /* Temporary holding space for an out-of-line register save/restore
18784 static char savres_routine_name[30];
18786 /* Return the name for an out-of-line register save/restore routine.
18787 We are saving/restoring GPRs if GPR is true. */
18790 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18791 bool savep, bool gpr, bool lr)
18793 const char *prefix = "";
18794 const char *suffix = "";
18796 /* Different targets are supposed to define
18797 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18798 routine name could be defined with:
18800 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18802 This is a nice idea in practice, but in reality, things are
18803 complicated in several ways:
18805 - ELF targets have save/restore routines for GPRs.
18807 - SPE targets use different prefixes for 32/64-bit registers, and
18808 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18810 - PPC64 ELF targets have routines for save/restore of GPRs that
18811 differ in what they do with the link register, so having a set
18812 prefix doesn't work. (We only use one of the save routines at
18813 the moment, though.)
18815 - PPC32 elf targets have "exit" versions of the restore routines
18816 that restore the link register and can save some extra space.
18817 These require an extra suffix. (There are also "tail" versions
18818 of the restore routines and "GOT" versions of the save routines,
18819 but we don't generate those at present. Same problems apply,
18822 We deal with all this by synthesizing our own prefix/suffix and
18823 using that for the simple sprintf call shown above. */
18826 /* No floating point saves on the SPE. */
18830 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
18832 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
18837 else if (DEFAULT_ABI == ABI_V4)
18843 prefix = savep ? "_savegpr_" : "_restgpr_";
18845 prefix = savep ? "_savefpr_" : "_restfpr_";
18850 else if (DEFAULT_ABI == ABI_AIX)
18852 #ifndef POWERPC_LINUX
18853 /* No out-of-line save/restore routines for GPRs on AIX. */
18854 gcc_assert (!TARGET_AIX || !gpr);
18860 ? (lr ? "_savegpr0_" : "_savegpr1_")
18861 : (lr ? "_restgpr0_" : "_restgpr1_"));
18862 #ifdef POWERPC_LINUX
18864 prefix = (savep ? "_savefpr_" : "_restfpr_");
18868 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
18869 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
18872 else if (DEFAULT_ABI == ABI_DARWIN)
18873 sorry ("Out-of-line save/restore routines not supported on Darwin");
18875 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
18877 return savres_routine_name;
18880 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18881 We are saving/restoring GPRs if GPR is true. */
18884 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
18887 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18889 int select = ((savep ? 1 : 0) << 2
18891 /* On the SPE, we never have any FPRs, but we do have
18892 32/64-bit versions of the routines. */
18893 ? (info->spe_64bit_regs_used ? 1 : 0)
18894 : (gpr ? 1 : 0)) << 1)
18897 /* Don't generate bogus routine names. */
18898 gcc_assert (FIRST_SAVRES_REGISTER <= regno
18899 && regno <= LAST_SAVRES_REGISTER);
18901 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18907 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
18909 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18910 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18911 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
18917 /* Emit a sequence of insns, including a stack tie if needed, for
18918 resetting the stack pointer. If SAVRES is true, then don't reset the
18919 stack pointer, but move the base of the frame into r11 for use by
18920 out-of-line register restore routines. */
18923 rs6000_emit_stack_reset (rs6000_stack_t *info,
18924 rtx sp_reg_rtx, rtx frame_reg_rtx,
18925 int sp_offset, bool savres)
18927 /* This blockage is needed so that sched doesn't decide to move
18928 the sp change before the register restores. */
18929 if (frame_reg_rtx != sp_reg_rtx
18931 && info->spe_64bit_regs_used != 0
18932 && info->first_gp_reg_save != 32))
18933 rs6000_emit_stack_tie ();
18935 if (frame_reg_rtx != sp_reg_rtx)
18937 if (sp_offset != 0)
18939 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
18940 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
18941 GEN_INT (sp_offset)));
18944 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18946 else if (sp_offset != 0)
18948 /* If we are restoring registers out-of-line, we will be using the
18949 "exit" variants of the restore routines, which will reset the
18950 stack for us. But we do need to point r11 into the right place
18951 for those routines. */
18952 rtx dest_reg = (savres
18953 ? gen_rtx_REG (Pmode, 11)
18956 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18957 GEN_INT (sp_offset)));
18964 /* Construct a parallel rtx describing the effect of a call to an
18965 out-of-line register save/restore routine. */
18968 rs6000_make_savres_rtx (rs6000_stack_t *info,
18969 rtx frame_reg_rtx, int save_area_offset,
18970 enum machine_mode reg_mode,
18971 bool savep, bool gpr, bool lr)
18974 int offset, start_reg, end_reg, n_regs;
18975 int reg_size = GET_MODE_SIZE (reg_mode);
18981 ? info->first_gp_reg_save
18982 : info->first_fp_reg_save);
18983 end_reg = gpr ? 32 : 64;
18984 n_regs = end_reg - start_reg;
18985 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
18988 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18990 RTVEC_ELT (p, offset++)
18991 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18993 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
18994 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18995 RTVEC_ELT (p, offset++)
18996 = gen_rtx_USE (VOIDmode,
18997 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19001 for (i = 0; i < end_reg - start_reg; i++)
19003 rtx addr, reg, mem;
19004 reg = gen_rtx_REG (reg_mode, start_reg + i);
19005 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19006 GEN_INT (save_area_offset + reg_size*i));
19007 mem = gen_frame_mem (reg_mode, addr);
19009 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19011 savep ? reg : mem);
19016 rtx addr, reg, mem;
19017 reg = gen_rtx_REG (Pmode, 0);
19018 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19019 GEN_INT (info->lr_save_offset));
19020 mem = gen_frame_mem (Pmode, addr);
19021 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19024 return gen_rtx_PARALLEL (VOIDmode, p);
19027 /* Determine whether the gp REG is really used. */
19030 rs6000_reg_live_or_pic_offset_p (int reg)
19032 return ((df_regs_ever_live_p (reg)
19033 && (!call_used_regs[reg]
19034 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19035 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19036 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19037 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19038 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19042 SAVRES_MULTIPLE = 0x1,
19043 SAVRES_INLINE_FPRS = 0x2,
19044 SAVRES_INLINE_GPRS = 0x4,
19045 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
19046 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
19047 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
19050 /* Determine the strategy for savings/restoring registers. */
19053 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
19054 int using_static_chain_p, int sibcall)
19056 bool using_multiple_p;
19058 bool savres_fprs_inline;
19059 bool savres_gprs_inline;
19060 bool noclobber_global_gprs
19061 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
19064 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
19065 && (!TARGET_SPE_ABI
19066 || info->spe_64bit_regs_used == 0)
19067 && info->first_gp_reg_save < 31
19068 && noclobber_global_gprs);
19069 /* Don't bother to try to save things out-of-line if r11 is occupied
19070 by the static chain. It would require too much fiddling and the
19071 static chain is rarely used anyway. */
19072 common = (using_static_chain_p
19074 || crtl->calls_eh_return
19075 || !info->lr_save_p
19076 || cfun->machine->ra_need_lr
19077 || info->total_size > 32767);
19078 savres_fprs_inline = (common
19079 || info->first_fp_reg_save == 64
19080 || !no_global_regs_above (info->first_fp_reg_save,
19082 /* The out-of-line FP routines use
19083 double-precision stores; we can't use those
19084 routines if we don't have such stores. */
19085 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
19086 || FP_SAVE_INLINE (info->first_fp_reg_save));
19087 savres_gprs_inline = (common
19088 /* Saving CR interferes with the exit routines
19089 used on the SPE, so just punt here. */
19092 && info->spe_64bit_regs_used != 0
19093 && info->cr_save_p != 0)
19094 || info->first_gp_reg_save == 32
19095 || !noclobber_global_gprs
19096 || GP_SAVE_INLINE (info->first_gp_reg_save));
19099 /* If we are going to use store multiple, then don't even bother
19100 with the out-of-line routines, since the store-multiple instruction
19101 will always be smaller. */
19102 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19105 /* The situation is more complicated with load multiple. We'd
19106 prefer to use the out-of-line routines for restores, since the
19107 "exit" out-of-line routines can handle the restore of LR and
19108 the frame teardown. But we can only use the out-of-line
19109 routines if we know that we've used store multiple or
19110 out-of-line routines in the prologue, i.e. if we've saved all
19111 the registers from first_gp_reg_save. Otherwise, we risk
19112 loading garbage from the stack. Furthermore, we can only use
19113 the "exit" out-of-line gpr restore if we haven't saved any
19115 bool saved_all = !savres_gprs_inline || using_multiple_p;
19117 if (saved_all && info->first_fp_reg_save != 64)
19118 /* We can't use the exit routine; use load multiple if it's
19120 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19123 strategy = (using_multiple_p
19124 | (savres_fprs_inline << 1)
19125 | (savres_gprs_inline << 2));
19126 #ifdef POWERPC_LINUX
19129 if (!savres_fprs_inline)
19130 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
19131 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
19132 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
19135 if (TARGET_AIX && !savres_fprs_inline)
19136 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
19141 /* Emit function prologue as insns. */
19144 rs6000_emit_prologue (void)
19146 rs6000_stack_t *info = rs6000_stack_info ();
19147 enum machine_mode reg_mode = Pmode;
19148 int reg_size = TARGET_32BIT ? 4 : 8;
19149 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19150 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19151 rtx frame_reg_rtx = sp_reg_rtx;
19152 rtx cr_save_rtx = NULL_RTX;
19155 int saving_FPRs_inline;
19156 int saving_GPRs_inline;
19157 int using_store_multiple;
19158 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19159 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19160 && call_used_regs[STATIC_CHAIN_REGNUM]);
19161 HOST_WIDE_INT sp_offset = 0;
19163 if (TARGET_FIX_AND_CONTINUE)
19165 /* gdb on darwin arranges to forward a function from the old
19166 address by modifying the first 5 instructions of the function
19167 to branch to the overriding function. This is necessary to
19168 permit function pointers that point to the old function to
19169 actually forward to the new function. */
19170 emit_insn (gen_nop ());
19171 emit_insn (gen_nop ());
19172 emit_insn (gen_nop ());
19173 emit_insn (gen_nop ());
19174 emit_insn (gen_nop ());
19177 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19179 reg_mode = V2SImode;
19183 strategy = rs6000_savres_strategy (info, /*savep=*/true,
19184 /*static_chain_p=*/using_static_chain_p,
19186 using_store_multiple = strategy & SAVRES_MULTIPLE;
19187 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19188 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19190 /* For V.4, update stack before we do any saving and set back pointer. */
19191 if (! WORLD_SAVE_P (info)
19193 && (DEFAULT_ABI == ABI_V4
19194 || crtl->calls_eh_return))
19196 bool need_r11 = (TARGET_SPE
19197 ? (!saving_GPRs_inline
19198 && info->spe_64bit_regs_used == 0)
19199 : (!saving_FPRs_inline || !saving_GPRs_inline));
19200 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19202 if (info->total_size < 32767)
19203 sp_offset = info->total_size;
19205 frame_reg_rtx = copy_reg;
19206 else if (info->cr_save_p
19208 || info->first_fp_reg_save < 64
19209 || info->first_gp_reg_save < 32
19210 || info->altivec_size != 0
19211 || info->vrsave_mask != 0
19212 || crtl->calls_eh_return)
19214 copy_reg = frame_ptr_rtx;
19215 frame_reg_rtx = copy_reg;
19219 /* The prologue won't be saving any regs so there is no need
19220 to set up a frame register to access any frame save area.
19221 We also won't be using sp_offset anywhere below, but set
19222 the correct value anyway to protect against future
19223 changes to this function. */
19224 sp_offset = info->total_size;
19226 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19227 if (frame_reg_rtx != sp_reg_rtx)
19228 rs6000_emit_stack_tie ();
19231 /* Handle world saves specially here. */
19232 if (WORLD_SAVE_P (info))
19239 /* save_world expects lr in r0. */
19240 reg0 = gen_rtx_REG (Pmode, 0);
19241 if (info->lr_save_p)
19243 insn = emit_move_insn (reg0,
19244 gen_rtx_REG (Pmode, LR_REGNO));
19245 RTX_FRAME_RELATED_P (insn) = 1;
19248 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19249 assumptions about the offsets of various bits of the stack
19251 gcc_assert (info->gp_save_offset == -220
19252 && info->fp_save_offset == -144
19253 && info->lr_save_offset == 8
19254 && info->cr_save_offset == 4
19257 && (!crtl->calls_eh_return
19258 || info->ehrd_offset == -432)
19259 && info->vrsave_save_offset == -224
19260 && info->altivec_save_offset == -416);
19262 treg = gen_rtx_REG (SImode, 11);
19263 emit_move_insn (treg, GEN_INT (-info->total_size));
19265 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19266 in R11. It also clobbers R12, so beware! */
19268 /* Preserve CR2 for save_world prologues */
19270 sz += 32 - info->first_gp_reg_save;
19271 sz += 64 - info->first_fp_reg_save;
19272 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19273 p = rtvec_alloc (sz);
19275 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19276 gen_rtx_REG (SImode,
19278 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19279 gen_rtx_SYMBOL_REF (Pmode,
19281 /* We do floats first so that the instruction pattern matches
19283 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19285 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19286 ? DFmode : SFmode),
19287 info->first_fp_reg_save + i);
19288 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19289 GEN_INT (info->fp_save_offset
19290 + sp_offset + 8 * i));
19291 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19292 ? DFmode : SFmode), addr);
19294 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19296 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19298 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19299 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19300 GEN_INT (info->altivec_save_offset
19301 + sp_offset + 16 * i));
19302 rtx mem = gen_frame_mem (V4SImode, addr);
19304 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19306 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19308 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19309 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19310 GEN_INT (info->gp_save_offset
19311 + sp_offset + reg_size * i));
19312 rtx mem = gen_frame_mem (reg_mode, addr);
19314 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19318 /* CR register traditionally saved as CR2. */
19319 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19320 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19321 GEN_INT (info->cr_save_offset
19323 rtx mem = gen_frame_mem (reg_mode, addr);
19325 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19327 /* Explain about use of R0. */
19328 if (info->lr_save_p)
19330 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19331 GEN_INT (info->lr_save_offset
19333 rtx mem = gen_frame_mem (reg_mode, addr);
19335 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
19337 /* Explain what happens to the stack pointer. */
19339 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
19340 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
19343 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19344 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19345 treg, GEN_INT (-info->total_size));
19346 sp_offset = info->total_size;
19349 /* If we use the link register, get it into r0. */
19350 if (!WORLD_SAVE_P (info) && info->lr_save_p)
19352 rtx addr, reg, mem;
19354 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
19355 gen_rtx_REG (Pmode, LR_REGNO));
19356 RTX_FRAME_RELATED_P (insn) = 1;
19358 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
19359 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
19361 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19362 GEN_INT (info->lr_save_offset + sp_offset));
19363 reg = gen_rtx_REG (Pmode, 0);
19364 mem = gen_rtx_MEM (Pmode, addr);
19365 /* This should not be of rs6000_sr_alias_set, because of
19366 __builtin_return_address. */
19368 insn = emit_move_insn (mem, reg);
19369 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19370 NULL_RTX, NULL_RTX);
19374 /* If we need to save CR, put it into r12 or r11. */
19375 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
19380 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
19382 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19383 RTX_FRAME_RELATED_P (insn) = 1;
19384 /* Now, there's no way that dwarf2out_frame_debug_expr is going
19385 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
19386 But that's OK. All we have to do is specify that _one_ condition
19387 code register is saved in this stack slot. The thrower's epilogue
19388 will then restore all the call-saved registers.
19389 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
19390 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
19391 gen_rtx_REG (SImode, CR2_REGNO));
19392 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19395 /* Do any required saving of fpr's. If only one or two to save, do
19396 it ourselves. Otherwise, call function. */
19397 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
19400 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19401 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
19402 && ! call_used_regs[info->first_fp_reg_save+i]))
19403 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
19404 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19406 info->first_fp_reg_save + i,
19407 info->fp_save_offset + sp_offset + 8 * i,
19410 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
19414 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19415 info->fp_save_offset + sp_offset,
19417 /*savep=*/true, /*gpr=*/false,
19419 & SAVRES_NOINLINE_FPRS_SAVES_LR)
19421 insn = emit_insn (par);
19422 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19423 NULL_RTX, NULL_RTX);
19426 /* Save GPRs. This is done as a PARALLEL if we are using
19427 the store-multiple instructions. */
19428 if (!WORLD_SAVE_P (info)
19430 && info->spe_64bit_regs_used != 0
19431 && info->first_gp_reg_save != 32)
19434 rtx spe_save_area_ptr;
19436 /* Determine whether we can address all of the registers that need
19437 to be saved with an offset from the stack pointer that fits in
19438 the small const field for SPE memory instructions. */
19439 int spe_regs_addressable_via_sp
19440 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19441 + (32 - info->first_gp_reg_save - 1) * reg_size)
19442 && saving_GPRs_inline);
19445 if (spe_regs_addressable_via_sp)
19447 spe_save_area_ptr = frame_reg_rtx;
19448 spe_offset = info->spe_gp_save_offset + sp_offset;
19452 /* Make r11 point to the start of the SPE save area. We need
19453 to be careful here if r11 is holding the static chain. If
19454 it is, then temporarily save it in r0. We would use r0 as
19455 our base register here, but using r0 as a base register in
19456 loads and stores means something different from what we
19458 int ool_adjust = (saving_GPRs_inline
19460 : (info->first_gp_reg_save
19461 - (FIRST_SAVRES_REGISTER+1))*8);
19462 HOST_WIDE_INT offset = (info->spe_gp_save_offset
19463 + sp_offset - ool_adjust);
19465 if (using_static_chain_p)
19467 rtx r0 = gen_rtx_REG (Pmode, 0);
19468 gcc_assert (info->first_gp_reg_save > 11);
19470 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
19473 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
19474 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
19476 GEN_INT (offset)));
19477 /* We need to make sure the move to r11 gets noted for
19478 properly outputting unwind information. */
19479 if (!saving_GPRs_inline)
19480 rs6000_frame_related (insn, frame_reg_rtx, offset,
19481 NULL_RTX, NULL_RTX);
19485 if (saving_GPRs_inline)
19487 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19488 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19490 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19491 rtx offset, addr, mem;
19493 /* We're doing all this to ensure that the offset fits into
19494 the immediate offset of 'evstdd'. */
19495 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
19497 offset = GEN_INT (reg_size * i + spe_offset);
19498 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
19499 mem = gen_rtx_MEM (V2SImode, addr);
19501 insn = emit_move_insn (mem, reg);
19503 rs6000_frame_related (insn, spe_save_area_ptr,
19504 info->spe_gp_save_offset
19505 + sp_offset + reg_size * i,
19506 offset, const0_rtx);
19513 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19515 /*savep=*/true, /*gpr=*/true,
19517 insn = emit_insn (par);
19518 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19519 NULL_RTX, NULL_RTX);
19523 /* Move the static chain pointer back. */
19524 if (using_static_chain_p && !spe_regs_addressable_via_sp)
19525 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
19527 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
19531 /* Need to adjust r11 (r12) if we saved any FPRs. */
19532 if (info->first_fp_reg_save != 64)
19534 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
19536 rtx offset = GEN_INT (sp_offset
19537 + (-8 * (64-info->first_fp_reg_save)));
19538 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
19541 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19542 info->gp_save_offset + sp_offset,
19544 /*savep=*/true, /*gpr=*/true,
19546 & SAVRES_NOINLINE_GPRS_SAVES_LR)
19548 insn = emit_insn (par);
19549 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19550 NULL_RTX, NULL_RTX);
19552 else if (!WORLD_SAVE_P (info) && using_store_multiple)
19556 p = rtvec_alloc (32 - info->first_gp_reg_save);
19557 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19559 rtx addr, reg, mem;
19560 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19561 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19562 GEN_INT (info->gp_save_offset
19565 mem = gen_frame_mem (reg_mode, addr);
19567 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
19569 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19570 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19571 NULL_RTX, NULL_RTX);
19573 else if (!WORLD_SAVE_P (info))
19576 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19577 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19579 rtx addr, reg, mem;
19580 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19582 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19583 GEN_INT (info->gp_save_offset
19586 mem = gen_frame_mem (reg_mode, addr);
19588 insn = emit_move_insn (mem, reg);
19589 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19590 NULL_RTX, NULL_RTX);
19594 /* ??? There's no need to emit actual instructions here, but it's the
19595 easiest way to get the frame unwind information emitted. */
19596 if (crtl->calls_eh_return)
19598 unsigned int i, regno;
19600 /* In AIX ABI we need to pretend we save r2 here. */
19603 rtx addr, reg, mem;
19605 reg = gen_rtx_REG (reg_mode, 2);
19606 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19607 GEN_INT (sp_offset + 5 * reg_size));
19608 mem = gen_frame_mem (reg_mode, addr);
19610 insn = emit_move_insn (mem, reg);
19611 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19612 NULL_RTX, NULL_RTX);
19613 PATTERN (insn) = gen_blockage ();
19618 regno = EH_RETURN_DATA_REGNO (i);
19619 if (regno == INVALID_REGNUM)
19622 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
19623 info->ehrd_offset + sp_offset
19624 + reg_size * (int) i,
19629 /* Save CR if we use any that must be preserved. */
19630 if (!WORLD_SAVE_P (info) && info->cr_save_p)
19632 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19633 GEN_INT (info->cr_save_offset + sp_offset));
19634 rtx mem = gen_frame_mem (SImode, addr);
19635 /* See the large comment above about why CR2_REGNO is used. */
19636 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
19638 /* If r12 was used to hold the original sp, copy cr into r0 now
19640 if (REGNO (frame_reg_rtx) == 12)
19644 cr_save_rtx = gen_rtx_REG (SImode, 0);
19645 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19646 RTX_FRAME_RELATED_P (insn) = 1;
19647 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
19648 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19650 insn = emit_move_insn (mem, cr_save_rtx);
19652 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19653 NULL_RTX, NULL_RTX);
19656 /* Update stack and set back pointer unless this is V.4,
19657 for which it was done previously. */
19658 if (!WORLD_SAVE_P (info) && info->push_p
19659 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
19661 rtx copy_reg = NULL;
19663 if (info->total_size < 32767)
19664 sp_offset = info->total_size;
19665 else if (info->altivec_size != 0
19666 || info->vrsave_mask != 0)
19668 copy_reg = frame_ptr_rtx;
19669 frame_reg_rtx = copy_reg;
19672 sp_offset = info->total_size;
19673 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19674 if (frame_reg_rtx != sp_reg_rtx)
19675 rs6000_emit_stack_tie ();
19678 /* Set frame pointer, if needed. */
19679 if (frame_pointer_needed)
19681 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
19683 RTX_FRAME_RELATED_P (insn) = 1;
19686 /* Save AltiVec registers if needed. Save here because the red zone does
19687 not include AltiVec registers. */
19688 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
19692 /* There should be a non inline version of this, for when we
19693 are saving lots of vector registers. */
19694 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19695 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19697 rtx areg, savereg, mem;
19700 offset = info->altivec_save_offset + sp_offset
19701 + 16 * (i - info->first_altivec_reg_save);
19703 savereg = gen_rtx_REG (V4SImode, i);
19705 areg = gen_rtx_REG (Pmode, 0);
19706 emit_move_insn (areg, GEN_INT (offset));
19708 /* AltiVec addressing mode is [reg+reg]. */
19709 mem = gen_frame_mem (V4SImode,
19710 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
19712 insn = emit_move_insn (mem, savereg);
19714 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19715 areg, GEN_INT (offset));
19719 /* VRSAVE is a bit vector representing which AltiVec registers
19720 are used. The OS uses this to determine which vector
19721 registers to save on a context switch. We need to save
19722 VRSAVE on the stack frame, add whatever AltiVec registers we
19723 used in this function, and do the corresponding magic in the
19726 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
19727 && info->vrsave_mask != 0)
19729 rtx reg, mem, vrsave;
19732 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
19733 as frame_reg_rtx and r11 as the static chain pointer for
19734 nested functions. */
19735 reg = gen_rtx_REG (SImode, 0);
19736 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19738 emit_insn (gen_get_vrsave_internal (reg));
19740 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19742 if (!WORLD_SAVE_P (info))
19745 offset = info->vrsave_save_offset + sp_offset;
19746 mem = gen_frame_mem (SImode,
19747 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19748 GEN_INT (offset)));
19749 insn = emit_move_insn (mem, reg);
19752 /* Include the registers in the mask. */
19753 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19755 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19758 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19759 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19760 || (DEFAULT_ABI == ABI_V4
19761 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19762 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19764 /* If emit_load_toc_table will use the link register, we need to save
19765 it. We use R12 for this purpose because emit_load_toc_table
19766 can use register 0. This allows us to use a plain 'blr' to return
19767 from the procedure more often. */
19768 int save_LR_around_toc_setup = (TARGET_ELF
19769 && DEFAULT_ABI != ABI_AIX
19771 && ! info->lr_save_p
19772 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19773 if (save_LR_around_toc_setup)
19775 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19777 insn = emit_move_insn (frame_ptr_rtx, lr);
19778 RTX_FRAME_RELATED_P (insn) = 1;
19780 rs6000_emit_load_toc_table (TRUE);
19782 insn = emit_move_insn (lr, frame_ptr_rtx);
19783 RTX_FRAME_RELATED_P (insn) = 1;
19786 rs6000_emit_load_toc_table (TRUE);
19790 if (DEFAULT_ABI == ABI_DARWIN
19791 && flag_pic && crtl->uses_pic_offset_table)
19793 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19794 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19796 /* Save and restore LR locally around this call (in R0). */
19797 if (!info->lr_save_p)
19798 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19800 emit_insn (gen_load_macho_picbase (src));
19802 emit_move_insn (gen_rtx_REG (Pmode,
19803 RS6000_PIC_OFFSET_TABLE_REGNUM),
19806 if (!info->lr_save_p)
19807 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19812 /* Write function prologue. */
19815 rs6000_output_function_prologue (FILE *file,
19816 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19818 rs6000_stack_t *info = rs6000_stack_info ();
19820 if (TARGET_DEBUG_STACK)
19821 debug_stack_info (info);
19823 /* Write .extern for any function we will call to save and restore
19825 if (info->first_fp_reg_save < 64
19826 && !FP_SAVE_INLINE (info->first_fp_reg_save))
19829 int regno = info->first_fp_reg_save - 32;
19831 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
19832 /*gpr=*/false, /*lr=*/false);
19833 fprintf (file, "\t.extern %s\n", name);
19835 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
19836 /*gpr=*/false, /*lr=*/true);
19837 fprintf (file, "\t.extern %s\n", name);
19840 /* Write .extern for AIX common mode routines, if needed. */
19841 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
19843 fputs ("\t.extern __mulh\n", file);
19844 fputs ("\t.extern __mull\n", file);
19845 fputs ("\t.extern __divss\n", file);
19846 fputs ("\t.extern __divus\n", file);
19847 fputs ("\t.extern __quoss\n", file);
19848 fputs ("\t.extern __quous\n", file);
19849 common_mode_defined = 1;
19852 if (! HAVE_prologue)
19858 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19859 the "toplevel" insn chain. */
19860 emit_note (NOTE_INSN_DELETED);
19861 rs6000_emit_prologue ();
19862 emit_note (NOTE_INSN_DELETED);
19864 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19868 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19870 INSN_ADDRESSES_NEW (insn, addr);
19875 prologue = get_insns ();
19878 if (TARGET_DEBUG_STACK)
19879 debug_rtx_list (prologue, 100);
19881 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
19885 rs6000_pic_labelno++;
19888 /* Non-zero if vmx regs are restored before the frame pop, zero if
19889 we restore after the pop when possible. */
19890 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19892 /* Reload CR from REG. */
19895 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
19900 if (using_mfcr_multiple)
19902 for (i = 0; i < 8; i++)
19903 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19905 gcc_assert (count);
19908 if (using_mfcr_multiple && count > 1)
19913 p = rtvec_alloc (count);
19916 for (i = 0; i < 8; i++)
19917 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19919 rtvec r = rtvec_alloc (2);
19920 RTVEC_ELT (r, 0) = reg;
19921 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19922 RTVEC_ELT (p, ndx) =
19923 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19924 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19927 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19928 gcc_assert (ndx == count);
19931 for (i = 0; i < 8; i++)
19932 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19934 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19940 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19941 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19942 below stack pointer not cloberred by signals. */
19945 offset_below_red_zone_p (HOST_WIDE_INT offset)
19947 return offset < (DEFAULT_ABI == ABI_V4
19949 : TARGET_32BIT ? -220 : -288);
19952 /* Emit function epilogue as insns. */
19955 rs6000_emit_epilogue (int sibcall)
19957 rs6000_stack_t *info;
19958 int restoring_GPRs_inline;
19959 int restoring_FPRs_inline;
19960 int using_load_multiple;
19961 int using_mtcr_multiple;
19962 int use_backchain_to_restore_sp;
19966 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19967 rtx frame_reg_rtx = sp_reg_rtx;
19968 rtx cfa_restores = NULL_RTX;
19970 rtx cr_save_reg = NULL_RTX;
19971 enum machine_mode reg_mode = Pmode;
19972 int reg_size = TARGET_32BIT ? 4 : 8;
19975 info = rs6000_stack_info ();
19977 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19979 reg_mode = V2SImode;
19983 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19984 /*static_chain_p=*/0, sibcall);
19985 using_load_multiple = strategy & SAVRES_MULTIPLE;
19986 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19987 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19988 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19989 || rs6000_cpu == PROCESSOR_PPC603
19990 || rs6000_cpu == PROCESSOR_PPC750
19992 /* Restore via the backchain when we have a large frame, since this
19993 is more efficient than an addis, addi pair. The second condition
19994 here will not trigger at the moment; We don't actually need a
19995 frame pointer for alloca, but the generic parts of the compiler
19996 give us one anyway. */
19997 use_backchain_to_restore_sp = (info->total_size > 32767
19998 || info->total_size
19999 + (info->lr_save_p ? info->lr_save_offset : 0)
20001 || (cfun->calls_alloca
20002 && !frame_pointer_needed));
20003 restore_lr = (info->lr_save_p
20004 && (restoring_FPRs_inline
20005 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20006 && (restoring_GPRs_inline
20007 || info->first_fp_reg_save < 64));
20009 if (WORLD_SAVE_P (info))
20013 const char *alloc_rname;
20016 /* eh_rest_world_r10 will return to the location saved in the LR
20017 stack slot (which is not likely to be our caller.)
20018 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20019 rest_world is similar, except any R10 parameter is ignored.
20020 The exception-handling stuff that was here in 2.95 is no
20021 longer necessary. */
20025 + 32 - info->first_gp_reg_save
20026 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20027 + 63 + 1 - info->first_fp_reg_save);
20029 strcpy (rname, ((crtl->calls_eh_return) ?
20030 "*eh_rest_world_r10" : "*rest_world"));
20031 alloc_rname = ggc_strdup (rname);
20034 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
20035 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20036 gen_rtx_REG (Pmode,
20039 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20040 /* The instruction pattern requires a clobber here;
20041 it is shared with the restVEC helper. */
20043 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20046 /* CR register traditionally saved as CR2. */
20047 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20048 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20049 GEN_INT (info->cr_save_offset));
20050 rtx mem = gen_frame_mem (reg_mode, addr);
20052 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20055 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20057 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20058 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20059 GEN_INT (info->gp_save_offset
20061 rtx mem = gen_frame_mem (reg_mode, addr);
20063 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20065 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20067 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20068 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20069 GEN_INT (info->altivec_save_offset
20071 rtx mem = gen_frame_mem (V4SImode, addr);
20073 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20075 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20077 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20078 ? DFmode : SFmode),
20079 info->first_fp_reg_save + i);
20080 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20081 GEN_INT (info->fp_save_offset
20083 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20084 ? DFmode : SFmode), addr);
20086 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20089 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20091 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20093 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20095 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20097 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20098 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20103 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20105 sp_offset = info->total_size;
20107 /* Restore AltiVec registers if we must do so before adjusting the
20109 if (TARGET_ALTIVEC_ABI
20110 && info->altivec_size != 0
20111 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20112 || (DEFAULT_ABI != ABI_V4
20113 && offset_below_red_zone_p (info->altivec_save_offset))))
20117 if (use_backchain_to_restore_sp)
20119 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20120 emit_move_insn (frame_reg_rtx,
20121 gen_rtx_MEM (Pmode, sp_reg_rtx));
20124 else if (frame_pointer_needed)
20125 frame_reg_rtx = hard_frame_pointer_rtx;
20127 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20128 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20130 rtx addr, areg, mem, reg;
20132 areg = gen_rtx_REG (Pmode, 0);
20134 (areg, GEN_INT (info->altivec_save_offset
20136 + 16 * (i - info->first_altivec_reg_save)));
20138 /* AltiVec addressing mode is [reg+reg]. */
20139 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20140 mem = gen_frame_mem (V4SImode, addr);
20142 reg = gen_rtx_REG (V4SImode, i);
20143 emit_move_insn (reg, mem);
20144 if (offset_below_red_zone_p (info->altivec_save_offset
20145 + (i - info->first_altivec_reg_save)
20147 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20152 /* Restore VRSAVE if we must do so before adjusting the stack. */
20154 && TARGET_ALTIVEC_VRSAVE
20155 && info->vrsave_mask != 0
20156 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20157 || (DEFAULT_ABI != ABI_V4
20158 && offset_below_red_zone_p (info->vrsave_save_offset))))
20160 rtx addr, mem, reg;
20162 if (frame_reg_rtx == sp_reg_rtx)
20164 if (use_backchain_to_restore_sp)
20166 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20167 emit_move_insn (frame_reg_rtx,
20168 gen_rtx_MEM (Pmode, sp_reg_rtx));
20171 else if (frame_pointer_needed)
20172 frame_reg_rtx = hard_frame_pointer_rtx;
20175 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20176 GEN_INT (info->vrsave_save_offset + sp_offset));
20177 mem = gen_frame_mem (SImode, addr);
20178 reg = gen_rtx_REG (SImode, 12);
20179 emit_move_insn (reg, mem);
20181 emit_insn (generate_set_vrsave (reg, info, 1));
20185 /* If we have a large stack frame, restore the old stack pointer
20186 using the backchain. */
20187 if (use_backchain_to_restore_sp)
20189 if (frame_reg_rtx == sp_reg_rtx)
20191 /* Under V.4, don't reset the stack pointer until after we're done
20192 loading the saved registers. */
20193 if (DEFAULT_ABI == ABI_V4)
20194 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20196 insn = emit_move_insn (frame_reg_rtx,
20197 gen_rtx_MEM (Pmode, sp_reg_rtx));
20200 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20201 && DEFAULT_ABI == ABI_V4)
20202 /* frame_reg_rtx has been set up by the altivec restore. */
20206 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20207 frame_reg_rtx = sp_reg_rtx;
20210 /* If we have a frame pointer, we can restore the old stack pointer
20212 else if (frame_pointer_needed)
20214 frame_reg_rtx = sp_reg_rtx;
20215 if (DEFAULT_ABI == ABI_V4)
20216 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20217 /* Prevent reordering memory accesses against stack pointer restore. */
20218 else if (cfun->calls_alloca
20219 || offset_below_red_zone_p (-info->total_size))
20221 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20222 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20223 MEM_NOTRAP_P (mem1) = 1;
20224 MEM_NOTRAP_P (mem2) = 1;
20225 emit_insn (gen_frame_tie (mem1, mem2));
20228 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20229 GEN_INT (info->total_size)));
20232 else if (info->push_p
20233 && DEFAULT_ABI != ABI_V4
20234 && !crtl->calls_eh_return)
20236 /* Prevent reordering memory accesses against stack pointer restore. */
20237 if (cfun->calls_alloca
20238 || offset_below_red_zone_p (-info->total_size))
20240 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20241 MEM_NOTRAP_P (mem) = 1;
20242 emit_insn (gen_stack_tie (mem));
20244 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20245 GEN_INT (info->total_size)));
20248 if (insn && frame_reg_rtx == sp_reg_rtx)
20252 REG_NOTES (insn) = cfa_restores;
20253 cfa_restores = NULL_RTX;
20255 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20256 RTX_FRAME_RELATED_P (insn) = 1;
20259 /* Restore AltiVec registers if we have not done so already. */
20260 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20261 && TARGET_ALTIVEC_ABI
20262 && info->altivec_size != 0
20263 && (DEFAULT_ABI == ABI_V4
20264 || !offset_below_red_zone_p (info->altivec_save_offset)))
20268 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20269 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20271 rtx addr, areg, mem, reg;
20273 areg = gen_rtx_REG (Pmode, 0);
20275 (areg, GEN_INT (info->altivec_save_offset
20277 + 16 * (i - info->first_altivec_reg_save)));
20279 /* AltiVec addressing mode is [reg+reg]. */
20280 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20281 mem = gen_frame_mem (V4SImode, addr);
20283 reg = gen_rtx_REG (V4SImode, i);
20284 emit_move_insn (reg, mem);
20285 if (DEFAULT_ABI == ABI_V4)
20286 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20291 /* Restore VRSAVE if we have not done so already. */
20292 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20294 && TARGET_ALTIVEC_VRSAVE
20295 && info->vrsave_mask != 0
20296 && (DEFAULT_ABI == ABI_V4
20297 || !offset_below_red_zone_p (info->vrsave_save_offset)))
20299 rtx addr, mem, reg;
20301 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20302 GEN_INT (info->vrsave_save_offset + sp_offset));
20303 mem = gen_frame_mem (SImode, addr);
20304 reg = gen_rtx_REG (SImode, 12);
20305 emit_move_insn (reg, mem);
20307 emit_insn (generate_set_vrsave (reg, info, 1));
20310 /* Get the old lr if we saved it. If we are restoring registers
20311 out-of-line, then the out-of-line routines can do this for us. */
20312 if (restore_lr && restoring_GPRs_inline)
20314 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20315 info->lr_save_offset + sp_offset);
20317 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20320 /* Get the old cr if we saved it. */
20321 if (info->cr_save_p)
20323 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20324 GEN_INT (info->cr_save_offset + sp_offset));
20325 rtx mem = gen_frame_mem (SImode, addr);
20327 cr_save_reg = gen_rtx_REG (SImode,
20328 DEFAULT_ABI == ABI_AIX
20329 && !restoring_GPRs_inline
20330 && info->first_fp_reg_save < 64
20332 emit_move_insn (cr_save_reg, mem);
20335 /* Set LR here to try to overlap restores below. LR is always saved
20336 above incoming stack, so it never needs REG_CFA_RESTORE. */
20337 if (restore_lr && restoring_GPRs_inline)
20338 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20339 gen_rtx_REG (Pmode, 0));
20341 /* Load exception handler data registers, if needed. */
20342 if (crtl->calls_eh_return)
20344 unsigned int i, regno;
20348 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20349 GEN_INT (sp_offset + 5 * reg_size));
20350 rtx mem = gen_frame_mem (reg_mode, addr);
20352 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
20359 regno = EH_RETURN_DATA_REGNO (i);
20360 if (regno == INVALID_REGNUM)
20363 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
20364 info->ehrd_offset + sp_offset
20365 + reg_size * (int) i);
20367 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
20371 /* Restore GPRs. This is done as a PARALLEL if we are using
20372 the load-multiple instructions. */
20374 && info->spe_64bit_regs_used != 0
20375 && info->first_gp_reg_save != 32)
20377 /* Determine whether we can address all of the registers that need
20378 to be saved with an offset from the stack pointer that fits in
20379 the small const field for SPE memory instructions. */
20380 int spe_regs_addressable_via_sp
20381 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20382 + (32 - info->first_gp_reg_save - 1) * reg_size)
20383 && restoring_GPRs_inline);
20386 if (spe_regs_addressable_via_sp)
20387 spe_offset = info->spe_gp_save_offset + sp_offset;
20390 rtx old_frame_reg_rtx = frame_reg_rtx;
20391 /* Make r11 point to the start of the SPE save area. We worried about
20392 not clobbering it when we were saving registers in the prologue.
20393 There's no need to worry here because the static chain is passed
20394 anew to every function. */
20395 int ool_adjust = (restoring_GPRs_inline
20397 : (info->first_gp_reg_save
20398 - (FIRST_SAVRES_REGISTER+1))*8);
20400 if (frame_reg_rtx == sp_reg_rtx)
20401 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20402 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
20403 GEN_INT (info->spe_gp_save_offset
20406 /* Keep the invariant that frame_reg_rtx + sp_offset points
20407 at the top of the stack frame. */
20408 sp_offset = -info->spe_gp_save_offset;
20413 if (restoring_GPRs_inline)
20415 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20416 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20418 rtx offset, addr, mem, reg;
20420 /* We're doing all this to ensure that the immediate offset
20421 fits into the immediate field of 'evldd'. */
20422 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
20424 offset = GEN_INT (spe_offset + reg_size * i);
20425 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
20426 mem = gen_rtx_MEM (V2SImode, addr);
20427 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20429 insn = emit_move_insn (reg, mem);
20430 if (DEFAULT_ABI == ABI_V4)
20432 if (frame_pointer_needed
20433 && info->first_gp_reg_save + i
20434 == HARD_FRAME_POINTER_REGNUM)
20436 add_reg_note (insn, REG_CFA_DEF_CFA,
20437 plus_constant (frame_reg_rtx,
20439 RTX_FRAME_RELATED_P (insn) = 1;
20442 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20451 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20453 /*savep=*/false, /*gpr=*/true,
20455 emit_jump_insn (par);
20456 /* We don't want anybody else emitting things after we jumped
20461 else if (!restoring_GPRs_inline)
20463 /* We are jumping to an out-of-line function. */
20464 bool can_use_exit = info->first_fp_reg_save == 64;
20467 /* Emit stack reset code if we need it. */
20469 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20470 sp_offset, can_use_exit);
20473 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
20476 GEN_INT (sp_offset - info->fp_size)));
20477 if (REGNO (frame_reg_rtx) == 11)
20478 sp_offset += info->fp_size;
20481 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20482 info->gp_save_offset, reg_mode,
20483 /*savep=*/false, /*gpr=*/true,
20484 /*lr=*/can_use_exit);
20488 if (info->cr_save_p)
20490 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20491 if (DEFAULT_ABI == ABI_V4)
20493 = alloc_reg_note (REG_CFA_RESTORE,
20494 gen_rtx_REG (SImode, CR2_REGNO),
20498 emit_jump_insn (par);
20500 /* We don't want anybody else emitting things after we jumped
20505 insn = emit_insn (par);
20506 if (DEFAULT_ABI == ABI_V4)
20508 if (frame_pointer_needed)
20510 add_reg_note (insn, REG_CFA_DEF_CFA,
20511 plus_constant (frame_reg_rtx, sp_offset));
20512 RTX_FRAME_RELATED_P (insn) = 1;
20515 for (i = info->first_gp_reg_save; i < 32; i++)
20517 = alloc_reg_note (REG_CFA_RESTORE,
20518 gen_rtx_REG (reg_mode, i), cfa_restores);
20521 else if (using_load_multiple)
20524 p = rtvec_alloc (32 - info->first_gp_reg_save);
20525 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20527 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20528 GEN_INT (info->gp_save_offset
20531 rtx mem = gen_frame_mem (reg_mode, addr);
20532 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20534 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
20535 if (DEFAULT_ABI == ABI_V4)
20536 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20539 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20540 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
20542 add_reg_note (insn, REG_CFA_DEF_CFA,
20543 plus_constant (frame_reg_rtx, sp_offset));
20544 RTX_FRAME_RELATED_P (insn) = 1;
20549 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20550 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20552 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20553 GEN_INT (info->gp_save_offset
20556 rtx mem = gen_frame_mem (reg_mode, addr);
20557 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20559 insn = emit_move_insn (reg, mem);
20560 if (DEFAULT_ABI == ABI_V4)
20562 if (frame_pointer_needed
20563 && info->first_gp_reg_save + i
20564 == HARD_FRAME_POINTER_REGNUM)
20566 add_reg_note (insn, REG_CFA_DEF_CFA,
20567 plus_constant (frame_reg_rtx, sp_offset));
20568 RTX_FRAME_RELATED_P (insn) = 1;
20571 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20577 if (restore_lr && !restoring_GPRs_inline)
20579 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20580 info->lr_save_offset + sp_offset);
20582 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20583 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20584 gen_rtx_REG (Pmode, 0));
20587 /* Restore fpr's if we need to do it without calling a function. */
20588 if (restoring_FPRs_inline)
20589 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20590 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20591 && ! call_used_regs[info->first_fp_reg_save+i]))
20593 rtx addr, mem, reg;
20594 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20595 GEN_INT (info->fp_save_offset
20598 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20599 ? DFmode : SFmode), addr);
20600 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20601 ? DFmode : SFmode),
20602 info->first_fp_reg_save + i);
20604 emit_move_insn (reg, mem);
20605 if (DEFAULT_ABI == ABI_V4)
20606 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20610 /* If we saved cr, restore it here. Just those that were used. */
20611 if (info->cr_save_p)
20613 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20614 if (DEFAULT_ABI == ABI_V4)
20616 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
20620 /* If this is V.4, unwind the stack pointer after all of the loads
20622 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20623 sp_offset, !restoring_FPRs_inline);
20628 REG_NOTES (insn) = cfa_restores;
20629 cfa_restores = NULL_RTX;
20631 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20632 RTX_FRAME_RELATED_P (insn) = 1;
20635 if (crtl->calls_eh_return)
20637 rtx sa = EH_RETURN_STACKADJ_RTX;
20638 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
20644 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
20645 if (! restoring_FPRs_inline)
20646 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
20648 p = rtvec_alloc (2);
20650 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
20651 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
20652 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
20653 : gen_rtx_CLOBBER (VOIDmode,
20654 gen_rtx_REG (Pmode, 65)));
20656 /* If we have to restore more than two FP registers, branch to the
20657 restore function. It will return to our caller. */
20658 if (! restoring_FPRs_inline)
20663 sym = rs6000_savres_routine_sym (info,
20667 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
20668 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
20669 gen_rtx_REG (Pmode,
20670 DEFAULT_ABI == ABI_AIX
20672 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20675 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
20676 GEN_INT (info->fp_save_offset + 8*i));
20677 mem = gen_frame_mem (DFmode, addr);
20679 RTVEC_ELT (p, i+4) =
20680 gen_rtx_SET (VOIDmode,
20681 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
20686 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20690 /* Write function epilogue. */
20693 rs6000_output_function_epilogue (FILE *file,
20694 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20696 if (! HAVE_epilogue)
20698 rtx insn = get_last_insn ();
20699 /* If the last insn was a BARRIER, we don't have to write anything except
20700 the trace table. */
20701 if (GET_CODE (insn) == NOTE)
20702 insn = prev_nonnote_insn (insn);
20703 if (insn == 0 || GET_CODE (insn) != BARRIER)
20705 /* This is slightly ugly, but at least we don't have two
20706 copies of the epilogue-emitting code. */
20709 /* A NOTE_INSN_DELETED is supposed to be at the start
20710 and end of the "toplevel" insn chain. */
20711 emit_note (NOTE_INSN_DELETED);
20712 rs6000_emit_epilogue (FALSE);
20713 emit_note (NOTE_INSN_DELETED);
20715 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20719 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20721 INSN_ADDRESSES_NEW (insn, addr);
20726 if (TARGET_DEBUG_STACK)
20727 debug_rtx_list (get_insns (), 100);
20728 final (get_insns (), file, FALSE);
20734 macho_branch_islands ();
20735 /* Mach-O doesn't support labels at the end of objects, so if
20736 it looks like we might want one, insert a NOP. */
20738 rtx insn = get_last_insn ();
20741 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
20742 insn = PREV_INSN (insn);
20746 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
20747 fputs ("\tnop\n", file);
20751 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20754 We don't output a traceback table if -finhibit-size-directive was
20755 used. The documentation for -finhibit-size-directive reads
20756 ``don't output a @code{.size} assembler directive, or anything
20757 else that would cause trouble if the function is split in the
20758 middle, and the two halves are placed at locations far apart in
20759 memory.'' The traceback table has this property, since it
20760 includes the offset from the start of the function to the
20761 traceback table itself.
20763 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20764 different traceback table. */
20765 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20766 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20768 const char *fname = NULL;
20769 const char *language_string = lang_hooks.name;
20770 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20772 int optional_tbtab;
20773 rs6000_stack_t *info = rs6000_stack_info ();
20775 if (rs6000_traceback == traceback_full)
20776 optional_tbtab = 1;
20777 else if (rs6000_traceback == traceback_part)
20778 optional_tbtab = 0;
20780 optional_tbtab = !optimize_size && !TARGET_ELF;
20782 if (optional_tbtab)
20784 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20785 while (*fname == '.') /* V.4 encodes . in the name */
20788 /* Need label immediately before tbtab, so we can compute
20789 its offset from the function start. */
20790 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20791 ASM_OUTPUT_LABEL (file, fname);
20794 /* The .tbtab pseudo-op can only be used for the first eight
20795 expressions, since it can't handle the possibly variable
20796 length fields that follow. However, if you omit the optional
20797 fields, the assembler outputs zeros for all optional fields
20798 anyways, giving each variable length field is minimum length
20799 (as defined in sys/debug.h). Thus we can not use the .tbtab
20800 pseudo-op at all. */
20802 /* An all-zero word flags the start of the tbtab, for debuggers
20803 that have to find it by searching forward from the entry
20804 point or from the current pc. */
20805 fputs ("\t.long 0\n", file);
20807 /* Tbtab format type. Use format type 0. */
20808 fputs ("\t.byte 0,", file);
20810 /* Language type. Unfortunately, there does not seem to be any
20811 official way to discover the language being compiled, so we
20812 use language_string.
20813 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20814 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20815 a number, so for now use 9. LTO isn't assigned a number either,
20816 so for now use 0. */
20817 if (! strcmp (language_string, "GNU C")
20818 || ! strcmp (language_string, "GNU GIMPLE"))
20820 else if (! strcmp (language_string, "GNU F77")
20821 || ! strcmp (language_string, "GNU Fortran"))
20823 else if (! strcmp (language_string, "GNU Pascal"))
20825 else if (! strcmp (language_string, "GNU Ada"))
20827 else if (! strcmp (language_string, "GNU C++")
20828 || ! strcmp (language_string, "GNU Objective-C++"))
20830 else if (! strcmp (language_string, "GNU Java"))
20832 else if (! strcmp (language_string, "GNU Objective-C"))
20835 gcc_unreachable ();
20836 fprintf (file, "%d,", i);
20838 /* 8 single bit fields: global linkage (not set for C extern linkage,
20839 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20840 from start of procedure stored in tbtab, internal function, function
20841 has controlled storage, function has no toc, function uses fp,
20842 function logs/aborts fp operations. */
20843 /* Assume that fp operations are used if any fp reg must be saved. */
20844 fprintf (file, "%d,",
20845 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
20847 /* 6 bitfields: function is interrupt handler, name present in
20848 proc table, function calls alloca, on condition directives
20849 (controls stack walks, 3 bits), saves condition reg, saves
20851 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20852 set up as a frame pointer, even when there is no alloca call. */
20853 fprintf (file, "%d,",
20854 ((optional_tbtab << 6)
20855 | ((optional_tbtab & frame_pointer_needed) << 5)
20856 | (info->cr_save_p << 1)
20857 | (info->lr_save_p)));
20859 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20861 fprintf (file, "%d,",
20862 (info->push_p << 7) | (64 - info->first_fp_reg_save));
20864 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20865 fprintf (file, "%d,", (32 - first_reg_to_save ()));
20867 if (optional_tbtab)
20869 /* Compute the parameter info from the function decl argument
20872 int next_parm_info_bit = 31;
20874 for (decl = DECL_ARGUMENTS (current_function_decl);
20875 decl; decl = TREE_CHAIN (decl))
20877 rtx parameter = DECL_INCOMING_RTL (decl);
20878 enum machine_mode mode = GET_MODE (parameter);
20880 if (GET_CODE (parameter) == REG)
20882 if (SCALAR_FLOAT_MODE_P (mode))
20903 gcc_unreachable ();
20906 /* If only one bit will fit, don't or in this entry. */
20907 if (next_parm_info_bit > 0)
20908 parm_info |= (bits << (next_parm_info_bit - 1));
20909 next_parm_info_bit -= 2;
20913 fixed_parms += ((GET_MODE_SIZE (mode)
20914 + (UNITS_PER_WORD - 1))
20916 next_parm_info_bit -= 1;
20922 /* Number of fixed point parameters. */
20923 /* This is actually the number of words of fixed point parameters; thus
20924 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20925 fprintf (file, "%d,", fixed_parms);
20927 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20929 /* This is actually the number of fp registers that hold parameters;
20930 and thus the maximum value is 13. */
20931 /* Set parameters on stack bit if parameters are not in their original
20932 registers, regardless of whether they are on the stack? Xlc
20933 seems to set the bit when not optimizing. */
20934 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
20936 if (! optional_tbtab)
20939 /* Optional fields follow. Some are variable length. */
20941 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20942 11 double float. */
20943 /* There is an entry for each parameter in a register, in the order that
20944 they occur in the parameter list. Any intervening arguments on the
20945 stack are ignored. If the list overflows a long (max possible length
20946 34 bits) then completely leave off all elements that don't fit. */
20947 /* Only emit this long if there was at least one parameter. */
20948 if (fixed_parms || float_parms)
20949 fprintf (file, "\t.long %d\n", parm_info);
20951 /* Offset from start of code to tb table. */
20952 fputs ("\t.long ", file);
20953 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20954 RS6000_OUTPUT_BASENAME (file, fname);
20956 rs6000_output_function_entry (file, fname);
20959 /* Interrupt handler mask. */
20960 /* Omit this long, since we never set the interrupt handler bit
20963 /* Number of CTL (controlled storage) anchors. */
20964 /* Omit this long, since the has_ctl bit is never set above. */
20966 /* Displacement into stack of each CTL anchor. */
20967 /* Omit this list of longs, because there are no CTL anchors. */
20969 /* Length of function name. */
20972 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20974 /* Function name. */
20975 assemble_string (fname, strlen (fname));
20977 /* Register for alloca automatic storage; this is always reg 31.
20978 Only emit this if the alloca bit was set above. */
20979 if (frame_pointer_needed)
20980 fputs ("\t.byte 31\n", file);
20982 fputs ("\t.align 2\n", file);
20986 /* A C compound statement that outputs the assembler code for a thunk
20987 function, used to implement C++ virtual function calls with
20988 multiple inheritance. The thunk acts as a wrapper around a virtual
20989 function, adjusting the implicit object parameter before handing
20990 control off to the real function.
20992 First, emit code to add the integer DELTA to the location that
20993 contains the incoming first argument. Assume that this argument
20994 contains a pointer, and is the one used to pass the `this' pointer
20995 in C++. This is the incoming argument *before* the function
20996 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20997 values of all other incoming arguments.
20999 After the addition, emit code to jump to FUNCTION, which is a
21000 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21001 not touch the return address. Hence returning from FUNCTION will
21002 return to whoever called the current `thunk'.
21004 The effect must be as if FUNCTION had been called directly with the
21005 adjusted first argument. This macro is responsible for emitting
21006 all of the code for a thunk function; output_function_prologue()
21007 and output_function_epilogue() are not invoked.
21009 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21010 been extracted from it.) It might possibly be useful on some
21011 targets, but probably not.
21013 If you do not define this macro, the target-independent code in the
21014 C++ frontend will generate a less efficient heavyweight thunk that
21015 calls FUNCTION instead of jumping to it. The generic approach does
21016 not support varargs. */
21019 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21020 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21023 rtx this_rtx, insn, funexp;
21025 reload_completed = 1;
21026 epilogue_completed = 1;
21028 /* Mark the end of the (empty) prologue. */
21029 emit_note (NOTE_INSN_PROLOGUE_END);
21031 /* Find the "this" pointer. If the function returns a structure,
21032 the structure return pointer is in r3. */
21033 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21034 this_rtx = gen_rtx_REG (Pmode, 4);
21036 this_rtx = gen_rtx_REG (Pmode, 3);
21038 /* Apply the constant offset, if required. */
21040 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21042 /* Apply the offset from the vtable, if required. */
21045 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21046 rtx tmp = gen_rtx_REG (Pmode, 12);
21048 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21049 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21051 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21052 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21056 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21058 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21060 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21063 /* Generate a tail call to the target function. */
21064 if (!TREE_USED (function))
21066 assemble_external (function);
21067 TREE_USED (function) = 1;
21069 funexp = XEXP (DECL_RTL (function), 0);
21070 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21073 if (MACHOPIC_INDIRECT)
21074 funexp = machopic_indirect_call_target (funexp);
21077 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21078 generate sibcall RTL explicitly. */
21079 insn = emit_call_insn (
21080 gen_rtx_PARALLEL (VOIDmode,
21082 gen_rtx_CALL (VOIDmode,
21083 funexp, const0_rtx),
21084 gen_rtx_USE (VOIDmode, const0_rtx),
21085 gen_rtx_USE (VOIDmode,
21086 gen_rtx_REG (SImode,
21088 gen_rtx_RETURN (VOIDmode))));
21089 SIBLING_CALL_P (insn) = 1;
21092 /* Run just enough of rest_of_compilation to get the insns emitted.
21093 There's not really enough bulk here to make other passes such as
21094 instruction scheduling worth while. Note that use_thunk calls
21095 assemble_start_function and assemble_end_function. */
21096 insn = get_insns ();
21097 insn_locators_alloc ();
21098 shorten_branches (insn);
21099 final_start_function (insn, file, 1);
21100 final (insn, file, 1);
21101 final_end_function ();
21103 reload_completed = 0;
21104 epilogue_completed = 0;
21107 /* A quick summary of the various types of 'constant-pool tables'
21110 Target Flags Name One table per
21111 AIX (none) AIX TOC object file
21112 AIX -mfull-toc AIX TOC object file
21113 AIX -mminimal-toc AIX minimal TOC translation unit
21114 SVR4/EABI (none) SVR4 SDATA object file
21115 SVR4/EABI -fpic SVR4 pic object file
21116 SVR4/EABI -fPIC SVR4 PIC translation unit
21117 SVR4/EABI -mrelocatable EABI TOC function
21118 SVR4/EABI -maix AIX TOC object file
21119 SVR4/EABI -maix -mminimal-toc
21120 AIX minimal TOC translation unit
21122 Name Reg. Set by entries contains:
21123 made by addrs? fp? sum?
21125 AIX TOC 2 crt0 as Y option option
21126 AIX minimal TOC 30 prolog gcc Y Y option
21127 SVR4 SDATA 13 crt0 gcc N Y N
21128 SVR4 pic 30 prolog ld Y not yet N
21129 SVR4 PIC 30 prolog gcc Y option option
21130 EABI TOC 30 prolog gcc Y option option
21134 /* Hash functions for the hash table. */
21137 rs6000_hash_constant (rtx k)
21139 enum rtx_code code = GET_CODE (k);
21140 enum machine_mode mode = GET_MODE (k);
21141 unsigned result = (code << 3) ^ mode;
21142 const char *format;
21145 format = GET_RTX_FORMAT (code);
21146 flen = strlen (format);
21152 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21155 if (mode != VOIDmode)
21156 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21168 for (; fidx < flen; fidx++)
21169 switch (format[fidx])
21174 const char *str = XSTR (k, fidx);
21175 len = strlen (str);
21176 result = result * 613 + len;
21177 for (i = 0; i < len; i++)
21178 result = result * 613 + (unsigned) str[i];
21183 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21187 result = result * 613 + (unsigned) XINT (k, fidx);
21190 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21191 result = result * 613 + (unsigned) XWINT (k, fidx);
21195 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21196 result = result * 613 + (unsigned) (XWINT (k, fidx)
21203 gcc_unreachable ();
21210 toc_hash_function (const void *hash_entry)
21212 const struct toc_hash_struct *thc =
21213 (const struct toc_hash_struct *) hash_entry;
21214 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21217 /* Compare H1 and H2 for equivalence. */
21220 toc_hash_eq (const void *h1, const void *h2)
21222 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21223 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21225 if (((const struct toc_hash_struct *) h1)->key_mode
21226 != ((const struct toc_hash_struct *) h2)->key_mode)
21229 return rtx_equal_p (r1, r2);
21232 /* These are the names given by the C++ front-end to vtables, and
21233 vtable-like objects. Ideally, this logic should not be here;
21234 instead, there should be some programmatic way of inquiring as
21235 to whether or not an object is a vtable. */
21237 #define VTABLE_NAME_P(NAME) \
21238 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21239 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21240 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21241 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21242 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21244 #ifdef NO_DOLLAR_IN_LABEL
21245 /* Return a GGC-allocated character string translating dollar signs in
21246 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21249 rs6000_xcoff_strip_dollar (const char *name)
21254 p = strchr (name, '$');
21256 if (p == 0 || p == name)
21259 len = strlen (name);
21260 strip = (char *) alloca (len + 1);
21261 strcpy (strip, name);
21262 p = strchr (strip, '$');
21266 p = strchr (p + 1, '$');
21269 return ggc_alloc_string (strip, len);
21274 rs6000_output_symbol_ref (FILE *file, rtx x)
21276 /* Currently C++ toc references to vtables can be emitted before it
21277 is decided whether the vtable is public or private. If this is
21278 the case, then the linker will eventually complain that there is
21279 a reference to an unknown section. Thus, for vtables only,
21280 we emit the TOC reference to reference the symbol and not the
21282 const char *name = XSTR (x, 0);
21284 if (VTABLE_NAME_P (name))
21286 RS6000_OUTPUT_BASENAME (file, name);
21289 assemble_name (file, name);
21292 /* Output a TOC entry. We derive the entry name from what is being
21296 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
21299 const char *name = buf;
21301 HOST_WIDE_INT offset = 0;
21303 gcc_assert (!TARGET_NO_TOC);
21305 /* When the linker won't eliminate them, don't output duplicate
21306 TOC entries (this happens on AIX if there is any kind of TOC,
21307 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
21309 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
21311 struct toc_hash_struct *h;
21314 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
21315 time because GGC is not initialized at that point. */
21316 if (toc_hash_table == NULL)
21317 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
21318 toc_hash_eq, NULL);
21320 h = ggc_alloc_toc_hash_struct ();
21322 h->key_mode = mode;
21323 h->labelno = labelno;
21325 found = htab_find_slot (toc_hash_table, h, INSERT);
21326 if (*found == NULL)
21328 else /* This is indeed a duplicate.
21329 Set this label equal to that label. */
21331 fputs ("\t.set ", file);
21332 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21333 fprintf (file, "%d,", labelno);
21334 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21335 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
21341 /* If we're going to put a double constant in the TOC, make sure it's
21342 aligned properly when strict alignment is on. */
21343 if (GET_CODE (x) == CONST_DOUBLE
21344 && STRICT_ALIGNMENT
21345 && GET_MODE_BITSIZE (mode) >= 64
21346 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
21347 ASM_OUTPUT_ALIGN (file, 3);
21350 (*targetm.asm_out.internal_label) (file, "LC", labelno);
21352 /* Handle FP constants specially. Note that if we have a minimal
21353 TOC, things we put here aren't actually in the TOC, so we can allow
21355 if (GET_CODE (x) == CONST_DOUBLE &&
21356 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
21358 REAL_VALUE_TYPE rv;
21361 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21362 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21363 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
21365 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
21369 if (TARGET_MINIMAL_TOC)
21370 fputs (DOUBLE_INT_ASM_OP, file);
21372 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
21373 k[0] & 0xffffffff, k[1] & 0xffffffff,
21374 k[2] & 0xffffffff, k[3] & 0xffffffff);
21375 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
21376 k[0] & 0xffffffff, k[1] & 0xffffffff,
21377 k[2] & 0xffffffff, k[3] & 0xffffffff);
21382 if (TARGET_MINIMAL_TOC)
21383 fputs ("\t.long ", file);
21385 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
21386 k[0] & 0xffffffff, k[1] & 0xffffffff,
21387 k[2] & 0xffffffff, k[3] & 0xffffffff);
21388 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
21389 k[0] & 0xffffffff, k[1] & 0xffffffff,
21390 k[2] & 0xffffffff, k[3] & 0xffffffff);
21394 else if (GET_CODE (x) == CONST_DOUBLE &&
21395 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
21397 REAL_VALUE_TYPE rv;
21400 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21402 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21403 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
21405 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
21409 if (TARGET_MINIMAL_TOC)
21410 fputs (DOUBLE_INT_ASM_OP, file);
21412 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
21413 k[0] & 0xffffffff, k[1] & 0xffffffff);
21414 fprintf (file, "0x%lx%08lx\n",
21415 k[0] & 0xffffffff, k[1] & 0xffffffff);
21420 if (TARGET_MINIMAL_TOC)
21421 fputs ("\t.long ", file);
21423 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
21424 k[0] & 0xffffffff, k[1] & 0xffffffff);
21425 fprintf (file, "0x%lx,0x%lx\n",
21426 k[0] & 0xffffffff, k[1] & 0xffffffff);
21430 else if (GET_CODE (x) == CONST_DOUBLE &&
21431 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
21433 REAL_VALUE_TYPE rv;
21436 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21437 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21438 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
21440 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
21444 if (TARGET_MINIMAL_TOC)
21445 fputs (DOUBLE_INT_ASM_OP, file);
21447 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
21448 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
21453 if (TARGET_MINIMAL_TOC)
21454 fputs ("\t.long ", file);
21456 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
21457 fprintf (file, "0x%lx\n", l & 0xffffffff);
21461 else if (GET_MODE (x) == VOIDmode
21462 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
21464 unsigned HOST_WIDE_INT low;
21465 HOST_WIDE_INT high;
21467 if (GET_CODE (x) == CONST_DOUBLE)
21469 low = CONST_DOUBLE_LOW (x);
21470 high = CONST_DOUBLE_HIGH (x);
21473 #if HOST_BITS_PER_WIDE_INT == 32
21476 high = (low & 0x80000000) ? ~0 : 0;
21480 low = INTVAL (x) & 0xffffffff;
21481 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
21485 /* TOC entries are always Pmode-sized, but since this
21486 is a bigendian machine then if we're putting smaller
21487 integer constants in the TOC we have to pad them.
21488 (This is still a win over putting the constants in
21489 a separate constant pool, because then we'd have
21490 to have both a TOC entry _and_ the actual constant.)
21492 For a 32-bit target, CONST_INT values are loaded and shifted
21493 entirely within `low' and can be stored in one TOC entry. */
21495 /* It would be easy to make this work, but it doesn't now. */
21496 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
21498 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
21500 #if HOST_BITS_PER_WIDE_INT == 32
21501 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
21502 POINTER_SIZE, &low, &high, 0);
21505 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
21506 high = (HOST_WIDE_INT) low >> 32;
21513 if (TARGET_MINIMAL_TOC)
21514 fputs (DOUBLE_INT_ASM_OP, file);
21516 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21517 (long) high & 0xffffffff, (long) low & 0xffffffff);
21518 fprintf (file, "0x%lx%08lx\n",
21519 (long) high & 0xffffffff, (long) low & 0xffffffff);
21524 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
21526 if (TARGET_MINIMAL_TOC)
21527 fputs ("\t.long ", file);
21529 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21530 (long) high & 0xffffffff, (long) low & 0xffffffff);
21531 fprintf (file, "0x%lx,0x%lx\n",
21532 (long) high & 0xffffffff, (long) low & 0xffffffff);
21536 if (TARGET_MINIMAL_TOC)
21537 fputs ("\t.long ", file);
21539 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
21540 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
21546 if (GET_CODE (x) == CONST)
21548 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
21549 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
21551 base = XEXP (XEXP (x, 0), 0);
21552 offset = INTVAL (XEXP (XEXP (x, 0), 1));
21555 switch (GET_CODE (base))
21558 name = XSTR (base, 0);
21562 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
21563 CODE_LABEL_NUMBER (XEXP (base, 0)));
21567 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
21571 gcc_unreachable ();
21574 if (TARGET_MINIMAL_TOC)
21575 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
21578 fputs ("\t.tc ", file);
21579 RS6000_OUTPUT_BASENAME (file, name);
21582 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
21584 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
21586 fputs ("[TC],", file);
21589 /* Currently C++ toc references to vtables can be emitted before it
21590 is decided whether the vtable is public or private. If this is
21591 the case, then the linker will eventually complain that there is
21592 a TOC reference to an unknown section. Thus, for vtables only,
21593 we emit the TOC reference to reference the symbol and not the
21595 if (VTABLE_NAME_P (name))
21597 RS6000_OUTPUT_BASENAME (file, name);
21599 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
21600 else if (offset > 0)
21601 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
21604 output_addr_const (file, x);
21608 /* Output an assembler pseudo-op to write an ASCII string of N characters
21609 starting at P to FILE.
21611 On the RS/6000, we have to do this using the .byte operation and
21612 write out special characters outside the quoted string.
21613 Also, the assembler is broken; very long strings are truncated,
21614 so we must artificially break them up early. */
21617 output_ascii (FILE *file, const char *p, int n)
21620 int i, count_string;
21621 const char *for_string = "\t.byte \"";
21622 const char *for_decimal = "\t.byte ";
21623 const char *to_close = NULL;
21626 for (i = 0; i < n; i++)
21629 if (c >= ' ' && c < 0177)
21632 fputs (for_string, file);
21635 /* Write two quotes to get one. */
21643 for_decimal = "\"\n\t.byte ";
21647 if (count_string >= 512)
21649 fputs (to_close, file);
21651 for_string = "\t.byte \"";
21652 for_decimal = "\t.byte ";
21660 fputs (for_decimal, file);
21661 fprintf (file, "%d", c);
21663 for_string = "\n\t.byte \"";
21664 for_decimal = ", ";
21670 /* Now close the string if we have written one. Then end the line. */
21672 fputs (to_close, file);
21675 /* Generate a unique section name for FILENAME for a section type
21676 represented by SECTION_DESC. Output goes into BUF.
21678 SECTION_DESC can be any string, as long as it is different for each
21679 possible section type.
21681 We name the section in the same manner as xlc. The name begins with an
21682 underscore followed by the filename (after stripping any leading directory
21683 names) with the last period replaced by the string SECTION_DESC. If
21684 FILENAME does not contain a period, SECTION_DESC is appended to the end of
21688 rs6000_gen_section_name (char **buf, const char *filename,
21689 const char *section_desc)
21691 const char *q, *after_last_slash, *last_period = 0;
21695 after_last_slash = filename;
21696 for (q = filename; *q; q++)
21699 after_last_slash = q + 1;
21700 else if (*q == '.')
21704 len = strlen (after_last_slash) + strlen (section_desc) + 2;
21705 *buf = (char *) xmalloc (len);
21710 for (q = after_last_slash; *q; q++)
21712 if (q == last_period)
21714 strcpy (p, section_desc);
21715 p += strlen (section_desc);
21719 else if (ISALNUM (*q))
21723 if (last_period == 0)
21724 strcpy (p, section_desc);
21729 /* Emit profile function. */
21732 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
21734 /* Non-standard profiling for kernels, which just saves LR then calls
21735 _mcount without worrying about arg saves. The idea is to change
21736 the function prologue as little as possible as it isn't easy to
21737 account for arg save/restore code added just for _mcount. */
21738 if (TARGET_PROFILE_KERNEL)
21741 if (DEFAULT_ABI == ABI_AIX)
21743 #ifndef NO_PROFILE_COUNTERS
21744 # define NO_PROFILE_COUNTERS 0
21746 if (NO_PROFILE_COUNTERS)
21747 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21748 LCT_NORMAL, VOIDmode, 0);
21752 const char *label_name;
21755 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21756 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21757 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21759 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21760 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21763 else if (DEFAULT_ABI == ABI_DARWIN)
21765 const char *mcount_name = RS6000_MCOUNT;
21766 int caller_addr_regno = LR_REGNO;
21768 /* Be conservative and always set this, at least for now. */
21769 crtl->uses_pic_offset_table = 1;
21772 /* For PIC code, set up a stub and collect the caller's address
21773 from r0, which is where the prologue puts it. */
21774 if (MACHOPIC_INDIRECT
21775 && crtl->uses_pic_offset_table)
21776 caller_addr_regno = 0;
21778 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21779 LCT_NORMAL, VOIDmode, 1,
21780 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21784 /* Write function profiler code. */
21787 output_function_profiler (FILE *file, int labelno)
21791 switch (DEFAULT_ABI)
21794 gcc_unreachable ();
21799 warning (0, "no profiling of 64-bit code for this ABI");
21802 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21803 fprintf (file, "\tmflr %s\n", reg_names[0]);
21804 if (NO_PROFILE_COUNTERS)
21806 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21807 reg_names[0], reg_names[1]);
21809 else if (TARGET_SECURE_PLT && flag_pic)
21811 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21812 reg_names[0], reg_names[1]);
21813 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21814 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21815 reg_names[12], reg_names[12]);
21816 assemble_name (file, buf);
21817 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21818 assemble_name (file, buf);
21819 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21821 else if (flag_pic == 1)
21823 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21824 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21825 reg_names[0], reg_names[1]);
21826 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21827 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
21828 assemble_name (file, buf);
21829 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
21831 else if (flag_pic > 1)
21833 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21834 reg_names[0], reg_names[1]);
21835 /* Now, we need to get the address of the label. */
21836 fputs ("\tbcl 20,31,1f\n\t.long ", file);
21837 assemble_name (file, buf);
21838 fputs ("-.\n1:", file);
21839 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
21840 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
21841 reg_names[0], reg_names[11]);
21842 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
21843 reg_names[0], reg_names[0], reg_names[11]);
21847 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
21848 assemble_name (file, buf);
21849 fputs ("@ha\n", file);
21850 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21851 reg_names[0], reg_names[1]);
21852 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
21853 assemble_name (file, buf);
21854 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
21857 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21858 fprintf (file, "\tbl %s%s\n",
21859 RS6000_MCOUNT, flag_pic ? "@plt" : "");
21864 if (!TARGET_PROFILE_KERNEL)
21866 /* Don't do anything, done in output_profile_hook (). */
21870 gcc_assert (!TARGET_32BIT);
21872 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
21873 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
21875 if (cfun->static_chain_decl != NULL)
21877 asm_fprintf (file, "\tstd %s,24(%s)\n",
21878 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21879 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21880 asm_fprintf (file, "\tld %s,24(%s)\n",
21881 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21884 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21892 /* The following variable value is the last issued insn. */
21894 static rtx last_scheduled_insn;
21896 /* The following variable helps to balance issuing of load and
21897 store instructions */
21899 static int load_store_pendulum;
21901 /* Power4 load update and store update instructions are cracked into a
21902 load or store and an integer insn which are executed in the same cycle.
21903 Branches have their own dispatch slot which does not count against the
21904 GCC issue rate, but it changes the program flow so there are no other
21905 instructions to issue in this cycle. */
21908 rs6000_variable_issue_1 (rtx insn, int more)
21910 last_scheduled_insn = insn;
21911 if (GET_CODE (PATTERN (insn)) == USE
21912 || GET_CODE (PATTERN (insn)) == CLOBBER)
21914 cached_can_issue_more = more;
21915 return cached_can_issue_more;
21918 if (insn_terminates_group_p (insn, current_group))
21920 cached_can_issue_more = 0;
21921 return cached_can_issue_more;
21924 /* If no reservation, but reach here */
21925 if (recog_memoized (insn) < 0)
21928 if (rs6000_sched_groups)
21930 if (is_microcoded_insn (insn))
21931 cached_can_issue_more = 0;
21932 else if (is_cracked_insn (insn))
21933 cached_can_issue_more = more > 2 ? more - 2 : 0;
21935 cached_can_issue_more = more - 1;
21937 return cached_can_issue_more;
21940 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21943 cached_can_issue_more = more - 1;
21944 return cached_can_issue_more;
21948 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
21950 int r = rs6000_variable_issue_1 (insn, more);
21952 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
21956 /* Adjust the cost of a scheduling dependency. Return the new cost of
21957 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21960 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21962 enum attr_type attr_type;
21964 if (! recog_memoized (insn))
21967 switch (REG_NOTE_KIND (link))
21971 /* Data dependency; DEP_INSN writes a register that INSN reads
21972 some cycles later. */
21974 /* Separate a load from a narrower, dependent store. */
21975 if (rs6000_sched_groups
21976 && GET_CODE (PATTERN (insn)) == SET
21977 && GET_CODE (PATTERN (dep_insn)) == SET
21978 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21979 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21980 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21981 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21984 attr_type = get_attr_type (insn);
21989 /* Tell the first scheduling pass about the latency between
21990 a mtctr and bctr (and mtlr and br/blr). The first
21991 scheduling pass will not know about this latency since
21992 the mtctr instruction, which has the latency associated
21993 to it, will be generated by reload. */
21994 return TARGET_POWER ? 5 : 4;
21996 /* Leave some extra cycles between a compare and its
21997 dependent branch, to inhibit expensive mispredicts. */
21998 if ((rs6000_cpu_attr == CPU_PPC603
21999 || rs6000_cpu_attr == CPU_PPC604
22000 || rs6000_cpu_attr == CPU_PPC604E
22001 || rs6000_cpu_attr == CPU_PPC620
22002 || rs6000_cpu_attr == CPU_PPC630
22003 || rs6000_cpu_attr == CPU_PPC750
22004 || rs6000_cpu_attr == CPU_PPC7400
22005 || rs6000_cpu_attr == CPU_PPC7450
22006 || rs6000_cpu_attr == CPU_POWER4
22007 || rs6000_cpu_attr == CPU_POWER5
22008 || rs6000_cpu_attr == CPU_POWER7
22009 || rs6000_cpu_attr == CPU_CELL)
22010 && recog_memoized (dep_insn)
22011 && (INSN_CODE (dep_insn) >= 0))
22013 switch (get_attr_type (dep_insn))
22017 case TYPE_DELAYED_COMPARE:
22018 case TYPE_IMUL_COMPARE:
22019 case TYPE_LMUL_COMPARE:
22020 case TYPE_FPCOMPARE:
22021 case TYPE_CR_LOGICAL:
22022 case TYPE_DELAYED_CR:
22031 case TYPE_STORE_UX:
22033 case TYPE_FPSTORE_U:
22034 case TYPE_FPSTORE_UX:
22035 if ((rs6000_cpu == PROCESSOR_POWER6)
22036 && recog_memoized (dep_insn)
22037 && (INSN_CODE (dep_insn) >= 0))
22040 if (GET_CODE (PATTERN (insn)) != SET)
22041 /* If this happens, we have to extend this to schedule
22042 optimally. Return default for now. */
22045 /* Adjust the cost for the case where the value written
22046 by a fixed point operation is used as the address
22047 gen value on a store. */
22048 switch (get_attr_type (dep_insn))
22055 if (! store_data_bypass_p (dep_insn, insn))
22059 case TYPE_LOAD_EXT:
22060 case TYPE_LOAD_EXT_U:
22061 case TYPE_LOAD_EXT_UX:
22062 case TYPE_VAR_SHIFT_ROTATE:
22063 case TYPE_VAR_DELAYED_COMPARE:
22065 if (! store_data_bypass_p (dep_insn, insn))
22071 case TYPE_FAST_COMPARE:
22074 case TYPE_INSERT_WORD:
22075 case TYPE_INSERT_DWORD:
22076 case TYPE_FPLOAD_U:
22077 case TYPE_FPLOAD_UX:
22079 case TYPE_STORE_UX:
22080 case TYPE_FPSTORE_U:
22081 case TYPE_FPSTORE_UX:
22083 if (! store_data_bypass_p (dep_insn, insn))
22091 case TYPE_IMUL_COMPARE:
22092 case TYPE_LMUL_COMPARE:
22094 if (! store_data_bypass_p (dep_insn, insn))
22100 if (! store_data_bypass_p (dep_insn, insn))
22106 if (! store_data_bypass_p (dep_insn, insn))
22119 case TYPE_LOAD_EXT:
22120 case TYPE_LOAD_EXT_U:
22121 case TYPE_LOAD_EXT_UX:
22122 if ((rs6000_cpu == PROCESSOR_POWER6)
22123 && recog_memoized (dep_insn)
22124 && (INSN_CODE (dep_insn) >= 0))
22127 /* Adjust the cost for the case where the value written
22128 by a fixed point instruction is used within the address
22129 gen portion of a subsequent load(u)(x) */
22130 switch (get_attr_type (dep_insn))
22137 if (set_to_load_agen (dep_insn, insn))
22141 case TYPE_LOAD_EXT:
22142 case TYPE_LOAD_EXT_U:
22143 case TYPE_LOAD_EXT_UX:
22144 case TYPE_VAR_SHIFT_ROTATE:
22145 case TYPE_VAR_DELAYED_COMPARE:
22147 if (set_to_load_agen (dep_insn, insn))
22153 case TYPE_FAST_COMPARE:
22156 case TYPE_INSERT_WORD:
22157 case TYPE_INSERT_DWORD:
22158 case TYPE_FPLOAD_U:
22159 case TYPE_FPLOAD_UX:
22161 case TYPE_STORE_UX:
22162 case TYPE_FPSTORE_U:
22163 case TYPE_FPSTORE_UX:
22165 if (set_to_load_agen (dep_insn, insn))
22173 case TYPE_IMUL_COMPARE:
22174 case TYPE_LMUL_COMPARE:
22176 if (set_to_load_agen (dep_insn, insn))
22182 if (set_to_load_agen (dep_insn, insn))
22188 if (set_to_load_agen (dep_insn, insn))
22199 if ((rs6000_cpu == PROCESSOR_POWER6)
22200 && recog_memoized (dep_insn)
22201 && (INSN_CODE (dep_insn) >= 0)
22202 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22209 /* Fall out to return default cost. */
22213 case REG_DEP_OUTPUT:
22214 /* Output dependency; DEP_INSN writes a register that INSN writes some
22216 if ((rs6000_cpu == PROCESSOR_POWER6)
22217 && recog_memoized (dep_insn)
22218 && (INSN_CODE (dep_insn) >= 0))
22220 attr_type = get_attr_type (insn);
22225 if (get_attr_type (dep_insn) == TYPE_FP)
22229 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22237 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22242 gcc_unreachable ();
22248 /* Debug version of rs6000_adjust_cost. */
22251 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22253 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
22259 switch (REG_NOTE_KIND (link))
22261 default: dep = "unknown depencency"; break;
22262 case REG_DEP_TRUE: dep = "data dependency"; break;
22263 case REG_DEP_OUTPUT: dep = "output dependency"; break;
22264 case REG_DEP_ANTI: dep = "anti depencency"; break;
22268 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22269 "%s, insn:\n", ret, cost, dep);
22277 /* The function returns a true if INSN is microcoded.
22278 Return false otherwise. */
22281 is_microcoded_insn (rtx insn)
22283 if (!insn || !NONDEBUG_INSN_P (insn)
22284 || GET_CODE (PATTERN (insn)) == USE
22285 || GET_CODE (PATTERN (insn)) == CLOBBER)
22288 if (rs6000_cpu_attr == CPU_CELL)
22289 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
22291 if (rs6000_sched_groups)
22293 enum attr_type type = get_attr_type (insn);
22294 if (type == TYPE_LOAD_EXT_U
22295 || type == TYPE_LOAD_EXT_UX
22296 || type == TYPE_LOAD_UX
22297 || type == TYPE_STORE_UX
22298 || type == TYPE_MFCR)
22305 /* The function returns true if INSN is cracked into 2 instructions
22306 by the processor (and therefore occupies 2 issue slots). */
22309 is_cracked_insn (rtx insn)
22311 if (!insn || !NONDEBUG_INSN_P (insn)
22312 || GET_CODE (PATTERN (insn)) == USE
22313 || GET_CODE (PATTERN (insn)) == CLOBBER)
22316 if (rs6000_sched_groups)
22318 enum attr_type type = get_attr_type (insn);
22319 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
22320 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
22321 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
22322 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
22323 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
22324 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
22325 || type == TYPE_IDIV || type == TYPE_LDIV
22326 || type == TYPE_INSERT_WORD)
22333 /* The function returns true if INSN can be issued only from
22334 the branch slot. */
22337 is_branch_slot_insn (rtx insn)
22339 if (!insn || !NONDEBUG_INSN_P (insn)
22340 || GET_CODE (PATTERN (insn)) == USE
22341 || GET_CODE (PATTERN (insn)) == CLOBBER)
22344 if (rs6000_sched_groups)
22346 enum attr_type type = get_attr_type (insn);
22347 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
22355 /* The function returns true if out_inst sets a value that is
22356 used in the address generation computation of in_insn */
22358 set_to_load_agen (rtx out_insn, rtx in_insn)
22360 rtx out_set, in_set;
22362 /* For performance reasons, only handle the simple case where
22363 both loads are a single_set. */
22364 out_set = single_set (out_insn);
22367 in_set = single_set (in_insn);
22369 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
22375 /* The function returns true if the target storage location of
22376 out_insn is adjacent to the target storage location of in_insn */
22377 /* Return 1 if memory locations are adjacent. */
22380 adjacent_mem_locations (rtx insn1, rtx insn2)
22383 rtx a = get_store_dest (PATTERN (insn1));
22384 rtx b = get_store_dest (PATTERN (insn2));
22386 if ((GET_CODE (XEXP (a, 0)) == REG
22387 || (GET_CODE (XEXP (a, 0)) == PLUS
22388 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
22389 && (GET_CODE (XEXP (b, 0)) == REG
22390 || (GET_CODE (XEXP (b, 0)) == PLUS
22391 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
22393 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
22396 if (GET_CODE (XEXP (a, 0)) == PLUS)
22398 reg0 = XEXP (XEXP (a, 0), 0);
22399 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
22402 reg0 = XEXP (a, 0);
22404 if (GET_CODE (XEXP (b, 0)) == PLUS)
22406 reg1 = XEXP (XEXP (b, 0), 0);
22407 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
22410 reg1 = XEXP (b, 0);
22412 val_diff = val1 - val0;
22414 return ((REGNO (reg0) == REGNO (reg1))
22415 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
22416 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
22422 /* A C statement (sans semicolon) to update the integer scheduling
22423 priority INSN_PRIORITY (INSN). Increase the priority to execute the
22424 INSN earlier, reduce the priority to execute INSN later. Do not
22425 define this macro if you do not need to adjust the scheduling
22426 priorities of insns. */
22429 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
22431 /* On machines (like the 750) which have asymmetric integer units,
22432 where one integer unit can do multiply and divides and the other
22433 can't, reduce the priority of multiply/divide so it is scheduled
22434 before other integer operations. */
22437 if (! INSN_P (insn))
22440 if (GET_CODE (PATTERN (insn)) == USE)
22443 switch (rs6000_cpu_attr) {
22445 switch (get_attr_type (insn))
22452 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
22453 priority, priority);
22454 if (priority >= 0 && priority < 0x01000000)
22461 if (insn_must_be_first_in_group (insn)
22462 && reload_completed
22463 && current_sched_info->sched_max_insns_priority
22464 && rs6000_sched_restricted_insns_priority)
22467 /* Prioritize insns that can be dispatched only in the first
22469 if (rs6000_sched_restricted_insns_priority == 1)
22470 /* Attach highest priority to insn. This means that in
22471 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
22472 precede 'priority' (critical path) considerations. */
22473 return current_sched_info->sched_max_insns_priority;
22474 else if (rs6000_sched_restricted_insns_priority == 2)
22475 /* Increase priority of insn by a minimal amount. This means that in
22476 haifa-sched.c:ready_sort(), only 'priority' (critical path)
22477 considerations precede dispatch-slot restriction considerations. */
22478 return (priority + 1);
22481 if (rs6000_cpu == PROCESSOR_POWER6
22482 && ((load_store_pendulum == -2 && is_load_insn (insn))
22483 || (load_store_pendulum == 2 && is_store_insn (insn))))
22484 /* Attach highest priority to insn if the scheduler has just issued two
22485 stores and this instruction is a load, or two loads and this instruction
22486 is a store. Power6 wants loads and stores scheduled alternately
22488 return current_sched_info->sched_max_insns_priority;
22493 /* Return true if the instruction is nonpipelined on the Cell. */
22495 is_nonpipeline_insn (rtx insn)
22497 enum attr_type type;
22498 if (!insn || !NONDEBUG_INSN_P (insn)
22499 || GET_CODE (PATTERN (insn)) == USE
22500 || GET_CODE (PATTERN (insn)) == CLOBBER)
22503 type = get_attr_type (insn);
22504 if (type == TYPE_IMUL
22505 || type == TYPE_IMUL2
22506 || type == TYPE_IMUL3
22507 || type == TYPE_LMUL
22508 || type == TYPE_IDIV
22509 || type == TYPE_LDIV
22510 || type == TYPE_SDIV
22511 || type == TYPE_DDIV
22512 || type == TYPE_SSQRT
22513 || type == TYPE_DSQRT
22514 || type == TYPE_MFCR
22515 || type == TYPE_MFCRF
22516 || type == TYPE_MFJMPR)
22524 /* Return how many instructions the machine can issue per cycle. */
22527 rs6000_issue_rate (void)
22529 /* Unless scheduling for register pressure, use issue rate of 1 for
22530 first scheduling pass to decrease degradation. */
22531 if (!reload_completed && !flag_sched_pressure)
22534 switch (rs6000_cpu_attr) {
22535 case CPU_RIOS1: /* ? */
22537 case CPU_PPC601: /* ? */
22546 case CPU_PPCE300C2:
22547 case CPU_PPCE300C3:
22548 case CPU_PPCE500MC:
22549 case CPU_PPCE500MC64:
22569 /* Return how many instructions to look ahead for better insn
22573 rs6000_use_sched_lookahead (void)
22575 if (rs6000_cpu_attr == CPU_PPC8540)
22577 if (rs6000_cpu_attr == CPU_CELL)
22578 return (reload_completed ? 8 : 0);
22582 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
22584 rs6000_use_sched_lookahead_guard (rtx insn)
22586 if (rs6000_cpu_attr != CPU_CELL)
22589 if (insn == NULL_RTX || !INSN_P (insn))
22592 if (!reload_completed
22593 || is_nonpipeline_insn (insn)
22594 || is_microcoded_insn (insn))
22600 /* Determine is PAT refers to memory. */
22603 is_mem_ref (rtx pat)
22609 /* stack_tie does not produce any real memory traffic. */
22610 if (GET_CODE (pat) == UNSPEC
22611 && XINT (pat, 1) == UNSPEC_TIE)
22614 if (GET_CODE (pat) == MEM)
22617 /* Recursively process the pattern. */
22618 fmt = GET_RTX_FORMAT (GET_CODE (pat));
22620 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
22623 ret |= is_mem_ref (XEXP (pat, i));
22624 else if (fmt[i] == 'E')
22625 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
22626 ret |= is_mem_ref (XVECEXP (pat, i, j));
22632 /* Determine if PAT is a PATTERN of a load insn. */
22635 is_load_insn1 (rtx pat)
22637 if (!pat || pat == NULL_RTX)
22640 if (GET_CODE (pat) == SET)
22641 return is_mem_ref (SET_SRC (pat));
22643 if (GET_CODE (pat) == PARALLEL)
22647 for (i = 0; i < XVECLEN (pat, 0); i++)
22648 if (is_load_insn1 (XVECEXP (pat, 0, i)))
22655 /* Determine if INSN loads from memory. */
22658 is_load_insn (rtx insn)
22660 if (!insn || !INSN_P (insn))
22663 if (GET_CODE (insn) == CALL_INSN)
22666 return is_load_insn1 (PATTERN (insn));
22669 /* Determine if PAT is a PATTERN of a store insn. */
22672 is_store_insn1 (rtx pat)
22674 if (!pat || pat == NULL_RTX)
22677 if (GET_CODE (pat) == SET)
22678 return is_mem_ref (SET_DEST (pat));
22680 if (GET_CODE (pat) == PARALLEL)
22684 for (i = 0; i < XVECLEN (pat, 0); i++)
22685 if (is_store_insn1 (XVECEXP (pat, 0, i)))
22692 /* Determine if INSN stores to memory. */
22695 is_store_insn (rtx insn)
22697 if (!insn || !INSN_P (insn))
22700 return is_store_insn1 (PATTERN (insn));
22703 /* Return the dest of a store insn. */
22706 get_store_dest (rtx pat)
22708 gcc_assert (is_store_insn1 (pat));
22710 if (GET_CODE (pat) == SET)
22711 return SET_DEST (pat);
22712 else if (GET_CODE (pat) == PARALLEL)
22716 for (i = 0; i < XVECLEN (pat, 0); i++)
22718 rtx inner_pat = XVECEXP (pat, 0, i);
22719 if (GET_CODE (inner_pat) == SET
22720 && is_mem_ref (SET_DEST (inner_pat)))
22724 /* We shouldn't get here, because we should have either a simple
22725 store insn or a store with update which are covered above. */
22729 /* Returns whether the dependence between INSN and NEXT is considered
22730 costly by the given target. */
22733 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
22738 /* If the flag is not enabled - no dependence is considered costly;
22739 allow all dependent insns in the same group.
22740 This is the most aggressive option. */
22741 if (rs6000_sched_costly_dep == no_dep_costly)
22744 /* If the flag is set to 1 - a dependence is always considered costly;
22745 do not allow dependent instructions in the same group.
22746 This is the most conservative option. */
22747 if (rs6000_sched_costly_dep == all_deps_costly)
22750 insn = DEP_PRO (dep);
22751 next = DEP_CON (dep);
22753 if (rs6000_sched_costly_dep == store_to_load_dep_costly
22754 && is_load_insn (next)
22755 && is_store_insn (insn))
22756 /* Prevent load after store in the same group. */
22759 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
22760 && is_load_insn (next)
22761 && is_store_insn (insn)
22762 && DEP_TYPE (dep) == REG_DEP_TRUE)
22763 /* Prevent load after store in the same group if it is a true
22767 /* The flag is set to X; dependences with latency >= X are considered costly,
22768 and will not be scheduled in the same group. */
22769 if (rs6000_sched_costly_dep <= max_dep_latency
22770 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22776 /* Return the next insn after INSN that is found before TAIL is reached,
22777 skipping any "non-active" insns - insns that will not actually occupy
22778 an issue slot. Return NULL_RTX if such an insn is not found. */
22781 get_next_active_insn (rtx insn, rtx tail)
22783 if (insn == NULL_RTX || insn == tail)
22788 insn = NEXT_INSN (insn);
22789 if (insn == NULL_RTX || insn == tail)
22794 || (NONJUMP_INSN_P (insn)
22795 && GET_CODE (PATTERN (insn)) != USE
22796 && GET_CODE (PATTERN (insn)) != CLOBBER
22797 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22803 /* We are about to begin issuing insns for this clock cycle. */
22806 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22807 rtx *ready ATTRIBUTE_UNUSED,
22808 int *pn_ready ATTRIBUTE_UNUSED,
22809 int clock_var ATTRIBUTE_UNUSED)
22811 int n_ready = *pn_ready;
22814 fprintf (dump, "// rs6000_sched_reorder :\n");
22816 /* Reorder the ready list, if the second to last ready insn
22817 is a nonepipeline insn. */
22818 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22820 if (is_nonpipeline_insn (ready[n_ready - 1])
22821 && (recog_memoized (ready[n_ready - 2]) > 0))
22822 /* Simply swap first two insns. */
22824 rtx tmp = ready[n_ready - 1];
22825 ready[n_ready - 1] = ready[n_ready - 2];
22826 ready[n_ready - 2] = tmp;
22830 if (rs6000_cpu == PROCESSOR_POWER6)
22831 load_store_pendulum = 0;
22833 return rs6000_issue_rate ();
22836 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22839 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
22840 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
22843 fprintf (dump, "// rs6000_sched_reorder2 :\n");
22845 /* For Power6, we need to handle some special cases to try and keep the
22846 store queue from overflowing and triggering expensive flushes.
22848 This code monitors how load and store instructions are being issued
22849 and skews the ready list one way or the other to increase the likelihood
22850 that a desired instruction is issued at the proper time.
22852 A couple of things are done. First, we maintain a "load_store_pendulum"
22853 to track the current state of load/store issue.
22855 - If the pendulum is at zero, then no loads or stores have been
22856 issued in the current cycle so we do nothing.
22858 - If the pendulum is 1, then a single load has been issued in this
22859 cycle and we attempt to locate another load in the ready list to
22862 - If the pendulum is -2, then two stores have already been
22863 issued in this cycle, so we increase the priority of the first load
22864 in the ready list to increase it's likelihood of being chosen first
22867 - If the pendulum is -1, then a single store has been issued in this
22868 cycle and we attempt to locate another store in the ready list to
22869 issue with it, preferring a store to an adjacent memory location to
22870 facilitate store pairing in the store queue.
22872 - If the pendulum is 2, then two loads have already been
22873 issued in this cycle, so we increase the priority of the first store
22874 in the ready list to increase it's likelihood of being chosen first
22877 - If the pendulum < -2 or > 2, then do nothing.
22879 Note: This code covers the most common scenarios. There exist non
22880 load/store instructions which make use of the LSU and which
22881 would need to be accounted for to strictly model the behavior
22882 of the machine. Those instructions are currently unaccounted
22883 for to help minimize compile time overhead of this code.
22885 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
22891 if (is_store_insn (last_scheduled_insn))
22892 /* Issuing a store, swing the load_store_pendulum to the left */
22893 load_store_pendulum--;
22894 else if (is_load_insn (last_scheduled_insn))
22895 /* Issuing a load, swing the load_store_pendulum to the right */
22896 load_store_pendulum++;
22898 return cached_can_issue_more;
22900 /* If the pendulum is balanced, or there is only one instruction on
22901 the ready list, then all is well, so return. */
22902 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
22903 return cached_can_issue_more;
22905 if (load_store_pendulum == 1)
22907 /* A load has been issued in this cycle. Scan the ready list
22908 for another load to issue with it */
22913 if (is_load_insn (ready[pos]))
22915 /* Found a load. Move it to the head of the ready list,
22916 and adjust it's priority so that it is more likely to
22919 for (i=pos; i<*pn_ready-1; i++)
22920 ready[i] = ready[i + 1];
22921 ready[*pn_ready-1] = tmp;
22923 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22924 INSN_PRIORITY (tmp)++;
22930 else if (load_store_pendulum == -2)
22932 /* Two stores have been issued in this cycle. Increase the
22933 priority of the first load in the ready list to favor it for
22934 issuing in the next cycle. */
22939 if (is_load_insn (ready[pos])
22941 && INSN_PRIORITY_KNOWN (ready[pos]))
22943 INSN_PRIORITY (ready[pos])++;
22945 /* Adjust the pendulum to account for the fact that a load
22946 was found and increased in priority. This is to prevent
22947 increasing the priority of multiple loads */
22948 load_store_pendulum--;
22955 else if (load_store_pendulum == -1)
22957 /* A store has been issued in this cycle. Scan the ready list for
22958 another store to issue with it, preferring a store to an adjacent
22960 int first_store_pos = -1;
22966 if (is_store_insn (ready[pos]))
22968 /* Maintain the index of the first store found on the
22970 if (first_store_pos == -1)
22971 first_store_pos = pos;
22973 if (is_store_insn (last_scheduled_insn)
22974 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22976 /* Found an adjacent store. Move it to the head of the
22977 ready list, and adjust it's priority so that it is
22978 more likely to stay there */
22980 for (i=pos; i<*pn_ready-1; i++)
22981 ready[i] = ready[i + 1];
22982 ready[*pn_ready-1] = tmp;
22984 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22985 INSN_PRIORITY (tmp)++;
22987 first_store_pos = -1;
22995 if (first_store_pos >= 0)
22997 /* An adjacent store wasn't found, but a non-adjacent store was,
22998 so move the non-adjacent store to the front of the ready
22999 list, and adjust its priority so that it is more likely to
23001 tmp = ready[first_store_pos];
23002 for (i=first_store_pos; i<*pn_ready-1; i++)
23003 ready[i] = ready[i + 1];
23004 ready[*pn_ready-1] = tmp;
23005 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23006 INSN_PRIORITY (tmp)++;
23009 else if (load_store_pendulum == 2)
23011 /* Two loads have been issued in this cycle. Increase the priority
23012 of the first store in the ready list to favor it for issuing in
23018 if (is_store_insn (ready[pos])
23020 && INSN_PRIORITY_KNOWN (ready[pos]))
23022 INSN_PRIORITY (ready[pos])++;
23024 /* Adjust the pendulum to account for the fact that a store
23025 was found and increased in priority. This is to prevent
23026 increasing the priority of multiple stores */
23027 load_store_pendulum++;
23036 return cached_can_issue_more;
23039 /* Return whether the presence of INSN causes a dispatch group termination
23040 of group WHICH_GROUP.
23042 If WHICH_GROUP == current_group, this function will return true if INSN
23043 causes the termination of the current group (i.e, the dispatch group to
23044 which INSN belongs). This means that INSN will be the last insn in the
23045 group it belongs to.
23047 If WHICH_GROUP == previous_group, this function will return true if INSN
23048 causes the termination of the previous group (i.e, the dispatch group that
23049 precedes the group to which INSN belongs). This means that INSN will be
23050 the first insn in the group it belongs to). */
23053 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23060 first = insn_must_be_first_in_group (insn);
23061 last = insn_must_be_last_in_group (insn);
23066 if (which_group == current_group)
23068 else if (which_group == previous_group)
23076 insn_must_be_first_in_group (rtx insn)
23078 enum attr_type type;
23081 || GET_CODE (insn) == NOTE
23082 || DEBUG_INSN_P (insn)
23083 || GET_CODE (PATTERN (insn)) == USE
23084 || GET_CODE (PATTERN (insn)) == CLOBBER)
23087 switch (rs6000_cpu)
23089 case PROCESSOR_POWER5:
23090 if (is_cracked_insn (insn))
23092 case PROCESSOR_POWER4:
23093 if (is_microcoded_insn (insn))
23096 if (!rs6000_sched_groups)
23099 type = get_attr_type (insn);
23106 case TYPE_DELAYED_CR:
23107 case TYPE_CR_LOGICAL:
23121 case PROCESSOR_POWER6:
23122 type = get_attr_type (insn);
23126 case TYPE_INSERT_DWORD:
23130 case TYPE_VAR_SHIFT_ROTATE:
23137 case TYPE_INSERT_WORD:
23138 case TYPE_DELAYED_COMPARE:
23139 case TYPE_IMUL_COMPARE:
23140 case TYPE_LMUL_COMPARE:
23141 case TYPE_FPCOMPARE:
23152 case TYPE_LOAD_EXT_UX:
23154 case TYPE_STORE_UX:
23155 case TYPE_FPLOAD_U:
23156 case TYPE_FPLOAD_UX:
23157 case TYPE_FPSTORE_U:
23158 case TYPE_FPSTORE_UX:
23164 case PROCESSOR_POWER7:
23165 type = get_attr_type (insn);
23169 case TYPE_CR_LOGICAL:
23176 case TYPE_DELAYED_COMPARE:
23177 case TYPE_VAR_DELAYED_COMPARE:
23183 case TYPE_LOAD_EXT:
23184 case TYPE_LOAD_EXT_U:
23185 case TYPE_LOAD_EXT_UX:
23187 case TYPE_STORE_UX:
23188 case TYPE_FPLOAD_U:
23189 case TYPE_FPLOAD_UX:
23190 case TYPE_FPSTORE_U:
23191 case TYPE_FPSTORE_UX:
23207 insn_must_be_last_in_group (rtx insn)
23209 enum attr_type type;
23212 || GET_CODE (insn) == NOTE
23213 || DEBUG_INSN_P (insn)
23214 || GET_CODE (PATTERN (insn)) == USE
23215 || GET_CODE (PATTERN (insn)) == CLOBBER)
23218 switch (rs6000_cpu) {
23219 case PROCESSOR_POWER4:
23220 case PROCESSOR_POWER5:
23221 if (is_microcoded_insn (insn))
23224 if (is_branch_slot_insn (insn))
23228 case PROCESSOR_POWER6:
23229 type = get_attr_type (insn);
23236 case TYPE_VAR_SHIFT_ROTATE:
23243 case TYPE_DELAYED_COMPARE:
23244 case TYPE_IMUL_COMPARE:
23245 case TYPE_LMUL_COMPARE:
23246 case TYPE_FPCOMPARE:
23260 case PROCESSOR_POWER7:
23261 type = get_attr_type (insn);
23269 case TYPE_LOAD_EXT_U:
23270 case TYPE_LOAD_EXT_UX:
23271 case TYPE_STORE_UX:
23284 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
23285 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
23288 is_costly_group (rtx *group_insns, rtx next_insn)
23291 int issue_rate = rs6000_issue_rate ();
23293 for (i = 0; i < issue_rate; i++)
23295 sd_iterator_def sd_it;
23297 rtx insn = group_insns[i];
23302 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
23304 rtx next = DEP_CON (dep);
23306 if (next == next_insn
23307 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
23315 /* Utility of the function redefine_groups.
23316 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
23317 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
23318 to keep it "far" (in a separate group) from GROUP_INSNS, following
23319 one of the following schemes, depending on the value of the flag
23320 -minsert_sched_nops = X:
23321 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
23322 in order to force NEXT_INSN into a separate group.
23323 (2) X < sched_finish_regroup_exact: insert exactly X nops.
23324 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
23325 insertion (has a group just ended, how many vacant issue slots remain in the
23326 last group, and how many dispatch groups were encountered so far). */
23329 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
23330 rtx next_insn, bool *group_end, int can_issue_more,
23335 int issue_rate = rs6000_issue_rate ();
23336 bool end = *group_end;
23339 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
23340 return can_issue_more;
23342 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
23343 return can_issue_more;
23345 force = is_costly_group (group_insns, next_insn);
23347 return can_issue_more;
23349 if (sched_verbose > 6)
23350 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
23351 *group_count ,can_issue_more);
23353 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
23356 can_issue_more = 0;
23358 /* Since only a branch can be issued in the last issue_slot, it is
23359 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
23360 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
23361 in this case the last nop will start a new group and the branch
23362 will be forced to the new group. */
23363 if (can_issue_more && !is_branch_slot_insn (next_insn))
23366 while (can_issue_more > 0)
23369 emit_insn_before (nop, next_insn);
23377 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
23379 int n_nops = rs6000_sched_insert_nops;
23381 /* Nops can't be issued from the branch slot, so the effective
23382 issue_rate for nops is 'issue_rate - 1'. */
23383 if (can_issue_more == 0)
23384 can_issue_more = issue_rate;
23386 if (can_issue_more == 0)
23388 can_issue_more = issue_rate - 1;
23391 for (i = 0; i < issue_rate; i++)
23393 group_insns[i] = 0;
23400 emit_insn_before (nop, next_insn);
23401 if (can_issue_more == issue_rate - 1) /* new group begins */
23404 if (can_issue_more == 0)
23406 can_issue_more = issue_rate - 1;
23409 for (i = 0; i < issue_rate; i++)
23411 group_insns[i] = 0;
23417 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
23420 /* Is next_insn going to start a new group? */
23423 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23424 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23425 || (can_issue_more < issue_rate &&
23426 insn_terminates_group_p (next_insn, previous_group)));
23427 if (*group_end && end)
23430 if (sched_verbose > 6)
23431 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
23432 *group_count, can_issue_more);
23433 return can_issue_more;
23436 return can_issue_more;
23439 /* This function tries to synch the dispatch groups that the compiler "sees"
23440 with the dispatch groups that the processor dispatcher is expected to
23441 form in practice. It tries to achieve this synchronization by forcing the
23442 estimated processor grouping on the compiler (as opposed to the function
23443 'pad_goups' which tries to force the scheduler's grouping on the processor).
23445 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
23446 examines the (estimated) dispatch groups that will be formed by the processor
23447 dispatcher. It marks these group boundaries to reflect the estimated
23448 processor grouping, overriding the grouping that the scheduler had marked.
23449 Depending on the value of the flag '-minsert-sched-nops' this function can
23450 force certain insns into separate groups or force a certain distance between
23451 them by inserting nops, for example, if there exists a "costly dependence"
23454 The function estimates the group boundaries that the processor will form as
23455 follows: It keeps track of how many vacant issue slots are available after
23456 each insn. A subsequent insn will start a new group if one of the following
23458 - no more vacant issue slots remain in the current dispatch group.
23459 - only the last issue slot, which is the branch slot, is vacant, but the next
23460 insn is not a branch.
23461 - only the last 2 or less issue slots, including the branch slot, are vacant,
23462 which means that a cracked insn (which occupies two issue slots) can't be
23463 issued in this group.
23464 - less than 'issue_rate' slots are vacant, and the next insn always needs to
23465 start a new group. */
23468 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23470 rtx insn, next_insn;
23472 int can_issue_more;
23475 int group_count = 0;
23479 issue_rate = rs6000_issue_rate ();
23480 group_insns = XALLOCAVEC (rtx, issue_rate);
23481 for (i = 0; i < issue_rate; i++)
23483 group_insns[i] = 0;
23485 can_issue_more = issue_rate;
23487 insn = get_next_active_insn (prev_head_insn, tail);
23490 while (insn != NULL_RTX)
23492 slot = (issue_rate - can_issue_more);
23493 group_insns[slot] = insn;
23495 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23496 if (insn_terminates_group_p (insn, current_group))
23497 can_issue_more = 0;
23499 next_insn = get_next_active_insn (insn, tail);
23500 if (next_insn == NULL_RTX)
23501 return group_count + 1;
23503 /* Is next_insn going to start a new group? */
23505 = (can_issue_more == 0
23506 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23507 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23508 || (can_issue_more < issue_rate &&
23509 insn_terminates_group_p (next_insn, previous_group)));
23511 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
23512 next_insn, &group_end, can_issue_more,
23518 can_issue_more = 0;
23519 for (i = 0; i < issue_rate; i++)
23521 group_insns[i] = 0;
23525 if (GET_MODE (next_insn) == TImode && can_issue_more)
23526 PUT_MODE (next_insn, VOIDmode);
23527 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
23528 PUT_MODE (next_insn, TImode);
23531 if (can_issue_more == 0)
23532 can_issue_more = issue_rate;
23535 return group_count;
23538 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
23539 dispatch group boundaries that the scheduler had marked. Pad with nops
23540 any dispatch groups which have vacant issue slots, in order to force the
23541 scheduler's grouping on the processor dispatcher. The function
23542 returns the number of dispatch groups found. */
23545 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23547 rtx insn, next_insn;
23550 int can_issue_more;
23552 int group_count = 0;
23554 /* Initialize issue_rate. */
23555 issue_rate = rs6000_issue_rate ();
23556 can_issue_more = issue_rate;
23558 insn = get_next_active_insn (prev_head_insn, tail);
23559 next_insn = get_next_active_insn (insn, tail);
23561 while (insn != NULL_RTX)
23564 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23566 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
23568 if (next_insn == NULL_RTX)
23573 /* If the scheduler had marked group termination at this location
23574 (between insn and next_insn), and neither insn nor next_insn will
23575 force group termination, pad the group with nops to force group
23578 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
23579 && !insn_terminates_group_p (insn, current_group)
23580 && !insn_terminates_group_p (next_insn, previous_group))
23582 if (!is_branch_slot_insn (next_insn))
23585 while (can_issue_more)
23588 emit_insn_before (nop, next_insn);
23593 can_issue_more = issue_rate;
23598 next_insn = get_next_active_insn (insn, tail);
23601 return group_count;
23604 /* We're beginning a new block. Initialize data structures as necessary. */
23607 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
23608 int sched_verbose ATTRIBUTE_UNUSED,
23609 int max_ready ATTRIBUTE_UNUSED)
23611 last_scheduled_insn = NULL_RTX;
23612 load_store_pendulum = 0;
23615 /* The following function is called at the end of scheduling BB.
23616 After reload, it inserts nops at insn group bundling. */
23619 rs6000_sched_finish (FILE *dump, int sched_verbose)
23624 fprintf (dump, "=== Finishing schedule.\n");
23626 if (reload_completed && rs6000_sched_groups)
23628 /* Do not run sched_finish hook when selective scheduling enabled. */
23629 if (sel_sched_p ())
23632 if (rs6000_sched_insert_nops == sched_finish_none)
23635 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
23636 n_groups = pad_groups (dump, sched_verbose,
23637 current_sched_info->prev_head,
23638 current_sched_info->next_tail);
23640 n_groups = redefine_groups (dump, sched_verbose,
23641 current_sched_info->prev_head,
23642 current_sched_info->next_tail);
23644 if (sched_verbose >= 6)
23646 fprintf (dump, "ngroups = %d\n", n_groups);
23647 print_rtl (dump, current_sched_info->prev_head);
23648 fprintf (dump, "Done finish_sched\n");
23653 struct _rs6000_sched_context
23655 short cached_can_issue_more;
23656 rtx last_scheduled_insn;
23657 int load_store_pendulum;
23660 typedef struct _rs6000_sched_context rs6000_sched_context_def;
23661 typedef rs6000_sched_context_def *rs6000_sched_context_t;
23663 /* Allocate store for new scheduling context. */
23665 rs6000_alloc_sched_context (void)
23667 return xmalloc (sizeof (rs6000_sched_context_def));
23670 /* If CLEAN_P is true then initializes _SC with clean data,
23671 and from the global context otherwise. */
23673 rs6000_init_sched_context (void *_sc, bool clean_p)
23675 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23679 sc->cached_can_issue_more = 0;
23680 sc->last_scheduled_insn = NULL_RTX;
23681 sc->load_store_pendulum = 0;
23685 sc->cached_can_issue_more = cached_can_issue_more;
23686 sc->last_scheduled_insn = last_scheduled_insn;
23687 sc->load_store_pendulum = load_store_pendulum;
23691 /* Sets the global scheduling context to the one pointed to by _SC. */
23693 rs6000_set_sched_context (void *_sc)
23695 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23697 gcc_assert (sc != NULL);
23699 cached_can_issue_more = sc->cached_can_issue_more;
23700 last_scheduled_insn = sc->last_scheduled_insn;
23701 load_store_pendulum = sc->load_store_pendulum;
23706 rs6000_free_sched_context (void *_sc)
23708 gcc_assert (_sc != NULL);
23714 /* Length in units of the trampoline for entering a nested function. */
23717 rs6000_trampoline_size (void)
23721 switch (DEFAULT_ABI)
23724 gcc_unreachable ();
23727 ret = (TARGET_32BIT) ? 12 : 24;
23732 ret = (TARGET_32BIT) ? 40 : 48;
23739 /* Emit RTL insns to initialize the variable parts of a trampoline.
23740 FNADDR is an RTX for the address of the function's pure code.
23741 CXT is an RTX for the static chain value for the function. */
23744 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
23746 int regsize = (TARGET_32BIT) ? 4 : 8;
23747 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
23748 rtx ctx_reg = force_reg (Pmode, cxt);
23749 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
23751 switch (DEFAULT_ABI)
23754 gcc_unreachable ();
23756 /* Under AIX, just build the 3 word function descriptor */
23759 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
23760 rtx fn_reg = gen_reg_rtx (Pmode);
23761 rtx toc_reg = gen_reg_rtx (Pmode);
23763 /* Macro to shorten the code expansions below. */
23764 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23766 m_tramp = replace_equiv_address (m_tramp, addr);
23768 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
23769 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23770 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23771 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23772 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23778 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23781 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23782 LCT_NORMAL, VOIDmode, 4,
23784 GEN_INT (rs6000_trampoline_size ()), SImode,
23792 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
23793 identifier as an argument, so the front end shouldn't look it up. */
23796 rs6000_attribute_takes_identifier_p (const_tree attr_id)
23798 return is_attribute_p ("altivec", attr_id);
23801 /* Handle the "altivec" attribute. The attribute may have
23802 arguments as follows:
23804 __attribute__((altivec(vector__)))
23805 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23806 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23808 and may appear more than once (e.g., 'vector bool char') in a
23809 given declaration. */
23812 rs6000_handle_altivec_attribute (tree *node,
23813 tree name ATTRIBUTE_UNUSED,
23815 int flags ATTRIBUTE_UNUSED,
23816 bool *no_add_attrs)
23818 tree type = *node, result = NULL_TREE;
23819 enum machine_mode mode;
23822 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23823 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23824 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23827 while (POINTER_TYPE_P (type)
23828 || TREE_CODE (type) == FUNCTION_TYPE
23829 || TREE_CODE (type) == METHOD_TYPE
23830 || TREE_CODE (type) == ARRAY_TYPE)
23831 type = TREE_TYPE (type);
23833 mode = TYPE_MODE (type);
23835 /* Check for invalid AltiVec type qualifiers. */
23836 if (type == long_double_type_node)
23837 error ("use of %<long double%> in AltiVec types is invalid");
23838 else if (type == boolean_type_node)
23839 error ("use of boolean types in AltiVec types is invalid");
23840 else if (TREE_CODE (type) == COMPLEX_TYPE)
23841 error ("use of %<complex%> in AltiVec types is invalid");
23842 else if (DECIMAL_FLOAT_MODE_P (mode))
23843 error ("use of decimal floating point types in AltiVec types is invalid");
23844 else if (!TARGET_VSX)
23846 if (type == long_unsigned_type_node || type == long_integer_type_node)
23849 error ("use of %<long%> in AltiVec types is invalid for "
23850 "64-bit code without -mvsx");
23851 else if (rs6000_warn_altivec_long)
23852 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23855 else if (type == long_long_unsigned_type_node
23856 || type == long_long_integer_type_node)
23857 error ("use of %<long long%> in AltiVec types is invalid without "
23859 else if (type == double_type_node)
23860 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23863 switch (altivec_type)
23866 unsigned_p = TYPE_UNSIGNED (type);
23870 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
23873 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
23876 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
23879 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
23881 case SFmode: result = V4SF_type_node; break;
23882 case DFmode: result = V2DF_type_node; break;
23883 /* If the user says 'vector int bool', we may be handed the 'bool'
23884 attribute _before_ the 'vector' attribute, and so select the
23885 proper type in the 'b' case below. */
23886 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
23887 case V2DImode: case V2DFmode:
23895 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
23896 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
23897 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
23898 case QImode: case V16QImode: result = bool_V16QI_type_node;
23905 case V8HImode: result = pixel_V8HI_type_node;
23911 /* Propagate qualifiers attached to the element type
23912 onto the vector type. */
23913 if (result && result != type && TYPE_QUALS (type))
23914 result = build_qualified_type (result, TYPE_QUALS (type));
23916 *no_add_attrs = true; /* No need to hang on to the attribute. */
23919 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
23924 /* AltiVec defines four built-in scalar types that serve as vector
23925 elements; we must teach the compiler how to mangle them. */
23927 static const char *
23928 rs6000_mangle_type (const_tree type)
23930 type = TYPE_MAIN_VARIANT (type);
23932 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
23933 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
23936 if (type == bool_char_type_node) return "U6__boolc";
23937 if (type == bool_short_type_node) return "U6__bools";
23938 if (type == pixel_type_node) return "u7__pixel";
23939 if (type == bool_int_type_node) return "U6__booli";
23940 if (type == bool_long_type_node) return "U6__booll";
23942 /* Mangle IBM extended float long double as `g' (__float128) on
23943 powerpc*-linux where long-double-64 previously was the default. */
23944 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
23946 && TARGET_LONG_DOUBLE_128
23947 && !TARGET_IEEEQUAD)
23950 /* For all other types, use normal C++ mangling. */
23954 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23955 struct attribute_spec.handler. */
23958 rs6000_handle_longcall_attribute (tree *node, tree name,
23959 tree args ATTRIBUTE_UNUSED,
23960 int flags ATTRIBUTE_UNUSED,
23961 bool *no_add_attrs)
23963 if (TREE_CODE (*node) != FUNCTION_TYPE
23964 && TREE_CODE (*node) != FIELD_DECL
23965 && TREE_CODE (*node) != TYPE_DECL)
23967 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23969 *no_add_attrs = true;
23975 /* Set longcall attributes on all functions declared when
23976 rs6000_default_long_calls is true. */
23978 rs6000_set_default_type_attributes (tree type)
23980 if (rs6000_default_long_calls
23981 && (TREE_CODE (type) == FUNCTION_TYPE
23982 || TREE_CODE (type) == METHOD_TYPE))
23983 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23985 TYPE_ATTRIBUTES (type));
23988 darwin_set_default_type_attributes (type);
23992 /* Return a reference suitable for calling a function with the
23993 longcall attribute. */
23996 rs6000_longcall_ref (rtx call_ref)
23998 const char *call_name;
24001 if (GET_CODE (call_ref) != SYMBOL_REF)
24004 /* System V adds '.' to the internal name, so skip them. */
24005 call_name = XSTR (call_ref, 0);
24006 if (*call_name == '.')
24008 while (*call_name == '.')
24011 node = get_identifier (call_name);
24012 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24015 return force_reg (Pmode, call_ref);
24018 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24019 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24022 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24023 struct attribute_spec.handler. */
24025 rs6000_handle_struct_attribute (tree *node, tree name,
24026 tree args ATTRIBUTE_UNUSED,
24027 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24030 if (DECL_P (*node))
24032 if (TREE_CODE (*node) == TYPE_DECL)
24033 type = &TREE_TYPE (*node);
24038 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24039 || TREE_CODE (*type) == UNION_TYPE)))
24041 warning (OPT_Wattributes, "%qE attribute ignored", name);
24042 *no_add_attrs = true;
24045 else if ((is_attribute_p ("ms_struct", name)
24046 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24047 || ((is_attribute_p ("gcc_struct", name)
24048 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24050 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24052 *no_add_attrs = true;
24059 rs6000_ms_bitfield_layout_p (const_tree record_type)
24061 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24062 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24063 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24066 #ifdef USING_ELFOS_H
24068 /* A get_unnamed_section callback, used for switching to toc_section. */
24071 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24073 if (DEFAULT_ABI == ABI_AIX
24074 && TARGET_MINIMAL_TOC
24075 && !TARGET_RELOCATABLE)
24077 if (!toc_initialized)
24079 toc_initialized = 1;
24080 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24081 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24082 fprintf (asm_out_file, "\t.tc ");
24083 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24084 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24085 fprintf (asm_out_file, "\n");
24087 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24088 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24089 fprintf (asm_out_file, " = .+32768\n");
24092 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24094 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24095 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24098 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24099 if (!toc_initialized)
24101 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24102 fprintf (asm_out_file, " = .+32768\n");
24103 toc_initialized = 1;
24108 /* Implement TARGET_ASM_INIT_SECTIONS. */
24111 rs6000_elf_asm_init_sections (void)
24114 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24117 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24118 SDATA2_SECTION_ASM_OP);
24121 /* Implement TARGET_SELECT_RTX_SECTION. */
24124 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24125 unsigned HOST_WIDE_INT align)
24127 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24128 return toc_section;
24130 return default_elf_select_rtx_section (mode, x, align);
24133 /* For a SYMBOL_REF, set generic flags and then perform some
24134 target-specific processing.
24136 When the AIX ABI is requested on a non-AIX system, replace the
24137 function name with the real name (with a leading .) rather than the
24138 function descriptor name. This saves a lot of overriding code to
24139 read the prefixes. */
24142 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24144 default_encode_section_info (decl, rtl, first);
24147 && TREE_CODE (decl) == FUNCTION_DECL
24149 && DEFAULT_ABI == ABI_AIX)
24151 rtx sym_ref = XEXP (rtl, 0);
24152 size_t len = strlen (XSTR (sym_ref, 0));
24153 char *str = XALLOCAVEC (char, len + 2);
24155 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24156 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24161 compare_section_name (const char *section, const char *templ)
24165 len = strlen (templ);
24166 return (strncmp (section, templ, len) == 0
24167 && (section[len] == 0 || section[len] == '.'));
24171 rs6000_elf_in_small_data_p (const_tree decl)
24173 if (rs6000_sdata == SDATA_NONE)
24176 /* We want to merge strings, so we never consider them small data. */
24177 if (TREE_CODE (decl) == STRING_CST)
24180 /* Functions are never in the small data area. */
24181 if (TREE_CODE (decl) == FUNCTION_DECL)
24184 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24186 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24187 if (compare_section_name (section, ".sdata")
24188 || compare_section_name (section, ".sdata2")
24189 || compare_section_name (section, ".gnu.linkonce.s")
24190 || compare_section_name (section, ".sbss")
24191 || compare_section_name (section, ".sbss2")
24192 || compare_section_name (section, ".gnu.linkonce.sb")
24193 || strcmp (section, ".PPC.EMB.sdata0") == 0
24194 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24199 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24202 && (unsigned HOST_WIDE_INT) size <= g_switch_value
24203 /* If it's not public, and we're not going to reference it there,
24204 there's no need to put it in the small data section. */
24205 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24212 #endif /* USING_ELFOS_H */
24214 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24217 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24219 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24222 /* Return a REG that occurs in ADDR with coefficient 1.
24223 ADDR can be effectively incremented by incrementing REG.
24225 r0 is special and we must not select it as an address
24226 register by this routine since our caller will try to
24227 increment the returned register via an "la" instruction. */
24230 find_addr_reg (rtx addr)
24232 while (GET_CODE (addr) == PLUS)
24234 if (GET_CODE (XEXP (addr, 0)) == REG
24235 && REGNO (XEXP (addr, 0)) != 0)
24236 addr = XEXP (addr, 0);
24237 else if (GET_CODE (XEXP (addr, 1)) == REG
24238 && REGNO (XEXP (addr, 1)) != 0)
24239 addr = XEXP (addr, 1);
24240 else if (CONSTANT_P (XEXP (addr, 0)))
24241 addr = XEXP (addr, 1);
24242 else if (CONSTANT_P (XEXP (addr, 1)))
24243 addr = XEXP (addr, 0);
24245 gcc_unreachable ();
24247 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
24252 rs6000_fatal_bad_address (rtx op)
24254 fatal_insn ("bad address", op);
24259 static tree branch_island_list = 0;
24261 /* Remember to generate a branch island for far calls to the given
24265 add_compiler_branch_island (tree label_name, tree function_name,
24268 tree branch_island = build_tree_list (function_name, label_name);
24269 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
24270 TREE_CHAIN (branch_island) = branch_island_list;
24271 branch_island_list = branch_island;
24274 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
24275 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
24276 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
24277 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
24279 /* Generate far-jump branch islands for everything on the
24280 branch_island_list. Invoked immediately after the last instruction
24281 of the epilogue has been emitted; the branch-islands must be
24282 appended to, and contiguous with, the function body. Mach-O stubs
24283 are generated in machopic_output_stub(). */
24286 macho_branch_islands (void)
24289 tree branch_island;
24291 for (branch_island = branch_island_list;
24293 branch_island = TREE_CHAIN (branch_island))
24295 const char *label =
24296 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
24298 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
24299 char name_buf[512];
24300 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
24301 if (name[0] == '*' || name[0] == '&')
24302 strcpy (name_buf, name+1);
24306 strcpy (name_buf+1, name);
24308 strcpy (tmp_buf, "\n");
24309 strcat (tmp_buf, label);
24310 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24311 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24312 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
24313 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24316 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
24317 strcat (tmp_buf, label);
24318 strcat (tmp_buf, "_pic\n");
24319 strcat (tmp_buf, label);
24320 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
24322 strcat (tmp_buf, "\taddis r11,r11,ha16(");
24323 strcat (tmp_buf, name_buf);
24324 strcat (tmp_buf, " - ");
24325 strcat (tmp_buf, label);
24326 strcat (tmp_buf, "_pic)\n");
24328 strcat (tmp_buf, "\tmtlr r0\n");
24330 strcat (tmp_buf, "\taddi r12,r11,lo16(");
24331 strcat (tmp_buf, name_buf);
24332 strcat (tmp_buf, " - ");
24333 strcat (tmp_buf, label);
24334 strcat (tmp_buf, "_pic)\n");
24336 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
24340 strcat (tmp_buf, ":\nlis r12,hi16(");
24341 strcat (tmp_buf, name_buf);
24342 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
24343 strcat (tmp_buf, name_buf);
24344 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
24346 output_asm_insn (tmp_buf, 0);
24347 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24348 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24349 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
24350 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24353 branch_island_list = 0;
24356 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
24357 already there or not. */
24360 no_previous_def (tree function_name)
24362 tree branch_island;
24363 for (branch_island = branch_island_list;
24365 branch_island = TREE_CHAIN (branch_island))
24366 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
24371 /* GET_PREV_LABEL gets the label name from the previous definition of
24375 get_prev_label (tree function_name)
24377 tree branch_island;
24378 for (branch_island = branch_island_list;
24380 branch_island = TREE_CHAIN (branch_island))
24381 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
24382 return BRANCH_ISLAND_LABEL_NAME (branch_island);
24386 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
24387 #define DARWIN_LINKER_GENERATES_ISLANDS 0
24390 /* KEXTs still need branch islands. */
24391 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
24392 || flag_mkernel || flag_apple_kext)
24394 /* INSN is either a function call or a millicode call. It may have an
24395 unconditional jump in its delay slot.
24397 CALL_DEST is the routine we are calling. */
24400 output_call (rtx insn, rtx *operands, int dest_operand_number,
24401 int cookie_operand_number)
24403 static char buf[256];
24404 if (DARWIN_GENERATE_ISLANDS
24405 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
24406 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
24409 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
24411 if (no_previous_def (funname))
24413 rtx label_rtx = gen_label_rtx ();
24414 char *label_buf, temp_buf[256];
24415 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
24416 CODE_LABEL_NUMBER (label_rtx));
24417 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
24418 labelname = get_identifier (label_buf);
24419 add_compiler_branch_island (labelname, funname, insn_line (insn));
24422 labelname = get_prev_label (funname);
24424 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
24425 instruction will reach 'foo', otherwise link as 'bl L42'".
24426 "L42" should be a 'branch island', that will do a far jump to
24427 'foo'. Branch islands are generated in
24428 macho_branch_islands(). */
24429 sprintf (buf, "jbsr %%z%d,%.246s",
24430 dest_operand_number, IDENTIFIER_POINTER (labelname));
24433 sprintf (buf, "bl %%z%d", dest_operand_number);
24437 /* Generate PIC and indirect symbol stubs. */
24440 machopic_output_stub (FILE *file, const char *symb, const char *stub)
24442 unsigned int length;
24443 char *symbol_name, *lazy_ptr_name;
24444 char *local_label_0;
24445 static int label = 0;
24447 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
24448 symb = (*targetm.strip_name_encoding) (symb);
24451 length = strlen (symb);
24452 symbol_name = XALLOCAVEC (char, length + 32);
24453 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
24455 lazy_ptr_name = XALLOCAVEC (char, length + 32);
24456 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
24459 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
24461 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
24465 fprintf (file, "\t.align 5\n");
24467 fprintf (file, "%s:\n", stub);
24468 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24471 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
24472 sprintf (local_label_0, "\"L%011d$spb\"", label);
24474 fprintf (file, "\tmflr r0\n");
24475 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
24476 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
24477 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
24478 lazy_ptr_name, local_label_0);
24479 fprintf (file, "\tmtlr r0\n");
24480 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
24481 (TARGET_64BIT ? "ldu" : "lwzu"),
24482 lazy_ptr_name, local_label_0);
24483 fprintf (file, "\tmtctr r12\n");
24484 fprintf (file, "\tbctr\n");
24488 fprintf (file, "\t.align 4\n");
24490 fprintf (file, "%s:\n", stub);
24491 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24493 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
24494 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
24495 (TARGET_64BIT ? "ldu" : "lwzu"),
24497 fprintf (file, "\tmtctr r12\n");
24498 fprintf (file, "\tbctr\n");
24501 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
24502 fprintf (file, "%s:\n", lazy_ptr_name);
24503 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24504 fprintf (file, "%sdyld_stub_binding_helper\n",
24505 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
24508 /* Legitimize PIC addresses. If the address is already
24509 position-independent, we return ORIG. Newly generated
24510 position-independent addresses go into a reg. This is REG if non
24511 zero, otherwise we allocate register(s) as necessary. */
24513 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
24516 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
24521 if (reg == NULL && ! reload_in_progress && ! reload_completed)
24522 reg = gen_reg_rtx (Pmode);
24524 if (GET_CODE (orig) == CONST)
24528 if (GET_CODE (XEXP (orig, 0)) == PLUS
24529 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
24532 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
24534 /* Use a different reg for the intermediate value, as
24535 it will be marked UNCHANGING. */
24536 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
24537 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
24540 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
24543 if (GET_CODE (offset) == CONST_INT)
24545 if (SMALL_INT (offset))
24546 return plus_constant (base, INTVAL (offset));
24547 else if (! reload_in_progress && ! reload_completed)
24548 offset = force_reg (Pmode, offset);
24551 rtx mem = force_const_mem (Pmode, orig);
24552 return machopic_legitimize_pic_address (mem, Pmode, reg);
24555 return gen_rtx_PLUS (Pmode, base, offset);
24558 /* Fall back on generic machopic code. */
24559 return machopic_legitimize_pic_address (orig, mode, reg);
24562 /* Output a .machine directive for the Darwin assembler, and call
24563 the generic start_file routine. */
24566 rs6000_darwin_file_start (void)
24568 static const struct
24574 { "ppc64", "ppc64", MASK_64BIT },
24575 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
24576 { "power4", "ppc970", 0 },
24577 { "G5", "ppc970", 0 },
24578 { "7450", "ppc7450", 0 },
24579 { "7400", "ppc7400", MASK_ALTIVEC },
24580 { "G4", "ppc7400", 0 },
24581 { "750", "ppc750", 0 },
24582 { "740", "ppc750", 0 },
24583 { "G3", "ppc750", 0 },
24584 { "604e", "ppc604e", 0 },
24585 { "604", "ppc604", 0 },
24586 { "603e", "ppc603", 0 },
24587 { "603", "ppc603", 0 },
24588 { "601", "ppc601", 0 },
24589 { NULL, "ppc", 0 } };
24590 const char *cpu_id = "";
24593 rs6000_file_start ();
24594 darwin_file_start ();
24596 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
24597 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
24598 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
24599 && rs6000_select[i].string[0] != '\0')
24600 cpu_id = rs6000_select[i].string;
24602 /* Look through the mapping array. Pick the first name that either
24603 matches the argument, has a bit set in IF_SET that is also set
24604 in the target flags, or has a NULL name. */
24607 while (mapping[i].arg != NULL
24608 && strcmp (mapping[i].arg, cpu_id) != 0
24609 && (mapping[i].if_set & target_flags) == 0)
24612 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
24615 #endif /* TARGET_MACHO */
24619 rs6000_elf_reloc_rw_mask (void)
24623 else if (DEFAULT_ABI == ABI_AIX)
24629 /* Record an element in the table of global constructors. SYMBOL is
24630 a SYMBOL_REF of the function to be called; PRIORITY is a number
24631 between 0 and MAX_INIT_PRIORITY.
24633 This differs from default_named_section_asm_out_constructor in
24634 that we have special handling for -mrelocatable. */
24637 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
24639 const char *section = ".ctors";
24642 if (priority != DEFAULT_INIT_PRIORITY)
24644 sprintf (buf, ".ctors.%.5u",
24645 /* Invert the numbering so the linker puts us in the proper
24646 order; constructors are run from right to left, and the
24647 linker sorts in increasing order. */
24648 MAX_INIT_PRIORITY - priority);
24652 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24653 assemble_align (POINTER_SIZE);
24655 if (TARGET_RELOCATABLE)
24657 fputs ("\t.long (", asm_out_file);
24658 output_addr_const (asm_out_file, symbol);
24659 fputs (")@fixup\n", asm_out_file);
24662 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24666 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
24668 const char *section = ".dtors";
24671 if (priority != DEFAULT_INIT_PRIORITY)
24673 sprintf (buf, ".dtors.%.5u",
24674 /* Invert the numbering so the linker puts us in the proper
24675 order; constructors are run from right to left, and the
24676 linker sorts in increasing order. */
24677 MAX_INIT_PRIORITY - priority);
24681 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24682 assemble_align (POINTER_SIZE);
24684 if (TARGET_RELOCATABLE)
24686 fputs ("\t.long (", asm_out_file);
24687 output_addr_const (asm_out_file, symbol);
24688 fputs (")@fixup\n", asm_out_file);
24691 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24695 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
24699 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
24700 ASM_OUTPUT_LABEL (file, name);
24701 fputs (DOUBLE_INT_ASM_OP, file);
24702 rs6000_output_function_entry (file, name);
24703 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
24706 fputs ("\t.size\t", file);
24707 assemble_name (file, name);
24708 fputs (",24\n\t.type\t.", file);
24709 assemble_name (file, name);
24710 fputs (",@function\n", file);
24711 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
24713 fputs ("\t.globl\t.", file);
24714 assemble_name (file, name);
24719 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24720 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24721 rs6000_output_function_entry (file, name);
24722 fputs (":\n", file);
24726 if (TARGET_RELOCATABLE
24727 && !TARGET_SECURE_PLT
24728 && (get_pool_size () != 0 || crtl->profile)
24733 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
24735 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
24736 fprintf (file, "\t.long ");
24737 assemble_name (file, buf);
24739 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
24740 assemble_name (file, buf);
24744 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24745 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24747 if (DEFAULT_ABI == ABI_AIX)
24749 const char *desc_name, *orig_name;
24751 orig_name = (*targetm.strip_name_encoding) (name);
24752 desc_name = orig_name;
24753 while (*desc_name == '.')
24756 if (TREE_PUBLIC (decl))
24757 fprintf (file, "\t.globl %s\n", desc_name);
24759 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24760 fprintf (file, "%s:\n", desc_name);
24761 fprintf (file, "\t.long %s\n", orig_name);
24762 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
24763 if (DEFAULT_ABI == ABI_AIX)
24764 fputs ("\t.long 0\n", file);
24765 fprintf (file, "\t.previous\n");
24767 ASM_OUTPUT_LABEL (file, name);
24771 rs6000_elf_end_indicate_exec_stack (void)
24774 file_end_indicate_exec_stack ();
24780 rs6000_xcoff_asm_output_anchor (rtx symbol)
24784 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24785 SYMBOL_REF_BLOCK_OFFSET (symbol));
24786 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24790 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24792 fputs (GLOBAL_ASM_OP, stream);
24793 RS6000_OUTPUT_BASENAME (stream, name);
24794 putc ('\n', stream);
24797 /* A get_unnamed_decl callback, used for read-only sections. PTR
24798 points to the section string variable. */
24801 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24803 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24804 *(const char *const *) directive,
24805 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24808 /* Likewise for read-write sections. */
24811 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24813 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24814 *(const char *const *) directive,
24815 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24818 /* A get_unnamed_section callback, used for switching to toc_section. */
24821 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24823 if (TARGET_MINIMAL_TOC)
24825 /* toc_section is always selected at least once from
24826 rs6000_xcoff_file_start, so this is guaranteed to
24827 always be defined once and only once in each file. */
24828 if (!toc_initialized)
24830 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24831 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24832 toc_initialized = 1;
24834 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
24835 (TARGET_32BIT ? "" : ",3"));
24838 fputs ("\t.toc\n", asm_out_file);
24841 /* Implement TARGET_ASM_INIT_SECTIONS. */
24844 rs6000_xcoff_asm_init_sections (void)
24846 read_only_data_section
24847 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24848 &xcoff_read_only_section_name);
24850 private_data_section
24851 = get_unnamed_section (SECTION_WRITE,
24852 rs6000_xcoff_output_readwrite_section_asm_op,
24853 &xcoff_private_data_section_name);
24855 read_only_private_data_section
24856 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24857 &xcoff_private_data_section_name);
24860 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
24862 readonly_data_section = read_only_data_section;
24863 exception_section = data_section;
24867 rs6000_xcoff_reloc_rw_mask (void)
24873 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
24874 tree decl ATTRIBUTE_UNUSED)
24877 static const char * const suffix[3] = { "PR", "RO", "RW" };
24879 if (flags & SECTION_CODE)
24881 else if (flags & SECTION_WRITE)
24886 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
24887 (flags & SECTION_CODE) ? "." : "",
24888 name, suffix[smclass], flags & SECTION_ENTSIZE);
24892 rs6000_xcoff_select_section (tree decl, int reloc,
24893 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24895 if (decl_readonly_section (decl, reloc))
24897 if (TREE_PUBLIC (decl))
24898 return read_only_data_section;
24900 return read_only_private_data_section;
24904 if (TREE_PUBLIC (decl))
24905 return data_section;
24907 return private_data_section;
24912 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
24916 /* Use select_section for private and uninitialized data. */
24917 if (!TREE_PUBLIC (decl)
24918 || DECL_COMMON (decl)
24919 || DECL_INITIAL (decl) == NULL_TREE
24920 || DECL_INITIAL (decl) == error_mark_node
24921 || (flag_zero_initialized_in_bss
24922 && initializer_zerop (DECL_INITIAL (decl))))
24925 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
24926 name = (*targetm.strip_name_encoding) (name);
24927 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
24930 /* Select section for constant in constant pool.
24932 On RS/6000, all constants are in the private read-only data area.
24933 However, if this is being placed in the TOC it must be output as a
24937 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
24938 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24940 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24941 return toc_section;
24943 return read_only_private_data_section;
24946 /* Remove any trailing [DS] or the like from the symbol name. */
24948 static const char *
24949 rs6000_xcoff_strip_name_encoding (const char *name)
24954 len = strlen (name);
24955 if (name[len - 1] == ']')
24956 return ggc_alloc_string (name, len - 4);
24961 /* Section attributes. AIX is always PIC. */
24963 static unsigned int
24964 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24966 unsigned int align;
24967 unsigned int flags = default_section_type_flags (decl, name, reloc);
24969 /* Align to at least UNIT size. */
24970 if (flags & SECTION_CODE)
24971 align = MIN_UNITS_PER_WORD;
24973 /* Increase alignment of large objects if not already stricter. */
24974 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24975 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24976 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24978 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24981 /* Output at beginning of assembler file.
24983 Initialize the section names for the RS/6000 at this point.
24985 Specify filename, including full path, to assembler.
24987 We want to go into the TOC section so at least one .toc will be emitted.
24988 Also, in order to output proper .bs/.es pairs, we need at least one static
24989 [RW] section emitted.
24991 Finally, declare mcount when profiling to make the assembler happy. */
24994 rs6000_xcoff_file_start (void)
24996 rs6000_gen_section_name (&xcoff_bss_section_name,
24997 main_input_filename, ".bss_");
24998 rs6000_gen_section_name (&xcoff_private_data_section_name,
24999 main_input_filename, ".rw_");
25000 rs6000_gen_section_name (&xcoff_read_only_section_name,
25001 main_input_filename, ".ro_");
25003 fputs ("\t.file\t", asm_out_file);
25004 output_quoted_string (asm_out_file, main_input_filename);
25005 fputc ('\n', asm_out_file);
25006 if (write_symbols != NO_DEBUG)
25007 switch_to_section (private_data_section);
25008 switch_to_section (text_section);
25010 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25011 rs6000_file_start ();
25014 /* Output at end of assembler file.
25015 On the RS/6000, referencing data should automatically pull in text. */
25018 rs6000_xcoff_file_end (void)
25020 switch_to_section (text_section);
25021 fputs ("_section_.text:\n", asm_out_file);
25022 switch_to_section (data_section);
25023 fputs (TARGET_32BIT
25024 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25027 #endif /* TARGET_XCOFF */
25029 /* Compute a (partial) cost for rtx X. Return true if the complete
25030 cost has been computed, and false if subexpressions should be
25031 scanned. In either case, *TOTAL contains the cost result. */
25034 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25037 enum machine_mode mode = GET_MODE (x);
25041 /* On the RS/6000, if it is valid in the insn, it is free. */
25043 if (((outer_code == SET
25044 || outer_code == PLUS
25045 || outer_code == MINUS)
25046 && (satisfies_constraint_I (x)
25047 || satisfies_constraint_L (x)))
25048 || (outer_code == AND
25049 && (satisfies_constraint_K (x)
25051 ? satisfies_constraint_L (x)
25052 : satisfies_constraint_J (x))
25053 || mask_operand (x, mode)
25055 && mask64_operand (x, DImode))))
25056 || ((outer_code == IOR || outer_code == XOR)
25057 && (satisfies_constraint_K (x)
25059 ? satisfies_constraint_L (x)
25060 : satisfies_constraint_J (x))))
25061 || outer_code == ASHIFT
25062 || outer_code == ASHIFTRT
25063 || outer_code == LSHIFTRT
25064 || outer_code == ROTATE
25065 || outer_code == ROTATERT
25066 || outer_code == ZERO_EXTRACT
25067 || (outer_code == MULT
25068 && satisfies_constraint_I (x))
25069 || ((outer_code == DIV || outer_code == UDIV
25070 || outer_code == MOD || outer_code == UMOD)
25071 && exact_log2 (INTVAL (x)) >= 0)
25072 || (outer_code == COMPARE
25073 && (satisfies_constraint_I (x)
25074 || satisfies_constraint_K (x)))
25075 || (outer_code == EQ
25076 && (satisfies_constraint_I (x)
25077 || satisfies_constraint_K (x)
25079 ? satisfies_constraint_L (x)
25080 : satisfies_constraint_J (x))))
25081 || (outer_code == GTU
25082 && satisfies_constraint_I (x))
25083 || (outer_code == LTU
25084 && satisfies_constraint_P (x)))
25089 else if ((outer_code == PLUS
25090 && reg_or_add_cint_operand (x, VOIDmode))
25091 || (outer_code == MINUS
25092 && reg_or_sub_cint_operand (x, VOIDmode))
25093 || ((outer_code == SET
25094 || outer_code == IOR
25095 || outer_code == XOR)
25097 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25099 *total = COSTS_N_INSNS (1);
25105 if (mode == DImode && code == CONST_DOUBLE)
25107 if ((outer_code == IOR || outer_code == XOR)
25108 && CONST_DOUBLE_HIGH (x) == 0
25109 && (CONST_DOUBLE_LOW (x)
25110 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25115 else if ((outer_code == AND && and64_2_operand (x, DImode))
25116 || ((outer_code == SET
25117 || outer_code == IOR
25118 || outer_code == XOR)
25119 && CONST_DOUBLE_HIGH (x) == 0))
25121 *total = COSTS_N_INSNS (1);
25131 /* When optimizing for size, MEM should be slightly more expensive
25132 than generating address, e.g., (plus (reg) (const)).
25133 L1 cache latency is about two instructions. */
25134 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25142 if (mode == DFmode)
25144 if (GET_CODE (XEXP (x, 0)) == MULT)
25146 /* FNMA accounted in outer NEG. */
25147 if (outer_code == NEG)
25148 *total = rs6000_cost->dmul - rs6000_cost->fp;
25150 *total = rs6000_cost->dmul;
25153 *total = rs6000_cost->fp;
25155 else if (mode == SFmode)
25157 /* FNMA accounted in outer NEG. */
25158 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25161 *total = rs6000_cost->fp;
25164 *total = COSTS_N_INSNS (1);
25168 if (mode == DFmode)
25170 if (GET_CODE (XEXP (x, 0)) == MULT
25171 || GET_CODE (XEXP (x, 1)) == MULT)
25173 /* FNMA accounted in outer NEG. */
25174 if (outer_code == NEG)
25175 *total = rs6000_cost->dmul - rs6000_cost->fp;
25177 *total = rs6000_cost->dmul;
25180 *total = rs6000_cost->fp;
25182 else if (mode == SFmode)
25184 /* FNMA accounted in outer NEG. */
25185 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25188 *total = rs6000_cost->fp;
25191 *total = COSTS_N_INSNS (1);
25195 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25196 && satisfies_constraint_I (XEXP (x, 1)))
25198 if (INTVAL (XEXP (x, 1)) >= -256
25199 && INTVAL (XEXP (x, 1)) <= 255)
25200 *total = rs6000_cost->mulsi_const9;
25202 *total = rs6000_cost->mulsi_const;
25204 /* FMA accounted in outer PLUS/MINUS. */
25205 else if ((mode == DFmode || mode == SFmode)
25206 && (outer_code == PLUS || outer_code == MINUS))
25208 else if (mode == DFmode)
25209 *total = rs6000_cost->dmul;
25210 else if (mode == SFmode)
25211 *total = rs6000_cost->fp;
25212 else if (mode == DImode)
25213 *total = rs6000_cost->muldi;
25215 *total = rs6000_cost->mulsi;
25220 if (FLOAT_MODE_P (mode))
25222 *total = mode == DFmode ? rs6000_cost->ddiv
25223 : rs6000_cost->sdiv;
25230 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25231 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25233 if (code == DIV || code == MOD)
25235 *total = COSTS_N_INSNS (2);
25238 *total = COSTS_N_INSNS (1);
25242 if (GET_MODE (XEXP (x, 1)) == DImode)
25243 *total = rs6000_cost->divdi;
25245 *total = rs6000_cost->divsi;
25247 /* Add in shift and subtract for MOD. */
25248 if (code == MOD || code == UMOD)
25249 *total += COSTS_N_INSNS (2);
25254 *total = COSTS_N_INSNS (4);
25258 *total = COSTS_N_INSNS (6);
25262 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
25274 *total = COSTS_N_INSNS (1);
25282 /* Handle mul_highpart. */
25283 if (outer_code == TRUNCATE
25284 && GET_CODE (XEXP (x, 0)) == MULT)
25286 if (mode == DImode)
25287 *total = rs6000_cost->muldi;
25289 *total = rs6000_cost->mulsi;
25292 else if (outer_code == AND)
25295 *total = COSTS_N_INSNS (1);
25300 if (GET_CODE (XEXP (x, 0)) == MEM)
25303 *total = COSTS_N_INSNS (1);
25309 if (!FLOAT_MODE_P (mode))
25311 *total = COSTS_N_INSNS (1);
25317 case UNSIGNED_FLOAT:
25320 case FLOAT_TRUNCATE:
25321 *total = rs6000_cost->fp;
25325 if (mode == DFmode)
25328 *total = rs6000_cost->fp;
25332 switch (XINT (x, 1))
25335 *total = rs6000_cost->fp;
25347 *total = COSTS_N_INSNS (1);
25350 else if (FLOAT_MODE_P (mode)
25351 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
25353 *total = rs6000_cost->fp;
25361 /* Carry bit requires mode == Pmode.
25362 NEG or PLUS already counted so only add one. */
25364 && (outer_code == NEG || outer_code == PLUS))
25366 *total = COSTS_N_INSNS (1);
25369 if (outer_code == SET)
25371 if (XEXP (x, 1) == const0_rtx)
25373 if (TARGET_ISEL && !TARGET_MFCRF)
25374 *total = COSTS_N_INSNS (8);
25376 *total = COSTS_N_INSNS (2);
25379 else if (mode == Pmode)
25381 *total = COSTS_N_INSNS (3);
25390 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
25392 if (TARGET_ISEL && !TARGET_MFCRF)
25393 *total = COSTS_N_INSNS (8);
25395 *total = COSTS_N_INSNS (2);
25399 if (outer_code == COMPARE)
25413 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
25416 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
25419 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
25422 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
25423 "total = %d, speed = %s, x:\n",
25424 ret ? "complete" : "scan inner",
25425 GET_RTX_NAME (code),
25426 GET_RTX_NAME (outer_code),
25428 speed ? "true" : "false");
25435 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
25438 rs6000_debug_address_cost (rtx x, bool speed)
25440 int ret = TARGET_ADDRESS_COST (x, speed);
25442 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
25443 ret, speed ? "true" : "false");
25450 /* A C expression returning the cost of moving data from a register of class
25451 CLASS1 to one of CLASS2. */
25454 rs6000_register_move_cost (enum machine_mode mode,
25455 enum reg_class from, enum reg_class to)
25459 /* Moves from/to GENERAL_REGS. */
25460 if (reg_classes_intersect_p (to, GENERAL_REGS)
25461 || reg_classes_intersect_p (from, GENERAL_REGS))
25463 if (! reg_classes_intersect_p (to, GENERAL_REGS))
25466 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
25467 ret = (rs6000_memory_move_cost (mode, from, 0)
25468 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
25470 /* It's more expensive to move CR_REGS than CR0_REGS because of the
25472 else if (from == CR_REGS)
25475 /* Power6 has slower LR/CTR moves so make them more expensive than
25476 memory in order to bias spills to memory .*/
25477 else if (rs6000_cpu == PROCESSOR_POWER6
25478 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
25479 ret = 6 * hard_regno_nregs[0][mode];
25482 /* A move will cost one instruction per GPR moved. */
25483 ret = 2 * hard_regno_nregs[0][mode];
25486 /* If we have VSX, we can easily move between FPR or Altivec registers. */
25487 else if (VECTOR_UNIT_VSX_P (mode)
25488 && reg_classes_intersect_p (to, VSX_REGS)
25489 && reg_classes_intersect_p (from, VSX_REGS))
25490 ret = 2 * hard_regno_nregs[32][mode];
25492 /* Moving between two similar registers is just one instruction. */
25493 else if (reg_classes_intersect_p (to, from))
25494 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
25496 /* Everything else has to go through GENERAL_REGS. */
25498 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
25499 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
25501 if (TARGET_DEBUG_COST)
25503 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
25504 ret, GET_MODE_NAME (mode), reg_class_names[from],
25505 reg_class_names[to]);
25510 /* A C expressions returning the cost of moving data of MODE from a register to
25514 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
25515 int in ATTRIBUTE_UNUSED)
25519 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
25520 ret = 4 * hard_regno_nregs[0][mode];
25521 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
25522 ret = 4 * hard_regno_nregs[32][mode];
25523 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
25524 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
25526 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
25528 if (TARGET_DEBUG_COST)
25530 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
25531 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
25536 /* Returns a code for a target-specific builtin that implements
25537 reciprocal of the function, or NULL_TREE if not available. */
25540 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
25541 bool sqrt ATTRIBUTE_UNUSED)
25543 if (optimize_insn_for_size_p ())
25549 case VSX_BUILTIN_XVSQRTDP:
25550 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
25553 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
25555 case VSX_BUILTIN_XVSQRTSP:
25556 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
25559 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
25568 case BUILT_IN_SQRT:
25569 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
25572 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
25574 case BUILT_IN_SQRTF:
25575 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
25578 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
25585 /* Load up a constant. If the mode is a vector mode, splat the value across
25586 all of the vector elements. */
25589 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
25593 if (mode == SFmode || mode == DFmode)
25595 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
25596 reg = force_reg (mode, d);
25598 else if (mode == V4SFmode)
25600 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
25601 rtvec v = gen_rtvec (4, d, d, d, d);
25602 reg = gen_reg_rtx (mode);
25603 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
25605 else if (mode == V2DFmode)
25607 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
25608 rtvec v = gen_rtvec (2, d, d);
25609 reg = gen_reg_rtx (mode);
25610 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
25613 gcc_unreachable ();
25618 /* Generate a FMADD instruction:
25619 dst = (m1 * m2) + a
25621 generating different RTL based on the fused multiply/add switch. */
25624 rs6000_emit_madd (rtx dst, rtx m1, rtx m2, rtx a)
25626 enum machine_mode mode = GET_MODE (dst);
25628 if (!TARGET_FUSED_MADD)
25630 /* For the simple ops, use the generator function, rather than assuming
25631 that the RTL is standard. */
25632 enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code;
25633 enum insn_code acode = optab_handler (add_optab, mode)->insn_code;
25634 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25635 gen_2arg_fn_t gen_add = (gen_2arg_fn_t) GEN_FCN (acode);
25636 rtx mreg = gen_reg_rtx (mode);
25638 gcc_assert (mcode != CODE_FOR_nothing && acode != CODE_FOR_nothing);
25639 emit_insn (gen_mul (mreg, m1, m2));
25640 emit_insn (gen_add (dst, mreg, a));
25644 emit_insn (gen_rtx_SET (VOIDmode, dst,
25645 gen_rtx_PLUS (mode,
25646 gen_rtx_MULT (mode, m1, m2),
25650 /* Generate a FMSUB instruction:
25651 dst = (m1 * m2) - a
25653 generating different RTL based on the fused multiply/add switch. */
25656 rs6000_emit_msub (rtx dst, rtx m1, rtx m2, rtx a)
25658 enum machine_mode mode = GET_MODE (dst);
25660 if (!TARGET_FUSED_MADD
25661 || (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (V4SFmode)))
25663 /* For the simple ops, use the generator function, rather than assuming
25664 that the RTL is standard. */
25665 enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code;
25666 enum insn_code scode = optab_handler (add_optab, mode)->insn_code;
25667 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25668 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
25669 rtx mreg = gen_reg_rtx (mode);
25671 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
25672 emit_insn (gen_mul (mreg, m1, m2));
25673 emit_insn (gen_sub (dst, mreg, a));
25677 emit_insn (gen_rtx_SET (VOIDmode, dst,
25678 gen_rtx_MINUS (mode,
25679 gen_rtx_MULT (mode, m1, m2),
25683 /* Generate a FNMSUB instruction:
25684 dst = - ((m1 * m2) - a)
25686 Which is equivalent to (except in the prescence of -0.0):
25687 dst = a - (m1 * m2)
25689 generating different RTL based on the fast-math and fused multiply/add
25693 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
25695 enum machine_mode mode = GET_MODE (dst);
25697 if (!TARGET_FUSED_MADD)
25699 /* For the simple ops, use the generator function, rather than assuming
25700 that the RTL is standard. */
25701 enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code;
25702 enum insn_code scode = optab_handler (sub_optab, mode)->insn_code;
25703 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25704 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
25705 rtx mreg = gen_reg_rtx (mode);
25707 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
25708 emit_insn (gen_mul (mreg, m1, m2));
25709 emit_insn (gen_sub (dst, a, mreg));
25714 rtx m = gen_rtx_MULT (mode, m1, m2);
25716 if (!HONOR_SIGNED_ZEROS (mode))
25717 emit_insn (gen_rtx_SET (VOIDmode, dst, gen_rtx_MINUS (mode, a, m)));
25720 emit_insn (gen_rtx_SET (VOIDmode, dst,
25722 gen_rtx_MINUS (mode, m, a))));
25726 /* Newton-Raphson approximation of floating point divide with just 2 passes
25727 (either single precision floating point, or newer machines with higher
25728 accuracy estimates). Support both scalar and vector divide. Assumes no
25729 trapping math and finite arguments. */
25732 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
25734 enum machine_mode mode = GET_MODE (dst);
25735 rtx x0, e0, e1, y1, u0, v0;
25736 enum insn_code code = optab_handler (smul_optab, mode)->insn_code;
25737 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25738 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
25740 gcc_assert (code != CODE_FOR_nothing);
25742 /* x0 = 1./d estimate */
25743 x0 = gen_reg_rtx (mode);
25744 emit_insn (gen_rtx_SET (VOIDmode, x0,
25745 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
25748 e0 = gen_reg_rtx (mode);
25749 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
25751 e1 = gen_reg_rtx (mode);
25752 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
25754 y1 = gen_reg_rtx (mode);
25755 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
25757 u0 = gen_reg_rtx (mode);
25758 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
25760 v0 = gen_reg_rtx (mode);
25761 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
25763 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
25766 /* Newton-Raphson approximation of floating point divide that has a low
25767 precision estimate. Assumes no trapping math and finite arguments. */
25770 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
25772 enum machine_mode mode = GET_MODE (dst);
25773 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
25774 enum insn_code code = optab_handler (smul_optab, mode)->insn_code;
25775 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25777 gcc_assert (code != CODE_FOR_nothing);
25779 one = rs6000_load_constant_and_splat (mode, dconst1);
25781 /* x0 = 1./d estimate */
25782 x0 = gen_reg_rtx (mode);
25783 emit_insn (gen_rtx_SET (VOIDmode, x0,
25784 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
25787 e0 = gen_reg_rtx (mode);
25788 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
25790 y1 = gen_reg_rtx (mode);
25791 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
25793 e1 = gen_reg_rtx (mode);
25794 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
25796 y2 = gen_reg_rtx (mode);
25797 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
25799 e2 = gen_reg_rtx (mode);
25800 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
25802 y3 = gen_reg_rtx (mode);
25803 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
25805 u0 = gen_reg_rtx (mode);
25806 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
25808 v0 = gen_reg_rtx (mode);
25809 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
25811 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
25814 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
25815 add a reg_note saying that this was a division. Support both scalar and
25816 vector divide. Assumes no trapping math and finite arguments. */
25819 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
25821 enum machine_mode mode = GET_MODE (dst);
25823 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
25824 rs6000_emit_swdiv_high_precision (dst, n, d);
25826 rs6000_emit_swdiv_low_precision (dst, n, d);
25829 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
25832 /* Newton-Raphson approximation of single/double-precision floating point
25833 rsqrt. Assumes no trapping math and finite arguments. */
25836 rs6000_emit_swrsqrt (rtx dst, rtx src)
25838 enum machine_mode mode = GET_MODE (src);
25839 rtx x0 = gen_reg_rtx (mode);
25840 rtx y = gen_reg_rtx (mode);
25841 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
25842 REAL_VALUE_TYPE dconst3_2;
25845 enum insn_code code = optab_handler (smul_optab, mode)->insn_code;
25846 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25848 gcc_assert (code != CODE_FOR_nothing);
25850 /* Load up the constant 1.5 either as a scalar, or as a vector. */
25851 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
25852 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
25854 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
25856 /* x0 = rsqrt estimate */
25857 emit_insn (gen_rtx_SET (VOIDmode, x0,
25858 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
25861 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
25862 rs6000_emit_msub (y, src, halfthree, src);
25864 for (i = 0; i < passes; i++)
25866 rtx x1 = gen_reg_rtx (mode);
25867 rtx u = gen_reg_rtx (mode);
25868 rtx v = gen_reg_rtx (mode);
25870 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
25871 emit_insn (gen_mul (u, x0, x0));
25872 rs6000_emit_nmsub (v, y, u, halfthree);
25873 emit_insn (gen_mul (x1, x0, v));
25877 emit_move_insn (dst, x0);
25881 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
25882 (Power7) targets. DST is the target, and SRC is the argument operand. */
25885 rs6000_emit_popcount (rtx dst, rtx src)
25887 enum machine_mode mode = GET_MODE (dst);
25890 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
25891 if (TARGET_POPCNTD)
25893 if (mode == SImode)
25894 emit_insn (gen_popcntwsi2 (dst, src));
25896 emit_insn (gen_popcntddi2 (dst, src));
25900 tmp1 = gen_reg_rtx (mode);
25902 if (mode == SImode)
25904 emit_insn (gen_popcntbsi2 (tmp1, src));
25905 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
25907 tmp2 = force_reg (SImode, tmp2);
25908 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
25912 emit_insn (gen_popcntbdi2 (tmp1, src));
25913 tmp2 = expand_mult (DImode, tmp1,
25914 GEN_INT ((HOST_WIDE_INT)
25915 0x01010101 << 32 | 0x01010101),
25917 tmp2 = force_reg (DImode, tmp2);
25918 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
25923 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25924 target, and SRC is the argument operand. */
25927 rs6000_emit_parity (rtx dst, rtx src)
25929 enum machine_mode mode = GET_MODE (dst);
25932 tmp = gen_reg_rtx (mode);
25933 if (mode == SImode)
25935 /* Is mult+shift >= shift+xor+shift+xor? */
25936 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
25938 rtx tmp1, tmp2, tmp3, tmp4;
25940 tmp1 = gen_reg_rtx (SImode);
25941 emit_insn (gen_popcntbsi2 (tmp1, src));
25943 tmp2 = gen_reg_rtx (SImode);
25944 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
25945 tmp3 = gen_reg_rtx (SImode);
25946 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
25948 tmp4 = gen_reg_rtx (SImode);
25949 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
25950 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
25953 rs6000_emit_popcount (tmp, src);
25954 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
25958 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25959 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
25961 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
25963 tmp1 = gen_reg_rtx (DImode);
25964 emit_insn (gen_popcntbdi2 (tmp1, src));
25966 tmp2 = gen_reg_rtx (DImode);
25967 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
25968 tmp3 = gen_reg_rtx (DImode);
25969 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
25971 tmp4 = gen_reg_rtx (DImode);
25972 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
25973 tmp5 = gen_reg_rtx (DImode);
25974 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
25976 tmp6 = gen_reg_rtx (DImode);
25977 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
25978 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
25981 rs6000_emit_popcount (tmp, src);
25982 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
25986 /* Return an RTX representing where to find the function value of a
25987 function returning MODE. */
25989 rs6000_complex_function_value (enum machine_mode mode)
25991 unsigned int regno;
25993 enum machine_mode inner = GET_MODE_INNER (mode);
25994 unsigned int inner_bytes = GET_MODE_SIZE (inner);
25996 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25997 regno = FP_ARG_RETURN;
26000 regno = GP_ARG_RETURN;
26002 /* 32-bit is OK since it'll go in r3/r4. */
26003 if (TARGET_32BIT && inner_bytes >= 4)
26004 return gen_rtx_REG (mode, regno);
26007 if (inner_bytes >= 8)
26008 return gen_rtx_REG (mode, regno);
26010 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26012 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26013 GEN_INT (inner_bytes));
26014 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26017 /* Target hook for TARGET_FUNCTION_VALUE.
26019 On the SPE, both FPs and vectors are returned in r3.
26021 On RS/6000 an integer value is in r3 and a floating-point value is in
26022 fp1, unless -msoft-float. */
26025 rs6000_function_value (const_tree valtype,
26026 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26027 bool outgoing ATTRIBUTE_UNUSED)
26029 enum machine_mode mode;
26030 unsigned int regno;
26032 /* Special handling for structs in darwin64. */
26033 if (rs6000_darwin64_abi
26034 && TYPE_MODE (valtype) == BLKmode
26035 && TREE_CODE (valtype) == RECORD_TYPE
26036 && int_size_in_bytes (valtype) > 0)
26038 CUMULATIVE_ARGS valcum;
26042 valcum.fregno = FP_ARG_MIN_REG;
26043 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26044 /* Do a trial code generation as if this were going to be passed as
26045 an argument; if any part goes in memory, we return NULL. */
26046 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
26049 /* Otherwise fall through to standard ABI rules. */
26052 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26054 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26055 return gen_rtx_PARALLEL (DImode,
26057 gen_rtx_EXPR_LIST (VOIDmode,
26058 gen_rtx_REG (SImode, GP_ARG_RETURN),
26060 gen_rtx_EXPR_LIST (VOIDmode,
26061 gen_rtx_REG (SImode,
26062 GP_ARG_RETURN + 1),
26065 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26067 return gen_rtx_PARALLEL (DCmode,
26069 gen_rtx_EXPR_LIST (VOIDmode,
26070 gen_rtx_REG (SImode, GP_ARG_RETURN),
26072 gen_rtx_EXPR_LIST (VOIDmode,
26073 gen_rtx_REG (SImode,
26074 GP_ARG_RETURN + 1),
26076 gen_rtx_EXPR_LIST (VOIDmode,
26077 gen_rtx_REG (SImode,
26078 GP_ARG_RETURN + 2),
26080 gen_rtx_EXPR_LIST (VOIDmode,
26081 gen_rtx_REG (SImode,
26082 GP_ARG_RETURN + 3),
26086 mode = TYPE_MODE (valtype);
26087 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26088 || POINTER_TYPE_P (valtype))
26089 mode = TARGET_32BIT ? SImode : DImode;
26091 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26092 /* _Decimal128 must use an even/odd register pair. */
26093 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26094 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26095 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26096 regno = FP_ARG_RETURN;
26097 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26098 && targetm.calls.split_complex_arg)
26099 return rs6000_complex_function_value (mode);
26100 else if (TREE_CODE (valtype) == VECTOR_TYPE
26101 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26102 && ALTIVEC_VECTOR_MODE (mode))
26103 regno = ALTIVEC_ARG_RETURN;
26104 else if (TREE_CODE (valtype) == VECTOR_TYPE
26105 && TARGET_VSX && TARGET_ALTIVEC_ABI
26106 && VSX_VECTOR_MODE (mode))
26107 regno = ALTIVEC_ARG_RETURN;
26108 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26109 && (mode == DFmode || mode == DCmode
26110 || mode == TFmode || mode == TCmode))
26111 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26113 regno = GP_ARG_RETURN;
26115 return gen_rtx_REG (mode, regno);
26118 /* Define how to find the value returned by a library function
26119 assuming the value has mode MODE. */
26121 rs6000_libcall_value (enum machine_mode mode)
26123 unsigned int regno;
26125 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26127 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26128 return gen_rtx_PARALLEL (DImode,
26130 gen_rtx_EXPR_LIST (VOIDmode,
26131 gen_rtx_REG (SImode, GP_ARG_RETURN),
26133 gen_rtx_EXPR_LIST (VOIDmode,
26134 gen_rtx_REG (SImode,
26135 GP_ARG_RETURN + 1),
26139 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26140 /* _Decimal128 must use an even/odd register pair. */
26141 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26142 else if (SCALAR_FLOAT_MODE_P (mode)
26143 && TARGET_HARD_FLOAT && TARGET_FPRS
26144 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26145 regno = FP_ARG_RETURN;
26146 else if (ALTIVEC_VECTOR_MODE (mode)
26147 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26148 regno = ALTIVEC_ARG_RETURN;
26149 else if (VSX_VECTOR_MODE (mode)
26150 && TARGET_VSX && TARGET_ALTIVEC_ABI)
26151 regno = ALTIVEC_ARG_RETURN;
26152 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26153 return rs6000_complex_function_value (mode);
26154 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26155 && (mode == DFmode || mode == DCmode
26156 || mode == TFmode || mode == TCmode))
26157 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26159 regno = GP_ARG_RETURN;
26161 return gen_rtx_REG (mode, regno);
26165 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26166 Frame pointer elimination is automatically handled.
26168 For the RS/6000, if frame pointer elimination is being done, we would like
26169 to convert ap into fp, not sp.
26171 We need r30 if -mminimal-toc was specified, and there are constant pool
26175 rs6000_can_eliminate (const int from, const int to)
26177 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26178 ? ! frame_pointer_needed
26179 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26180 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26184 /* Define the offset between two registers, FROM to be eliminated and its
26185 replacement TO, at the start of a routine. */
26187 rs6000_initial_elimination_offset (int from, int to)
26189 rs6000_stack_t *info = rs6000_stack_info ();
26190 HOST_WIDE_INT offset;
26192 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26193 offset = info->push_p ? 0 : -info->total_size;
26194 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26196 offset = info->push_p ? 0 : -info->total_size;
26197 if (FRAME_GROWS_DOWNWARD)
26198 offset += info->fixed_size + info->vars_size + info->parm_size;
26200 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26201 offset = FRAME_GROWS_DOWNWARD
26202 ? info->fixed_size + info->vars_size + info->parm_size
26204 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26205 offset = info->total_size;
26206 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26207 offset = info->push_p ? info->total_size : 0;
26208 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26211 gcc_unreachable ();
26217 rs6000_dwarf_register_span (rtx reg)
26221 unsigned regno = REGNO (reg);
26222 enum machine_mode mode = GET_MODE (reg);
26226 && (SPE_VECTOR_MODE (GET_MODE (reg))
26227 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26228 && mode != SFmode && mode != SDmode && mode != SCmode)))
26233 regno = REGNO (reg);
26235 /* The duality of the SPE register size wreaks all kinds of havoc.
26236 This is a way of distinguishing r0 in 32-bits from r0 in
26238 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26239 gcc_assert (words <= 4);
26240 for (i = 0; i < words; i++, regno++)
26242 if (BYTES_BIG_ENDIAN)
26244 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26245 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
26249 parts[2 * i] = gen_rtx_REG (SImode, regno);
26250 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
26254 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
26257 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26260 rs6000_init_dwarf_reg_sizes_extra (tree address)
26265 enum machine_mode mode = TYPE_MODE (char_type_node);
26266 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
26267 rtx mem = gen_rtx_MEM (BLKmode, addr);
26268 rtx value = gen_int_mode (4, mode);
26270 for (i = 1201; i < 1232; i++)
26272 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
26273 HOST_WIDE_INT offset
26274 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
26276 emit_move_insn (adjust_address (mem, mode, offset), value);
26281 /* Map internal gcc register numbers to DWARF2 register numbers. */
26284 rs6000_dbx_register_number (unsigned int regno)
26286 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
26288 if (regno == MQ_REGNO)
26290 if (regno == LR_REGNO)
26292 if (regno == CTR_REGNO)
26294 if (CR_REGNO_P (regno))
26295 return regno - CR0_REGNO + 86;
26296 if (regno == CA_REGNO)
26297 return 101; /* XER */
26298 if (ALTIVEC_REGNO_P (regno))
26299 return regno - FIRST_ALTIVEC_REGNO + 1124;
26300 if (regno == VRSAVE_REGNO)
26302 if (regno == VSCR_REGNO)
26304 if (regno == SPE_ACC_REGNO)
26306 if (regno == SPEFSCR_REGNO)
26308 /* SPE high reg number. We get these values of regno from
26309 rs6000_dwarf_register_span. */
26310 gcc_assert (regno >= 1200 && regno < 1232);
26314 /* target hook eh_return_filter_mode */
26315 static enum machine_mode
26316 rs6000_eh_return_filter_mode (void)
26318 return TARGET_32BIT ? SImode : word_mode;
26321 /* Target hook for scalar_mode_supported_p. */
26323 rs6000_scalar_mode_supported_p (enum machine_mode mode)
26325 if (DECIMAL_FLOAT_MODE_P (mode))
26326 return default_decimal_float_supported_p ();
26328 return default_scalar_mode_supported_p (mode);
26331 /* Target hook for vector_mode_supported_p. */
26333 rs6000_vector_mode_supported_p (enum machine_mode mode)
26336 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
26339 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
26342 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
26349 /* Target hook for invalid_arg_for_unprototyped_fn. */
26350 static const char *
26351 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
26353 return (!rs6000_darwin64_abi
26355 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
26356 && (funcdecl == NULL_TREE
26357 || (TREE_CODE (funcdecl) == FUNCTION_DECL
26358 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
26359 ? N_("AltiVec argument passed to unprototyped function")
26363 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
26364 setup by using __stack_chk_fail_local hidden function instead of
26365 calling __stack_chk_fail directly. Otherwise it is better to call
26366 __stack_chk_fail directly. */
26369 rs6000_stack_protect_fail (void)
26371 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
26372 ? default_hidden_stack_protect_fail ()
26373 : default_external_stack_protect_fail ();
26377 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
26378 int num_operands ATTRIBUTE_UNUSED)
26380 if (rs6000_warn_cell_microcode)
26383 int insn_code_number = recog_memoized (insn);
26384 location_t location = locator_location (INSN_LOCATOR (insn));
26386 /* Punt on insns we cannot recognize. */
26387 if (insn_code_number < 0)
26390 temp = get_insn_template (insn_code_number, insn);
26392 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
26393 warning_at (location, OPT_mwarn_cell_microcode,
26394 "emitting microcode insn %s\t[%s] #%d",
26395 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
26396 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
26397 warning_at (location, OPT_mwarn_cell_microcode,
26398 "emitting conditional microcode insn %s\t[%s] #%d",
26399 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
26403 #include "gt-rs6000.h"