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 reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1245 struct secondary_reload_info *);
1247 static const reg_class_t *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
13732 rs6000_secondary_reload (bool in_p,
13734 reg_class_t rclass_i,
13735 enum machine_mode mode,
13736 secondary_reload_info *sri)
13738 enum reg_class rclass = (enum reg_class) rclass_i;
13739 reg_class_t ret = ALL_REGS;
13740 enum insn_code icode;
13741 bool default_p = false;
13743 sri->icode = CODE_FOR_nothing;
13745 /* Convert vector loads and stores into gprs to use an additional base
13747 icode = rs6000_vector_reload[mode][in_p != false];
13748 if (icode != CODE_FOR_nothing)
13751 sri->icode = CODE_FOR_nothing;
13752 sri->extra_cost = 0;
13754 if (GET_CODE (x) == MEM)
13756 rtx addr = XEXP (x, 0);
13758 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13759 an extra register in that case, but it would need an extra
13760 register if the addressing is reg+reg or (reg+reg)&(-16). */
13761 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13763 if (!legitimate_indirect_address_p (addr, false)
13764 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13766 sri->icode = icode;
13767 /* account for splitting the loads, and converting the
13768 address from reg+reg to reg. */
13769 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13770 + ((GET_CODE (addr) == AND) ? 1 : 0));
13773 /* Loads to and stores from vector registers can only do reg+reg
13774 addressing. Altivec registers can also do (reg+reg)&(-16). */
13775 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13776 || rclass == FLOAT_REGS || rclass == NO_REGS)
13778 if (!VECTOR_MEM_ALTIVEC_P (mode)
13779 && GET_CODE (addr) == AND
13780 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13781 && INTVAL (XEXP (addr, 1)) == -16
13782 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13783 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13785 sri->icode = icode;
13786 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13789 else if (!legitimate_indirect_address_p (addr, false)
13790 && (rclass == NO_REGS
13791 || !legitimate_indexed_address_p (addr, false)))
13793 sri->icode = icode;
13794 sri->extra_cost = 1;
13797 icode = CODE_FOR_nothing;
13799 /* Any other loads, including to pseudo registers which haven't been
13800 assigned to a register yet, default to require a scratch
13804 sri->icode = icode;
13805 sri->extra_cost = 2;
13808 else if (REG_P (x))
13810 int regno = true_regnum (x);
13812 icode = CODE_FOR_nothing;
13813 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13817 enum reg_class xclass = REGNO_REG_CLASS (regno);
13818 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13819 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13821 /* If memory is needed, use default_secondary_reload to create the
13823 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13836 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13838 gcc_assert (ret != ALL_REGS);
13840 if (TARGET_DEBUG_ADDR)
13843 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13845 reg_class_names[ret],
13846 in_p ? "true" : "false",
13847 reg_class_names[rclass],
13848 GET_MODE_NAME (mode));
13851 fprintf (stderr, ", default secondary reload");
13853 if (sri->icode != CODE_FOR_nothing)
13854 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13855 insn_data[sri->icode].name, sri->extra_cost);
13857 fprintf (stderr, "\n");
13865 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13866 to SP+reg addressing. */
13869 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13871 int regno = true_regnum (reg);
13872 enum machine_mode mode = GET_MODE (reg);
13873 enum reg_class rclass;
13875 rtx and_op2 = NULL_RTX;
13878 rtx scratch_or_premodify = scratch;
13882 if (TARGET_DEBUG_ADDR)
13884 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13885 store_p ? "store" : "load");
13886 fprintf (stderr, "reg:\n");
13888 fprintf (stderr, "mem:\n");
13890 fprintf (stderr, "scratch:\n");
13891 debug_rtx (scratch);
13894 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13895 gcc_assert (GET_CODE (mem) == MEM);
13896 rclass = REGNO_REG_CLASS (regno);
13897 addr = XEXP (mem, 0);
13901 /* GPRs can handle reg + small constant, all other addresses need to use
13902 the scratch register. */
13905 if (GET_CODE (addr) == AND)
13907 and_op2 = XEXP (addr, 1);
13908 addr = XEXP (addr, 0);
13911 if (GET_CODE (addr) == PRE_MODIFY)
13913 scratch_or_premodify = XEXP (addr, 0);
13914 gcc_assert (REG_P (scratch_or_premodify));
13915 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13916 addr = XEXP (addr, 1);
13919 if (GET_CODE (addr) == PLUS
13920 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13921 || and_op2 != NULL_RTX))
13923 addr_op1 = XEXP (addr, 0);
13924 addr_op2 = XEXP (addr, 1);
13925 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13927 if (!REG_P (addr_op2)
13928 && (GET_CODE (addr_op2) != CONST_INT
13929 || !satisfies_constraint_I (addr_op2)))
13931 if (TARGET_DEBUG_ADDR)
13934 "\nMove plus addr to register %s, mode = %s: ",
13935 rs6000_reg_names[REGNO (scratch)],
13936 GET_MODE_NAME (mode));
13937 debug_rtx (addr_op2);
13939 rs6000_emit_move (scratch, addr_op2, Pmode);
13940 addr_op2 = scratch;
13943 emit_insn (gen_rtx_SET (VOIDmode,
13944 scratch_or_premodify,
13945 gen_rtx_PLUS (Pmode,
13949 addr = scratch_or_premodify;
13950 scratch_or_premodify = scratch;
13952 else if (!legitimate_indirect_address_p (addr, false)
13953 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13955 if (TARGET_DEBUG_ADDR)
13957 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13958 rs6000_reg_names[REGNO (scratch_or_premodify)],
13959 GET_MODE_NAME (mode));
13962 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13963 addr = scratch_or_premodify;
13964 scratch_or_premodify = scratch;
13968 /* Float/Altivec registers can only handle reg+reg addressing. Move
13969 other addresses into a scratch register. */
13974 /* With float regs, we need to handle the AND ourselves, since we can't
13975 use the Altivec instruction with an implicit AND -16. Allow scalar
13976 loads to float registers to use reg+offset even if VSX. */
13977 if (GET_CODE (addr) == AND
13978 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13979 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13980 || INTVAL (XEXP (addr, 1)) != -16
13981 || !VECTOR_MEM_ALTIVEC_P (mode)))
13983 and_op2 = XEXP (addr, 1);
13984 addr = XEXP (addr, 0);
13987 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13988 as the address later. */
13989 if (GET_CODE (addr) == PRE_MODIFY
13990 && (!VECTOR_MEM_VSX_P (mode)
13991 || and_op2 != NULL_RTX
13992 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13994 scratch_or_premodify = XEXP (addr, 0);
13995 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13997 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13998 addr = XEXP (addr, 1);
14001 if (legitimate_indirect_address_p (addr, false) /* reg */
14002 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14003 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14004 || (GET_CODE (addr) == AND /* Altivec memory */
14005 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14006 && INTVAL (XEXP (addr, 1)) == -16
14007 && VECTOR_MEM_ALTIVEC_P (mode))
14008 || (rclass == FLOAT_REGS /* legacy float mem */
14009 && GET_MODE_SIZE (mode) == 8
14010 && and_op2 == NULL_RTX
14011 && scratch_or_premodify == scratch
14012 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14015 else if (GET_CODE (addr) == PLUS)
14017 addr_op1 = XEXP (addr, 0);
14018 addr_op2 = XEXP (addr, 1);
14019 gcc_assert (REG_P (addr_op1));
14021 if (TARGET_DEBUG_ADDR)
14023 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14024 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14025 debug_rtx (addr_op2);
14027 rs6000_emit_move (scratch, addr_op2, Pmode);
14028 emit_insn (gen_rtx_SET (VOIDmode,
14029 scratch_or_premodify,
14030 gen_rtx_PLUS (Pmode,
14033 addr = scratch_or_premodify;
14034 scratch_or_premodify = scratch;
14037 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14038 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14040 if (TARGET_DEBUG_ADDR)
14042 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14043 rs6000_reg_names[REGNO (scratch_or_premodify)],
14044 GET_MODE_NAME (mode));
14048 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14049 addr = scratch_or_premodify;
14050 scratch_or_premodify = scratch;
14054 gcc_unreachable ();
14059 gcc_unreachable ();
14062 /* If the original address involved a pre-modify that we couldn't use the VSX
14063 memory instruction with update, and we haven't taken care of already,
14064 store the address in the pre-modify register and use that as the
14066 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14068 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14069 addr = scratch_or_premodify;
14072 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14073 memory instruction, recreate the AND now, including the clobber which is
14074 generated by the general ANDSI3/ANDDI3 patterns for the
14075 andi. instruction. */
14076 if (and_op2 != NULL_RTX)
14078 if (! legitimate_indirect_address_p (addr, false))
14080 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14084 if (TARGET_DEBUG_ADDR)
14086 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14087 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14088 debug_rtx (and_op2);
14091 and_rtx = gen_rtx_SET (VOIDmode,
14093 gen_rtx_AND (Pmode,
14097 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14098 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14099 gen_rtvec (2, and_rtx, cc_clobber)));
14103 /* Adjust the address if it changed. */
14104 if (addr != XEXP (mem, 0))
14106 mem = change_address (mem, mode, addr);
14107 if (TARGET_DEBUG_ADDR)
14108 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14111 /* Now create the move. */
14113 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14115 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14120 /* Target hook to return the cover classes for Integrated Register Allocator.
14121 Cover classes is a set of non-intersected register classes covering all hard
14122 registers used for register allocation purpose. Any move between two
14123 registers of a cover class should be cheaper than load or store of the
14124 registers. The value is array of register classes with LIM_REG_CLASSES used
14127 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14128 account for the Altivec and Floating registers being subsets of the VSX
14129 register set under VSX, but distinct register sets on pre-VSX machines. */
14131 static const reg_class_t *
14132 rs6000_ira_cover_classes (void)
14134 static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
14135 static const reg_class_t cover_vsx[] = IRA_COVER_CLASSES_VSX;
14137 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
14140 /* Allocate a 64-bit stack slot to be used for copying SDmode
14141 values through if this function has any SDmode references. */
14144 rs6000_alloc_sdmode_stack_slot (void)
14148 gimple_stmt_iterator gsi;
14150 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14153 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14155 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14158 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14159 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14165 /* Check for any SDmode parameters of the function. */
14166 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
14168 if (TREE_TYPE (t) == error_mark_node)
14171 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14172 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14174 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14175 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14183 rs6000_instantiate_decls (void)
14185 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14186 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14189 /* Given an rtx X being reloaded into a reg required to be
14190 in class CLASS, return the class of reg to actually use.
14191 In general this is just CLASS; but on some machines
14192 in some cases it is preferable to use a more restrictive class.
14194 On the RS/6000, we have to return NO_REGS when we want to reload a
14195 floating-point CONST_DOUBLE to force it to be copied to memory.
14197 We also don't want to reload integer values into floating-point
14198 registers if we can at all help it. In fact, this can
14199 cause reload to die, if it tries to generate a reload of CTR
14200 into a FP register and discovers it doesn't have the memory location
14203 ??? Would it be a good idea to have reload do the converse, that is
14204 try to reload floating modes into FP registers if possible?
14207 static enum reg_class
14208 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14210 enum machine_mode mode = GET_MODE (x);
14212 if (VECTOR_UNIT_VSX_P (mode)
14213 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14216 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14217 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14218 && easy_vector_constant (x, mode))
14219 return ALTIVEC_REGS;
14221 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14224 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14225 return GENERAL_REGS;
14227 /* For VSX, prefer the traditional registers for 64-bit values because we can
14228 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14229 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14230 prefer Altivec loads.. */
14231 if (rclass == VSX_REGS)
14233 if (GET_MODE_SIZE (mode) <= 8)
14236 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14237 return ALTIVEC_REGS;
14245 /* Debug version of rs6000_preferred_reload_class. */
14246 static enum reg_class
14247 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14249 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14252 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14254 reg_class_names[ret], reg_class_names[rclass],
14255 GET_MODE_NAME (GET_MODE (x)));
14261 /* If we are copying between FP or AltiVec registers and anything else, we need
14262 a memory location. The exception is when we are targeting ppc64 and the
14263 move to/from fpr to gpr instructions are available. Also, under VSX, you
14264 can copy vector registers from the FP register set to the Altivec register
14265 set and vice versa. */
14268 rs6000_secondary_memory_needed (enum reg_class class1,
14269 enum reg_class class2,
14270 enum machine_mode mode)
14272 if (class1 == class2)
14275 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14276 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14277 between these classes. But we need memory for other things that can go in
14278 FLOAT_REGS like SFmode. */
14280 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14281 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14282 || class1 == FLOAT_REGS))
14283 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14284 && class2 != FLOAT_REGS);
14286 if (class1 == VSX_REGS || class2 == VSX_REGS)
14289 if (class1 == FLOAT_REGS
14290 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14291 || ((mode != DFmode)
14292 && (mode != DDmode)
14293 && (mode != DImode))))
14296 if (class2 == FLOAT_REGS
14297 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14298 || ((mode != DFmode)
14299 && (mode != DDmode)
14300 && (mode != DImode))))
14303 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14309 /* Debug version of rs6000_secondary_memory_needed. */
14311 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14312 enum reg_class class2,
14313 enum machine_mode mode)
14315 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14318 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14319 "class2 = %s, mode = %s\n",
14320 ret ? "true" : "false", reg_class_names[class1],
14321 reg_class_names[class2], GET_MODE_NAME (mode));
14326 /* Return the register class of a scratch register needed to copy IN into
14327 or out of a register in RCLASS in MODE. If it can be done directly,
14328 NO_REGS is returned. */
14330 static enum reg_class
14331 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14336 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14338 && MACHOPIC_INDIRECT
14342 /* We cannot copy a symbolic operand directly into anything
14343 other than BASE_REGS for TARGET_ELF. So indicate that a
14344 register from BASE_REGS is needed as an intermediate
14347 On Darwin, pic addresses require a load from memory, which
14348 needs a base register. */
14349 if (rclass != BASE_REGS
14350 && (GET_CODE (in) == SYMBOL_REF
14351 || GET_CODE (in) == HIGH
14352 || GET_CODE (in) == LABEL_REF
14353 || GET_CODE (in) == CONST))
14357 if (GET_CODE (in) == REG)
14359 regno = REGNO (in);
14360 if (regno >= FIRST_PSEUDO_REGISTER)
14362 regno = true_regnum (in);
14363 if (regno >= FIRST_PSEUDO_REGISTER)
14367 else if (GET_CODE (in) == SUBREG)
14369 regno = true_regnum (in);
14370 if (regno >= FIRST_PSEUDO_REGISTER)
14376 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14378 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14379 || (regno >= 0 && INT_REGNO_P (regno)))
14382 /* Constants, memory, and FP registers can go into FP registers. */
14383 if ((regno == -1 || FP_REGNO_P (regno))
14384 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14385 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14387 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14390 && (regno == -1 || VSX_REGNO_P (regno))
14391 && VSX_REG_CLASS_P (rclass))
14394 /* Memory, and AltiVec registers can go into AltiVec registers. */
14395 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14396 && rclass == ALTIVEC_REGS)
14399 /* We can copy among the CR registers. */
14400 if ((rclass == CR_REGS || rclass == CR0_REGS)
14401 && regno >= 0 && CR_REGNO_P (regno))
14404 /* Otherwise, we need GENERAL_REGS. */
14405 return GENERAL_REGS;
14408 /* Debug version of rs6000_secondary_reload_class. */
14409 static enum reg_class
14410 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14411 enum machine_mode mode, rtx in)
14413 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14415 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14416 "mode = %s, input rtx:\n",
14417 reg_class_names[ret], reg_class_names[rclass],
14418 GET_MODE_NAME (mode));
14424 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14427 rs6000_cannot_change_mode_class (enum machine_mode from,
14428 enum machine_mode to,
14429 enum reg_class rclass)
14431 unsigned from_size = GET_MODE_SIZE (from);
14432 unsigned to_size = GET_MODE_SIZE (to);
14434 if (from_size != to_size)
14436 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14437 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14438 && reg_classes_intersect_p (xclass, rclass));
14441 if (TARGET_E500_DOUBLE
14442 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14443 || (((to) == TFmode) + ((from) == TFmode)) == 1
14444 || (((to) == DDmode) + ((from) == DDmode)) == 1
14445 || (((to) == TDmode) + ((from) == TDmode)) == 1
14446 || (((to) == DImode) + ((from) == DImode)) == 1))
14449 /* Since the VSX register set includes traditional floating point registers
14450 and altivec registers, just check for the size being different instead of
14451 trying to check whether the modes are vector modes. Otherwise it won't
14452 allow say DF and DI to change classes. */
14453 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14454 return (from_size != 8 && from_size != 16);
14456 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14457 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14460 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14461 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14467 /* Debug version of rs6000_cannot_change_mode_class. */
14469 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14470 enum machine_mode to,
14471 enum reg_class rclass)
14473 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
14476 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14477 "to = %s, rclass = %s\n",
14478 ret ? "true" : "false",
14479 GET_MODE_NAME (from), GET_MODE_NAME (to),
14480 reg_class_names[rclass]);
14485 /* Given a comparison operation, return the bit number in CCR to test. We
14486 know this is a valid comparison.
14488 SCC_P is 1 if this is for an scc. That means that %D will have been
14489 used instead of %C, so the bits will be in different places.
14491 Return -1 if OP isn't a valid comparison for some reason. */
14494 ccr_bit (rtx op, int scc_p)
14496 enum rtx_code code = GET_CODE (op);
14497 enum machine_mode cc_mode;
14502 if (!COMPARISON_P (op))
14505 reg = XEXP (op, 0);
14507 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14509 cc_mode = GET_MODE (reg);
14510 cc_regnum = REGNO (reg);
14511 base_bit = 4 * (cc_regnum - CR0_REGNO);
14513 validate_condition_mode (code, cc_mode);
14515 /* When generating a sCOND operation, only positive conditions are
14518 || code == EQ || code == GT || code == LT || code == UNORDERED
14519 || code == GTU || code == LTU);
14524 return scc_p ? base_bit + 3 : base_bit + 2;
14526 return base_bit + 2;
14527 case GT: case GTU: case UNLE:
14528 return base_bit + 1;
14529 case LT: case LTU: case UNGE:
14531 case ORDERED: case UNORDERED:
14532 return base_bit + 3;
14535 /* If scc, we will have done a cror to put the bit in the
14536 unordered position. So test that bit. For integer, this is ! LT
14537 unless this is an scc insn. */
14538 return scc_p ? base_bit + 3 : base_bit;
14541 return scc_p ? base_bit + 3 : base_bit + 1;
14544 gcc_unreachable ();
14548 /* Return the GOT register. */
14551 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
14553 /* The second flow pass currently (June 1999) can't update
14554 regs_ever_live without disturbing other parts of the compiler, so
14555 update it here to make the prolog/epilogue code happy. */
14556 if (!can_create_pseudo_p ()
14557 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
14558 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
14560 crtl->uses_pic_offset_table = 1;
14562 return pic_offset_table_rtx;
14565 /* Function to init struct machine_function.
14566 This will be called, via a pointer variable,
14567 from push_function_context. */
14569 static struct machine_function *
14570 rs6000_init_machine_status (void)
14572 return ggc_alloc_cleared_machine_function ();
14575 /* These macros test for integers and extract the low-order bits. */
14577 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
14578 && GET_MODE (X) == VOIDmode)
14580 #define INT_LOWPART(X) \
14581 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
14584 extract_MB (rtx op)
14587 unsigned long val = INT_LOWPART (op);
14589 /* If the high bit is zero, the value is the first 1 bit we find
14591 if ((val & 0x80000000) == 0)
14593 gcc_assert (val & 0xffffffff);
14596 while (((val <<= 1) & 0x80000000) == 0)
14601 /* If the high bit is set and the low bit is not, or the mask is all
14602 1's, the value is zero. */
14603 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14606 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14609 while (((val >>= 1) & 1) != 0)
14616 extract_ME (rtx op)
14619 unsigned long val = INT_LOWPART (op);
14621 /* If the low bit is zero, the value is the first 1 bit we find from
14623 if ((val & 1) == 0)
14625 gcc_assert (val & 0xffffffff);
14628 while (((val >>= 1) & 1) == 0)
14634 /* If the low bit is set and the high bit is not, or the mask is all
14635 1's, the value is 31. */
14636 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14639 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14642 while (((val <<= 1) & 0x80000000) != 0)
14648 /* Locate some local-dynamic symbol still in use by this function
14649 so that we can print its name in some tls_ld pattern. */
14651 static const char *
14652 rs6000_get_some_local_dynamic_name (void)
14656 if (cfun->machine->some_ld_name)
14657 return cfun->machine->some_ld_name;
14659 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14661 && for_each_rtx (&PATTERN (insn),
14662 rs6000_get_some_local_dynamic_name_1, 0))
14663 return cfun->machine->some_ld_name;
14665 gcc_unreachable ();
14668 /* Helper function for rs6000_get_some_local_dynamic_name. */
14671 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14675 if (GET_CODE (x) == SYMBOL_REF)
14677 const char *str = XSTR (x, 0);
14678 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14680 cfun->machine->some_ld_name = str;
14688 /* Write out a function code label. */
14691 rs6000_output_function_entry (FILE *file, const char *fname)
14693 if (fname[0] != '.')
14695 switch (DEFAULT_ABI)
14698 gcc_unreachable ();
14704 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14713 RS6000_OUTPUT_BASENAME (file, fname);
14716 /* Print an operand. Recognize special options, documented below. */
14719 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14720 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14722 #define SMALL_DATA_RELOC "sda21"
14723 #define SMALL_DATA_REG 0
14727 print_operand (FILE *file, rtx x, int code)
14731 unsigned HOST_WIDE_INT uval;
14736 /* Write out an instruction after the call which may be replaced
14737 with glue code by the loader. This depends on the AIX version. */
14738 asm_fprintf (file, RS6000_CALL_GLUE);
14741 /* %a is output_address. */
14744 /* If X is a constant integer whose low-order 5 bits are zero,
14745 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14746 in the AIX assembler where "sri" with a zero shift count
14747 writes a trash instruction. */
14748 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14755 /* If constant, low-order 16 bits of constant, unsigned.
14756 Otherwise, write normally. */
14758 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14760 print_operand (file, x, 0);
14764 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14765 for 64-bit mask direction. */
14766 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14769 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14773 /* X is a CR register. Print the number of the GT bit of the CR. */
14774 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14775 output_operand_lossage ("invalid %%c value");
14777 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14781 /* Like 'J' but get to the GT bit only. */
14782 gcc_assert (GET_CODE (x) == REG);
14784 /* Bit 1 is GT bit. */
14785 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14787 /* Add one for shift count in rlinm for scc. */
14788 fprintf (file, "%d", i + 1);
14792 /* X is a CR register. Print the number of the EQ bit of the CR */
14793 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14794 output_operand_lossage ("invalid %%E value");
14796 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14800 /* X is a CR register. Print the shift count needed to move it
14801 to the high-order four bits. */
14802 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14803 output_operand_lossage ("invalid %%f value");
14805 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14809 /* Similar, but print the count for the rotate in the opposite
14811 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14812 output_operand_lossage ("invalid %%F value");
14814 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14818 /* X is a constant integer. If it is negative, print "m",
14819 otherwise print "z". This is to make an aze or ame insn. */
14820 if (GET_CODE (x) != CONST_INT)
14821 output_operand_lossage ("invalid %%G value");
14822 else if (INTVAL (x) >= 0)
14829 /* If constant, output low-order five bits. Otherwise, write
14832 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14834 print_operand (file, x, 0);
14838 /* If constant, output low-order six bits. Otherwise, write
14841 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14843 print_operand (file, x, 0);
14847 /* Print `i' if this is a constant, else nothing. */
14853 /* Write the bit number in CCR for jump. */
14854 i = ccr_bit (x, 0);
14856 output_operand_lossage ("invalid %%j code");
14858 fprintf (file, "%d", i);
14862 /* Similar, but add one for shift count in rlinm for scc and pass
14863 scc flag to `ccr_bit'. */
14864 i = ccr_bit (x, 1);
14866 output_operand_lossage ("invalid %%J code");
14868 /* If we want bit 31, write a shift count of zero, not 32. */
14869 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14873 /* X must be a constant. Write the 1's complement of the
14876 output_operand_lossage ("invalid %%k value");
14878 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14882 /* X must be a symbolic constant on ELF. Write an
14883 expression suitable for an 'addi' that adds in the low 16
14884 bits of the MEM. */
14885 if (GET_CODE (x) == CONST)
14887 if (GET_CODE (XEXP (x, 0)) != PLUS
14888 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14889 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14890 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14891 output_operand_lossage ("invalid %%K value");
14893 print_operand_address (file, x);
14894 fputs ("@l", file);
14897 /* %l is output_asm_label. */
14900 /* Write second word of DImode or DFmode reference. Works on register
14901 or non-indexed memory only. */
14902 if (GET_CODE (x) == REG)
14903 fputs (reg_names[REGNO (x) + 1], file);
14904 else if (GET_CODE (x) == MEM)
14906 /* Handle possible auto-increment. Since it is pre-increment and
14907 we have already done it, we can just use an offset of word. */
14908 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14909 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14910 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14912 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14913 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14916 output_address (XEXP (adjust_address_nv (x, SImode,
14920 if (small_data_operand (x, GET_MODE (x)))
14921 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14922 reg_names[SMALL_DATA_REG]);
14927 /* MB value for a mask operand. */
14928 if (! mask_operand (x, SImode))
14929 output_operand_lossage ("invalid %%m value");
14931 fprintf (file, "%d", extract_MB (x));
14935 /* ME value for a mask operand. */
14936 if (! mask_operand (x, SImode))
14937 output_operand_lossage ("invalid %%M value");
14939 fprintf (file, "%d", extract_ME (x));
14942 /* %n outputs the negative of its operand. */
14945 /* Write the number of elements in the vector times 4. */
14946 if (GET_CODE (x) != PARALLEL)
14947 output_operand_lossage ("invalid %%N value");
14949 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14953 /* Similar, but subtract 1 first. */
14954 if (GET_CODE (x) != PARALLEL)
14955 output_operand_lossage ("invalid %%O value");
14957 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14961 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14963 || INT_LOWPART (x) < 0
14964 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14965 output_operand_lossage ("invalid %%p value");
14967 fprintf (file, "%d", i);
14971 /* The operand must be an indirect memory reference. The result
14972 is the register name. */
14973 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14974 || REGNO (XEXP (x, 0)) >= 32)
14975 output_operand_lossage ("invalid %%P value");
14977 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14981 /* This outputs the logical code corresponding to a boolean
14982 expression. The expression may have one or both operands
14983 negated (if one, only the first one). For condition register
14984 logical operations, it will also treat the negated
14985 CR codes as NOTs, but not handle NOTs of them. */
14987 const char *const *t = 0;
14989 enum rtx_code code = GET_CODE (x);
14990 static const char * const tbl[3][3] = {
14991 { "and", "andc", "nor" },
14992 { "or", "orc", "nand" },
14993 { "xor", "eqv", "xor" } };
14997 else if (code == IOR)
14999 else if (code == XOR)
15002 output_operand_lossage ("invalid %%q value");
15004 if (GET_CODE (XEXP (x, 0)) != NOT)
15008 if (GET_CODE (XEXP (x, 1)) == NOT)
15026 /* X is a CR register. Print the mask for `mtcrf'. */
15027 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15028 output_operand_lossage ("invalid %%R value");
15030 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15034 /* Low 5 bits of 32 - value */
15036 output_operand_lossage ("invalid %%s value");
15038 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15042 /* PowerPC64 mask position. All 0's is excluded.
15043 CONST_INT 32-bit mask is considered sign-extended so any
15044 transition must occur within the CONST_INT, not on the boundary. */
15045 if (! mask64_operand (x, DImode))
15046 output_operand_lossage ("invalid %%S value");
15048 uval = INT_LOWPART (x);
15050 if (uval & 1) /* Clear Left */
15052 #if HOST_BITS_PER_WIDE_INT > 64
15053 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15057 else /* Clear Right */
15060 #if HOST_BITS_PER_WIDE_INT > 64
15061 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15067 gcc_assert (i >= 0);
15068 fprintf (file, "%d", i);
15072 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15073 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15075 /* Bit 3 is OV bit. */
15076 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15078 /* If we want bit 31, write a shift count of zero, not 32. */
15079 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15083 /* Print the symbolic name of a branch target register. */
15084 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15085 && REGNO (x) != CTR_REGNO))
15086 output_operand_lossage ("invalid %%T value");
15087 else if (REGNO (x) == LR_REGNO)
15088 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15090 fputs ("ctr", file);
15094 /* High-order 16 bits of constant for use in unsigned operand. */
15096 output_operand_lossage ("invalid %%u value");
15098 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15099 (INT_LOWPART (x) >> 16) & 0xffff);
15103 /* High-order 16 bits of constant for use in signed operand. */
15105 output_operand_lossage ("invalid %%v value");
15107 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15108 (INT_LOWPART (x) >> 16) & 0xffff);
15112 /* Print `u' if this has an auto-increment or auto-decrement. */
15113 if (GET_CODE (x) == MEM
15114 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15115 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15116 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15121 /* Print the trap code for this operand. */
15122 switch (GET_CODE (x))
15125 fputs ("eq", file); /* 4 */
15128 fputs ("ne", file); /* 24 */
15131 fputs ("lt", file); /* 16 */
15134 fputs ("le", file); /* 20 */
15137 fputs ("gt", file); /* 8 */
15140 fputs ("ge", file); /* 12 */
15143 fputs ("llt", file); /* 2 */
15146 fputs ("lle", file); /* 6 */
15149 fputs ("lgt", file); /* 1 */
15152 fputs ("lge", file); /* 5 */
15155 gcc_unreachable ();
15160 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15163 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15164 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15166 print_operand (file, x, 0);
15170 /* MB value for a PowerPC64 rldic operand. */
15171 val = (GET_CODE (x) == CONST_INT
15172 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15177 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15178 if ((val <<= 1) < 0)
15181 #if HOST_BITS_PER_WIDE_INT == 32
15182 if (GET_CODE (x) == CONST_INT && i >= 0)
15183 i += 32; /* zero-extend high-part was all 0's */
15184 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15186 val = CONST_DOUBLE_LOW (x);
15192 for ( ; i < 64; i++)
15193 if ((val <<= 1) < 0)
15198 fprintf (file, "%d", i + 1);
15202 /* X is a FPR or Altivec register used in a VSX context. */
15203 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15204 output_operand_lossage ("invalid %%x value");
15207 int reg = REGNO (x);
15208 int vsx_reg = (FP_REGNO_P (reg)
15210 : reg - FIRST_ALTIVEC_REGNO + 32);
15212 #ifdef TARGET_REGNAMES
15213 if (TARGET_REGNAMES)
15214 fprintf (file, "%%vs%d", vsx_reg);
15217 fprintf (file, "%d", vsx_reg);
15222 if (GET_CODE (x) == MEM
15223 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15224 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15225 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15230 /* Like 'L', for third word of TImode */
15231 if (GET_CODE (x) == REG)
15232 fputs (reg_names[REGNO (x) + 2], file);
15233 else if (GET_CODE (x) == MEM)
15235 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15236 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15237 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15238 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15239 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15241 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15242 if (small_data_operand (x, GET_MODE (x)))
15243 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15244 reg_names[SMALL_DATA_REG]);
15249 /* X is a SYMBOL_REF. Write out the name preceded by a
15250 period and without any trailing data in brackets. Used for function
15251 names. If we are configured for System V (or the embedded ABI) on
15252 the PowerPC, do not emit the period, since those systems do not use
15253 TOCs and the like. */
15254 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15256 /* Mark the decl as referenced so that cgraph will output the
15258 if (SYMBOL_REF_DECL (x))
15259 mark_decl_referenced (SYMBOL_REF_DECL (x));
15261 /* For macho, check to see if we need a stub. */
15264 const char *name = XSTR (x, 0);
15266 if (MACHOPIC_INDIRECT
15267 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15268 name = machopic_indirection_name (x, /*stub_p=*/true);
15270 assemble_name (file, name);
15272 else if (!DOT_SYMBOLS)
15273 assemble_name (file, XSTR (x, 0));
15275 rs6000_output_function_entry (file, XSTR (x, 0));
15279 /* Like 'L', for last word of TImode. */
15280 if (GET_CODE (x) == REG)
15281 fputs (reg_names[REGNO (x) + 3], file);
15282 else if (GET_CODE (x) == MEM)
15284 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15285 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15286 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15287 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15288 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15290 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15291 if (small_data_operand (x, GET_MODE (x)))
15292 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15293 reg_names[SMALL_DATA_REG]);
15297 /* Print AltiVec or SPE memory operand. */
15302 gcc_assert (GET_CODE (x) == MEM);
15306 /* Ugly hack because %y is overloaded. */
15307 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15308 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15309 || GET_MODE (x) == TFmode
15310 || GET_MODE (x) == TImode))
15312 /* Handle [reg]. */
15313 if (GET_CODE (tmp) == REG)
15315 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15318 /* Handle [reg+UIMM]. */
15319 else if (GET_CODE (tmp) == PLUS &&
15320 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15324 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15326 x = INTVAL (XEXP (tmp, 1));
15327 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15331 /* Fall through. Must be [reg+reg]. */
15333 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15334 && GET_CODE (tmp) == AND
15335 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15336 && INTVAL (XEXP (tmp, 1)) == -16)
15337 tmp = XEXP (tmp, 0);
15338 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15339 && GET_CODE (tmp) == PRE_MODIFY)
15340 tmp = XEXP (tmp, 1);
15341 if (GET_CODE (tmp) == REG)
15342 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15345 if (!GET_CODE (tmp) == PLUS
15346 || !REG_P (XEXP (tmp, 0))
15347 || !REG_P (XEXP (tmp, 1)))
15349 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15353 if (REGNO (XEXP (tmp, 0)) == 0)
15354 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15355 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15357 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15358 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15364 if (GET_CODE (x) == REG)
15365 fprintf (file, "%s", reg_names[REGNO (x)]);
15366 else if (GET_CODE (x) == MEM)
15368 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15369 know the width from the mode. */
15370 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15371 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15372 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15373 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15374 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15375 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15376 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15377 output_address (XEXP (XEXP (x, 0), 1));
15379 output_address (XEXP (x, 0));
15382 output_addr_const (file, x);
15386 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15390 output_operand_lossage ("invalid %%xn code");
15394 /* Print the address of an operand. */
15397 print_operand_address (FILE *file, rtx x)
15399 if (GET_CODE (x) == REG)
15400 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15401 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15402 || GET_CODE (x) == LABEL_REF)
15404 output_addr_const (file, x);
15405 if (small_data_operand (x, GET_MODE (x)))
15406 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15407 reg_names[SMALL_DATA_REG]);
15409 gcc_assert (!TARGET_TOC);
15411 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15413 gcc_assert (REG_P (XEXP (x, 0)));
15414 if (REGNO (XEXP (x, 0)) == 0)
15415 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15416 reg_names[ REGNO (XEXP (x, 0)) ]);
15418 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15419 reg_names[ REGNO (XEXP (x, 1)) ]);
15421 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15422 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15423 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15425 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15426 && CONSTANT_P (XEXP (x, 1)))
15428 fprintf (file, "lo16(");
15429 output_addr_const (file, XEXP (x, 1));
15430 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15433 else if (legitimate_constant_pool_address_p (x, true))
15435 /* This hack along with a corresponding hack in
15436 rs6000_output_addr_const_extra arranges to output addends
15437 where the assembler expects to find them. eg.
15439 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
15440 without this hack would be output as "x@toc+8@l(9)". We
15441 want "x+8@toc@l(9)". */
15442 output_addr_const (file, tocrel_base);
15443 if (GET_CODE (x) == LO_SUM)
15444 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15446 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15449 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15450 && CONSTANT_P (XEXP (x, 1)))
15452 output_addr_const (file, XEXP (x, 1));
15453 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15457 gcc_unreachable ();
15460 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
15463 rs6000_output_addr_const_extra (FILE *file, rtx x)
15465 if (GET_CODE (x) == UNSPEC)
15466 switch (XINT (x, 1))
15468 case UNSPEC_TOCREL:
15469 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
15470 output_addr_const (file, XVECEXP (x, 0, 0));
15471 if (x == tocrel_base && tocrel_offset != const0_rtx)
15473 if (INTVAL (tocrel_offset) >= 0)
15474 fprintf (file, "+");
15475 output_addr_const (file, tocrel_offset);
15477 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
15480 assemble_name (file, toc_label_name);
15482 else if (TARGET_ELF)
15483 fputs ("@toc", file);
15487 case UNSPEC_MACHOPIC_OFFSET:
15488 output_addr_const (file, XVECEXP (x, 0, 0));
15490 machopic_output_function_base_name (file);
15497 /* Target hook for assembling integer objects. The PowerPC version has
15498 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15499 is defined. It also needs to handle DI-mode objects on 64-bit
15503 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15505 #ifdef RELOCATABLE_NEEDS_FIXUP
15506 /* Special handling for SI values. */
15507 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
15509 static int recurse = 0;
15511 /* For -mrelocatable, we mark all addresses that need to be fixed up
15512 in the .fixup section. */
15513 if (TARGET_RELOCATABLE
15514 && in_section != toc_section
15515 && in_section != text_section
15516 && !unlikely_text_section_p (in_section)
15518 && GET_CODE (x) != CONST_INT
15519 && GET_CODE (x) != CONST_DOUBLE
15525 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
15527 ASM_OUTPUT_LABEL (asm_out_file, buf);
15528 fprintf (asm_out_file, "\t.long\t(");
15529 output_addr_const (asm_out_file, x);
15530 fprintf (asm_out_file, ")@fixup\n");
15531 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
15532 ASM_OUTPUT_ALIGN (asm_out_file, 2);
15533 fprintf (asm_out_file, "\t.long\t");
15534 assemble_name (asm_out_file, buf);
15535 fprintf (asm_out_file, "\n\t.previous\n");
15539 /* Remove initial .'s to turn a -mcall-aixdesc function
15540 address into the address of the descriptor, not the function
15542 else if (GET_CODE (x) == SYMBOL_REF
15543 && XSTR (x, 0)[0] == '.'
15544 && DEFAULT_ABI == ABI_AIX)
15546 const char *name = XSTR (x, 0);
15547 while (*name == '.')
15550 fprintf (asm_out_file, "\t.long\t%s\n", name);
15554 #endif /* RELOCATABLE_NEEDS_FIXUP */
15555 return default_assemble_integer (x, size, aligned_p);
15558 #ifdef HAVE_GAS_HIDDEN
15559 /* Emit an assembler directive to set symbol visibility for DECL to
15560 VISIBILITY_TYPE. */
15563 rs6000_assemble_visibility (tree decl, int vis)
15565 /* Functions need to have their entry point symbol visibility set as
15566 well as their descriptor symbol visibility. */
15567 if (DEFAULT_ABI == ABI_AIX
15569 && TREE_CODE (decl) == FUNCTION_DECL)
15571 static const char * const visibility_types[] = {
15572 NULL, "internal", "hidden", "protected"
15575 const char *name, *type;
15577 name = ((* targetm.strip_name_encoding)
15578 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
15579 type = visibility_types[vis];
15581 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
15582 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
15585 default_assemble_visibility (decl, vis);
15590 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15592 /* Reversal of FP compares takes care -- an ordered compare
15593 becomes an unordered compare and vice versa. */
15594 if (mode == CCFPmode
15595 && (!flag_finite_math_only
15596 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15597 || code == UNEQ || code == LTGT))
15598 return reverse_condition_maybe_unordered (code);
15600 return reverse_condition (code);
15603 /* Generate a compare for CODE. Return a brand-new rtx that
15604 represents the result of the compare. */
15607 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15609 enum machine_mode comp_mode;
15610 rtx compare_result;
15611 enum rtx_code code = GET_CODE (cmp);
15612 rtx op0 = XEXP (cmp, 0);
15613 rtx op1 = XEXP (cmp, 1);
15615 if (FLOAT_MODE_P (mode))
15616 comp_mode = CCFPmode;
15617 else if (code == GTU || code == LTU
15618 || code == GEU || code == LEU)
15619 comp_mode = CCUNSmode;
15620 else if ((code == EQ || code == NE)
15621 && GET_CODE (op0) == SUBREG
15622 && GET_CODE (op1) == SUBREG
15623 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15624 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15625 /* These are unsigned values, perhaps there will be a later
15626 ordering compare that can be shared with this one.
15627 Unfortunately we cannot detect the signedness of the operands
15628 for non-subregs. */
15629 comp_mode = CCUNSmode;
15631 comp_mode = CCmode;
15633 /* First, the compare. */
15634 compare_result = gen_reg_rtx (comp_mode);
15636 /* E500 FP compare instructions on the GPRs. Yuck! */
15637 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15638 && FLOAT_MODE_P (mode))
15640 rtx cmp, or_result, compare_result2;
15641 enum machine_mode op_mode = GET_MODE (op0);
15643 if (op_mode == VOIDmode)
15644 op_mode = GET_MODE (op1);
15646 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15647 This explains the following mess. */
15651 case EQ: case UNEQ: case NE: case LTGT:
15655 cmp = (flag_finite_math_only && !flag_trapping_math)
15656 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15657 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15661 cmp = (flag_finite_math_only && !flag_trapping_math)
15662 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15663 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15667 cmp = (flag_finite_math_only && !flag_trapping_math)
15668 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15669 : gen_cmptfeq_gpr (compare_result, op0, op1);
15673 gcc_unreachable ();
15677 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15681 cmp = (flag_finite_math_only && !flag_trapping_math)
15682 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15683 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15687 cmp = (flag_finite_math_only && !flag_trapping_math)
15688 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15689 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15693 cmp = (flag_finite_math_only && !flag_trapping_math)
15694 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15695 : gen_cmptfgt_gpr (compare_result, op0, op1);
15699 gcc_unreachable ();
15703 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15707 cmp = (flag_finite_math_only && !flag_trapping_math)
15708 ? gen_tstsflt_gpr (compare_result, op0, op1)
15709 : gen_cmpsflt_gpr (compare_result, op0, op1);
15713 cmp = (flag_finite_math_only && !flag_trapping_math)
15714 ? gen_tstdflt_gpr (compare_result, op0, op1)
15715 : gen_cmpdflt_gpr (compare_result, op0, op1);
15719 cmp = (flag_finite_math_only && !flag_trapping_math)
15720 ? gen_tsttflt_gpr (compare_result, op0, op1)
15721 : gen_cmptflt_gpr (compare_result, op0, op1);
15725 gcc_unreachable ();
15729 gcc_unreachable ();
15732 /* Synthesize LE and GE from LT/GT || EQ. */
15733 if (code == LE || code == GE || code == LEU || code == GEU)
15739 case LE: code = LT; break;
15740 case GE: code = GT; break;
15741 case LEU: code = LT; break;
15742 case GEU: code = GT; break;
15743 default: gcc_unreachable ();
15746 compare_result2 = gen_reg_rtx (CCFPmode);
15752 cmp = (flag_finite_math_only && !flag_trapping_math)
15753 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15754 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15758 cmp = (flag_finite_math_only && !flag_trapping_math)
15759 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15760 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15764 cmp = (flag_finite_math_only && !flag_trapping_math)
15765 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15766 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15770 gcc_unreachable ();
15774 /* OR them together. */
15775 or_result = gen_reg_rtx (CCFPmode);
15776 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15778 compare_result = or_result;
15783 if (code == NE || code == LTGT)
15793 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15794 CLOBBERs to match cmptf_internal2 pattern. */
15795 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15796 && GET_MODE (op0) == TFmode
15797 && !TARGET_IEEEQUAD
15798 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15799 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15801 gen_rtx_SET (VOIDmode,
15803 gen_rtx_COMPARE (comp_mode, op0, op1)),
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 (DFmode)),
15812 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
15813 else if (GET_CODE (op1) == UNSPEC
15814 && XINT (op1, 1) == UNSPEC_SP_TEST)
15816 rtx op1b = XVECEXP (op1, 0, 0);
15817 comp_mode = CCEQmode;
15818 compare_result = gen_reg_rtx (CCEQmode);
15820 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15822 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15825 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15826 gen_rtx_COMPARE (comp_mode, op0, op1)));
15829 /* Some kinds of FP comparisons need an OR operation;
15830 under flag_finite_math_only we don't bother. */
15831 if (FLOAT_MODE_P (mode)
15832 && !flag_finite_math_only
15833 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15834 && (code == LE || code == GE
15835 || code == UNEQ || code == LTGT
15836 || code == UNGT || code == UNLT))
15838 enum rtx_code or1, or2;
15839 rtx or1_rtx, or2_rtx, compare2_rtx;
15840 rtx or_result = gen_reg_rtx (CCEQmode);
15844 case LE: or1 = LT; or2 = EQ; break;
15845 case GE: or1 = GT; or2 = EQ; break;
15846 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15847 case LTGT: or1 = LT; or2 = GT; break;
15848 case UNGT: or1 = UNORDERED; or2 = GT; break;
15849 case UNLT: or1 = UNORDERED; or2 = LT; break;
15850 default: gcc_unreachable ();
15852 validate_condition_mode (or1, comp_mode);
15853 validate_condition_mode (or2, comp_mode);
15854 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15855 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15856 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15857 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15859 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15861 compare_result = or_result;
15865 validate_condition_mode (code, GET_MODE (compare_result));
15867 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15871 /* Emit the RTL for an sCOND pattern. */
15874 rs6000_emit_sISEL (enum machine_mode mode, rtx operands[])
15877 enum machine_mode op_mode;
15878 enum rtx_code cond_code;
15879 rtx result = operands[0];
15881 condition_rtx = rs6000_generate_compare (operands[1], mode);
15882 cond_code = GET_CODE (condition_rtx);
15884 op_mode = GET_MODE (XEXP (operands[1], 0));
15885 if (op_mode == VOIDmode)
15886 op_mode = GET_MODE (XEXP (operands[1], 1));
15888 if (TARGET_POWERPC64 && GET_MODE (result) == DImode)
15890 PUT_MODE (condition_rtx, DImode);
15891 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15892 || cond_code == LTU)
15893 emit_insn (gen_isel_unsigned_di (result, condition_rtx,
15894 force_reg (DImode, const1_rtx),
15895 force_reg (DImode, const0_rtx),
15896 XEXP (condition_rtx, 0)));
15898 emit_insn (gen_isel_signed_di (result, condition_rtx,
15899 force_reg (DImode, const1_rtx),
15900 force_reg (DImode, const0_rtx),
15901 XEXP (condition_rtx, 0)));
15905 PUT_MODE (condition_rtx, SImode);
15906 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15907 || cond_code == LTU)
15908 emit_insn (gen_isel_unsigned_si (result, condition_rtx,
15909 force_reg (SImode, const1_rtx),
15910 force_reg (SImode, const0_rtx),
15911 XEXP (condition_rtx, 0)));
15913 emit_insn (gen_isel_signed_si (result, condition_rtx,
15914 force_reg (SImode, const1_rtx),
15915 force_reg (SImode, const0_rtx),
15916 XEXP (condition_rtx, 0)));
15921 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15924 enum machine_mode op_mode;
15925 enum rtx_code cond_code;
15926 rtx result = operands[0];
15928 if (TARGET_ISEL && (mode == SImode || mode == DImode))
15930 rs6000_emit_sISEL (mode, operands);
15934 condition_rtx = rs6000_generate_compare (operands[1], mode);
15935 cond_code = GET_CODE (condition_rtx);
15937 if (FLOAT_MODE_P (mode)
15938 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15942 PUT_MODE (condition_rtx, SImode);
15943 t = XEXP (condition_rtx, 0);
15945 gcc_assert (cond_code == NE || cond_code == EQ);
15947 if (cond_code == NE)
15948 emit_insn (gen_e500_flip_gt_bit (t, t));
15950 emit_insn (gen_move_from_CR_gt_bit (result, t));
15954 if (cond_code == NE
15955 || cond_code == GE || cond_code == LE
15956 || cond_code == GEU || cond_code == LEU
15957 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15959 rtx not_result = gen_reg_rtx (CCEQmode);
15960 rtx not_op, rev_cond_rtx;
15961 enum machine_mode cc_mode;
15963 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15965 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15966 SImode, XEXP (condition_rtx, 0), const0_rtx);
15967 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15968 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15969 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15972 op_mode = GET_MODE (XEXP (operands[1], 0));
15973 if (op_mode == VOIDmode)
15974 op_mode = GET_MODE (XEXP (operands[1], 1));
15976 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15978 PUT_MODE (condition_rtx, DImode);
15979 convert_move (result, condition_rtx, 0);
15983 PUT_MODE (condition_rtx, SImode);
15984 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15988 /* Emit a branch of kind CODE to location LOC. */
15991 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15993 rtx condition_rtx, loc_ref;
15995 condition_rtx = rs6000_generate_compare (operands[0], mode);
15996 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15997 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15998 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15999 loc_ref, pc_rtx)));
16002 /* Return the string to output a conditional branch to LABEL, which is
16003 the operand number of the label, or -1 if the branch is really a
16004 conditional return.
16006 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16007 condition code register and its mode specifies what kind of
16008 comparison we made.
16010 REVERSED is nonzero if we should reverse the sense of the comparison.
16012 INSN is the insn. */
16015 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16017 static char string[64];
16018 enum rtx_code code = GET_CODE (op);
16019 rtx cc_reg = XEXP (op, 0);
16020 enum machine_mode mode = GET_MODE (cc_reg);
16021 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16022 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16023 int really_reversed = reversed ^ need_longbranch;
16029 validate_condition_mode (code, mode);
16031 /* Work out which way this really branches. We could use
16032 reverse_condition_maybe_unordered here always but this
16033 makes the resulting assembler clearer. */
16034 if (really_reversed)
16036 /* Reversal of FP compares takes care -- an ordered compare
16037 becomes an unordered compare and vice versa. */
16038 if (mode == CCFPmode)
16039 code = reverse_condition_maybe_unordered (code);
16041 code = reverse_condition (code);
16044 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16046 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16051 /* Opposite of GT. */
16060 gcc_unreachable ();
16066 /* Not all of these are actually distinct opcodes, but
16067 we distinguish them for clarity of the resulting assembler. */
16068 case NE: case LTGT:
16069 ccode = "ne"; break;
16070 case EQ: case UNEQ:
16071 ccode = "eq"; break;
16073 ccode = "ge"; break;
16074 case GT: case GTU: case UNGT:
16075 ccode = "gt"; break;
16077 ccode = "le"; break;
16078 case LT: case LTU: case UNLT:
16079 ccode = "lt"; break;
16080 case UNORDERED: ccode = "un"; break;
16081 case ORDERED: ccode = "nu"; break;
16082 case UNGE: ccode = "nl"; break;
16083 case UNLE: ccode = "ng"; break;
16085 gcc_unreachable ();
16088 /* Maybe we have a guess as to how likely the branch is.
16089 The old mnemonics don't have a way to specify this information. */
16091 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16092 if (note != NULL_RTX)
16094 /* PROB is the difference from 50%. */
16095 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16097 /* Only hint for highly probable/improbable branches on newer
16098 cpus as static prediction overrides processor dynamic
16099 prediction. For older cpus we may as well always hint, but
16100 assume not taken for branches that are very close to 50% as a
16101 mispredicted taken branch is more expensive than a
16102 mispredicted not-taken branch. */
16103 if (rs6000_always_hint
16104 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16105 && br_prob_note_reliable_p (note)))
16107 if (abs (prob) > REG_BR_PROB_BASE / 20
16108 && ((prob > 0) ^ need_longbranch))
16116 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16118 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16120 /* We need to escape any '%' characters in the reg_names string.
16121 Assume they'd only be the first character.... */
16122 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16124 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16128 /* If the branch distance was too far, we may have to use an
16129 unconditional branch to go the distance. */
16130 if (need_longbranch)
16131 s += sprintf (s, ",$+8\n\tb %s", label);
16133 s += sprintf (s, ",%s", label);
16139 /* Return the string to flip the GT bit on a CR. */
16141 output_e500_flip_gt_bit (rtx dst, rtx src)
16143 static char string[64];
16146 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16147 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16150 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16151 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16153 sprintf (string, "crnot %d,%d", a, b);
16157 /* Return insn for VSX or Altivec comparisons. */
16160 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16163 enum machine_mode mode = GET_MODE (op0);
16171 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16177 mask = gen_reg_rtx (mode);
16178 emit_insn (gen_rtx_SET (VOIDmode,
16180 gen_rtx_fmt_ee (code, mode, op0, op1)));
16187 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16188 DMODE is expected destination mode. This is a recursive function. */
16191 rs6000_emit_vector_compare (enum rtx_code rcode,
16193 enum machine_mode dmode)
16196 bool swap_operands = false;
16197 bool try_again = false;
16199 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16200 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16202 /* See if the comparison works as is. */
16203 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16211 swap_operands = true;
16216 swap_operands = true;
16224 /* Invert condition and try again.
16225 e.g., A != B becomes ~(A==B). */
16227 enum rtx_code rev_code;
16228 enum insn_code nor_code;
16231 rev_code = reverse_condition_maybe_unordered (rcode);
16232 if (rev_code == UNKNOWN)
16235 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
16236 if (nor_code == CODE_FOR_nothing)
16239 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16243 mask = gen_reg_rtx (dmode);
16244 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16252 /* Try GT/GTU/LT/LTU OR EQ */
16255 enum insn_code ior_code;
16256 enum rtx_code new_code;
16277 gcc_unreachable ();
16280 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
16281 if (ior_code == CODE_FOR_nothing)
16284 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16288 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16292 mask = gen_reg_rtx (dmode);
16293 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16311 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16316 /* You only get two chances. */
16320 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16321 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16322 operands for the relation operation COND. */
16325 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16326 rtx cond, rtx cc_op0, rtx cc_op1)
16328 enum machine_mode dest_mode = GET_MODE (dest);
16329 enum rtx_code rcode = GET_CODE (cond);
16330 enum machine_mode cc_mode = CCmode;
16334 bool invert_move = false;
16336 if (VECTOR_UNIT_NONE_P (dest_mode))
16341 /* Swap operands if we can, and fall back to doing the operation as
16342 specified, and doing a NOR to invert the test. */
16348 /* Invert condition and try again.
16349 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16350 invert_move = true;
16351 rcode = reverse_condition_maybe_unordered (rcode);
16352 if (rcode == UNKNOWN)
16356 /* Mark unsigned tests with CCUNSmode. */
16361 cc_mode = CCUNSmode;
16368 /* Get the vector mask for the given relational operations. */
16369 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16377 op_true = op_false;
16381 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
16382 emit_insn (gen_rtx_SET (VOIDmode,
16384 gen_rtx_IF_THEN_ELSE (dest_mode,
16391 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16392 operands of the last comparison is nonzero/true, FALSE_COND if it
16393 is zero/false. Return 0 if the hardware has no such operation. */
16396 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16398 enum rtx_code code = GET_CODE (op);
16399 rtx op0 = XEXP (op, 0);
16400 rtx op1 = XEXP (op, 1);
16401 REAL_VALUE_TYPE c1;
16402 enum machine_mode compare_mode = GET_MODE (op0);
16403 enum machine_mode result_mode = GET_MODE (dest);
16405 bool is_against_zero;
16407 /* These modes should always match. */
16408 if (GET_MODE (op1) != compare_mode
16409 /* In the isel case however, we can use a compare immediate, so
16410 op1 may be a small constant. */
16411 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16413 if (GET_MODE (true_cond) != result_mode)
16415 if (GET_MODE (false_cond) != result_mode)
16418 /* First, work out if the hardware can do this at all, or
16419 if it's too slow.... */
16420 if (!FLOAT_MODE_P (compare_mode))
16423 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16426 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16427 && SCALAR_FLOAT_MODE_P (compare_mode))
16430 is_against_zero = op1 == CONST0_RTX (compare_mode);
16432 /* A floating-point subtract might overflow, underflow, or produce
16433 an inexact result, thus changing the floating-point flags, so it
16434 can't be generated if we care about that. It's safe if one side
16435 of the construct is zero, since then no subtract will be
16437 if (SCALAR_FLOAT_MODE_P (compare_mode)
16438 && flag_trapping_math && ! is_against_zero)
16441 /* Eliminate half of the comparisons by switching operands, this
16442 makes the remaining code simpler. */
16443 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16444 || code == LTGT || code == LT || code == UNLE)
16446 code = reverse_condition_maybe_unordered (code);
16448 true_cond = false_cond;
16452 /* UNEQ and LTGT take four instructions for a comparison with zero,
16453 it'll probably be faster to use a branch here too. */
16454 if (code == UNEQ && HONOR_NANS (compare_mode))
16457 if (GET_CODE (op1) == CONST_DOUBLE)
16458 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16460 /* We're going to try to implement comparisons by performing
16461 a subtract, then comparing against zero. Unfortunately,
16462 Inf - Inf is NaN which is not zero, and so if we don't
16463 know that the operand is finite and the comparison
16464 would treat EQ different to UNORDERED, we can't do it. */
16465 if (HONOR_INFINITIES (compare_mode)
16466 && code != GT && code != UNGE
16467 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16468 /* Constructs of the form (a OP b ? a : b) are safe. */
16469 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16470 || (! rtx_equal_p (op0, true_cond)
16471 && ! rtx_equal_p (op1, true_cond))))
16474 /* At this point we know we can use fsel. */
16476 /* Reduce the comparison to a comparison against zero. */
16477 if (! is_against_zero)
16479 temp = gen_reg_rtx (compare_mode);
16480 emit_insn (gen_rtx_SET (VOIDmode, temp,
16481 gen_rtx_MINUS (compare_mode, op0, op1)));
16483 op1 = CONST0_RTX (compare_mode);
16486 /* If we don't care about NaNs we can reduce some of the comparisons
16487 down to faster ones. */
16488 if (! HONOR_NANS (compare_mode))
16494 true_cond = false_cond;
16507 /* Now, reduce everything down to a GE. */
16514 temp = gen_reg_rtx (compare_mode);
16515 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16520 temp = gen_reg_rtx (compare_mode);
16521 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
16526 temp = gen_reg_rtx (compare_mode);
16527 emit_insn (gen_rtx_SET (VOIDmode, temp,
16528 gen_rtx_NEG (compare_mode,
16529 gen_rtx_ABS (compare_mode, op0))));
16534 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16535 temp = gen_reg_rtx (result_mode);
16536 emit_insn (gen_rtx_SET (VOIDmode, temp,
16537 gen_rtx_IF_THEN_ELSE (result_mode,
16538 gen_rtx_GE (VOIDmode,
16540 true_cond, false_cond)));
16541 false_cond = true_cond;
16544 temp = gen_reg_rtx (compare_mode);
16545 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16550 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
16551 temp = gen_reg_rtx (result_mode);
16552 emit_insn (gen_rtx_SET (VOIDmode, temp,
16553 gen_rtx_IF_THEN_ELSE (result_mode,
16554 gen_rtx_GE (VOIDmode,
16556 true_cond, false_cond)));
16557 true_cond = false_cond;
16560 temp = gen_reg_rtx (compare_mode);
16561 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16566 gcc_unreachable ();
16569 emit_insn (gen_rtx_SET (VOIDmode, dest,
16570 gen_rtx_IF_THEN_ELSE (result_mode,
16571 gen_rtx_GE (VOIDmode,
16573 true_cond, false_cond)));
16577 /* Same as above, but for ints (isel). */
16580 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16582 rtx condition_rtx, cr;
16583 enum machine_mode mode = GET_MODE (dest);
16585 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
16588 /* We still have to do the compare, because isel doesn't do a
16589 compare, it just looks at the CRx bits set by a previous compare
16591 condition_rtx = rs6000_generate_compare (op, mode);
16592 cr = XEXP (condition_rtx, 0);
16594 if (mode == SImode)
16596 if (GET_MODE (cr) == CCmode)
16597 emit_insn (gen_isel_signed_si (dest, condition_rtx,
16598 true_cond, false_cond, cr));
16600 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
16601 true_cond, false_cond, cr));
16605 if (GET_MODE (cr) == CCmode)
16606 emit_insn (gen_isel_signed_di (dest, condition_rtx,
16607 true_cond, false_cond, cr));
16609 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
16610 true_cond, false_cond, cr));
16617 output_isel (rtx *operands)
16619 enum rtx_code code;
16621 code = GET_CODE (operands[1]);
16622 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
16624 PUT_CODE (operands[1], reverse_condition (code));
16625 return "isel %0,%3,%2,%j1";
16628 return "isel %0,%2,%3,%j1";
16632 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
16634 enum machine_mode mode = GET_MODE (op0);
16638 /* VSX/altivec have direct min/max insns. */
16639 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
16641 emit_insn (gen_rtx_SET (VOIDmode,
16643 gen_rtx_fmt_ee (code, mode, op0, op1)));
16647 if (code == SMAX || code == SMIN)
16652 if (code == SMAX || code == UMAX)
16653 target = emit_conditional_move (dest, c, op0, op1, mode,
16654 op0, op1, mode, 0);
16656 target = emit_conditional_move (dest, c, op0, op1, mode,
16657 op1, op0, mode, 0);
16658 gcc_assert (target);
16659 if (target != dest)
16660 emit_move_insn (dest, target);
16663 /* Emit instructions to perform a load-reserved/store-conditional operation.
16664 The operation performed is an atomic
16665 (set M (CODE:MODE M OP))
16666 If not NULL, BEFORE is atomically set to M before the operation, and
16667 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16668 If SYNC_P then a memory barrier is emitted before the operation.
16669 Either OP or M may be wrapped in a NOT operation. */
16672 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16673 rtx m, rtx op, rtx before_param, rtx after_param,
16676 enum machine_mode used_mode;
16677 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16680 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16681 rtx shift = NULL_RTX;
16684 emit_insn (gen_lwsync ());
16688 /* If this is smaller than SImode, we'll have to use SImode with
16690 if (mode == QImode || mode == HImode)
16694 if (MEM_ALIGN (used_m) >= 32)
16697 if (BYTES_BIG_ENDIAN)
16698 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16700 shift = GEN_INT (ishift);
16701 used_m = change_address (used_m, SImode, 0);
16705 rtx addrSI, aligned_addr;
16706 int shift_mask = mode == QImode ? 0x18 : 0x10;
16708 addrSI = gen_lowpart_common (SImode,
16709 force_reg (Pmode, XEXP (used_m, 0)));
16710 addrSI = force_reg (SImode, addrSI);
16711 shift = gen_reg_rtx (SImode);
16713 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16714 GEN_INT (shift_mask)));
16715 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16717 aligned_addr = expand_binop (Pmode, and_optab,
16719 GEN_INT (-4), NULL_RTX,
16720 1, OPTAB_LIB_WIDEN);
16721 used_m = change_address (used_m, SImode, aligned_addr);
16722 set_mem_align (used_m, 32);
16724 /* It's safe to keep the old alias set of USED_M, because
16725 the operation is atomic and only affects the original
16729 if (GET_CODE (op) == NOT)
16731 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16732 oldop = gen_rtx_NOT (SImode, oldop);
16735 oldop = lowpart_subreg (SImode, op, mode);
16741 newop = expand_binop (SImode, and_optab,
16742 oldop, GEN_INT (imask), NULL_RTX,
16743 1, OPTAB_LIB_WIDEN);
16744 emit_insn (gen_ashlsi3 (newop, newop, shift));
16747 case NOT: /* NAND */
16748 newop = expand_binop (SImode, ior_optab,
16749 oldop, GEN_INT (~imask), NULL_RTX,
16750 1, OPTAB_LIB_WIDEN);
16751 emit_insn (gen_rotlsi3 (newop, newop, shift));
16755 newop = expand_binop (SImode, ior_optab,
16756 oldop, GEN_INT (~imask), NULL_RTX,
16757 1, OPTAB_LIB_WIDEN);
16758 emit_insn (gen_rotlsi3 (newop, newop, shift));
16766 newop = expand_binop (SImode, and_optab,
16767 oldop, GEN_INT (imask), NULL_RTX,
16768 1, OPTAB_LIB_WIDEN);
16769 emit_insn (gen_ashlsi3 (newop, newop, shift));
16771 mask = gen_reg_rtx (SImode);
16772 emit_move_insn (mask, GEN_INT (imask));
16773 emit_insn (gen_ashlsi3 (mask, mask, shift));
16776 newop = gen_rtx_PLUS (SImode, m, newop);
16778 newop = gen_rtx_MINUS (SImode, m, newop);
16779 newop = gen_rtx_AND (SImode, newop, mask);
16780 newop = gen_rtx_IOR (SImode, newop,
16781 gen_rtx_AND (SImode,
16782 gen_rtx_NOT (SImode, mask),
16788 gcc_unreachable ();
16792 used_mode = SImode;
16793 before = gen_reg_rtx (used_mode);
16794 after = gen_reg_rtx (used_mode);
16799 before = before_param;
16800 after = after_param;
16802 if (before == NULL_RTX)
16803 before = gen_reg_rtx (used_mode);
16804 if (after == NULL_RTX)
16805 after = gen_reg_rtx (used_mode);
16808 if ((code == PLUS || code == MINUS)
16809 && used_mode != mode)
16810 the_op = op; /* Computed above. */
16811 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16812 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16813 else if (code == NOT)
16814 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16815 gen_rtx_NOT (used_mode, m),
16816 gen_rtx_NOT (used_mode, op));
16818 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16820 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16821 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16822 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16823 gen_rtx_UNSPEC (used_mode,
16824 gen_rtvec (1, the_op),
16826 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16828 if ((code == PLUS || code == MINUS) && used_mode != mode)
16829 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16830 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16832 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16833 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16835 /* Shift and mask the return values properly. */
16836 if (used_mode != mode && before_param)
16838 emit_insn (gen_lshrsi3 (before, before, shift));
16839 convert_move (before_param, before, 1);
16842 if (used_mode != mode && after_param)
16844 emit_insn (gen_lshrsi3 (after, after, shift));
16845 convert_move (after_param, after, 1);
16848 /* The previous sequence will end with a branch that's dependent on
16849 the conditional store, so placing an isync will ensure that no
16850 other instructions (especially, no load or store instructions)
16851 can start before the atomic operation completes. */
16853 emit_insn (gen_isync ());
16856 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16857 COND is true. Mark the jump as unlikely to be taken. */
16860 emit_unlikely_jump (rtx cond, rtx label)
16862 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16865 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16866 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16867 add_reg_note (x, REG_BR_PROB, very_unlikely);
16870 /* A subroutine of the atomic operation splitters. Emit a load-locked
16871 instruction in MODE. */
16874 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16876 rtx (*fn) (rtx, rtx) = NULL;
16877 if (mode == SImode)
16878 fn = gen_load_locked_si;
16879 else if (mode == DImode)
16880 fn = gen_load_locked_di;
16881 emit_insn (fn (reg, mem));
16884 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16885 instruction in MODE. */
16888 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16890 rtx (*fn) (rtx, rtx, rtx) = NULL;
16891 if (mode == SImode)
16892 fn = gen_store_conditional_si;
16893 else if (mode == DImode)
16894 fn = gen_store_conditional_di;
16896 /* Emit sync before stwcx. to address PPC405 Erratum. */
16897 if (PPC405_ERRATUM77)
16898 emit_insn (gen_memory_barrier ());
16900 emit_insn (fn (res, mem, val));
16903 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16904 to perform. MEM is the memory on which to operate. VAL is the second
16905 operand of the binary operator. BEFORE and AFTER are optional locations to
16906 return the value of MEM either before of after the operation. SCRATCH is
16907 a scratch register. */
16910 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16911 rtx before, rtx after, rtx scratch)
16913 enum machine_mode mode = GET_MODE (mem);
16914 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16916 emit_insn (gen_lwsync ());
16918 label = gen_label_rtx ();
16919 emit_label (label);
16920 label = gen_rtx_LABEL_REF (VOIDmode, label);
16922 if (before == NULL_RTX)
16924 emit_load_locked (mode, before, mem);
16927 x = gen_rtx_IOR (mode,
16928 gen_rtx_NOT (mode, before),
16929 gen_rtx_NOT (mode, val));
16930 else if (code == AND)
16931 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16933 x = gen_rtx_fmt_ee (code, mode, before, val);
16935 if (after != NULL_RTX)
16936 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16937 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16939 emit_store_conditional (mode, cond, mem, scratch);
16941 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16942 emit_unlikely_jump (x, label);
16944 emit_insn (gen_isync ());
16947 /* Expand an atomic compare and swap operation. MEM is the memory on which
16948 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16949 value to be stored. SCRATCH is a scratch GPR. */
16952 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16955 enum machine_mode mode = GET_MODE (mem);
16956 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16958 emit_insn (gen_lwsync ());
16960 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16961 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16962 emit_label (XEXP (label1, 0));
16964 emit_load_locked (mode, retval, mem);
16966 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16967 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16969 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16970 emit_unlikely_jump (x, label2);
16972 emit_move_insn (scratch, newval);
16973 emit_store_conditional (mode, cond, mem, scratch);
16975 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16976 emit_unlikely_jump (x, label1);
16978 emit_insn (gen_isync ());
16979 emit_label (XEXP (label2, 0));
16982 /* Expand an atomic test and set operation. MEM is the memory on which
16983 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16986 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16988 enum machine_mode mode = GET_MODE (mem);
16989 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16991 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16992 emit_label (XEXP (label, 0));
16994 emit_load_locked (mode, retval, mem);
16995 emit_move_insn (scratch, val);
16996 emit_store_conditional (mode, cond, mem, scratch);
16998 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16999 emit_unlikely_jump (x, label);
17001 emit_insn (gen_isync ());
17005 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17007 enum machine_mode mode = GET_MODE (mem);
17008 rtx addrSI, align, wdst, shift, mask;
17009 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17010 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17012 /* Shift amount for subword relative to aligned word. */
17013 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17014 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17015 shift = gen_reg_rtx (SImode);
17016 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17017 GEN_INT (shift_mask)));
17018 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17020 /* Shift and mask old value into position within word. */
17021 oldval = convert_modes (SImode, mode, oldval, 1);
17022 oldval = expand_binop (SImode, and_optab,
17023 oldval, GEN_INT (imask), NULL_RTX,
17024 1, OPTAB_LIB_WIDEN);
17025 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17027 /* Shift and mask new value into position within word. */
17028 newval = convert_modes (SImode, mode, newval, 1);
17029 newval = expand_binop (SImode, and_optab,
17030 newval, GEN_INT (imask), NULL_RTX,
17031 1, OPTAB_LIB_WIDEN);
17032 emit_insn (gen_ashlsi3 (newval, newval, shift));
17034 /* Mask for insertion. */
17035 mask = gen_reg_rtx (SImode);
17036 emit_move_insn (mask, GEN_INT (imask));
17037 emit_insn (gen_ashlsi3 (mask, mask, shift));
17039 /* Address of aligned word containing subword. */
17040 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17041 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17042 mem = change_address (mem, SImode, align);
17043 set_mem_align (mem, 32);
17044 MEM_VOLATILE_P (mem) = 1;
17046 wdst = gen_reg_rtx (SImode);
17047 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17048 oldval, newval, mem));
17050 /* Shift the result back. */
17051 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17053 emit_move_insn (dst, gen_lowpart (mode, wdst));
17057 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17058 rtx oldval, rtx newval, rtx mem,
17061 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17063 emit_insn (gen_lwsync ());
17064 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17065 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17066 emit_label (XEXP (label1, 0));
17068 emit_load_locked (SImode, scratch, mem);
17070 /* Mask subword within loaded value for comparison with oldval.
17071 Use UNSPEC_AND to avoid clobber.*/
17072 emit_insn (gen_rtx_SET (SImode, dest,
17073 gen_rtx_UNSPEC (SImode,
17074 gen_rtvec (2, scratch, mask),
17077 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17078 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17080 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17081 emit_unlikely_jump (x, label2);
17083 /* Clear subword within loaded value for insertion of new value. */
17084 emit_insn (gen_rtx_SET (SImode, scratch,
17085 gen_rtx_AND (SImode,
17086 gen_rtx_NOT (SImode, mask), scratch)));
17087 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17088 emit_store_conditional (SImode, cond, mem, scratch);
17090 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17091 emit_unlikely_jump (x, label1);
17093 emit_insn (gen_isync ());
17094 emit_label (XEXP (label2, 0));
17098 /* Emit instructions to move SRC to DST. Called by splitters for
17099 multi-register moves. It will emit at most one instruction for
17100 each register that is accessed; that is, it won't emit li/lis pairs
17101 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17105 rs6000_split_multireg_move (rtx dst, rtx src)
17107 /* The register number of the first register being moved. */
17109 /* The mode that is to be moved. */
17110 enum machine_mode mode;
17111 /* The mode that the move is being done in, and its size. */
17112 enum machine_mode reg_mode;
17114 /* The number of registers that will be moved. */
17117 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17118 mode = GET_MODE (dst);
17119 nregs = hard_regno_nregs[reg][mode];
17120 if (FP_REGNO_P (reg))
17121 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17122 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17123 else if (ALTIVEC_REGNO_P (reg))
17124 reg_mode = V16QImode;
17125 else if (TARGET_E500_DOUBLE && mode == TFmode)
17128 reg_mode = word_mode;
17129 reg_mode_size = GET_MODE_SIZE (reg_mode);
17131 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17133 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17135 /* Move register range backwards, if we might have destructive
17138 for (i = nregs - 1; i >= 0; i--)
17139 emit_insn (gen_rtx_SET (VOIDmode,
17140 simplify_gen_subreg (reg_mode, dst, mode,
17141 i * reg_mode_size),
17142 simplify_gen_subreg (reg_mode, src, mode,
17143 i * reg_mode_size)));
17149 bool used_update = false;
17150 rtx restore_basereg = NULL_RTX;
17152 if (MEM_P (src) && INT_REGNO_P (reg))
17156 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17157 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17160 breg = XEXP (XEXP (src, 0), 0);
17161 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17162 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17163 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17164 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17165 src = replace_equiv_address (src, breg);
17167 else if (! rs6000_offsettable_memref_p (src))
17169 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17171 rtx basereg = XEXP (XEXP (src, 0), 0);
17174 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17175 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17176 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17177 used_update = true;
17180 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17181 XEXP (XEXP (src, 0), 1)));
17182 src = replace_equiv_address (src, basereg);
17186 rtx basereg = gen_rtx_REG (Pmode, reg);
17187 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17188 src = replace_equiv_address (src, basereg);
17192 breg = XEXP (src, 0);
17193 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17194 breg = XEXP (breg, 0);
17196 /* If the base register we are using to address memory is
17197 also a destination reg, then change that register last. */
17199 && REGNO (breg) >= REGNO (dst)
17200 && REGNO (breg) < REGNO (dst) + nregs)
17201 j = REGNO (breg) - REGNO (dst);
17203 else if (MEM_P (dst) && INT_REGNO_P (reg))
17207 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17208 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17211 breg = XEXP (XEXP (dst, 0), 0);
17212 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17213 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17214 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17216 /* We have to update the breg before doing the store.
17217 Use store with update, if available. */
17221 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17222 emit_insn (TARGET_32BIT
17223 ? (TARGET_POWERPC64
17224 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17225 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17226 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17227 used_update = true;
17230 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17231 dst = replace_equiv_address (dst, breg);
17233 else if (!rs6000_offsettable_memref_p (dst)
17234 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17236 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17238 rtx basereg = XEXP (XEXP (dst, 0), 0);
17241 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17242 emit_insn (gen_rtx_SET (VOIDmode,
17243 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17244 used_update = true;
17247 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17248 XEXP (XEXP (dst, 0), 1)));
17249 dst = replace_equiv_address (dst, basereg);
17253 rtx basereg = XEXP (XEXP (dst, 0), 0);
17254 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17255 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17257 && REG_P (offsetreg)
17258 && REGNO (basereg) != REGNO (offsetreg));
17259 if (REGNO (basereg) == 0)
17261 rtx tmp = offsetreg;
17262 offsetreg = basereg;
17265 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17266 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17267 dst = replace_equiv_address (dst, basereg);
17270 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17271 gcc_assert (rs6000_offsettable_memref_p (dst));
17274 for (i = 0; i < nregs; i++)
17276 /* Calculate index to next subword. */
17281 /* If compiler already emitted move of first word by
17282 store with update, no need to do anything. */
17283 if (j == 0 && used_update)
17286 emit_insn (gen_rtx_SET (VOIDmode,
17287 simplify_gen_subreg (reg_mode, dst, mode,
17288 j * reg_mode_size),
17289 simplify_gen_subreg (reg_mode, src, mode,
17290 j * reg_mode_size)));
17292 if (restore_basereg != NULL_RTX)
17293 emit_insn (restore_basereg);
17298 /* This page contains routines that are used to determine what the
17299 function prologue and epilogue code will do and write them out. */
17301 /* Return the first fixed-point register that is required to be
17302 saved. 32 if none. */
17305 first_reg_to_save (void)
17309 /* Find lowest numbered live register. */
17310 for (first_reg = 13; first_reg <= 31; first_reg++)
17311 if (df_regs_ever_live_p (first_reg)
17312 && (! call_used_regs[first_reg]
17313 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17314 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17315 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17316 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17321 && crtl->uses_pic_offset_table
17322 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17323 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17329 /* Similar, for FP regs. */
17332 first_fp_reg_to_save (void)
17336 /* Find lowest numbered live register. */
17337 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17338 if (df_regs_ever_live_p (first_reg))
17344 /* Similar, for AltiVec regs. */
17347 first_altivec_reg_to_save (void)
17351 /* Stack frame remains as is unless we are in AltiVec ABI. */
17352 if (! TARGET_ALTIVEC_ABI)
17353 return LAST_ALTIVEC_REGNO + 1;
17355 /* On Darwin, the unwind routines are compiled without
17356 TARGET_ALTIVEC, and use save_world to save/restore the
17357 altivec registers when necessary. */
17358 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17359 && ! TARGET_ALTIVEC)
17360 return FIRST_ALTIVEC_REGNO + 20;
17362 /* Find lowest numbered live register. */
17363 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17364 if (df_regs_ever_live_p (i))
17370 /* Return a 32-bit mask of the AltiVec registers we need to set in
17371 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17372 the 32-bit word is 0. */
17374 static unsigned int
17375 compute_vrsave_mask (void)
17377 unsigned int i, mask = 0;
17379 /* On Darwin, the unwind routines are compiled without
17380 TARGET_ALTIVEC, and use save_world to save/restore the
17381 call-saved altivec registers when necessary. */
17382 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17383 && ! TARGET_ALTIVEC)
17386 /* First, find out if we use _any_ altivec registers. */
17387 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17388 if (df_regs_ever_live_p (i))
17389 mask |= ALTIVEC_REG_BIT (i);
17394 /* Next, remove the argument registers from the set. These must
17395 be in the VRSAVE mask set by the caller, so we don't need to add
17396 them in again. More importantly, the mask we compute here is
17397 used to generate CLOBBERs in the set_vrsave insn, and we do not
17398 wish the argument registers to die. */
17399 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17400 mask &= ~ALTIVEC_REG_BIT (i);
17402 /* Similarly, remove the return value from the set. */
17405 diddle_return_value (is_altivec_return_reg, &yes);
17407 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17413 /* For a very restricted set of circumstances, we can cut down the
17414 size of prologues/epilogues by calling our own save/restore-the-world
17418 compute_save_world_info (rs6000_stack_t *info_ptr)
17420 info_ptr->world_save_p = 1;
17421 info_ptr->world_save_p
17422 = (WORLD_SAVE_P (info_ptr)
17423 && DEFAULT_ABI == ABI_DARWIN
17424 && ! (cfun->calls_setjmp && flag_exceptions)
17425 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17426 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17427 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17428 && info_ptr->cr_save_p);
17430 /* This will not work in conjunction with sibcalls. Make sure there
17431 are none. (This check is expensive, but seldom executed.) */
17432 if (WORLD_SAVE_P (info_ptr))
17435 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17436 if ( GET_CODE (insn) == CALL_INSN
17437 && SIBLING_CALL_P (insn))
17439 info_ptr->world_save_p = 0;
17444 if (WORLD_SAVE_P (info_ptr))
17446 /* Even if we're not touching VRsave, make sure there's room on the
17447 stack for it, if it looks like we're calling SAVE_WORLD, which
17448 will attempt to save it. */
17449 info_ptr->vrsave_size = 4;
17451 /* If we are going to save the world, we need to save the link register too. */
17452 info_ptr->lr_save_p = 1;
17454 /* "Save" the VRsave register too if we're saving the world. */
17455 if (info_ptr->vrsave_mask == 0)
17456 info_ptr->vrsave_mask = compute_vrsave_mask ();
17458 /* Because the Darwin register save/restore routines only handle
17459 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17461 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17462 && (info_ptr->first_altivec_reg_save
17463 >= FIRST_SAVED_ALTIVEC_REGNO));
17470 is_altivec_return_reg (rtx reg, void *xyes)
17472 bool *yes = (bool *) xyes;
17473 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17478 /* Calculate the stack information for the current function. This is
17479 complicated by having two separate calling sequences, the AIX calling
17480 sequence and the V.4 calling sequence.
17482 AIX (and Darwin/Mac OS X) stack frames look like:
17484 SP----> +---------------------------------------+
17485 | back chain to caller | 0 0
17486 +---------------------------------------+
17487 | saved CR | 4 8 (8-11)
17488 +---------------------------------------+
17490 +---------------------------------------+
17491 | reserved for compilers | 12 24
17492 +---------------------------------------+
17493 | reserved for binders | 16 32
17494 +---------------------------------------+
17495 | saved TOC pointer | 20 40
17496 +---------------------------------------+
17497 | Parameter save area (P) | 24 48
17498 +---------------------------------------+
17499 | Alloca space (A) | 24+P etc.
17500 +---------------------------------------+
17501 | Local variable space (L) | 24+P+A
17502 +---------------------------------------+
17503 | Float/int conversion temporary (X) | 24+P+A+L
17504 +---------------------------------------+
17505 | Save area for AltiVec registers (W) | 24+P+A+L+X
17506 +---------------------------------------+
17507 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
17508 +---------------------------------------+
17509 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
17510 +---------------------------------------+
17511 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
17512 +---------------------------------------+
17513 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
17514 +---------------------------------------+
17515 old SP->| back chain to caller's caller |
17516 +---------------------------------------+
17518 The required alignment for AIX configurations is two words (i.e., 8
17522 V.4 stack frames look like:
17524 SP----> +---------------------------------------+
17525 | back chain to caller | 0
17526 +---------------------------------------+
17527 | caller's saved LR | 4
17528 +---------------------------------------+
17529 | Parameter save area (P) | 8
17530 +---------------------------------------+
17531 | Alloca space (A) | 8+P
17532 +---------------------------------------+
17533 | Varargs save area (V) | 8+P+A
17534 +---------------------------------------+
17535 | Local variable space (L) | 8+P+A+V
17536 +---------------------------------------+
17537 | Float/int conversion temporary (X) | 8+P+A+V+L
17538 +---------------------------------------+
17539 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
17540 +---------------------------------------+
17541 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
17542 +---------------------------------------+
17543 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
17544 +---------------------------------------+
17545 | SPE: area for 64-bit GP registers |
17546 +---------------------------------------+
17547 | SPE alignment padding |
17548 +---------------------------------------+
17549 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
17550 +---------------------------------------+
17551 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
17552 +---------------------------------------+
17553 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
17554 +---------------------------------------+
17555 old SP->| back chain to caller's caller |
17556 +---------------------------------------+
17558 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
17559 given. (But note below and in sysv4.h that we require only 8 and
17560 may round up the size of our stack frame anyways. The historical
17561 reason is early versions of powerpc-linux which didn't properly
17562 align the stack at program startup. A happy side-effect is that
17563 -mno-eabi libraries can be used with -meabi programs.)
17565 The EABI configuration defaults to the V.4 layout. However,
17566 the stack alignment requirements may differ. If -mno-eabi is not
17567 given, the required stack alignment is 8 bytes; if -mno-eabi is
17568 given, the required alignment is 16 bytes. (But see V.4 comment
17571 #ifndef ABI_STACK_BOUNDARY
17572 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
17575 static rs6000_stack_t *
17576 rs6000_stack_info (void)
17578 static rs6000_stack_t info;
17579 rs6000_stack_t *info_ptr = &info;
17580 int reg_size = TARGET_32BIT ? 4 : 8;
17584 HOST_WIDE_INT non_fixed_size;
17586 memset (&info, 0, sizeof (info));
17590 /* Cache value so we don't rescan instruction chain over and over. */
17591 if (cfun->machine->insn_chain_scanned_p == 0)
17592 cfun->machine->insn_chain_scanned_p
17593 = spe_func_has_64bit_regs_p () + 1;
17594 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
17597 /* Select which calling sequence. */
17598 info_ptr->abi = DEFAULT_ABI;
17600 /* Calculate which registers need to be saved & save area size. */
17601 info_ptr->first_gp_reg_save = first_reg_to_save ();
17602 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
17603 even if it currently looks like we won't. Reload may need it to
17604 get at a constant; if so, it will have already created a constant
17605 pool entry for it. */
17606 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
17607 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
17608 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
17609 && crtl->uses_const_pool
17610 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
17611 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
17613 first_gp = info_ptr->first_gp_reg_save;
17615 info_ptr->gp_size = reg_size * (32 - first_gp);
17617 /* For the SPE, we have an additional upper 32-bits on each GPR.
17618 Ideally we should save the entire 64-bits only when the upper
17619 half is used in SIMD instructions. Since we only record
17620 registers live (not the size they are used in), this proves
17621 difficult because we'd have to traverse the instruction chain at
17622 the right time, taking reload into account. This is a real pain,
17623 so we opt to save the GPRs in 64-bits always if but one register
17624 gets used in 64-bits. Otherwise, all the registers in the frame
17625 get saved in 32-bits.
17627 So... since when we save all GPRs (except the SP) in 64-bits, the
17628 traditional GP save area will be empty. */
17629 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17630 info_ptr->gp_size = 0;
17632 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
17633 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
17635 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
17636 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
17637 - info_ptr->first_altivec_reg_save);
17639 /* Does this function call anything? */
17640 info_ptr->calls_p = (! current_function_is_leaf
17641 || cfun->machine->ra_needs_full_frame);
17643 /* Determine if we need to save the link register. */
17644 if ((DEFAULT_ABI == ABI_AIX
17646 && !TARGET_PROFILE_KERNEL)
17647 #ifdef TARGET_RELOCATABLE
17648 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
17650 || (info_ptr->first_fp_reg_save != 64
17651 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
17652 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
17653 || info_ptr->calls_p
17654 || rs6000_ra_ever_killed ())
17656 info_ptr->lr_save_p = 1;
17657 df_set_regs_ever_live (LR_REGNO, true);
17660 /* Determine if we need to save the condition code registers. */
17661 if (df_regs_ever_live_p (CR2_REGNO)
17662 || df_regs_ever_live_p (CR3_REGNO)
17663 || df_regs_ever_live_p (CR4_REGNO))
17665 info_ptr->cr_save_p = 1;
17666 if (DEFAULT_ABI == ABI_V4)
17667 info_ptr->cr_size = reg_size;
17670 /* If the current function calls __builtin_eh_return, then we need
17671 to allocate stack space for registers that will hold data for
17672 the exception handler. */
17673 if (crtl->calls_eh_return)
17676 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
17679 /* SPE saves EH registers in 64-bits. */
17680 ehrd_size = i * (TARGET_SPE_ABI
17681 && info_ptr->spe_64bit_regs_used != 0
17682 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
17687 /* Determine various sizes. */
17688 info_ptr->reg_size = reg_size;
17689 info_ptr->fixed_size = RS6000_SAVE_AREA;
17690 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
17691 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
17692 TARGET_ALTIVEC ? 16 : 8);
17693 if (FRAME_GROWS_DOWNWARD)
17694 info_ptr->vars_size
17695 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
17696 + info_ptr->parm_size,
17697 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
17698 - (info_ptr->fixed_size + info_ptr->vars_size
17699 + info_ptr->parm_size);
17701 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17702 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17704 info_ptr->spe_gp_size = 0;
17706 if (TARGET_ALTIVEC_ABI)
17707 info_ptr->vrsave_mask = compute_vrsave_mask ();
17709 info_ptr->vrsave_mask = 0;
17711 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17712 info_ptr->vrsave_size = 4;
17714 info_ptr->vrsave_size = 0;
17716 compute_save_world_info (info_ptr);
17718 /* Calculate the offsets. */
17719 switch (DEFAULT_ABI)
17723 gcc_unreachable ();
17727 info_ptr->fp_save_offset = - info_ptr->fp_size;
17728 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17730 if (TARGET_ALTIVEC_ABI)
17732 info_ptr->vrsave_save_offset
17733 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17735 /* Align stack so vector save area is on a quadword boundary.
17736 The padding goes above the vectors. */
17737 if (info_ptr->altivec_size != 0)
17738 info_ptr->altivec_padding_size
17739 = info_ptr->vrsave_save_offset & 0xF;
17741 info_ptr->altivec_padding_size = 0;
17743 info_ptr->altivec_save_offset
17744 = info_ptr->vrsave_save_offset
17745 - info_ptr->altivec_padding_size
17746 - info_ptr->altivec_size;
17747 gcc_assert (info_ptr->altivec_size == 0
17748 || info_ptr->altivec_save_offset % 16 == 0);
17750 /* Adjust for AltiVec case. */
17751 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17754 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17755 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17756 info_ptr->lr_save_offset = 2*reg_size;
17760 info_ptr->fp_save_offset = - info_ptr->fp_size;
17761 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17762 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17764 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17766 /* Align stack so SPE GPR save area is aligned on a
17767 double-word boundary. */
17768 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17769 info_ptr->spe_padding_size
17770 = 8 - (-info_ptr->cr_save_offset % 8);
17772 info_ptr->spe_padding_size = 0;
17774 info_ptr->spe_gp_save_offset
17775 = info_ptr->cr_save_offset
17776 - info_ptr->spe_padding_size
17777 - info_ptr->spe_gp_size;
17779 /* Adjust for SPE case. */
17780 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17782 else if (TARGET_ALTIVEC_ABI)
17784 info_ptr->vrsave_save_offset
17785 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17787 /* Align stack so vector save area is on a quadword boundary. */
17788 if (info_ptr->altivec_size != 0)
17789 info_ptr->altivec_padding_size
17790 = 16 - (-info_ptr->vrsave_save_offset % 16);
17792 info_ptr->altivec_padding_size = 0;
17794 info_ptr->altivec_save_offset
17795 = info_ptr->vrsave_save_offset
17796 - info_ptr->altivec_padding_size
17797 - info_ptr->altivec_size;
17799 /* Adjust for AltiVec case. */
17800 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17803 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17804 info_ptr->ehrd_offset -= ehrd_size;
17805 info_ptr->lr_save_offset = reg_size;
17809 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17810 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17811 + info_ptr->gp_size
17812 + info_ptr->altivec_size
17813 + info_ptr->altivec_padding_size
17814 + info_ptr->spe_gp_size
17815 + info_ptr->spe_padding_size
17817 + info_ptr->cr_size
17818 + info_ptr->vrsave_size,
17821 non_fixed_size = (info_ptr->vars_size
17822 + info_ptr->parm_size
17823 + info_ptr->save_size);
17825 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17826 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17828 /* Determine if we need to allocate any stack frame:
17830 For AIX we need to push the stack if a frame pointer is needed
17831 (because the stack might be dynamically adjusted), if we are
17832 debugging, if we make calls, or if the sum of fp_save, gp_save,
17833 and local variables are more than the space needed to save all
17834 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17835 + 18*8 = 288 (GPR13 reserved).
17837 For V.4 we don't have the stack cushion that AIX uses, but assume
17838 that the debugger can handle stackless frames. */
17840 if (info_ptr->calls_p)
17841 info_ptr->push_p = 1;
17843 else if (DEFAULT_ABI == ABI_V4)
17844 info_ptr->push_p = non_fixed_size != 0;
17846 else if (frame_pointer_needed)
17847 info_ptr->push_p = 1;
17849 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17850 info_ptr->push_p = 1;
17853 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17855 /* Zero offsets if we're not saving those registers. */
17856 if (info_ptr->fp_size == 0)
17857 info_ptr->fp_save_offset = 0;
17859 if (info_ptr->gp_size == 0)
17860 info_ptr->gp_save_offset = 0;
17862 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17863 info_ptr->altivec_save_offset = 0;
17865 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17866 info_ptr->vrsave_save_offset = 0;
17868 if (! TARGET_SPE_ABI
17869 || info_ptr->spe_64bit_regs_used == 0
17870 || info_ptr->spe_gp_size == 0)
17871 info_ptr->spe_gp_save_offset = 0;
17873 if (! info_ptr->lr_save_p)
17874 info_ptr->lr_save_offset = 0;
17876 if (! info_ptr->cr_save_p)
17877 info_ptr->cr_save_offset = 0;
17882 /* Return true if the current function uses any GPRs in 64-bit SIMD
17886 spe_func_has_64bit_regs_p (void)
17890 /* Functions that save and restore all the call-saved registers will
17891 need to save/restore the registers in 64-bits. */
17892 if (crtl->calls_eh_return
17893 || cfun->calls_setjmp
17894 || crtl->has_nonlocal_goto)
17897 insns = get_insns ();
17899 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17905 /* FIXME: This should be implemented with attributes...
17907 (set_attr "spe64" "true")....then,
17908 if (get_spe64(insn)) return true;
17910 It's the only reliable way to do the stuff below. */
17912 i = PATTERN (insn);
17913 if (GET_CODE (i) == SET)
17915 enum machine_mode mode = GET_MODE (SET_SRC (i));
17917 if (SPE_VECTOR_MODE (mode))
17919 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17929 debug_stack_info (rs6000_stack_t *info)
17931 const char *abi_string;
17934 info = rs6000_stack_info ();
17936 fprintf (stderr, "\nStack information for function %s:\n",
17937 ((current_function_decl && DECL_NAME (current_function_decl))
17938 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17943 default: abi_string = "Unknown"; break;
17944 case ABI_NONE: abi_string = "NONE"; break;
17945 case ABI_AIX: abi_string = "AIX"; break;
17946 case ABI_DARWIN: abi_string = "Darwin"; break;
17947 case ABI_V4: abi_string = "V.4"; break;
17950 fprintf (stderr, "\tABI = %5s\n", abi_string);
17952 if (TARGET_ALTIVEC_ABI)
17953 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17955 if (TARGET_SPE_ABI)
17956 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17958 if (info->first_gp_reg_save != 32)
17959 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17961 if (info->first_fp_reg_save != 64)
17962 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17964 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17965 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17966 info->first_altivec_reg_save);
17968 if (info->lr_save_p)
17969 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17971 if (info->cr_save_p)
17972 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17974 if (info->vrsave_mask)
17975 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17978 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17981 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17983 if (info->gp_save_offset)
17984 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17986 if (info->fp_save_offset)
17987 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17989 if (info->altivec_save_offset)
17990 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17991 info->altivec_save_offset);
17993 if (info->spe_gp_save_offset)
17994 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17995 info->spe_gp_save_offset);
17997 if (info->vrsave_save_offset)
17998 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17999 info->vrsave_save_offset);
18001 if (info->lr_save_offset)
18002 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18004 if (info->cr_save_offset)
18005 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18007 if (info->varargs_save_offset)
18008 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18010 if (info->total_size)
18011 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18014 if (info->vars_size)
18015 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18018 if (info->parm_size)
18019 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18021 if (info->fixed_size)
18022 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18025 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18027 if (info->spe_gp_size)
18028 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18031 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18033 if (info->altivec_size)
18034 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18036 if (info->vrsave_size)
18037 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18039 if (info->altivec_padding_size)
18040 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18041 info->altivec_padding_size);
18043 if (info->spe_padding_size)
18044 fprintf (stderr, "\tspe_padding_size = %5d\n",
18045 info->spe_padding_size);
18048 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18050 if (info->save_size)
18051 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18053 if (info->reg_size != 4)
18054 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18056 fprintf (stderr, "\n");
18060 rs6000_return_addr (int count, rtx frame)
18062 /* Currently we don't optimize very well between prolog and body
18063 code and for PIC code the code can be actually quite bad, so
18064 don't try to be too clever here. */
18065 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18067 cfun->machine->ra_needs_full_frame = 1;
18074 plus_constant (copy_to_reg
18075 (gen_rtx_MEM (Pmode,
18076 memory_address (Pmode, frame))),
18077 RETURN_ADDRESS_OFFSET)));
18080 cfun->machine->ra_need_lr = 1;
18081 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18084 /* Say whether a function is a candidate for sibcall handling or not.
18085 We do not allow indirect calls to be optimized into sibling calls.
18086 Also, we can't do it if there are any vector parameters; there's
18087 nowhere to put the VRsave code so it works; note that functions with
18088 vector parameters are required to have a prototype, so the argument
18089 type info must be available here. (The tail recursion case can work
18090 with vector parameters, but there's no way to distinguish here.) */
18092 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
18097 if (TARGET_ALTIVEC_VRSAVE)
18099 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
18100 type; type = TREE_CHAIN (type))
18102 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
18106 if (DEFAULT_ABI == ABI_DARWIN
18107 || ((*targetm.binds_local_p) (decl)
18108 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
18110 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
18112 if (!lookup_attribute ("longcall", attr_list)
18113 || lookup_attribute ("shortcall", attr_list))
18120 /* NULL if INSN insn is valid within a low-overhead loop.
18121 Otherwise return why doloop cannot be applied.
18122 PowerPC uses the COUNT register for branch on table instructions. */
18124 static const char *
18125 rs6000_invalid_within_doloop (const_rtx insn)
18128 return "Function call in the loop.";
18131 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18132 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18133 return "Computed branch in the loop.";
18139 rs6000_ra_ever_killed (void)
18145 if (cfun->is_thunk)
18148 if (cfun->machine->lr_save_state)
18149 return cfun->machine->lr_save_state - 1;
18151 /* regs_ever_live has LR marked as used if any sibcalls are present,
18152 but this should not force saving and restoring in the
18153 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18154 clobbers LR, so that is inappropriate. */
18156 /* Also, the prologue can generate a store into LR that
18157 doesn't really count, like this:
18160 bcl to set PIC register
18164 When we're called from the epilogue, we need to avoid counting
18165 this as a store. */
18167 push_topmost_sequence ();
18168 top = get_insns ();
18169 pop_topmost_sequence ();
18170 reg = gen_rtx_REG (Pmode, LR_REGNO);
18172 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18178 if (!SIBLING_CALL_P (insn))
18181 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18183 else if (set_of (reg, insn) != NULL_RTX
18184 && !prologue_epilogue_contains (insn))
18191 /* Emit instructions needed to load the TOC register.
18192 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18193 a constant pool; or for SVR4 -fpic. */
18196 rs6000_emit_load_toc_table (int fromprolog)
18199 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18201 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18204 rtx lab, tmp1, tmp2, got;
18206 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18207 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18209 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18211 got = rs6000_got_sym ();
18212 tmp1 = tmp2 = dest;
18215 tmp1 = gen_reg_rtx (Pmode);
18216 tmp2 = gen_reg_rtx (Pmode);
18218 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18219 emit_move_insn (tmp1,
18220 gen_rtx_REG (Pmode, LR_REGNO));
18221 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18222 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18224 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18226 emit_insn (gen_load_toc_v4_pic_si ());
18227 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18229 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18232 rtx temp0 = (fromprolog
18233 ? gen_rtx_REG (Pmode, 0)
18234 : gen_reg_rtx (Pmode));
18240 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18241 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18243 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18244 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18246 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18247 emit_move_insn (dest,
18248 gen_rtx_REG (Pmode, LR_REGNO));
18249 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18255 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18256 lab = gen_label_rtx ();
18257 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18258 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18259 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18261 emit_insn (gen_addsi3 (dest, temp0, dest));
18263 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18265 /* This is for AIX code running in non-PIC ELF32. */
18268 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18269 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18271 emit_insn (gen_elf_high (dest, realsym));
18272 emit_insn (gen_elf_low (dest, dest, realsym));
18276 gcc_assert (DEFAULT_ABI == ABI_AIX);
18279 emit_insn (gen_load_toc_aix_si (dest));
18281 emit_insn (gen_load_toc_aix_di (dest));
18285 /* Emit instructions to restore the link register after determining where
18286 its value has been stored. */
18289 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18291 rs6000_stack_t *info = rs6000_stack_info ();
18294 operands[0] = source;
18295 operands[1] = scratch;
18297 if (info->lr_save_p)
18299 rtx frame_rtx = stack_pointer_rtx;
18300 HOST_WIDE_INT sp_offset = 0;
18303 if (frame_pointer_needed
18304 || cfun->calls_alloca
18305 || info->total_size > 32767)
18307 tmp = gen_frame_mem (Pmode, frame_rtx);
18308 emit_move_insn (operands[1], tmp);
18309 frame_rtx = operands[1];
18311 else if (info->push_p)
18312 sp_offset = info->total_size;
18314 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18315 tmp = gen_frame_mem (Pmode, tmp);
18316 emit_move_insn (tmp, operands[0]);
18319 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
18321 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18322 state of lr_save_p so any change from here on would be a bug. In
18323 particular, stop rs6000_ra_ever_killed from considering the SET
18324 of lr we may have added just above. */
18325 cfun->machine->lr_save_state = info->lr_save_p + 1;
18328 static GTY(()) alias_set_type set = -1;
18331 get_TOC_alias_set (void)
18334 set = new_alias_set ();
18338 /* This returns nonzero if the current function uses the TOC. This is
18339 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
18340 is generated by the ABI_V4 load_toc_* patterns. */
18347 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
18350 rtx pat = PATTERN (insn);
18353 if (GET_CODE (pat) == PARALLEL)
18354 for (i = 0; i < XVECLEN (pat, 0); i++)
18356 rtx sub = XVECEXP (pat, 0, i);
18357 if (GET_CODE (sub) == USE)
18359 sub = XEXP (sub, 0);
18360 if (GET_CODE (sub) == UNSPEC
18361 && XINT (sub, 1) == UNSPEC_TOC)
18371 create_TOC_reference (rtx symbol, rtx largetoc_reg)
18373 rtx tocrel, tocreg;
18375 if (TARGET_DEBUG_ADDR)
18377 if (GET_CODE (symbol) == SYMBOL_REF)
18378 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
18382 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
18383 GET_RTX_NAME (GET_CODE (symbol)));
18384 debug_rtx (symbol);
18388 if (!can_create_pseudo_p ())
18389 df_set_regs_ever_live (TOC_REGISTER, true);
18391 tocrel = gen_rtx_CONST (Pmode,
18392 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
18394 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
18395 if (TARGET_CMODEL != CMODEL_SMALL)
18397 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
18398 if (largetoc_reg != NULL)
18400 emit_move_insn (largetoc_reg, hi);
18403 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
18406 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
18409 /* Issue assembly directives that create a reference to the given DWARF
18410 FRAME_TABLE_LABEL from the current function section. */
18412 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
18414 fprintf (asm_out_file, "\t.ref %s\n",
18415 TARGET_STRIP_NAME_ENCODING (frame_table_label));
18418 /* If _Unwind_* has been called from within the same module,
18419 toc register is not guaranteed to be saved to 40(1) on function
18420 entry. Save it there in that case. */
18423 rs6000_aix_emit_builtin_unwind_init (void)
18426 rtx stack_top = gen_reg_rtx (Pmode);
18427 rtx opcode_addr = gen_reg_rtx (Pmode);
18428 rtx opcode = gen_reg_rtx (SImode);
18429 rtx tocompare = gen_reg_rtx (SImode);
18430 rtx no_toc_save_needed = gen_label_rtx ();
18432 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
18433 emit_move_insn (stack_top, mem);
18435 mem = gen_frame_mem (Pmode,
18436 gen_rtx_PLUS (Pmode, stack_top,
18437 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
18438 emit_move_insn (opcode_addr, mem);
18439 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
18440 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
18441 : 0xE8410028, SImode));
18443 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
18444 SImode, NULL_RTX, NULL_RTX,
18445 no_toc_save_needed, -1);
18447 mem = gen_frame_mem (Pmode,
18448 gen_rtx_PLUS (Pmode, stack_top,
18449 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
18450 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
18451 emit_label (no_toc_save_needed);
18454 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18455 and the change to the stack pointer. */
18458 rs6000_emit_stack_tie (void)
18460 rtx mem = gen_frame_mem (BLKmode,
18461 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
18463 emit_insn (gen_stack_tie (mem));
18466 /* Emit the correct code for allocating stack space, as insns.
18467 If COPY_REG, make sure a copy of the old frame is left there.
18468 The generated code may use hard register 0 as a temporary. */
18471 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
18474 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18475 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
18476 rtx todec = gen_int_mode (-size, Pmode);
18479 if (INTVAL (todec) != -size)
18481 warning (0, "stack frame too large");
18482 emit_insn (gen_trap ());
18486 if (crtl->limit_stack)
18488 if (REG_P (stack_limit_rtx)
18489 && REGNO (stack_limit_rtx) > 1
18490 && REGNO (stack_limit_rtx) <= 31)
18492 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
18493 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18496 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
18498 && DEFAULT_ABI == ABI_V4)
18500 rtx toload = gen_rtx_CONST (VOIDmode,
18501 gen_rtx_PLUS (Pmode,
18505 emit_insn (gen_elf_high (tmp_reg, toload));
18506 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
18507 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18511 warning (0, "stack limit expression is not supported");
18515 emit_move_insn (copy_reg, stack_reg);
18519 /* Need a note here so that try_split doesn't get confused. */
18520 if (get_last_insn () == NULL_RTX)
18521 emit_note (NOTE_INSN_DELETED);
18522 insn = emit_move_insn (tmp_reg, todec);
18523 try_split (PATTERN (insn), insn, 0);
18527 insn = emit_insn (TARGET_32BIT
18528 ? gen_movsi_update_stack (stack_reg, stack_reg,
18530 : gen_movdi_di_update_stack (stack_reg, stack_reg,
18531 todec, stack_reg));
18532 /* Since we didn't use gen_frame_mem to generate the MEM, grab
18533 it now and set the alias set/attributes. The above gen_*_update
18534 calls will generate a PARALLEL with the MEM set being the first
18536 par = PATTERN (insn);
18537 gcc_assert (GET_CODE (par) == PARALLEL);
18538 set = XVECEXP (par, 0, 0);
18539 gcc_assert (GET_CODE (set) == SET);
18540 mem = SET_DEST (set);
18541 gcc_assert (MEM_P (mem));
18542 MEM_NOTRAP_P (mem) = 1;
18543 set_mem_alias_set (mem, get_frame_alias_set ());
18545 RTX_FRAME_RELATED_P (insn) = 1;
18546 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
18547 gen_rtx_SET (VOIDmode, stack_reg,
18548 gen_rtx_PLUS (Pmode, stack_reg,
18549 GEN_INT (-size))));
18552 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
18553 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
18554 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
18555 deduce these equivalences by itself so it wasn't necessary to hold
18556 its hand so much. */
18559 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
18560 rtx reg2, rtx rreg)
18564 /* copy_rtx will not make unique copies of registers, so we need to
18565 ensure we don't have unwanted sharing here. */
18567 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18570 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18572 real = copy_rtx (PATTERN (insn));
18574 if (reg2 != NULL_RTX)
18575 real = replace_rtx (real, reg2, rreg);
18577 real = replace_rtx (real, reg,
18578 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
18579 STACK_POINTER_REGNUM),
18582 /* We expect that 'real' is either a SET or a PARALLEL containing
18583 SETs (and possibly other stuff). In a PARALLEL, all the SETs
18584 are important so they all have to be marked RTX_FRAME_RELATED_P. */
18586 if (GET_CODE (real) == SET)
18590 temp = simplify_rtx (SET_SRC (set));
18592 SET_SRC (set) = temp;
18593 temp = simplify_rtx (SET_DEST (set));
18595 SET_DEST (set) = temp;
18596 if (GET_CODE (SET_DEST (set)) == MEM)
18598 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18600 XEXP (SET_DEST (set), 0) = temp;
18607 gcc_assert (GET_CODE (real) == PARALLEL);
18608 for (i = 0; i < XVECLEN (real, 0); i++)
18609 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
18611 rtx set = XVECEXP (real, 0, i);
18613 temp = simplify_rtx (SET_SRC (set));
18615 SET_SRC (set) = temp;
18616 temp = simplify_rtx (SET_DEST (set));
18618 SET_DEST (set) = temp;
18619 if (GET_CODE (SET_DEST (set)) == MEM)
18621 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18623 XEXP (SET_DEST (set), 0) = temp;
18625 RTX_FRAME_RELATED_P (set) = 1;
18629 RTX_FRAME_RELATED_P (insn) = 1;
18630 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
18633 /* Returns an insn that has a vrsave set operation with the
18634 appropriate CLOBBERs. */
18637 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
18640 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
18641 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18644 = gen_rtx_SET (VOIDmode,
18646 gen_rtx_UNSPEC_VOLATILE (SImode,
18647 gen_rtvec (2, reg, vrsave),
18648 UNSPECV_SET_VRSAVE));
18652 /* We need to clobber the registers in the mask so the scheduler
18653 does not move sets to VRSAVE before sets of AltiVec registers.
18655 However, if the function receives nonlocal gotos, reload will set
18656 all call saved registers live. We will end up with:
18658 (set (reg 999) (mem))
18659 (parallel [ (set (reg vrsave) (unspec blah))
18660 (clobber (reg 999))])
18662 The clobber will cause the store into reg 999 to be dead, and
18663 flow will attempt to delete an epilogue insn. In this case, we
18664 need an unspec use/set of the register. */
18666 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18667 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18669 if (!epiloguep || call_used_regs [i])
18670 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
18671 gen_rtx_REG (V4SImode, i));
18674 rtx reg = gen_rtx_REG (V4SImode, i);
18677 = gen_rtx_SET (VOIDmode,
18679 gen_rtx_UNSPEC (V4SImode,
18680 gen_rtvec (1, reg), 27));
18684 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
18686 for (i = 0; i < nclobs; ++i)
18687 XVECEXP (insn, 0, i) = clobs[i];
18692 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
18693 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
18696 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
18697 unsigned int regno, int offset, HOST_WIDE_INT total_size)
18699 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
18700 rtx replacea, replaceb;
18702 int_rtx = GEN_INT (offset);
18704 /* Some cases that need register indexed addressing. */
18705 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
18706 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
18707 || (TARGET_E500_DOUBLE && mode == DFmode)
18709 && SPE_VECTOR_MODE (mode)
18710 && !SPE_CONST_OFFSET_OK (offset)))
18712 /* Whomever calls us must make sure r11 is available in the
18713 flow path of instructions in the prologue. */
18714 offset_rtx = gen_rtx_REG (Pmode, 11);
18715 emit_move_insn (offset_rtx, int_rtx);
18717 replacea = offset_rtx;
18718 replaceb = int_rtx;
18722 offset_rtx = int_rtx;
18723 replacea = NULL_RTX;
18724 replaceb = NULL_RTX;
18727 reg = gen_rtx_REG (mode, regno);
18728 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18729 mem = gen_frame_mem (mode, addr);
18731 insn = emit_move_insn (mem, reg);
18733 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18736 /* Emit an offset memory reference suitable for a frame store, while
18737 converting to a valid addressing mode. */
18740 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18742 rtx int_rtx, offset_rtx;
18744 int_rtx = GEN_INT (offset);
18746 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18747 || (TARGET_E500_DOUBLE && mode == DFmode))
18749 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18750 emit_move_insn (offset_rtx, int_rtx);
18753 offset_rtx = int_rtx;
18755 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18758 /* Look for user-defined global regs. We should not save and restore these,
18759 and cannot use stmw/lmw if there are any in its range. */
18762 no_global_regs_above (int first, bool gpr)
18765 int last = gpr ? 32 : 64;
18766 for (i = first; i < last; i++)
18767 if (global_regs[i])
18772 #ifndef TARGET_FIX_AND_CONTINUE
18773 #define TARGET_FIX_AND_CONTINUE 0
18776 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18777 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18778 #define LAST_SAVRES_REGISTER 31
18779 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18781 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18783 /* Temporary holding space for an out-of-line register save/restore
18785 static char savres_routine_name[30];
18787 /* Return the name for an out-of-line register save/restore routine.
18788 We are saving/restoring GPRs if GPR is true. */
18791 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18792 bool savep, bool gpr, bool lr)
18794 const char *prefix = "";
18795 const char *suffix = "";
18797 /* Different targets are supposed to define
18798 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18799 routine name could be defined with:
18801 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18803 This is a nice idea in practice, but in reality, things are
18804 complicated in several ways:
18806 - ELF targets have save/restore routines for GPRs.
18808 - SPE targets use different prefixes for 32/64-bit registers, and
18809 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18811 - PPC64 ELF targets have routines for save/restore of GPRs that
18812 differ in what they do with the link register, so having a set
18813 prefix doesn't work. (We only use one of the save routines at
18814 the moment, though.)
18816 - PPC32 elf targets have "exit" versions of the restore routines
18817 that restore the link register and can save some extra space.
18818 These require an extra suffix. (There are also "tail" versions
18819 of the restore routines and "GOT" versions of the save routines,
18820 but we don't generate those at present. Same problems apply,
18823 We deal with all this by synthesizing our own prefix/suffix and
18824 using that for the simple sprintf call shown above. */
18827 /* No floating point saves on the SPE. */
18831 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
18833 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
18838 else if (DEFAULT_ABI == ABI_V4)
18844 prefix = savep ? "_savegpr_" : "_restgpr_";
18846 prefix = savep ? "_savefpr_" : "_restfpr_";
18851 else if (DEFAULT_ABI == ABI_AIX)
18853 #ifndef POWERPC_LINUX
18854 /* No out-of-line save/restore routines for GPRs on AIX. */
18855 gcc_assert (!TARGET_AIX || !gpr);
18861 ? (lr ? "_savegpr0_" : "_savegpr1_")
18862 : (lr ? "_restgpr0_" : "_restgpr1_"));
18863 #ifdef POWERPC_LINUX
18865 prefix = (savep ? "_savefpr_" : "_restfpr_");
18869 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
18870 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
18873 else if (DEFAULT_ABI == ABI_DARWIN)
18874 sorry ("Out-of-line save/restore routines not supported on Darwin");
18876 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
18878 return savres_routine_name;
18881 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18882 We are saving/restoring GPRs if GPR is true. */
18885 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
18888 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18890 int select = ((savep ? 1 : 0) << 2
18892 /* On the SPE, we never have any FPRs, but we do have
18893 32/64-bit versions of the routines. */
18894 ? (info->spe_64bit_regs_used ? 1 : 0)
18895 : (gpr ? 1 : 0)) << 1)
18898 /* Don't generate bogus routine names. */
18899 gcc_assert (FIRST_SAVRES_REGISTER <= regno
18900 && regno <= LAST_SAVRES_REGISTER);
18902 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18908 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
18910 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18911 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18912 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
18918 /* Emit a sequence of insns, including a stack tie if needed, for
18919 resetting the stack pointer. If SAVRES is true, then don't reset the
18920 stack pointer, but move the base of the frame into r11 for use by
18921 out-of-line register restore routines. */
18924 rs6000_emit_stack_reset (rs6000_stack_t *info,
18925 rtx sp_reg_rtx, rtx frame_reg_rtx,
18926 int sp_offset, bool savres)
18928 /* This blockage is needed so that sched doesn't decide to move
18929 the sp change before the register restores. */
18930 if (frame_reg_rtx != sp_reg_rtx
18932 && info->spe_64bit_regs_used != 0
18933 && info->first_gp_reg_save != 32))
18934 rs6000_emit_stack_tie ();
18936 if (frame_reg_rtx != sp_reg_rtx)
18938 if (sp_offset != 0)
18940 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
18941 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
18942 GEN_INT (sp_offset)));
18945 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18947 else if (sp_offset != 0)
18949 /* If we are restoring registers out-of-line, we will be using the
18950 "exit" variants of the restore routines, which will reset the
18951 stack for us. But we do need to point r11 into the right place
18952 for those routines. */
18953 rtx dest_reg = (savres
18954 ? gen_rtx_REG (Pmode, 11)
18957 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18958 GEN_INT (sp_offset)));
18965 /* Construct a parallel rtx describing the effect of a call to an
18966 out-of-line register save/restore routine. */
18969 rs6000_make_savres_rtx (rs6000_stack_t *info,
18970 rtx frame_reg_rtx, int save_area_offset,
18971 enum machine_mode reg_mode,
18972 bool savep, bool gpr, bool lr)
18975 int offset, start_reg, end_reg, n_regs;
18976 int reg_size = GET_MODE_SIZE (reg_mode);
18982 ? info->first_gp_reg_save
18983 : info->first_fp_reg_save);
18984 end_reg = gpr ? 32 : 64;
18985 n_regs = end_reg - start_reg;
18986 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
18989 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18991 RTVEC_ELT (p, offset++)
18992 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18994 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
18995 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18996 RTVEC_ELT (p, offset++)
18997 = gen_rtx_USE (VOIDmode,
18998 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19002 for (i = 0; i < end_reg - start_reg; i++)
19004 rtx addr, reg, mem;
19005 reg = gen_rtx_REG (reg_mode, start_reg + i);
19006 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19007 GEN_INT (save_area_offset + reg_size*i));
19008 mem = gen_frame_mem (reg_mode, addr);
19010 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19012 savep ? reg : mem);
19017 rtx addr, reg, mem;
19018 reg = gen_rtx_REG (Pmode, 0);
19019 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19020 GEN_INT (info->lr_save_offset));
19021 mem = gen_frame_mem (Pmode, addr);
19022 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19025 return gen_rtx_PARALLEL (VOIDmode, p);
19028 /* Determine whether the gp REG is really used. */
19031 rs6000_reg_live_or_pic_offset_p (int reg)
19033 return ((df_regs_ever_live_p (reg)
19034 && (!call_used_regs[reg]
19035 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19036 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19037 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19038 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19039 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19043 SAVRES_MULTIPLE = 0x1,
19044 SAVRES_INLINE_FPRS = 0x2,
19045 SAVRES_INLINE_GPRS = 0x4,
19046 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
19047 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
19048 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
19051 /* Determine the strategy for savings/restoring registers. */
19054 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
19055 int using_static_chain_p, int sibcall)
19057 bool using_multiple_p;
19059 bool savres_fprs_inline;
19060 bool savres_gprs_inline;
19061 bool noclobber_global_gprs
19062 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
19065 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
19066 && (!TARGET_SPE_ABI
19067 || info->spe_64bit_regs_used == 0)
19068 && info->first_gp_reg_save < 31
19069 && noclobber_global_gprs);
19070 /* Don't bother to try to save things out-of-line if r11 is occupied
19071 by the static chain. It would require too much fiddling and the
19072 static chain is rarely used anyway. */
19073 common = (using_static_chain_p
19075 || crtl->calls_eh_return
19076 || !info->lr_save_p
19077 || cfun->machine->ra_need_lr
19078 || info->total_size > 32767);
19079 savres_fprs_inline = (common
19080 || info->first_fp_reg_save == 64
19081 || !no_global_regs_above (info->first_fp_reg_save,
19083 /* The out-of-line FP routines use
19084 double-precision stores; we can't use those
19085 routines if we don't have such stores. */
19086 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
19087 || FP_SAVE_INLINE (info->first_fp_reg_save));
19088 savres_gprs_inline = (common
19089 /* Saving CR interferes with the exit routines
19090 used on the SPE, so just punt here. */
19093 && info->spe_64bit_regs_used != 0
19094 && info->cr_save_p != 0)
19095 || info->first_gp_reg_save == 32
19096 || !noclobber_global_gprs
19097 || GP_SAVE_INLINE (info->first_gp_reg_save));
19100 /* If we are going to use store multiple, then don't even bother
19101 with the out-of-line routines, since the store-multiple instruction
19102 will always be smaller. */
19103 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19106 /* The situation is more complicated with load multiple. We'd
19107 prefer to use the out-of-line routines for restores, since the
19108 "exit" out-of-line routines can handle the restore of LR and
19109 the frame teardown. But we can only use the out-of-line
19110 routines if we know that we've used store multiple or
19111 out-of-line routines in the prologue, i.e. if we've saved all
19112 the registers from first_gp_reg_save. Otherwise, we risk
19113 loading garbage from the stack. Furthermore, we can only use
19114 the "exit" out-of-line gpr restore if we haven't saved any
19116 bool saved_all = !savres_gprs_inline || using_multiple_p;
19118 if (saved_all && info->first_fp_reg_save != 64)
19119 /* We can't use the exit routine; use load multiple if it's
19121 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19124 strategy = (using_multiple_p
19125 | (savres_fprs_inline << 1)
19126 | (savres_gprs_inline << 2));
19127 #ifdef POWERPC_LINUX
19130 if (!savres_fprs_inline)
19131 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
19132 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
19133 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
19136 if (TARGET_AIX && !savres_fprs_inline)
19137 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
19142 /* Emit function prologue as insns. */
19145 rs6000_emit_prologue (void)
19147 rs6000_stack_t *info = rs6000_stack_info ();
19148 enum machine_mode reg_mode = Pmode;
19149 int reg_size = TARGET_32BIT ? 4 : 8;
19150 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19151 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19152 rtx frame_reg_rtx = sp_reg_rtx;
19153 rtx cr_save_rtx = NULL_RTX;
19156 int saving_FPRs_inline;
19157 int saving_GPRs_inline;
19158 int using_store_multiple;
19159 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19160 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19161 && call_used_regs[STATIC_CHAIN_REGNUM]);
19162 HOST_WIDE_INT sp_offset = 0;
19164 if (TARGET_FIX_AND_CONTINUE)
19166 /* gdb on darwin arranges to forward a function from the old
19167 address by modifying the first 5 instructions of the function
19168 to branch to the overriding function. This is necessary to
19169 permit function pointers that point to the old function to
19170 actually forward to the new function. */
19171 emit_insn (gen_nop ());
19172 emit_insn (gen_nop ());
19173 emit_insn (gen_nop ());
19174 emit_insn (gen_nop ());
19175 emit_insn (gen_nop ());
19178 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19180 reg_mode = V2SImode;
19184 strategy = rs6000_savres_strategy (info, /*savep=*/true,
19185 /*static_chain_p=*/using_static_chain_p,
19187 using_store_multiple = strategy & SAVRES_MULTIPLE;
19188 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19189 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19191 /* For V.4, update stack before we do any saving and set back pointer. */
19192 if (! WORLD_SAVE_P (info)
19194 && (DEFAULT_ABI == ABI_V4
19195 || crtl->calls_eh_return))
19197 bool need_r11 = (TARGET_SPE
19198 ? (!saving_GPRs_inline
19199 && info->spe_64bit_regs_used == 0)
19200 : (!saving_FPRs_inline || !saving_GPRs_inline));
19201 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19203 if (info->total_size < 32767)
19204 sp_offset = info->total_size;
19206 frame_reg_rtx = copy_reg;
19207 else if (info->cr_save_p
19209 || info->first_fp_reg_save < 64
19210 || info->first_gp_reg_save < 32
19211 || info->altivec_size != 0
19212 || info->vrsave_mask != 0
19213 || crtl->calls_eh_return)
19215 copy_reg = frame_ptr_rtx;
19216 frame_reg_rtx = copy_reg;
19220 /* The prologue won't be saving any regs so there is no need
19221 to set up a frame register to access any frame save area.
19222 We also won't be using sp_offset anywhere below, but set
19223 the correct value anyway to protect against future
19224 changes to this function. */
19225 sp_offset = info->total_size;
19227 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19228 if (frame_reg_rtx != sp_reg_rtx)
19229 rs6000_emit_stack_tie ();
19232 /* Handle world saves specially here. */
19233 if (WORLD_SAVE_P (info))
19240 /* save_world expects lr in r0. */
19241 reg0 = gen_rtx_REG (Pmode, 0);
19242 if (info->lr_save_p)
19244 insn = emit_move_insn (reg0,
19245 gen_rtx_REG (Pmode, LR_REGNO));
19246 RTX_FRAME_RELATED_P (insn) = 1;
19249 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19250 assumptions about the offsets of various bits of the stack
19252 gcc_assert (info->gp_save_offset == -220
19253 && info->fp_save_offset == -144
19254 && info->lr_save_offset == 8
19255 && info->cr_save_offset == 4
19258 && (!crtl->calls_eh_return
19259 || info->ehrd_offset == -432)
19260 && info->vrsave_save_offset == -224
19261 && info->altivec_save_offset == -416);
19263 treg = gen_rtx_REG (SImode, 11);
19264 emit_move_insn (treg, GEN_INT (-info->total_size));
19266 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19267 in R11. It also clobbers R12, so beware! */
19269 /* Preserve CR2 for save_world prologues */
19271 sz += 32 - info->first_gp_reg_save;
19272 sz += 64 - info->first_fp_reg_save;
19273 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19274 p = rtvec_alloc (sz);
19276 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19277 gen_rtx_REG (SImode,
19279 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19280 gen_rtx_SYMBOL_REF (Pmode,
19282 /* We do floats first so that the instruction pattern matches
19284 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19286 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19287 ? DFmode : SFmode),
19288 info->first_fp_reg_save + i);
19289 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19290 GEN_INT (info->fp_save_offset
19291 + sp_offset + 8 * i));
19292 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19293 ? DFmode : SFmode), addr);
19295 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19297 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19299 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19300 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19301 GEN_INT (info->altivec_save_offset
19302 + sp_offset + 16 * i));
19303 rtx mem = gen_frame_mem (V4SImode, addr);
19305 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19307 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19309 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19310 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19311 GEN_INT (info->gp_save_offset
19312 + sp_offset + reg_size * i));
19313 rtx mem = gen_frame_mem (reg_mode, addr);
19315 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19319 /* CR register traditionally saved as CR2. */
19320 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19321 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19322 GEN_INT (info->cr_save_offset
19324 rtx mem = gen_frame_mem (reg_mode, addr);
19326 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19328 /* Explain about use of R0. */
19329 if (info->lr_save_p)
19331 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19332 GEN_INT (info->lr_save_offset
19334 rtx mem = gen_frame_mem (reg_mode, addr);
19336 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
19338 /* Explain what happens to the stack pointer. */
19340 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
19341 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
19344 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19345 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19346 treg, GEN_INT (-info->total_size));
19347 sp_offset = info->total_size;
19350 /* If we use the link register, get it into r0. */
19351 if (!WORLD_SAVE_P (info) && info->lr_save_p)
19353 rtx addr, reg, mem;
19355 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
19356 gen_rtx_REG (Pmode, LR_REGNO));
19357 RTX_FRAME_RELATED_P (insn) = 1;
19359 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
19360 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
19362 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19363 GEN_INT (info->lr_save_offset + sp_offset));
19364 reg = gen_rtx_REG (Pmode, 0);
19365 mem = gen_rtx_MEM (Pmode, addr);
19366 /* This should not be of rs6000_sr_alias_set, because of
19367 __builtin_return_address. */
19369 insn = emit_move_insn (mem, reg);
19370 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19371 NULL_RTX, NULL_RTX);
19375 /* If we need to save CR, put it into r12 or r11. */
19376 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
19381 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
19383 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19384 RTX_FRAME_RELATED_P (insn) = 1;
19385 /* Now, there's no way that dwarf2out_frame_debug_expr is going
19386 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
19387 But that's OK. All we have to do is specify that _one_ condition
19388 code register is saved in this stack slot. The thrower's epilogue
19389 will then restore all the call-saved registers.
19390 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
19391 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
19392 gen_rtx_REG (SImode, CR2_REGNO));
19393 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19396 /* Do any required saving of fpr's. If only one or two to save, do
19397 it ourselves. Otherwise, call function. */
19398 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
19401 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19402 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
19403 && ! call_used_regs[info->first_fp_reg_save+i]))
19404 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
19405 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19407 info->first_fp_reg_save + i,
19408 info->fp_save_offset + sp_offset + 8 * i,
19411 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
19415 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19416 info->fp_save_offset + sp_offset,
19418 /*savep=*/true, /*gpr=*/false,
19420 & SAVRES_NOINLINE_FPRS_SAVES_LR)
19422 insn = emit_insn (par);
19423 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19424 NULL_RTX, NULL_RTX);
19427 /* Save GPRs. This is done as a PARALLEL if we are using
19428 the store-multiple instructions. */
19429 if (!WORLD_SAVE_P (info)
19431 && info->spe_64bit_regs_used != 0
19432 && info->first_gp_reg_save != 32)
19435 rtx spe_save_area_ptr;
19437 /* Determine whether we can address all of the registers that need
19438 to be saved with an offset from the stack pointer that fits in
19439 the small const field for SPE memory instructions. */
19440 int spe_regs_addressable_via_sp
19441 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19442 + (32 - info->first_gp_reg_save - 1) * reg_size)
19443 && saving_GPRs_inline);
19446 if (spe_regs_addressable_via_sp)
19448 spe_save_area_ptr = frame_reg_rtx;
19449 spe_offset = info->spe_gp_save_offset + sp_offset;
19453 /* Make r11 point to the start of the SPE save area. We need
19454 to be careful here if r11 is holding the static chain. If
19455 it is, then temporarily save it in r0. We would use r0 as
19456 our base register here, but using r0 as a base register in
19457 loads and stores means something different from what we
19459 int ool_adjust = (saving_GPRs_inline
19461 : (info->first_gp_reg_save
19462 - (FIRST_SAVRES_REGISTER+1))*8);
19463 HOST_WIDE_INT offset = (info->spe_gp_save_offset
19464 + sp_offset - ool_adjust);
19466 if (using_static_chain_p)
19468 rtx r0 = gen_rtx_REG (Pmode, 0);
19469 gcc_assert (info->first_gp_reg_save > 11);
19471 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
19474 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
19475 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
19477 GEN_INT (offset)));
19478 /* We need to make sure the move to r11 gets noted for
19479 properly outputting unwind information. */
19480 if (!saving_GPRs_inline)
19481 rs6000_frame_related (insn, frame_reg_rtx, offset,
19482 NULL_RTX, NULL_RTX);
19486 if (saving_GPRs_inline)
19488 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19489 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19491 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19492 rtx offset, addr, mem;
19494 /* We're doing all this to ensure that the offset fits into
19495 the immediate offset of 'evstdd'. */
19496 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
19498 offset = GEN_INT (reg_size * i + spe_offset);
19499 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
19500 mem = gen_rtx_MEM (V2SImode, addr);
19502 insn = emit_move_insn (mem, reg);
19504 rs6000_frame_related (insn, spe_save_area_ptr,
19505 info->spe_gp_save_offset
19506 + sp_offset + reg_size * i,
19507 offset, const0_rtx);
19514 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19516 /*savep=*/true, /*gpr=*/true,
19518 insn = emit_insn (par);
19519 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19520 NULL_RTX, NULL_RTX);
19524 /* Move the static chain pointer back. */
19525 if (using_static_chain_p && !spe_regs_addressable_via_sp)
19526 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
19528 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
19532 /* Need to adjust r11 (r12) if we saved any FPRs. */
19533 if (info->first_fp_reg_save != 64)
19535 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
19537 rtx offset = GEN_INT (sp_offset
19538 + (-8 * (64-info->first_fp_reg_save)));
19539 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
19542 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19543 info->gp_save_offset + sp_offset,
19545 /*savep=*/true, /*gpr=*/true,
19547 & SAVRES_NOINLINE_GPRS_SAVES_LR)
19549 insn = emit_insn (par);
19550 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19551 NULL_RTX, NULL_RTX);
19553 else if (!WORLD_SAVE_P (info) && using_store_multiple)
19557 p = rtvec_alloc (32 - info->first_gp_reg_save);
19558 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19560 rtx addr, reg, mem;
19561 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19562 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19563 GEN_INT (info->gp_save_offset
19566 mem = gen_frame_mem (reg_mode, addr);
19568 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
19570 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19571 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19572 NULL_RTX, NULL_RTX);
19574 else if (!WORLD_SAVE_P (info))
19577 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19578 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19580 rtx addr, reg, mem;
19581 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19583 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19584 GEN_INT (info->gp_save_offset
19587 mem = gen_frame_mem (reg_mode, addr);
19589 insn = emit_move_insn (mem, reg);
19590 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19591 NULL_RTX, NULL_RTX);
19595 /* ??? There's no need to emit actual instructions here, but it's the
19596 easiest way to get the frame unwind information emitted. */
19597 if (crtl->calls_eh_return)
19599 unsigned int i, regno;
19601 /* In AIX ABI we need to pretend we save r2 here. */
19604 rtx addr, reg, mem;
19606 reg = gen_rtx_REG (reg_mode, 2);
19607 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19608 GEN_INT (sp_offset + 5 * reg_size));
19609 mem = gen_frame_mem (reg_mode, addr);
19611 insn = emit_move_insn (mem, reg);
19612 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19613 NULL_RTX, NULL_RTX);
19614 PATTERN (insn) = gen_blockage ();
19619 regno = EH_RETURN_DATA_REGNO (i);
19620 if (regno == INVALID_REGNUM)
19623 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
19624 info->ehrd_offset + sp_offset
19625 + reg_size * (int) i,
19630 /* Save CR if we use any that must be preserved. */
19631 if (!WORLD_SAVE_P (info) && info->cr_save_p)
19633 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19634 GEN_INT (info->cr_save_offset + sp_offset));
19635 rtx mem = gen_frame_mem (SImode, addr);
19636 /* See the large comment above about why CR2_REGNO is used. */
19637 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
19639 /* If r12 was used to hold the original sp, copy cr into r0 now
19641 if (REGNO (frame_reg_rtx) == 12)
19645 cr_save_rtx = gen_rtx_REG (SImode, 0);
19646 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19647 RTX_FRAME_RELATED_P (insn) = 1;
19648 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
19649 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19651 insn = emit_move_insn (mem, cr_save_rtx);
19653 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19654 NULL_RTX, NULL_RTX);
19657 /* Update stack and set back pointer unless this is V.4,
19658 for which it was done previously. */
19659 if (!WORLD_SAVE_P (info) && info->push_p
19660 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
19662 rtx copy_reg = NULL;
19664 if (info->total_size < 32767)
19665 sp_offset = info->total_size;
19666 else if (info->altivec_size != 0
19667 || info->vrsave_mask != 0)
19669 copy_reg = frame_ptr_rtx;
19670 frame_reg_rtx = copy_reg;
19673 sp_offset = info->total_size;
19674 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19675 if (frame_reg_rtx != sp_reg_rtx)
19676 rs6000_emit_stack_tie ();
19679 /* Set frame pointer, if needed. */
19680 if (frame_pointer_needed)
19682 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
19684 RTX_FRAME_RELATED_P (insn) = 1;
19687 /* Save AltiVec registers if needed. Save here because the red zone does
19688 not include AltiVec registers. */
19689 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
19693 /* There should be a non inline version of this, for when we
19694 are saving lots of vector registers. */
19695 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19696 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19698 rtx areg, savereg, mem;
19701 offset = info->altivec_save_offset + sp_offset
19702 + 16 * (i - info->first_altivec_reg_save);
19704 savereg = gen_rtx_REG (V4SImode, i);
19706 areg = gen_rtx_REG (Pmode, 0);
19707 emit_move_insn (areg, GEN_INT (offset));
19709 /* AltiVec addressing mode is [reg+reg]. */
19710 mem = gen_frame_mem (V4SImode,
19711 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
19713 insn = emit_move_insn (mem, savereg);
19715 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19716 areg, GEN_INT (offset));
19720 /* VRSAVE is a bit vector representing which AltiVec registers
19721 are used. The OS uses this to determine which vector
19722 registers to save on a context switch. We need to save
19723 VRSAVE on the stack frame, add whatever AltiVec registers we
19724 used in this function, and do the corresponding magic in the
19727 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
19728 && info->vrsave_mask != 0)
19730 rtx reg, mem, vrsave;
19733 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
19734 as frame_reg_rtx and r11 as the static chain pointer for
19735 nested functions. */
19736 reg = gen_rtx_REG (SImode, 0);
19737 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19739 emit_insn (gen_get_vrsave_internal (reg));
19741 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19743 if (!WORLD_SAVE_P (info))
19746 offset = info->vrsave_save_offset + sp_offset;
19747 mem = gen_frame_mem (SImode,
19748 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19749 GEN_INT (offset)));
19750 insn = emit_move_insn (mem, reg);
19753 /* Include the registers in the mask. */
19754 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19756 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19759 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19760 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19761 || (DEFAULT_ABI == ABI_V4
19762 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19763 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19765 /* If emit_load_toc_table will use the link register, we need to save
19766 it. We use R12 for this purpose because emit_load_toc_table
19767 can use register 0. This allows us to use a plain 'blr' to return
19768 from the procedure more often. */
19769 int save_LR_around_toc_setup = (TARGET_ELF
19770 && DEFAULT_ABI != ABI_AIX
19772 && ! info->lr_save_p
19773 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19774 if (save_LR_around_toc_setup)
19776 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19778 insn = emit_move_insn (frame_ptr_rtx, lr);
19779 RTX_FRAME_RELATED_P (insn) = 1;
19781 rs6000_emit_load_toc_table (TRUE);
19783 insn = emit_move_insn (lr, frame_ptr_rtx);
19784 RTX_FRAME_RELATED_P (insn) = 1;
19787 rs6000_emit_load_toc_table (TRUE);
19791 if (DEFAULT_ABI == ABI_DARWIN
19792 && flag_pic && crtl->uses_pic_offset_table)
19794 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19795 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19797 /* Save and restore LR locally around this call (in R0). */
19798 if (!info->lr_save_p)
19799 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19801 emit_insn (gen_load_macho_picbase (src));
19803 emit_move_insn (gen_rtx_REG (Pmode,
19804 RS6000_PIC_OFFSET_TABLE_REGNUM),
19807 if (!info->lr_save_p)
19808 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19813 /* Write function prologue. */
19816 rs6000_output_function_prologue (FILE *file,
19817 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19819 rs6000_stack_t *info = rs6000_stack_info ();
19821 if (TARGET_DEBUG_STACK)
19822 debug_stack_info (info);
19824 /* Write .extern for any function we will call to save and restore
19826 if (info->first_fp_reg_save < 64
19827 && !FP_SAVE_INLINE (info->first_fp_reg_save))
19830 int regno = info->first_fp_reg_save - 32;
19832 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
19833 /*gpr=*/false, /*lr=*/false);
19834 fprintf (file, "\t.extern %s\n", name);
19836 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
19837 /*gpr=*/false, /*lr=*/true);
19838 fprintf (file, "\t.extern %s\n", name);
19841 /* Write .extern for AIX common mode routines, if needed. */
19842 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
19844 fputs ("\t.extern __mulh\n", file);
19845 fputs ("\t.extern __mull\n", file);
19846 fputs ("\t.extern __divss\n", file);
19847 fputs ("\t.extern __divus\n", file);
19848 fputs ("\t.extern __quoss\n", file);
19849 fputs ("\t.extern __quous\n", file);
19850 common_mode_defined = 1;
19853 if (! HAVE_prologue)
19859 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19860 the "toplevel" insn chain. */
19861 emit_note (NOTE_INSN_DELETED);
19862 rs6000_emit_prologue ();
19863 emit_note (NOTE_INSN_DELETED);
19865 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19869 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19871 INSN_ADDRESSES_NEW (insn, addr);
19876 prologue = get_insns ();
19879 if (TARGET_DEBUG_STACK)
19880 debug_rtx_list (prologue, 100);
19882 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
19886 rs6000_pic_labelno++;
19889 /* Non-zero if vmx regs are restored before the frame pop, zero if
19890 we restore after the pop when possible. */
19891 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19893 /* Reload CR from REG. */
19896 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
19901 if (using_mfcr_multiple)
19903 for (i = 0; i < 8; i++)
19904 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19906 gcc_assert (count);
19909 if (using_mfcr_multiple && count > 1)
19914 p = rtvec_alloc (count);
19917 for (i = 0; i < 8; i++)
19918 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19920 rtvec r = rtvec_alloc (2);
19921 RTVEC_ELT (r, 0) = reg;
19922 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19923 RTVEC_ELT (p, ndx) =
19924 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19925 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19928 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19929 gcc_assert (ndx == count);
19932 for (i = 0; i < 8; i++)
19933 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19935 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19941 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19942 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19943 below stack pointer not cloberred by signals. */
19946 offset_below_red_zone_p (HOST_WIDE_INT offset)
19948 return offset < (DEFAULT_ABI == ABI_V4
19950 : TARGET_32BIT ? -220 : -288);
19953 /* Emit function epilogue as insns. */
19956 rs6000_emit_epilogue (int sibcall)
19958 rs6000_stack_t *info;
19959 int restoring_GPRs_inline;
19960 int restoring_FPRs_inline;
19961 int using_load_multiple;
19962 int using_mtcr_multiple;
19963 int use_backchain_to_restore_sp;
19967 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19968 rtx frame_reg_rtx = sp_reg_rtx;
19969 rtx cfa_restores = NULL_RTX;
19971 rtx cr_save_reg = NULL_RTX;
19972 enum machine_mode reg_mode = Pmode;
19973 int reg_size = TARGET_32BIT ? 4 : 8;
19976 info = rs6000_stack_info ();
19978 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19980 reg_mode = V2SImode;
19984 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19985 /*static_chain_p=*/0, sibcall);
19986 using_load_multiple = strategy & SAVRES_MULTIPLE;
19987 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19988 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19989 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19990 || rs6000_cpu == PROCESSOR_PPC603
19991 || rs6000_cpu == PROCESSOR_PPC750
19993 /* Restore via the backchain when we have a large frame, since this
19994 is more efficient than an addis, addi pair. The second condition
19995 here will not trigger at the moment; We don't actually need a
19996 frame pointer for alloca, but the generic parts of the compiler
19997 give us one anyway. */
19998 use_backchain_to_restore_sp = (info->total_size > 32767
19999 || info->total_size
20000 + (info->lr_save_p ? info->lr_save_offset : 0)
20002 || (cfun->calls_alloca
20003 && !frame_pointer_needed));
20004 restore_lr = (info->lr_save_p
20005 && (restoring_FPRs_inline
20006 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20007 && (restoring_GPRs_inline
20008 || info->first_fp_reg_save < 64));
20010 if (WORLD_SAVE_P (info))
20014 const char *alloc_rname;
20017 /* eh_rest_world_r10 will return to the location saved in the LR
20018 stack slot (which is not likely to be our caller.)
20019 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20020 rest_world is similar, except any R10 parameter is ignored.
20021 The exception-handling stuff that was here in 2.95 is no
20022 longer necessary. */
20026 + 32 - info->first_gp_reg_save
20027 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20028 + 63 + 1 - info->first_fp_reg_save);
20030 strcpy (rname, ((crtl->calls_eh_return) ?
20031 "*eh_rest_world_r10" : "*rest_world"));
20032 alloc_rname = ggc_strdup (rname);
20035 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
20036 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20037 gen_rtx_REG (Pmode,
20040 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20041 /* The instruction pattern requires a clobber here;
20042 it is shared with the restVEC helper. */
20044 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20047 /* CR register traditionally saved as CR2. */
20048 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20049 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20050 GEN_INT (info->cr_save_offset));
20051 rtx mem = gen_frame_mem (reg_mode, addr);
20053 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20056 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20058 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20059 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20060 GEN_INT (info->gp_save_offset
20062 rtx mem = gen_frame_mem (reg_mode, addr);
20064 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20066 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20068 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20069 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20070 GEN_INT (info->altivec_save_offset
20072 rtx mem = gen_frame_mem (V4SImode, addr);
20074 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20076 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20078 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20079 ? DFmode : SFmode),
20080 info->first_fp_reg_save + i);
20081 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20082 GEN_INT (info->fp_save_offset
20084 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20085 ? DFmode : SFmode), addr);
20087 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20090 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20092 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20094 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20096 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20098 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20099 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20104 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20106 sp_offset = info->total_size;
20108 /* Restore AltiVec registers if we must do so before adjusting the
20110 if (TARGET_ALTIVEC_ABI
20111 && info->altivec_size != 0
20112 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20113 || (DEFAULT_ABI != ABI_V4
20114 && offset_below_red_zone_p (info->altivec_save_offset))))
20118 if (use_backchain_to_restore_sp)
20120 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20121 emit_move_insn (frame_reg_rtx,
20122 gen_rtx_MEM (Pmode, sp_reg_rtx));
20125 else if (frame_pointer_needed)
20126 frame_reg_rtx = hard_frame_pointer_rtx;
20128 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20129 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20131 rtx addr, areg, mem, reg;
20133 areg = gen_rtx_REG (Pmode, 0);
20135 (areg, GEN_INT (info->altivec_save_offset
20137 + 16 * (i - info->first_altivec_reg_save)));
20139 /* AltiVec addressing mode is [reg+reg]. */
20140 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20141 mem = gen_frame_mem (V4SImode, addr);
20143 reg = gen_rtx_REG (V4SImode, i);
20144 emit_move_insn (reg, mem);
20145 if (offset_below_red_zone_p (info->altivec_save_offset
20146 + (i - info->first_altivec_reg_save)
20148 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20153 /* Restore VRSAVE if we must do so before adjusting the stack. */
20155 && TARGET_ALTIVEC_VRSAVE
20156 && info->vrsave_mask != 0
20157 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20158 || (DEFAULT_ABI != ABI_V4
20159 && offset_below_red_zone_p (info->vrsave_save_offset))))
20161 rtx addr, mem, reg;
20163 if (frame_reg_rtx == sp_reg_rtx)
20165 if (use_backchain_to_restore_sp)
20167 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20168 emit_move_insn (frame_reg_rtx,
20169 gen_rtx_MEM (Pmode, sp_reg_rtx));
20172 else if (frame_pointer_needed)
20173 frame_reg_rtx = hard_frame_pointer_rtx;
20176 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20177 GEN_INT (info->vrsave_save_offset + sp_offset));
20178 mem = gen_frame_mem (SImode, addr);
20179 reg = gen_rtx_REG (SImode, 12);
20180 emit_move_insn (reg, mem);
20182 emit_insn (generate_set_vrsave (reg, info, 1));
20186 /* If we have a large stack frame, restore the old stack pointer
20187 using the backchain. */
20188 if (use_backchain_to_restore_sp)
20190 if (frame_reg_rtx == sp_reg_rtx)
20192 /* Under V.4, don't reset the stack pointer until after we're done
20193 loading the saved registers. */
20194 if (DEFAULT_ABI == ABI_V4)
20195 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20197 insn = emit_move_insn (frame_reg_rtx,
20198 gen_rtx_MEM (Pmode, sp_reg_rtx));
20201 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20202 && DEFAULT_ABI == ABI_V4)
20203 /* frame_reg_rtx has been set up by the altivec restore. */
20207 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20208 frame_reg_rtx = sp_reg_rtx;
20211 /* If we have a frame pointer, we can restore the old stack pointer
20213 else if (frame_pointer_needed)
20215 frame_reg_rtx = sp_reg_rtx;
20216 if (DEFAULT_ABI == ABI_V4)
20217 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20218 /* Prevent reordering memory accesses against stack pointer restore. */
20219 else if (cfun->calls_alloca
20220 || offset_below_red_zone_p (-info->total_size))
20222 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20223 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20224 MEM_NOTRAP_P (mem1) = 1;
20225 MEM_NOTRAP_P (mem2) = 1;
20226 emit_insn (gen_frame_tie (mem1, mem2));
20229 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20230 GEN_INT (info->total_size)));
20233 else if (info->push_p
20234 && DEFAULT_ABI != ABI_V4
20235 && !crtl->calls_eh_return)
20237 /* Prevent reordering memory accesses against stack pointer restore. */
20238 if (cfun->calls_alloca
20239 || offset_below_red_zone_p (-info->total_size))
20241 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20242 MEM_NOTRAP_P (mem) = 1;
20243 emit_insn (gen_stack_tie (mem));
20245 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20246 GEN_INT (info->total_size)));
20249 if (insn && frame_reg_rtx == sp_reg_rtx)
20253 REG_NOTES (insn) = cfa_restores;
20254 cfa_restores = NULL_RTX;
20256 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20257 RTX_FRAME_RELATED_P (insn) = 1;
20260 /* Restore AltiVec registers if we have not done so already. */
20261 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20262 && TARGET_ALTIVEC_ABI
20263 && info->altivec_size != 0
20264 && (DEFAULT_ABI == ABI_V4
20265 || !offset_below_red_zone_p (info->altivec_save_offset)))
20269 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20270 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20272 rtx addr, areg, mem, reg;
20274 areg = gen_rtx_REG (Pmode, 0);
20276 (areg, GEN_INT (info->altivec_save_offset
20278 + 16 * (i - info->first_altivec_reg_save)));
20280 /* AltiVec addressing mode is [reg+reg]. */
20281 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20282 mem = gen_frame_mem (V4SImode, addr);
20284 reg = gen_rtx_REG (V4SImode, i);
20285 emit_move_insn (reg, mem);
20286 if (DEFAULT_ABI == ABI_V4)
20287 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20292 /* Restore VRSAVE if we have not done so already. */
20293 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20295 && TARGET_ALTIVEC_VRSAVE
20296 && info->vrsave_mask != 0
20297 && (DEFAULT_ABI == ABI_V4
20298 || !offset_below_red_zone_p (info->vrsave_save_offset)))
20300 rtx addr, mem, reg;
20302 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20303 GEN_INT (info->vrsave_save_offset + sp_offset));
20304 mem = gen_frame_mem (SImode, addr);
20305 reg = gen_rtx_REG (SImode, 12);
20306 emit_move_insn (reg, mem);
20308 emit_insn (generate_set_vrsave (reg, info, 1));
20311 /* Get the old lr if we saved it. If we are restoring registers
20312 out-of-line, then the out-of-line routines can do this for us. */
20313 if (restore_lr && restoring_GPRs_inline)
20315 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20316 info->lr_save_offset + sp_offset);
20318 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20321 /* Get the old cr if we saved it. */
20322 if (info->cr_save_p)
20324 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20325 GEN_INT (info->cr_save_offset + sp_offset));
20326 rtx mem = gen_frame_mem (SImode, addr);
20328 cr_save_reg = gen_rtx_REG (SImode,
20329 DEFAULT_ABI == ABI_AIX
20330 && !restoring_GPRs_inline
20331 && info->first_fp_reg_save < 64
20333 emit_move_insn (cr_save_reg, mem);
20336 /* Set LR here to try to overlap restores below. LR is always saved
20337 above incoming stack, so it never needs REG_CFA_RESTORE. */
20338 if (restore_lr && restoring_GPRs_inline)
20339 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20340 gen_rtx_REG (Pmode, 0));
20342 /* Load exception handler data registers, if needed. */
20343 if (crtl->calls_eh_return)
20345 unsigned int i, regno;
20349 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20350 GEN_INT (sp_offset + 5 * reg_size));
20351 rtx mem = gen_frame_mem (reg_mode, addr);
20353 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
20360 regno = EH_RETURN_DATA_REGNO (i);
20361 if (regno == INVALID_REGNUM)
20364 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
20365 info->ehrd_offset + sp_offset
20366 + reg_size * (int) i);
20368 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
20372 /* Restore GPRs. This is done as a PARALLEL if we are using
20373 the load-multiple instructions. */
20375 && info->spe_64bit_regs_used != 0
20376 && info->first_gp_reg_save != 32)
20378 /* Determine whether we can address all of the registers that need
20379 to be saved with an offset from the stack pointer that fits in
20380 the small const field for SPE memory instructions. */
20381 int spe_regs_addressable_via_sp
20382 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20383 + (32 - info->first_gp_reg_save - 1) * reg_size)
20384 && restoring_GPRs_inline);
20387 if (spe_regs_addressable_via_sp)
20388 spe_offset = info->spe_gp_save_offset + sp_offset;
20391 rtx old_frame_reg_rtx = frame_reg_rtx;
20392 /* Make r11 point to the start of the SPE save area. We worried about
20393 not clobbering it when we were saving registers in the prologue.
20394 There's no need to worry here because the static chain is passed
20395 anew to every function. */
20396 int ool_adjust = (restoring_GPRs_inline
20398 : (info->first_gp_reg_save
20399 - (FIRST_SAVRES_REGISTER+1))*8);
20401 if (frame_reg_rtx == sp_reg_rtx)
20402 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20403 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
20404 GEN_INT (info->spe_gp_save_offset
20407 /* Keep the invariant that frame_reg_rtx + sp_offset points
20408 at the top of the stack frame. */
20409 sp_offset = -info->spe_gp_save_offset;
20414 if (restoring_GPRs_inline)
20416 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20417 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20419 rtx offset, addr, mem, reg;
20421 /* We're doing all this to ensure that the immediate offset
20422 fits into the immediate field of 'evldd'. */
20423 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
20425 offset = GEN_INT (spe_offset + reg_size * i);
20426 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
20427 mem = gen_rtx_MEM (V2SImode, addr);
20428 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20430 insn = emit_move_insn (reg, mem);
20431 if (DEFAULT_ABI == ABI_V4)
20433 if (frame_pointer_needed
20434 && info->first_gp_reg_save + i
20435 == HARD_FRAME_POINTER_REGNUM)
20437 add_reg_note (insn, REG_CFA_DEF_CFA,
20438 plus_constant (frame_reg_rtx,
20440 RTX_FRAME_RELATED_P (insn) = 1;
20443 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20452 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20454 /*savep=*/false, /*gpr=*/true,
20456 emit_jump_insn (par);
20457 /* We don't want anybody else emitting things after we jumped
20462 else if (!restoring_GPRs_inline)
20464 /* We are jumping to an out-of-line function. */
20465 bool can_use_exit = info->first_fp_reg_save == 64;
20468 /* Emit stack reset code if we need it. */
20470 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20471 sp_offset, can_use_exit);
20474 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
20477 GEN_INT (sp_offset - info->fp_size)));
20478 if (REGNO (frame_reg_rtx) == 11)
20479 sp_offset += info->fp_size;
20482 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20483 info->gp_save_offset, reg_mode,
20484 /*savep=*/false, /*gpr=*/true,
20485 /*lr=*/can_use_exit);
20489 if (info->cr_save_p)
20491 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20492 if (DEFAULT_ABI == ABI_V4)
20494 = alloc_reg_note (REG_CFA_RESTORE,
20495 gen_rtx_REG (SImode, CR2_REGNO),
20499 emit_jump_insn (par);
20501 /* We don't want anybody else emitting things after we jumped
20506 insn = emit_insn (par);
20507 if (DEFAULT_ABI == ABI_V4)
20509 if (frame_pointer_needed)
20511 add_reg_note (insn, REG_CFA_DEF_CFA,
20512 plus_constant (frame_reg_rtx, sp_offset));
20513 RTX_FRAME_RELATED_P (insn) = 1;
20516 for (i = info->first_gp_reg_save; i < 32; i++)
20518 = alloc_reg_note (REG_CFA_RESTORE,
20519 gen_rtx_REG (reg_mode, i), cfa_restores);
20522 else if (using_load_multiple)
20525 p = rtvec_alloc (32 - info->first_gp_reg_save);
20526 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20528 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20529 GEN_INT (info->gp_save_offset
20532 rtx mem = gen_frame_mem (reg_mode, addr);
20533 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20535 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
20536 if (DEFAULT_ABI == ABI_V4)
20537 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20540 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20541 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
20543 add_reg_note (insn, REG_CFA_DEF_CFA,
20544 plus_constant (frame_reg_rtx, sp_offset));
20545 RTX_FRAME_RELATED_P (insn) = 1;
20550 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20551 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20553 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20554 GEN_INT (info->gp_save_offset
20557 rtx mem = gen_frame_mem (reg_mode, addr);
20558 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20560 insn = emit_move_insn (reg, mem);
20561 if (DEFAULT_ABI == ABI_V4)
20563 if (frame_pointer_needed
20564 && info->first_gp_reg_save + i
20565 == HARD_FRAME_POINTER_REGNUM)
20567 add_reg_note (insn, REG_CFA_DEF_CFA,
20568 plus_constant (frame_reg_rtx, sp_offset));
20569 RTX_FRAME_RELATED_P (insn) = 1;
20572 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20578 if (restore_lr && !restoring_GPRs_inline)
20580 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20581 info->lr_save_offset + sp_offset);
20583 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20584 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20585 gen_rtx_REG (Pmode, 0));
20588 /* Restore fpr's if we need to do it without calling a function. */
20589 if (restoring_FPRs_inline)
20590 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20591 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20592 && ! call_used_regs[info->first_fp_reg_save+i]))
20594 rtx addr, mem, reg;
20595 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20596 GEN_INT (info->fp_save_offset
20599 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20600 ? DFmode : SFmode), addr);
20601 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20602 ? DFmode : SFmode),
20603 info->first_fp_reg_save + i);
20605 emit_move_insn (reg, mem);
20606 if (DEFAULT_ABI == ABI_V4)
20607 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20611 /* If we saved cr, restore it here. Just those that were used. */
20612 if (info->cr_save_p)
20614 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20615 if (DEFAULT_ABI == ABI_V4)
20617 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
20621 /* If this is V.4, unwind the stack pointer after all of the loads
20623 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20624 sp_offset, !restoring_FPRs_inline);
20629 REG_NOTES (insn) = cfa_restores;
20630 cfa_restores = NULL_RTX;
20632 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20633 RTX_FRAME_RELATED_P (insn) = 1;
20636 if (crtl->calls_eh_return)
20638 rtx sa = EH_RETURN_STACKADJ_RTX;
20639 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
20645 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
20646 if (! restoring_FPRs_inline)
20647 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
20649 p = rtvec_alloc (2);
20651 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
20652 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
20653 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
20654 : gen_rtx_CLOBBER (VOIDmode,
20655 gen_rtx_REG (Pmode, 65)));
20657 /* If we have to restore more than two FP registers, branch to the
20658 restore function. It will return to our caller. */
20659 if (! restoring_FPRs_inline)
20664 sym = rs6000_savres_routine_sym (info,
20668 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
20669 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
20670 gen_rtx_REG (Pmode,
20671 DEFAULT_ABI == ABI_AIX
20673 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20676 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
20677 GEN_INT (info->fp_save_offset + 8*i));
20678 mem = gen_frame_mem (DFmode, addr);
20680 RTVEC_ELT (p, i+4) =
20681 gen_rtx_SET (VOIDmode,
20682 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
20687 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20691 /* Write function epilogue. */
20694 rs6000_output_function_epilogue (FILE *file,
20695 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20697 if (! HAVE_epilogue)
20699 rtx insn = get_last_insn ();
20700 /* If the last insn was a BARRIER, we don't have to write anything except
20701 the trace table. */
20702 if (GET_CODE (insn) == NOTE)
20703 insn = prev_nonnote_insn (insn);
20704 if (insn == 0 || GET_CODE (insn) != BARRIER)
20706 /* This is slightly ugly, but at least we don't have two
20707 copies of the epilogue-emitting code. */
20710 /* A NOTE_INSN_DELETED is supposed to be at the start
20711 and end of the "toplevel" insn chain. */
20712 emit_note (NOTE_INSN_DELETED);
20713 rs6000_emit_epilogue (FALSE);
20714 emit_note (NOTE_INSN_DELETED);
20716 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20720 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20722 INSN_ADDRESSES_NEW (insn, addr);
20727 if (TARGET_DEBUG_STACK)
20728 debug_rtx_list (get_insns (), 100);
20729 final (get_insns (), file, FALSE);
20735 macho_branch_islands ();
20736 /* Mach-O doesn't support labels at the end of objects, so if
20737 it looks like we might want one, insert a NOP. */
20739 rtx insn = get_last_insn ();
20742 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
20743 insn = PREV_INSN (insn);
20747 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
20748 fputs ("\tnop\n", file);
20752 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20755 We don't output a traceback table if -finhibit-size-directive was
20756 used. The documentation for -finhibit-size-directive reads
20757 ``don't output a @code{.size} assembler directive, or anything
20758 else that would cause trouble if the function is split in the
20759 middle, and the two halves are placed at locations far apart in
20760 memory.'' The traceback table has this property, since it
20761 includes the offset from the start of the function to the
20762 traceback table itself.
20764 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20765 different traceback table. */
20766 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20767 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20769 const char *fname = NULL;
20770 const char *language_string = lang_hooks.name;
20771 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20773 int optional_tbtab;
20774 rs6000_stack_t *info = rs6000_stack_info ();
20776 if (rs6000_traceback == traceback_full)
20777 optional_tbtab = 1;
20778 else if (rs6000_traceback == traceback_part)
20779 optional_tbtab = 0;
20781 optional_tbtab = !optimize_size && !TARGET_ELF;
20783 if (optional_tbtab)
20785 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20786 while (*fname == '.') /* V.4 encodes . in the name */
20789 /* Need label immediately before tbtab, so we can compute
20790 its offset from the function start. */
20791 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20792 ASM_OUTPUT_LABEL (file, fname);
20795 /* The .tbtab pseudo-op can only be used for the first eight
20796 expressions, since it can't handle the possibly variable
20797 length fields that follow. However, if you omit the optional
20798 fields, the assembler outputs zeros for all optional fields
20799 anyways, giving each variable length field is minimum length
20800 (as defined in sys/debug.h). Thus we can not use the .tbtab
20801 pseudo-op at all. */
20803 /* An all-zero word flags the start of the tbtab, for debuggers
20804 that have to find it by searching forward from the entry
20805 point or from the current pc. */
20806 fputs ("\t.long 0\n", file);
20808 /* Tbtab format type. Use format type 0. */
20809 fputs ("\t.byte 0,", file);
20811 /* Language type. Unfortunately, there does not seem to be any
20812 official way to discover the language being compiled, so we
20813 use language_string.
20814 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20815 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20816 a number, so for now use 9. LTO isn't assigned a number either,
20817 so for now use 0. */
20818 if (! strcmp (language_string, "GNU C")
20819 || ! strcmp (language_string, "GNU GIMPLE"))
20821 else if (! strcmp (language_string, "GNU F77")
20822 || ! strcmp (language_string, "GNU Fortran"))
20824 else if (! strcmp (language_string, "GNU Pascal"))
20826 else if (! strcmp (language_string, "GNU Ada"))
20828 else if (! strcmp (language_string, "GNU C++")
20829 || ! strcmp (language_string, "GNU Objective-C++"))
20831 else if (! strcmp (language_string, "GNU Java"))
20833 else if (! strcmp (language_string, "GNU Objective-C"))
20836 gcc_unreachable ();
20837 fprintf (file, "%d,", i);
20839 /* 8 single bit fields: global linkage (not set for C extern linkage,
20840 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20841 from start of procedure stored in tbtab, internal function, function
20842 has controlled storage, function has no toc, function uses fp,
20843 function logs/aborts fp operations. */
20844 /* Assume that fp operations are used if any fp reg must be saved. */
20845 fprintf (file, "%d,",
20846 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
20848 /* 6 bitfields: function is interrupt handler, name present in
20849 proc table, function calls alloca, on condition directives
20850 (controls stack walks, 3 bits), saves condition reg, saves
20852 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20853 set up as a frame pointer, even when there is no alloca call. */
20854 fprintf (file, "%d,",
20855 ((optional_tbtab << 6)
20856 | ((optional_tbtab & frame_pointer_needed) << 5)
20857 | (info->cr_save_p << 1)
20858 | (info->lr_save_p)));
20860 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20862 fprintf (file, "%d,",
20863 (info->push_p << 7) | (64 - info->first_fp_reg_save));
20865 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20866 fprintf (file, "%d,", (32 - first_reg_to_save ()));
20868 if (optional_tbtab)
20870 /* Compute the parameter info from the function decl argument
20873 int next_parm_info_bit = 31;
20875 for (decl = DECL_ARGUMENTS (current_function_decl);
20876 decl; decl = TREE_CHAIN (decl))
20878 rtx parameter = DECL_INCOMING_RTL (decl);
20879 enum machine_mode mode = GET_MODE (parameter);
20881 if (GET_CODE (parameter) == REG)
20883 if (SCALAR_FLOAT_MODE_P (mode))
20904 gcc_unreachable ();
20907 /* If only one bit will fit, don't or in this entry. */
20908 if (next_parm_info_bit > 0)
20909 parm_info |= (bits << (next_parm_info_bit - 1));
20910 next_parm_info_bit -= 2;
20914 fixed_parms += ((GET_MODE_SIZE (mode)
20915 + (UNITS_PER_WORD - 1))
20917 next_parm_info_bit -= 1;
20923 /* Number of fixed point parameters. */
20924 /* This is actually the number of words of fixed point parameters; thus
20925 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20926 fprintf (file, "%d,", fixed_parms);
20928 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20930 /* This is actually the number of fp registers that hold parameters;
20931 and thus the maximum value is 13. */
20932 /* Set parameters on stack bit if parameters are not in their original
20933 registers, regardless of whether they are on the stack? Xlc
20934 seems to set the bit when not optimizing. */
20935 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
20937 if (! optional_tbtab)
20940 /* Optional fields follow. Some are variable length. */
20942 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20943 11 double float. */
20944 /* There is an entry for each parameter in a register, in the order that
20945 they occur in the parameter list. Any intervening arguments on the
20946 stack are ignored. If the list overflows a long (max possible length
20947 34 bits) then completely leave off all elements that don't fit. */
20948 /* Only emit this long if there was at least one parameter. */
20949 if (fixed_parms || float_parms)
20950 fprintf (file, "\t.long %d\n", parm_info);
20952 /* Offset from start of code to tb table. */
20953 fputs ("\t.long ", file);
20954 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20955 RS6000_OUTPUT_BASENAME (file, fname);
20957 rs6000_output_function_entry (file, fname);
20960 /* Interrupt handler mask. */
20961 /* Omit this long, since we never set the interrupt handler bit
20964 /* Number of CTL (controlled storage) anchors. */
20965 /* Omit this long, since the has_ctl bit is never set above. */
20967 /* Displacement into stack of each CTL anchor. */
20968 /* Omit this list of longs, because there are no CTL anchors. */
20970 /* Length of function name. */
20973 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20975 /* Function name. */
20976 assemble_string (fname, strlen (fname));
20978 /* Register for alloca automatic storage; this is always reg 31.
20979 Only emit this if the alloca bit was set above. */
20980 if (frame_pointer_needed)
20981 fputs ("\t.byte 31\n", file);
20983 fputs ("\t.align 2\n", file);
20987 /* A C compound statement that outputs the assembler code for a thunk
20988 function, used to implement C++ virtual function calls with
20989 multiple inheritance. The thunk acts as a wrapper around a virtual
20990 function, adjusting the implicit object parameter before handing
20991 control off to the real function.
20993 First, emit code to add the integer DELTA to the location that
20994 contains the incoming first argument. Assume that this argument
20995 contains a pointer, and is the one used to pass the `this' pointer
20996 in C++. This is the incoming argument *before* the function
20997 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20998 values of all other incoming arguments.
21000 After the addition, emit code to jump to FUNCTION, which is a
21001 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21002 not touch the return address. Hence returning from FUNCTION will
21003 return to whoever called the current `thunk'.
21005 The effect must be as if FUNCTION had been called directly with the
21006 adjusted first argument. This macro is responsible for emitting
21007 all of the code for a thunk function; output_function_prologue()
21008 and output_function_epilogue() are not invoked.
21010 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21011 been extracted from it.) It might possibly be useful on some
21012 targets, but probably not.
21014 If you do not define this macro, the target-independent code in the
21015 C++ frontend will generate a less efficient heavyweight thunk that
21016 calls FUNCTION instead of jumping to it. The generic approach does
21017 not support varargs. */
21020 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21021 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21024 rtx this_rtx, insn, funexp;
21026 reload_completed = 1;
21027 epilogue_completed = 1;
21029 /* Mark the end of the (empty) prologue. */
21030 emit_note (NOTE_INSN_PROLOGUE_END);
21032 /* Find the "this" pointer. If the function returns a structure,
21033 the structure return pointer is in r3. */
21034 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21035 this_rtx = gen_rtx_REG (Pmode, 4);
21037 this_rtx = gen_rtx_REG (Pmode, 3);
21039 /* Apply the constant offset, if required. */
21041 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21043 /* Apply the offset from the vtable, if required. */
21046 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21047 rtx tmp = gen_rtx_REG (Pmode, 12);
21049 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21050 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21052 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21053 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21057 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21059 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21061 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21064 /* Generate a tail call to the target function. */
21065 if (!TREE_USED (function))
21067 assemble_external (function);
21068 TREE_USED (function) = 1;
21070 funexp = XEXP (DECL_RTL (function), 0);
21071 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21074 if (MACHOPIC_INDIRECT)
21075 funexp = machopic_indirect_call_target (funexp);
21078 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21079 generate sibcall RTL explicitly. */
21080 insn = emit_call_insn (
21081 gen_rtx_PARALLEL (VOIDmode,
21083 gen_rtx_CALL (VOIDmode,
21084 funexp, const0_rtx),
21085 gen_rtx_USE (VOIDmode, const0_rtx),
21086 gen_rtx_USE (VOIDmode,
21087 gen_rtx_REG (SImode,
21089 gen_rtx_RETURN (VOIDmode))));
21090 SIBLING_CALL_P (insn) = 1;
21093 /* Run just enough of rest_of_compilation to get the insns emitted.
21094 There's not really enough bulk here to make other passes such as
21095 instruction scheduling worth while. Note that use_thunk calls
21096 assemble_start_function and assemble_end_function. */
21097 insn = get_insns ();
21098 insn_locators_alloc ();
21099 shorten_branches (insn);
21100 final_start_function (insn, file, 1);
21101 final (insn, file, 1);
21102 final_end_function ();
21104 reload_completed = 0;
21105 epilogue_completed = 0;
21108 /* A quick summary of the various types of 'constant-pool tables'
21111 Target Flags Name One table per
21112 AIX (none) AIX TOC object file
21113 AIX -mfull-toc AIX TOC object file
21114 AIX -mminimal-toc AIX minimal TOC translation unit
21115 SVR4/EABI (none) SVR4 SDATA object file
21116 SVR4/EABI -fpic SVR4 pic object file
21117 SVR4/EABI -fPIC SVR4 PIC translation unit
21118 SVR4/EABI -mrelocatable EABI TOC function
21119 SVR4/EABI -maix AIX TOC object file
21120 SVR4/EABI -maix -mminimal-toc
21121 AIX minimal TOC translation unit
21123 Name Reg. Set by entries contains:
21124 made by addrs? fp? sum?
21126 AIX TOC 2 crt0 as Y option option
21127 AIX minimal TOC 30 prolog gcc Y Y option
21128 SVR4 SDATA 13 crt0 gcc N Y N
21129 SVR4 pic 30 prolog ld Y not yet N
21130 SVR4 PIC 30 prolog gcc Y option option
21131 EABI TOC 30 prolog gcc Y option option
21135 /* Hash functions for the hash table. */
21138 rs6000_hash_constant (rtx k)
21140 enum rtx_code code = GET_CODE (k);
21141 enum machine_mode mode = GET_MODE (k);
21142 unsigned result = (code << 3) ^ mode;
21143 const char *format;
21146 format = GET_RTX_FORMAT (code);
21147 flen = strlen (format);
21153 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21156 if (mode != VOIDmode)
21157 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21169 for (; fidx < flen; fidx++)
21170 switch (format[fidx])
21175 const char *str = XSTR (k, fidx);
21176 len = strlen (str);
21177 result = result * 613 + len;
21178 for (i = 0; i < len; i++)
21179 result = result * 613 + (unsigned) str[i];
21184 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21188 result = result * 613 + (unsigned) XINT (k, fidx);
21191 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21192 result = result * 613 + (unsigned) XWINT (k, fidx);
21196 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21197 result = result * 613 + (unsigned) (XWINT (k, fidx)
21204 gcc_unreachable ();
21211 toc_hash_function (const void *hash_entry)
21213 const struct toc_hash_struct *thc =
21214 (const struct toc_hash_struct *) hash_entry;
21215 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21218 /* Compare H1 and H2 for equivalence. */
21221 toc_hash_eq (const void *h1, const void *h2)
21223 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21224 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21226 if (((const struct toc_hash_struct *) h1)->key_mode
21227 != ((const struct toc_hash_struct *) h2)->key_mode)
21230 return rtx_equal_p (r1, r2);
21233 /* These are the names given by the C++ front-end to vtables, and
21234 vtable-like objects. Ideally, this logic should not be here;
21235 instead, there should be some programmatic way of inquiring as
21236 to whether or not an object is a vtable. */
21238 #define VTABLE_NAME_P(NAME) \
21239 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21240 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21241 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21242 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21243 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21245 #ifdef NO_DOLLAR_IN_LABEL
21246 /* Return a GGC-allocated character string translating dollar signs in
21247 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21250 rs6000_xcoff_strip_dollar (const char *name)
21255 p = strchr (name, '$');
21257 if (p == 0 || p == name)
21260 len = strlen (name);
21261 strip = (char *) alloca (len + 1);
21262 strcpy (strip, name);
21263 p = strchr (strip, '$');
21267 p = strchr (p + 1, '$');
21270 return ggc_alloc_string (strip, len);
21275 rs6000_output_symbol_ref (FILE *file, rtx x)
21277 /* Currently C++ toc references to vtables can be emitted before it
21278 is decided whether the vtable is public or private. If this is
21279 the case, then the linker will eventually complain that there is
21280 a reference to an unknown section. Thus, for vtables only,
21281 we emit the TOC reference to reference the symbol and not the
21283 const char *name = XSTR (x, 0);
21285 if (VTABLE_NAME_P (name))
21287 RS6000_OUTPUT_BASENAME (file, name);
21290 assemble_name (file, name);
21293 /* Output a TOC entry. We derive the entry name from what is being
21297 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
21300 const char *name = buf;
21302 HOST_WIDE_INT offset = 0;
21304 gcc_assert (!TARGET_NO_TOC);
21306 /* When the linker won't eliminate them, don't output duplicate
21307 TOC entries (this happens on AIX if there is any kind of TOC,
21308 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
21310 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
21312 struct toc_hash_struct *h;
21315 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
21316 time because GGC is not initialized at that point. */
21317 if (toc_hash_table == NULL)
21318 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
21319 toc_hash_eq, NULL);
21321 h = ggc_alloc_toc_hash_struct ();
21323 h->key_mode = mode;
21324 h->labelno = labelno;
21326 found = htab_find_slot (toc_hash_table, h, INSERT);
21327 if (*found == NULL)
21329 else /* This is indeed a duplicate.
21330 Set this label equal to that label. */
21332 fputs ("\t.set ", file);
21333 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21334 fprintf (file, "%d,", labelno);
21335 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21336 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
21342 /* If we're going to put a double constant in the TOC, make sure it's
21343 aligned properly when strict alignment is on. */
21344 if (GET_CODE (x) == CONST_DOUBLE
21345 && STRICT_ALIGNMENT
21346 && GET_MODE_BITSIZE (mode) >= 64
21347 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
21348 ASM_OUTPUT_ALIGN (file, 3);
21351 (*targetm.asm_out.internal_label) (file, "LC", labelno);
21353 /* Handle FP constants specially. Note that if we have a minimal
21354 TOC, things we put here aren't actually in the TOC, so we can allow
21356 if (GET_CODE (x) == CONST_DOUBLE &&
21357 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
21359 REAL_VALUE_TYPE rv;
21362 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21363 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21364 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
21366 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
21370 if (TARGET_MINIMAL_TOC)
21371 fputs (DOUBLE_INT_ASM_OP, file);
21373 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
21374 k[0] & 0xffffffff, k[1] & 0xffffffff,
21375 k[2] & 0xffffffff, k[3] & 0xffffffff);
21376 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
21377 k[0] & 0xffffffff, k[1] & 0xffffffff,
21378 k[2] & 0xffffffff, k[3] & 0xffffffff);
21383 if (TARGET_MINIMAL_TOC)
21384 fputs ("\t.long ", file);
21386 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
21387 k[0] & 0xffffffff, k[1] & 0xffffffff,
21388 k[2] & 0xffffffff, k[3] & 0xffffffff);
21389 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
21390 k[0] & 0xffffffff, k[1] & 0xffffffff,
21391 k[2] & 0xffffffff, k[3] & 0xffffffff);
21395 else if (GET_CODE (x) == CONST_DOUBLE &&
21396 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
21398 REAL_VALUE_TYPE rv;
21401 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21403 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21404 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
21406 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
21410 if (TARGET_MINIMAL_TOC)
21411 fputs (DOUBLE_INT_ASM_OP, file);
21413 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
21414 k[0] & 0xffffffff, k[1] & 0xffffffff);
21415 fprintf (file, "0x%lx%08lx\n",
21416 k[0] & 0xffffffff, k[1] & 0xffffffff);
21421 if (TARGET_MINIMAL_TOC)
21422 fputs ("\t.long ", file);
21424 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
21425 k[0] & 0xffffffff, k[1] & 0xffffffff);
21426 fprintf (file, "0x%lx,0x%lx\n",
21427 k[0] & 0xffffffff, k[1] & 0xffffffff);
21431 else if (GET_CODE (x) == CONST_DOUBLE &&
21432 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
21434 REAL_VALUE_TYPE rv;
21437 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21438 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21439 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
21441 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
21445 if (TARGET_MINIMAL_TOC)
21446 fputs (DOUBLE_INT_ASM_OP, file);
21448 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
21449 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
21454 if (TARGET_MINIMAL_TOC)
21455 fputs ("\t.long ", file);
21457 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
21458 fprintf (file, "0x%lx\n", l & 0xffffffff);
21462 else if (GET_MODE (x) == VOIDmode
21463 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
21465 unsigned HOST_WIDE_INT low;
21466 HOST_WIDE_INT high;
21468 if (GET_CODE (x) == CONST_DOUBLE)
21470 low = CONST_DOUBLE_LOW (x);
21471 high = CONST_DOUBLE_HIGH (x);
21474 #if HOST_BITS_PER_WIDE_INT == 32
21477 high = (low & 0x80000000) ? ~0 : 0;
21481 low = INTVAL (x) & 0xffffffff;
21482 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
21486 /* TOC entries are always Pmode-sized, but since this
21487 is a bigendian machine then if we're putting smaller
21488 integer constants in the TOC we have to pad them.
21489 (This is still a win over putting the constants in
21490 a separate constant pool, because then we'd have
21491 to have both a TOC entry _and_ the actual constant.)
21493 For a 32-bit target, CONST_INT values are loaded and shifted
21494 entirely within `low' and can be stored in one TOC entry. */
21496 /* It would be easy to make this work, but it doesn't now. */
21497 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
21499 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
21501 #if HOST_BITS_PER_WIDE_INT == 32
21502 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
21503 POINTER_SIZE, &low, &high, 0);
21506 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
21507 high = (HOST_WIDE_INT) low >> 32;
21514 if (TARGET_MINIMAL_TOC)
21515 fputs (DOUBLE_INT_ASM_OP, file);
21517 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21518 (long) high & 0xffffffff, (long) low & 0xffffffff);
21519 fprintf (file, "0x%lx%08lx\n",
21520 (long) high & 0xffffffff, (long) low & 0xffffffff);
21525 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
21527 if (TARGET_MINIMAL_TOC)
21528 fputs ("\t.long ", file);
21530 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21531 (long) high & 0xffffffff, (long) low & 0xffffffff);
21532 fprintf (file, "0x%lx,0x%lx\n",
21533 (long) high & 0xffffffff, (long) low & 0xffffffff);
21537 if (TARGET_MINIMAL_TOC)
21538 fputs ("\t.long ", file);
21540 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
21541 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
21547 if (GET_CODE (x) == CONST)
21549 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
21550 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
21552 base = XEXP (XEXP (x, 0), 0);
21553 offset = INTVAL (XEXP (XEXP (x, 0), 1));
21556 switch (GET_CODE (base))
21559 name = XSTR (base, 0);
21563 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
21564 CODE_LABEL_NUMBER (XEXP (base, 0)));
21568 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
21572 gcc_unreachable ();
21575 if (TARGET_MINIMAL_TOC)
21576 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
21579 fputs ("\t.tc ", file);
21580 RS6000_OUTPUT_BASENAME (file, name);
21583 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
21585 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
21587 fputs ("[TC],", file);
21590 /* Currently C++ toc references to vtables can be emitted before it
21591 is decided whether the vtable is public or private. If this is
21592 the case, then the linker will eventually complain that there is
21593 a TOC reference to an unknown section. Thus, for vtables only,
21594 we emit the TOC reference to reference the symbol and not the
21596 if (VTABLE_NAME_P (name))
21598 RS6000_OUTPUT_BASENAME (file, name);
21600 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
21601 else if (offset > 0)
21602 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
21605 output_addr_const (file, x);
21609 /* Output an assembler pseudo-op to write an ASCII string of N characters
21610 starting at P to FILE.
21612 On the RS/6000, we have to do this using the .byte operation and
21613 write out special characters outside the quoted string.
21614 Also, the assembler is broken; very long strings are truncated,
21615 so we must artificially break them up early. */
21618 output_ascii (FILE *file, const char *p, int n)
21621 int i, count_string;
21622 const char *for_string = "\t.byte \"";
21623 const char *for_decimal = "\t.byte ";
21624 const char *to_close = NULL;
21627 for (i = 0; i < n; i++)
21630 if (c >= ' ' && c < 0177)
21633 fputs (for_string, file);
21636 /* Write two quotes to get one. */
21644 for_decimal = "\"\n\t.byte ";
21648 if (count_string >= 512)
21650 fputs (to_close, file);
21652 for_string = "\t.byte \"";
21653 for_decimal = "\t.byte ";
21661 fputs (for_decimal, file);
21662 fprintf (file, "%d", c);
21664 for_string = "\n\t.byte \"";
21665 for_decimal = ", ";
21671 /* Now close the string if we have written one. Then end the line. */
21673 fputs (to_close, file);
21676 /* Generate a unique section name for FILENAME for a section type
21677 represented by SECTION_DESC. Output goes into BUF.
21679 SECTION_DESC can be any string, as long as it is different for each
21680 possible section type.
21682 We name the section in the same manner as xlc. The name begins with an
21683 underscore followed by the filename (after stripping any leading directory
21684 names) with the last period replaced by the string SECTION_DESC. If
21685 FILENAME does not contain a period, SECTION_DESC is appended to the end of
21689 rs6000_gen_section_name (char **buf, const char *filename,
21690 const char *section_desc)
21692 const char *q, *after_last_slash, *last_period = 0;
21696 after_last_slash = filename;
21697 for (q = filename; *q; q++)
21700 after_last_slash = q + 1;
21701 else if (*q == '.')
21705 len = strlen (after_last_slash) + strlen (section_desc) + 2;
21706 *buf = (char *) xmalloc (len);
21711 for (q = after_last_slash; *q; q++)
21713 if (q == last_period)
21715 strcpy (p, section_desc);
21716 p += strlen (section_desc);
21720 else if (ISALNUM (*q))
21724 if (last_period == 0)
21725 strcpy (p, section_desc);
21730 /* Emit profile function. */
21733 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
21735 /* Non-standard profiling for kernels, which just saves LR then calls
21736 _mcount without worrying about arg saves. The idea is to change
21737 the function prologue as little as possible as it isn't easy to
21738 account for arg save/restore code added just for _mcount. */
21739 if (TARGET_PROFILE_KERNEL)
21742 if (DEFAULT_ABI == ABI_AIX)
21744 #ifndef NO_PROFILE_COUNTERS
21745 # define NO_PROFILE_COUNTERS 0
21747 if (NO_PROFILE_COUNTERS)
21748 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21749 LCT_NORMAL, VOIDmode, 0);
21753 const char *label_name;
21756 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21757 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21758 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21760 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21761 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21764 else if (DEFAULT_ABI == ABI_DARWIN)
21766 const char *mcount_name = RS6000_MCOUNT;
21767 int caller_addr_regno = LR_REGNO;
21769 /* Be conservative and always set this, at least for now. */
21770 crtl->uses_pic_offset_table = 1;
21773 /* For PIC code, set up a stub and collect the caller's address
21774 from r0, which is where the prologue puts it. */
21775 if (MACHOPIC_INDIRECT
21776 && crtl->uses_pic_offset_table)
21777 caller_addr_regno = 0;
21779 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21780 LCT_NORMAL, VOIDmode, 1,
21781 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21785 /* Write function profiler code. */
21788 output_function_profiler (FILE *file, int labelno)
21792 switch (DEFAULT_ABI)
21795 gcc_unreachable ();
21800 warning (0, "no profiling of 64-bit code for this ABI");
21803 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21804 fprintf (file, "\tmflr %s\n", reg_names[0]);
21805 if (NO_PROFILE_COUNTERS)
21807 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21808 reg_names[0], reg_names[1]);
21810 else if (TARGET_SECURE_PLT && flag_pic)
21812 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21813 reg_names[0], reg_names[1]);
21814 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21815 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21816 reg_names[12], reg_names[12]);
21817 assemble_name (file, buf);
21818 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21819 assemble_name (file, buf);
21820 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21822 else if (flag_pic == 1)
21824 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21825 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21826 reg_names[0], reg_names[1]);
21827 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21828 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
21829 assemble_name (file, buf);
21830 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
21832 else if (flag_pic > 1)
21834 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21835 reg_names[0], reg_names[1]);
21836 /* Now, we need to get the address of the label. */
21837 fputs ("\tbcl 20,31,1f\n\t.long ", file);
21838 assemble_name (file, buf);
21839 fputs ("-.\n1:", file);
21840 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
21841 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
21842 reg_names[0], reg_names[11]);
21843 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
21844 reg_names[0], reg_names[0], reg_names[11]);
21848 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
21849 assemble_name (file, buf);
21850 fputs ("@ha\n", file);
21851 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21852 reg_names[0], reg_names[1]);
21853 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
21854 assemble_name (file, buf);
21855 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
21858 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21859 fprintf (file, "\tbl %s%s\n",
21860 RS6000_MCOUNT, flag_pic ? "@plt" : "");
21865 if (!TARGET_PROFILE_KERNEL)
21867 /* Don't do anything, done in output_profile_hook (). */
21871 gcc_assert (!TARGET_32BIT);
21873 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
21874 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
21876 if (cfun->static_chain_decl != NULL)
21878 asm_fprintf (file, "\tstd %s,24(%s)\n",
21879 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21880 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21881 asm_fprintf (file, "\tld %s,24(%s)\n",
21882 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21885 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21893 /* The following variable value is the last issued insn. */
21895 static rtx last_scheduled_insn;
21897 /* The following variable helps to balance issuing of load and
21898 store instructions */
21900 static int load_store_pendulum;
21902 /* Power4 load update and store update instructions are cracked into a
21903 load or store and an integer insn which are executed in the same cycle.
21904 Branches have their own dispatch slot which does not count against the
21905 GCC issue rate, but it changes the program flow so there are no other
21906 instructions to issue in this cycle. */
21909 rs6000_variable_issue_1 (rtx insn, int more)
21911 last_scheduled_insn = insn;
21912 if (GET_CODE (PATTERN (insn)) == USE
21913 || GET_CODE (PATTERN (insn)) == CLOBBER)
21915 cached_can_issue_more = more;
21916 return cached_can_issue_more;
21919 if (insn_terminates_group_p (insn, current_group))
21921 cached_can_issue_more = 0;
21922 return cached_can_issue_more;
21925 /* If no reservation, but reach here */
21926 if (recog_memoized (insn) < 0)
21929 if (rs6000_sched_groups)
21931 if (is_microcoded_insn (insn))
21932 cached_can_issue_more = 0;
21933 else if (is_cracked_insn (insn))
21934 cached_can_issue_more = more > 2 ? more - 2 : 0;
21936 cached_can_issue_more = more - 1;
21938 return cached_can_issue_more;
21941 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21944 cached_can_issue_more = more - 1;
21945 return cached_can_issue_more;
21949 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
21951 int r = rs6000_variable_issue_1 (insn, more);
21953 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
21957 /* Adjust the cost of a scheduling dependency. Return the new cost of
21958 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21961 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21963 enum attr_type attr_type;
21965 if (! recog_memoized (insn))
21968 switch (REG_NOTE_KIND (link))
21972 /* Data dependency; DEP_INSN writes a register that INSN reads
21973 some cycles later. */
21975 /* Separate a load from a narrower, dependent store. */
21976 if (rs6000_sched_groups
21977 && GET_CODE (PATTERN (insn)) == SET
21978 && GET_CODE (PATTERN (dep_insn)) == SET
21979 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21980 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21981 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21982 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21985 attr_type = get_attr_type (insn);
21990 /* Tell the first scheduling pass about the latency between
21991 a mtctr and bctr (and mtlr and br/blr). The first
21992 scheduling pass will not know about this latency since
21993 the mtctr instruction, which has the latency associated
21994 to it, will be generated by reload. */
21995 return TARGET_POWER ? 5 : 4;
21997 /* Leave some extra cycles between a compare and its
21998 dependent branch, to inhibit expensive mispredicts. */
21999 if ((rs6000_cpu_attr == CPU_PPC603
22000 || rs6000_cpu_attr == CPU_PPC604
22001 || rs6000_cpu_attr == CPU_PPC604E
22002 || rs6000_cpu_attr == CPU_PPC620
22003 || rs6000_cpu_attr == CPU_PPC630
22004 || rs6000_cpu_attr == CPU_PPC750
22005 || rs6000_cpu_attr == CPU_PPC7400
22006 || rs6000_cpu_attr == CPU_PPC7450
22007 || rs6000_cpu_attr == CPU_POWER4
22008 || rs6000_cpu_attr == CPU_POWER5
22009 || rs6000_cpu_attr == CPU_POWER7
22010 || rs6000_cpu_attr == CPU_CELL)
22011 && recog_memoized (dep_insn)
22012 && (INSN_CODE (dep_insn) >= 0))
22014 switch (get_attr_type (dep_insn))
22018 case TYPE_DELAYED_COMPARE:
22019 case TYPE_IMUL_COMPARE:
22020 case TYPE_LMUL_COMPARE:
22021 case TYPE_FPCOMPARE:
22022 case TYPE_CR_LOGICAL:
22023 case TYPE_DELAYED_CR:
22032 case TYPE_STORE_UX:
22034 case TYPE_FPSTORE_U:
22035 case TYPE_FPSTORE_UX:
22036 if ((rs6000_cpu == PROCESSOR_POWER6)
22037 && recog_memoized (dep_insn)
22038 && (INSN_CODE (dep_insn) >= 0))
22041 if (GET_CODE (PATTERN (insn)) != SET)
22042 /* If this happens, we have to extend this to schedule
22043 optimally. Return default for now. */
22046 /* Adjust the cost for the case where the value written
22047 by a fixed point operation is used as the address
22048 gen value on a store. */
22049 switch (get_attr_type (dep_insn))
22056 if (! store_data_bypass_p (dep_insn, insn))
22060 case TYPE_LOAD_EXT:
22061 case TYPE_LOAD_EXT_U:
22062 case TYPE_LOAD_EXT_UX:
22063 case TYPE_VAR_SHIFT_ROTATE:
22064 case TYPE_VAR_DELAYED_COMPARE:
22066 if (! store_data_bypass_p (dep_insn, insn))
22072 case TYPE_FAST_COMPARE:
22075 case TYPE_INSERT_WORD:
22076 case TYPE_INSERT_DWORD:
22077 case TYPE_FPLOAD_U:
22078 case TYPE_FPLOAD_UX:
22080 case TYPE_STORE_UX:
22081 case TYPE_FPSTORE_U:
22082 case TYPE_FPSTORE_UX:
22084 if (! store_data_bypass_p (dep_insn, insn))
22092 case TYPE_IMUL_COMPARE:
22093 case TYPE_LMUL_COMPARE:
22095 if (! store_data_bypass_p (dep_insn, insn))
22101 if (! store_data_bypass_p (dep_insn, insn))
22107 if (! store_data_bypass_p (dep_insn, insn))
22120 case TYPE_LOAD_EXT:
22121 case TYPE_LOAD_EXT_U:
22122 case TYPE_LOAD_EXT_UX:
22123 if ((rs6000_cpu == PROCESSOR_POWER6)
22124 && recog_memoized (dep_insn)
22125 && (INSN_CODE (dep_insn) >= 0))
22128 /* Adjust the cost for the case where the value written
22129 by a fixed point instruction is used within the address
22130 gen portion of a subsequent load(u)(x) */
22131 switch (get_attr_type (dep_insn))
22138 if (set_to_load_agen (dep_insn, insn))
22142 case TYPE_LOAD_EXT:
22143 case TYPE_LOAD_EXT_U:
22144 case TYPE_LOAD_EXT_UX:
22145 case TYPE_VAR_SHIFT_ROTATE:
22146 case TYPE_VAR_DELAYED_COMPARE:
22148 if (set_to_load_agen (dep_insn, insn))
22154 case TYPE_FAST_COMPARE:
22157 case TYPE_INSERT_WORD:
22158 case TYPE_INSERT_DWORD:
22159 case TYPE_FPLOAD_U:
22160 case TYPE_FPLOAD_UX:
22162 case TYPE_STORE_UX:
22163 case TYPE_FPSTORE_U:
22164 case TYPE_FPSTORE_UX:
22166 if (set_to_load_agen (dep_insn, insn))
22174 case TYPE_IMUL_COMPARE:
22175 case TYPE_LMUL_COMPARE:
22177 if (set_to_load_agen (dep_insn, insn))
22183 if (set_to_load_agen (dep_insn, insn))
22189 if (set_to_load_agen (dep_insn, insn))
22200 if ((rs6000_cpu == PROCESSOR_POWER6)
22201 && recog_memoized (dep_insn)
22202 && (INSN_CODE (dep_insn) >= 0)
22203 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22210 /* Fall out to return default cost. */
22214 case REG_DEP_OUTPUT:
22215 /* Output dependency; DEP_INSN writes a register that INSN writes some
22217 if ((rs6000_cpu == PROCESSOR_POWER6)
22218 && recog_memoized (dep_insn)
22219 && (INSN_CODE (dep_insn) >= 0))
22221 attr_type = get_attr_type (insn);
22226 if (get_attr_type (dep_insn) == TYPE_FP)
22230 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22238 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22243 gcc_unreachable ();
22249 /* Debug version of rs6000_adjust_cost. */
22252 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22254 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
22260 switch (REG_NOTE_KIND (link))
22262 default: dep = "unknown depencency"; break;
22263 case REG_DEP_TRUE: dep = "data dependency"; break;
22264 case REG_DEP_OUTPUT: dep = "output dependency"; break;
22265 case REG_DEP_ANTI: dep = "anti depencency"; break;
22269 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22270 "%s, insn:\n", ret, cost, dep);
22278 /* The function returns a true if INSN is microcoded.
22279 Return false otherwise. */
22282 is_microcoded_insn (rtx insn)
22284 if (!insn || !NONDEBUG_INSN_P (insn)
22285 || GET_CODE (PATTERN (insn)) == USE
22286 || GET_CODE (PATTERN (insn)) == CLOBBER)
22289 if (rs6000_cpu_attr == CPU_CELL)
22290 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
22292 if (rs6000_sched_groups)
22294 enum attr_type type = get_attr_type (insn);
22295 if (type == TYPE_LOAD_EXT_U
22296 || type == TYPE_LOAD_EXT_UX
22297 || type == TYPE_LOAD_UX
22298 || type == TYPE_STORE_UX
22299 || type == TYPE_MFCR)
22306 /* The function returns true if INSN is cracked into 2 instructions
22307 by the processor (and therefore occupies 2 issue slots). */
22310 is_cracked_insn (rtx insn)
22312 if (!insn || !NONDEBUG_INSN_P (insn)
22313 || GET_CODE (PATTERN (insn)) == USE
22314 || GET_CODE (PATTERN (insn)) == CLOBBER)
22317 if (rs6000_sched_groups)
22319 enum attr_type type = get_attr_type (insn);
22320 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
22321 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
22322 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
22323 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
22324 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
22325 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
22326 || type == TYPE_IDIV || type == TYPE_LDIV
22327 || type == TYPE_INSERT_WORD)
22334 /* The function returns true if INSN can be issued only from
22335 the branch slot. */
22338 is_branch_slot_insn (rtx insn)
22340 if (!insn || !NONDEBUG_INSN_P (insn)
22341 || GET_CODE (PATTERN (insn)) == USE
22342 || GET_CODE (PATTERN (insn)) == CLOBBER)
22345 if (rs6000_sched_groups)
22347 enum attr_type type = get_attr_type (insn);
22348 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
22356 /* The function returns true if out_inst sets a value that is
22357 used in the address generation computation of in_insn */
22359 set_to_load_agen (rtx out_insn, rtx in_insn)
22361 rtx out_set, in_set;
22363 /* For performance reasons, only handle the simple case where
22364 both loads are a single_set. */
22365 out_set = single_set (out_insn);
22368 in_set = single_set (in_insn);
22370 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
22376 /* The function returns true if the target storage location of
22377 out_insn is adjacent to the target storage location of in_insn */
22378 /* Return 1 if memory locations are adjacent. */
22381 adjacent_mem_locations (rtx insn1, rtx insn2)
22384 rtx a = get_store_dest (PATTERN (insn1));
22385 rtx b = get_store_dest (PATTERN (insn2));
22387 if ((GET_CODE (XEXP (a, 0)) == REG
22388 || (GET_CODE (XEXP (a, 0)) == PLUS
22389 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
22390 && (GET_CODE (XEXP (b, 0)) == REG
22391 || (GET_CODE (XEXP (b, 0)) == PLUS
22392 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
22394 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
22397 if (GET_CODE (XEXP (a, 0)) == PLUS)
22399 reg0 = XEXP (XEXP (a, 0), 0);
22400 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
22403 reg0 = XEXP (a, 0);
22405 if (GET_CODE (XEXP (b, 0)) == PLUS)
22407 reg1 = XEXP (XEXP (b, 0), 0);
22408 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
22411 reg1 = XEXP (b, 0);
22413 val_diff = val1 - val0;
22415 return ((REGNO (reg0) == REGNO (reg1))
22416 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
22417 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
22423 /* A C statement (sans semicolon) to update the integer scheduling
22424 priority INSN_PRIORITY (INSN). Increase the priority to execute the
22425 INSN earlier, reduce the priority to execute INSN later. Do not
22426 define this macro if you do not need to adjust the scheduling
22427 priorities of insns. */
22430 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
22432 /* On machines (like the 750) which have asymmetric integer units,
22433 where one integer unit can do multiply and divides and the other
22434 can't, reduce the priority of multiply/divide so it is scheduled
22435 before other integer operations. */
22438 if (! INSN_P (insn))
22441 if (GET_CODE (PATTERN (insn)) == USE)
22444 switch (rs6000_cpu_attr) {
22446 switch (get_attr_type (insn))
22453 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
22454 priority, priority);
22455 if (priority >= 0 && priority < 0x01000000)
22462 if (insn_must_be_first_in_group (insn)
22463 && reload_completed
22464 && current_sched_info->sched_max_insns_priority
22465 && rs6000_sched_restricted_insns_priority)
22468 /* Prioritize insns that can be dispatched only in the first
22470 if (rs6000_sched_restricted_insns_priority == 1)
22471 /* Attach highest priority to insn. This means that in
22472 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
22473 precede 'priority' (critical path) considerations. */
22474 return current_sched_info->sched_max_insns_priority;
22475 else if (rs6000_sched_restricted_insns_priority == 2)
22476 /* Increase priority of insn by a minimal amount. This means that in
22477 haifa-sched.c:ready_sort(), only 'priority' (critical path)
22478 considerations precede dispatch-slot restriction considerations. */
22479 return (priority + 1);
22482 if (rs6000_cpu == PROCESSOR_POWER6
22483 && ((load_store_pendulum == -2 && is_load_insn (insn))
22484 || (load_store_pendulum == 2 && is_store_insn (insn))))
22485 /* Attach highest priority to insn if the scheduler has just issued two
22486 stores and this instruction is a load, or two loads and this instruction
22487 is a store. Power6 wants loads and stores scheduled alternately
22489 return current_sched_info->sched_max_insns_priority;
22494 /* Return true if the instruction is nonpipelined on the Cell. */
22496 is_nonpipeline_insn (rtx insn)
22498 enum attr_type type;
22499 if (!insn || !NONDEBUG_INSN_P (insn)
22500 || GET_CODE (PATTERN (insn)) == USE
22501 || GET_CODE (PATTERN (insn)) == CLOBBER)
22504 type = get_attr_type (insn);
22505 if (type == TYPE_IMUL
22506 || type == TYPE_IMUL2
22507 || type == TYPE_IMUL3
22508 || type == TYPE_LMUL
22509 || type == TYPE_IDIV
22510 || type == TYPE_LDIV
22511 || type == TYPE_SDIV
22512 || type == TYPE_DDIV
22513 || type == TYPE_SSQRT
22514 || type == TYPE_DSQRT
22515 || type == TYPE_MFCR
22516 || type == TYPE_MFCRF
22517 || type == TYPE_MFJMPR)
22525 /* Return how many instructions the machine can issue per cycle. */
22528 rs6000_issue_rate (void)
22530 /* Unless scheduling for register pressure, use issue rate of 1 for
22531 first scheduling pass to decrease degradation. */
22532 if (!reload_completed && !flag_sched_pressure)
22535 switch (rs6000_cpu_attr) {
22536 case CPU_RIOS1: /* ? */
22538 case CPU_PPC601: /* ? */
22547 case CPU_PPCE300C2:
22548 case CPU_PPCE300C3:
22549 case CPU_PPCE500MC:
22550 case CPU_PPCE500MC64:
22570 /* Return how many instructions to look ahead for better insn
22574 rs6000_use_sched_lookahead (void)
22576 if (rs6000_cpu_attr == CPU_PPC8540)
22578 if (rs6000_cpu_attr == CPU_CELL)
22579 return (reload_completed ? 8 : 0);
22583 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
22585 rs6000_use_sched_lookahead_guard (rtx insn)
22587 if (rs6000_cpu_attr != CPU_CELL)
22590 if (insn == NULL_RTX || !INSN_P (insn))
22593 if (!reload_completed
22594 || is_nonpipeline_insn (insn)
22595 || is_microcoded_insn (insn))
22601 /* Determine is PAT refers to memory. */
22604 is_mem_ref (rtx pat)
22610 /* stack_tie does not produce any real memory traffic. */
22611 if (GET_CODE (pat) == UNSPEC
22612 && XINT (pat, 1) == UNSPEC_TIE)
22615 if (GET_CODE (pat) == MEM)
22618 /* Recursively process the pattern. */
22619 fmt = GET_RTX_FORMAT (GET_CODE (pat));
22621 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
22624 ret |= is_mem_ref (XEXP (pat, i));
22625 else if (fmt[i] == 'E')
22626 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
22627 ret |= is_mem_ref (XVECEXP (pat, i, j));
22633 /* Determine if PAT is a PATTERN of a load insn. */
22636 is_load_insn1 (rtx pat)
22638 if (!pat || pat == NULL_RTX)
22641 if (GET_CODE (pat) == SET)
22642 return is_mem_ref (SET_SRC (pat));
22644 if (GET_CODE (pat) == PARALLEL)
22648 for (i = 0; i < XVECLEN (pat, 0); i++)
22649 if (is_load_insn1 (XVECEXP (pat, 0, i)))
22656 /* Determine if INSN loads from memory. */
22659 is_load_insn (rtx insn)
22661 if (!insn || !INSN_P (insn))
22664 if (GET_CODE (insn) == CALL_INSN)
22667 return is_load_insn1 (PATTERN (insn));
22670 /* Determine if PAT is a PATTERN of a store insn. */
22673 is_store_insn1 (rtx pat)
22675 if (!pat || pat == NULL_RTX)
22678 if (GET_CODE (pat) == SET)
22679 return is_mem_ref (SET_DEST (pat));
22681 if (GET_CODE (pat) == PARALLEL)
22685 for (i = 0; i < XVECLEN (pat, 0); i++)
22686 if (is_store_insn1 (XVECEXP (pat, 0, i)))
22693 /* Determine if INSN stores to memory. */
22696 is_store_insn (rtx insn)
22698 if (!insn || !INSN_P (insn))
22701 return is_store_insn1 (PATTERN (insn));
22704 /* Return the dest of a store insn. */
22707 get_store_dest (rtx pat)
22709 gcc_assert (is_store_insn1 (pat));
22711 if (GET_CODE (pat) == SET)
22712 return SET_DEST (pat);
22713 else if (GET_CODE (pat) == PARALLEL)
22717 for (i = 0; i < XVECLEN (pat, 0); i++)
22719 rtx inner_pat = XVECEXP (pat, 0, i);
22720 if (GET_CODE (inner_pat) == SET
22721 && is_mem_ref (SET_DEST (inner_pat)))
22725 /* We shouldn't get here, because we should have either a simple
22726 store insn or a store with update which are covered above. */
22730 /* Returns whether the dependence between INSN and NEXT is considered
22731 costly by the given target. */
22734 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
22739 /* If the flag is not enabled - no dependence is considered costly;
22740 allow all dependent insns in the same group.
22741 This is the most aggressive option. */
22742 if (rs6000_sched_costly_dep == no_dep_costly)
22745 /* If the flag is set to 1 - a dependence is always considered costly;
22746 do not allow dependent instructions in the same group.
22747 This is the most conservative option. */
22748 if (rs6000_sched_costly_dep == all_deps_costly)
22751 insn = DEP_PRO (dep);
22752 next = DEP_CON (dep);
22754 if (rs6000_sched_costly_dep == store_to_load_dep_costly
22755 && is_load_insn (next)
22756 && is_store_insn (insn))
22757 /* Prevent load after store in the same group. */
22760 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
22761 && is_load_insn (next)
22762 && is_store_insn (insn)
22763 && DEP_TYPE (dep) == REG_DEP_TRUE)
22764 /* Prevent load after store in the same group if it is a true
22768 /* The flag is set to X; dependences with latency >= X are considered costly,
22769 and will not be scheduled in the same group. */
22770 if (rs6000_sched_costly_dep <= max_dep_latency
22771 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22777 /* Return the next insn after INSN that is found before TAIL is reached,
22778 skipping any "non-active" insns - insns that will not actually occupy
22779 an issue slot. Return NULL_RTX if such an insn is not found. */
22782 get_next_active_insn (rtx insn, rtx tail)
22784 if (insn == NULL_RTX || insn == tail)
22789 insn = NEXT_INSN (insn);
22790 if (insn == NULL_RTX || insn == tail)
22795 || (NONJUMP_INSN_P (insn)
22796 && GET_CODE (PATTERN (insn)) != USE
22797 && GET_CODE (PATTERN (insn)) != CLOBBER
22798 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22804 /* We are about to begin issuing insns for this clock cycle. */
22807 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22808 rtx *ready ATTRIBUTE_UNUSED,
22809 int *pn_ready ATTRIBUTE_UNUSED,
22810 int clock_var ATTRIBUTE_UNUSED)
22812 int n_ready = *pn_ready;
22815 fprintf (dump, "// rs6000_sched_reorder :\n");
22817 /* Reorder the ready list, if the second to last ready insn
22818 is a nonepipeline insn. */
22819 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22821 if (is_nonpipeline_insn (ready[n_ready - 1])
22822 && (recog_memoized (ready[n_ready - 2]) > 0))
22823 /* Simply swap first two insns. */
22825 rtx tmp = ready[n_ready - 1];
22826 ready[n_ready - 1] = ready[n_ready - 2];
22827 ready[n_ready - 2] = tmp;
22831 if (rs6000_cpu == PROCESSOR_POWER6)
22832 load_store_pendulum = 0;
22834 return rs6000_issue_rate ();
22837 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22840 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
22841 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
22844 fprintf (dump, "// rs6000_sched_reorder2 :\n");
22846 /* For Power6, we need to handle some special cases to try and keep the
22847 store queue from overflowing and triggering expensive flushes.
22849 This code monitors how load and store instructions are being issued
22850 and skews the ready list one way or the other to increase the likelihood
22851 that a desired instruction is issued at the proper time.
22853 A couple of things are done. First, we maintain a "load_store_pendulum"
22854 to track the current state of load/store issue.
22856 - If the pendulum is at zero, then no loads or stores have been
22857 issued in the current cycle so we do nothing.
22859 - If the pendulum is 1, then a single load has been issued in this
22860 cycle and we attempt to locate another load in the ready list to
22863 - If the pendulum is -2, then two stores have already been
22864 issued in this cycle, so we increase the priority of the first load
22865 in the ready list to increase it's likelihood of being chosen first
22868 - If the pendulum is -1, then a single store has been issued in this
22869 cycle and we attempt to locate another store in the ready list to
22870 issue with it, preferring a store to an adjacent memory location to
22871 facilitate store pairing in the store queue.
22873 - If the pendulum is 2, then two loads have already been
22874 issued in this cycle, so we increase the priority of the first store
22875 in the ready list to increase it's likelihood of being chosen first
22878 - If the pendulum < -2 or > 2, then do nothing.
22880 Note: This code covers the most common scenarios. There exist non
22881 load/store instructions which make use of the LSU and which
22882 would need to be accounted for to strictly model the behavior
22883 of the machine. Those instructions are currently unaccounted
22884 for to help minimize compile time overhead of this code.
22886 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
22892 if (is_store_insn (last_scheduled_insn))
22893 /* Issuing a store, swing the load_store_pendulum to the left */
22894 load_store_pendulum--;
22895 else if (is_load_insn (last_scheduled_insn))
22896 /* Issuing a load, swing the load_store_pendulum to the right */
22897 load_store_pendulum++;
22899 return cached_can_issue_more;
22901 /* If the pendulum is balanced, or there is only one instruction on
22902 the ready list, then all is well, so return. */
22903 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
22904 return cached_can_issue_more;
22906 if (load_store_pendulum == 1)
22908 /* A load has been issued in this cycle. Scan the ready list
22909 for another load to issue with it */
22914 if (is_load_insn (ready[pos]))
22916 /* Found a load. Move it to the head of the ready list,
22917 and adjust it's priority so that it is more likely to
22920 for (i=pos; i<*pn_ready-1; i++)
22921 ready[i] = ready[i + 1];
22922 ready[*pn_ready-1] = tmp;
22924 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22925 INSN_PRIORITY (tmp)++;
22931 else if (load_store_pendulum == -2)
22933 /* Two stores have been issued in this cycle. Increase the
22934 priority of the first load in the ready list to favor it for
22935 issuing in the next cycle. */
22940 if (is_load_insn (ready[pos])
22942 && INSN_PRIORITY_KNOWN (ready[pos]))
22944 INSN_PRIORITY (ready[pos])++;
22946 /* Adjust the pendulum to account for the fact that a load
22947 was found and increased in priority. This is to prevent
22948 increasing the priority of multiple loads */
22949 load_store_pendulum--;
22956 else if (load_store_pendulum == -1)
22958 /* A store has been issued in this cycle. Scan the ready list for
22959 another store to issue with it, preferring a store to an adjacent
22961 int first_store_pos = -1;
22967 if (is_store_insn (ready[pos]))
22969 /* Maintain the index of the first store found on the
22971 if (first_store_pos == -1)
22972 first_store_pos = pos;
22974 if (is_store_insn (last_scheduled_insn)
22975 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22977 /* Found an adjacent store. Move it to the head of the
22978 ready list, and adjust it's priority so that it is
22979 more likely to stay there */
22981 for (i=pos; i<*pn_ready-1; i++)
22982 ready[i] = ready[i + 1];
22983 ready[*pn_ready-1] = tmp;
22985 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22986 INSN_PRIORITY (tmp)++;
22988 first_store_pos = -1;
22996 if (first_store_pos >= 0)
22998 /* An adjacent store wasn't found, but a non-adjacent store was,
22999 so move the non-adjacent store to the front of the ready
23000 list, and adjust its priority so that it is more likely to
23002 tmp = ready[first_store_pos];
23003 for (i=first_store_pos; i<*pn_ready-1; i++)
23004 ready[i] = ready[i + 1];
23005 ready[*pn_ready-1] = tmp;
23006 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23007 INSN_PRIORITY (tmp)++;
23010 else if (load_store_pendulum == 2)
23012 /* Two loads have been issued in this cycle. Increase the priority
23013 of the first store in the ready list to favor it for issuing in
23019 if (is_store_insn (ready[pos])
23021 && INSN_PRIORITY_KNOWN (ready[pos]))
23023 INSN_PRIORITY (ready[pos])++;
23025 /* Adjust the pendulum to account for the fact that a store
23026 was found and increased in priority. This is to prevent
23027 increasing the priority of multiple stores */
23028 load_store_pendulum++;
23037 return cached_can_issue_more;
23040 /* Return whether the presence of INSN causes a dispatch group termination
23041 of group WHICH_GROUP.
23043 If WHICH_GROUP == current_group, this function will return true if INSN
23044 causes the termination of the current group (i.e, the dispatch group to
23045 which INSN belongs). This means that INSN will be the last insn in the
23046 group it belongs to.
23048 If WHICH_GROUP == previous_group, this function will return true if INSN
23049 causes the termination of the previous group (i.e, the dispatch group that
23050 precedes the group to which INSN belongs). This means that INSN will be
23051 the first insn in the group it belongs to). */
23054 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23061 first = insn_must_be_first_in_group (insn);
23062 last = insn_must_be_last_in_group (insn);
23067 if (which_group == current_group)
23069 else if (which_group == previous_group)
23077 insn_must_be_first_in_group (rtx insn)
23079 enum attr_type type;
23082 || GET_CODE (insn) == NOTE
23083 || DEBUG_INSN_P (insn)
23084 || GET_CODE (PATTERN (insn)) == USE
23085 || GET_CODE (PATTERN (insn)) == CLOBBER)
23088 switch (rs6000_cpu)
23090 case PROCESSOR_POWER5:
23091 if (is_cracked_insn (insn))
23093 case PROCESSOR_POWER4:
23094 if (is_microcoded_insn (insn))
23097 if (!rs6000_sched_groups)
23100 type = get_attr_type (insn);
23107 case TYPE_DELAYED_CR:
23108 case TYPE_CR_LOGICAL:
23122 case PROCESSOR_POWER6:
23123 type = get_attr_type (insn);
23127 case TYPE_INSERT_DWORD:
23131 case TYPE_VAR_SHIFT_ROTATE:
23138 case TYPE_INSERT_WORD:
23139 case TYPE_DELAYED_COMPARE:
23140 case TYPE_IMUL_COMPARE:
23141 case TYPE_LMUL_COMPARE:
23142 case TYPE_FPCOMPARE:
23153 case TYPE_LOAD_EXT_UX:
23155 case TYPE_STORE_UX:
23156 case TYPE_FPLOAD_U:
23157 case TYPE_FPLOAD_UX:
23158 case TYPE_FPSTORE_U:
23159 case TYPE_FPSTORE_UX:
23165 case PROCESSOR_POWER7:
23166 type = get_attr_type (insn);
23170 case TYPE_CR_LOGICAL:
23177 case TYPE_DELAYED_COMPARE:
23178 case TYPE_VAR_DELAYED_COMPARE:
23184 case TYPE_LOAD_EXT:
23185 case TYPE_LOAD_EXT_U:
23186 case TYPE_LOAD_EXT_UX:
23188 case TYPE_STORE_UX:
23189 case TYPE_FPLOAD_U:
23190 case TYPE_FPLOAD_UX:
23191 case TYPE_FPSTORE_U:
23192 case TYPE_FPSTORE_UX:
23208 insn_must_be_last_in_group (rtx insn)
23210 enum attr_type type;
23213 || GET_CODE (insn) == NOTE
23214 || DEBUG_INSN_P (insn)
23215 || GET_CODE (PATTERN (insn)) == USE
23216 || GET_CODE (PATTERN (insn)) == CLOBBER)
23219 switch (rs6000_cpu) {
23220 case PROCESSOR_POWER4:
23221 case PROCESSOR_POWER5:
23222 if (is_microcoded_insn (insn))
23225 if (is_branch_slot_insn (insn))
23229 case PROCESSOR_POWER6:
23230 type = get_attr_type (insn);
23237 case TYPE_VAR_SHIFT_ROTATE:
23244 case TYPE_DELAYED_COMPARE:
23245 case TYPE_IMUL_COMPARE:
23246 case TYPE_LMUL_COMPARE:
23247 case TYPE_FPCOMPARE:
23261 case PROCESSOR_POWER7:
23262 type = get_attr_type (insn);
23270 case TYPE_LOAD_EXT_U:
23271 case TYPE_LOAD_EXT_UX:
23272 case TYPE_STORE_UX:
23285 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
23286 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
23289 is_costly_group (rtx *group_insns, rtx next_insn)
23292 int issue_rate = rs6000_issue_rate ();
23294 for (i = 0; i < issue_rate; i++)
23296 sd_iterator_def sd_it;
23298 rtx insn = group_insns[i];
23303 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
23305 rtx next = DEP_CON (dep);
23307 if (next == next_insn
23308 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
23316 /* Utility of the function redefine_groups.
23317 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
23318 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
23319 to keep it "far" (in a separate group) from GROUP_INSNS, following
23320 one of the following schemes, depending on the value of the flag
23321 -minsert_sched_nops = X:
23322 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
23323 in order to force NEXT_INSN into a separate group.
23324 (2) X < sched_finish_regroup_exact: insert exactly X nops.
23325 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
23326 insertion (has a group just ended, how many vacant issue slots remain in the
23327 last group, and how many dispatch groups were encountered so far). */
23330 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
23331 rtx next_insn, bool *group_end, int can_issue_more,
23336 int issue_rate = rs6000_issue_rate ();
23337 bool end = *group_end;
23340 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
23341 return can_issue_more;
23343 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
23344 return can_issue_more;
23346 force = is_costly_group (group_insns, next_insn);
23348 return can_issue_more;
23350 if (sched_verbose > 6)
23351 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
23352 *group_count ,can_issue_more);
23354 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
23357 can_issue_more = 0;
23359 /* Since only a branch can be issued in the last issue_slot, it is
23360 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
23361 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
23362 in this case the last nop will start a new group and the branch
23363 will be forced to the new group. */
23364 if (can_issue_more && !is_branch_slot_insn (next_insn))
23367 while (can_issue_more > 0)
23370 emit_insn_before (nop, next_insn);
23378 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
23380 int n_nops = rs6000_sched_insert_nops;
23382 /* Nops can't be issued from the branch slot, so the effective
23383 issue_rate for nops is 'issue_rate - 1'. */
23384 if (can_issue_more == 0)
23385 can_issue_more = issue_rate;
23387 if (can_issue_more == 0)
23389 can_issue_more = issue_rate - 1;
23392 for (i = 0; i < issue_rate; i++)
23394 group_insns[i] = 0;
23401 emit_insn_before (nop, next_insn);
23402 if (can_issue_more == issue_rate - 1) /* new group begins */
23405 if (can_issue_more == 0)
23407 can_issue_more = issue_rate - 1;
23410 for (i = 0; i < issue_rate; i++)
23412 group_insns[i] = 0;
23418 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
23421 /* Is next_insn going to start a new group? */
23424 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23425 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23426 || (can_issue_more < issue_rate &&
23427 insn_terminates_group_p (next_insn, previous_group)));
23428 if (*group_end && end)
23431 if (sched_verbose > 6)
23432 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
23433 *group_count, can_issue_more);
23434 return can_issue_more;
23437 return can_issue_more;
23440 /* This function tries to synch the dispatch groups that the compiler "sees"
23441 with the dispatch groups that the processor dispatcher is expected to
23442 form in practice. It tries to achieve this synchronization by forcing the
23443 estimated processor grouping on the compiler (as opposed to the function
23444 'pad_goups' which tries to force the scheduler's grouping on the processor).
23446 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
23447 examines the (estimated) dispatch groups that will be formed by the processor
23448 dispatcher. It marks these group boundaries to reflect the estimated
23449 processor grouping, overriding the grouping that the scheduler had marked.
23450 Depending on the value of the flag '-minsert-sched-nops' this function can
23451 force certain insns into separate groups or force a certain distance between
23452 them by inserting nops, for example, if there exists a "costly dependence"
23455 The function estimates the group boundaries that the processor will form as
23456 follows: It keeps track of how many vacant issue slots are available after
23457 each insn. A subsequent insn will start a new group if one of the following
23459 - no more vacant issue slots remain in the current dispatch group.
23460 - only the last issue slot, which is the branch slot, is vacant, but the next
23461 insn is not a branch.
23462 - only the last 2 or less issue slots, including the branch slot, are vacant,
23463 which means that a cracked insn (which occupies two issue slots) can't be
23464 issued in this group.
23465 - less than 'issue_rate' slots are vacant, and the next insn always needs to
23466 start a new group. */
23469 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23471 rtx insn, next_insn;
23473 int can_issue_more;
23476 int group_count = 0;
23480 issue_rate = rs6000_issue_rate ();
23481 group_insns = XALLOCAVEC (rtx, issue_rate);
23482 for (i = 0; i < issue_rate; i++)
23484 group_insns[i] = 0;
23486 can_issue_more = issue_rate;
23488 insn = get_next_active_insn (prev_head_insn, tail);
23491 while (insn != NULL_RTX)
23493 slot = (issue_rate - can_issue_more);
23494 group_insns[slot] = insn;
23496 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23497 if (insn_terminates_group_p (insn, current_group))
23498 can_issue_more = 0;
23500 next_insn = get_next_active_insn (insn, tail);
23501 if (next_insn == NULL_RTX)
23502 return group_count + 1;
23504 /* Is next_insn going to start a new group? */
23506 = (can_issue_more == 0
23507 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23508 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23509 || (can_issue_more < issue_rate &&
23510 insn_terminates_group_p (next_insn, previous_group)));
23512 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
23513 next_insn, &group_end, can_issue_more,
23519 can_issue_more = 0;
23520 for (i = 0; i < issue_rate; i++)
23522 group_insns[i] = 0;
23526 if (GET_MODE (next_insn) == TImode && can_issue_more)
23527 PUT_MODE (next_insn, VOIDmode);
23528 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
23529 PUT_MODE (next_insn, TImode);
23532 if (can_issue_more == 0)
23533 can_issue_more = issue_rate;
23536 return group_count;
23539 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
23540 dispatch group boundaries that the scheduler had marked. Pad with nops
23541 any dispatch groups which have vacant issue slots, in order to force the
23542 scheduler's grouping on the processor dispatcher. The function
23543 returns the number of dispatch groups found. */
23546 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23548 rtx insn, next_insn;
23551 int can_issue_more;
23553 int group_count = 0;
23555 /* Initialize issue_rate. */
23556 issue_rate = rs6000_issue_rate ();
23557 can_issue_more = issue_rate;
23559 insn = get_next_active_insn (prev_head_insn, tail);
23560 next_insn = get_next_active_insn (insn, tail);
23562 while (insn != NULL_RTX)
23565 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23567 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
23569 if (next_insn == NULL_RTX)
23574 /* If the scheduler had marked group termination at this location
23575 (between insn and next_insn), and neither insn nor next_insn will
23576 force group termination, pad the group with nops to force group
23579 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
23580 && !insn_terminates_group_p (insn, current_group)
23581 && !insn_terminates_group_p (next_insn, previous_group))
23583 if (!is_branch_slot_insn (next_insn))
23586 while (can_issue_more)
23589 emit_insn_before (nop, next_insn);
23594 can_issue_more = issue_rate;
23599 next_insn = get_next_active_insn (insn, tail);
23602 return group_count;
23605 /* We're beginning a new block. Initialize data structures as necessary. */
23608 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
23609 int sched_verbose ATTRIBUTE_UNUSED,
23610 int max_ready ATTRIBUTE_UNUSED)
23612 last_scheduled_insn = NULL_RTX;
23613 load_store_pendulum = 0;
23616 /* The following function is called at the end of scheduling BB.
23617 After reload, it inserts nops at insn group bundling. */
23620 rs6000_sched_finish (FILE *dump, int sched_verbose)
23625 fprintf (dump, "=== Finishing schedule.\n");
23627 if (reload_completed && rs6000_sched_groups)
23629 /* Do not run sched_finish hook when selective scheduling enabled. */
23630 if (sel_sched_p ())
23633 if (rs6000_sched_insert_nops == sched_finish_none)
23636 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
23637 n_groups = pad_groups (dump, sched_verbose,
23638 current_sched_info->prev_head,
23639 current_sched_info->next_tail);
23641 n_groups = redefine_groups (dump, sched_verbose,
23642 current_sched_info->prev_head,
23643 current_sched_info->next_tail);
23645 if (sched_verbose >= 6)
23647 fprintf (dump, "ngroups = %d\n", n_groups);
23648 print_rtl (dump, current_sched_info->prev_head);
23649 fprintf (dump, "Done finish_sched\n");
23654 struct _rs6000_sched_context
23656 short cached_can_issue_more;
23657 rtx last_scheduled_insn;
23658 int load_store_pendulum;
23661 typedef struct _rs6000_sched_context rs6000_sched_context_def;
23662 typedef rs6000_sched_context_def *rs6000_sched_context_t;
23664 /* Allocate store for new scheduling context. */
23666 rs6000_alloc_sched_context (void)
23668 return xmalloc (sizeof (rs6000_sched_context_def));
23671 /* If CLEAN_P is true then initializes _SC with clean data,
23672 and from the global context otherwise. */
23674 rs6000_init_sched_context (void *_sc, bool clean_p)
23676 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23680 sc->cached_can_issue_more = 0;
23681 sc->last_scheduled_insn = NULL_RTX;
23682 sc->load_store_pendulum = 0;
23686 sc->cached_can_issue_more = cached_can_issue_more;
23687 sc->last_scheduled_insn = last_scheduled_insn;
23688 sc->load_store_pendulum = load_store_pendulum;
23692 /* Sets the global scheduling context to the one pointed to by _SC. */
23694 rs6000_set_sched_context (void *_sc)
23696 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23698 gcc_assert (sc != NULL);
23700 cached_can_issue_more = sc->cached_can_issue_more;
23701 last_scheduled_insn = sc->last_scheduled_insn;
23702 load_store_pendulum = sc->load_store_pendulum;
23707 rs6000_free_sched_context (void *_sc)
23709 gcc_assert (_sc != NULL);
23715 /* Length in units of the trampoline for entering a nested function. */
23718 rs6000_trampoline_size (void)
23722 switch (DEFAULT_ABI)
23725 gcc_unreachable ();
23728 ret = (TARGET_32BIT) ? 12 : 24;
23733 ret = (TARGET_32BIT) ? 40 : 48;
23740 /* Emit RTL insns to initialize the variable parts of a trampoline.
23741 FNADDR is an RTX for the address of the function's pure code.
23742 CXT is an RTX for the static chain value for the function. */
23745 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
23747 int regsize = (TARGET_32BIT) ? 4 : 8;
23748 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
23749 rtx ctx_reg = force_reg (Pmode, cxt);
23750 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
23752 switch (DEFAULT_ABI)
23755 gcc_unreachable ();
23757 /* Under AIX, just build the 3 word function descriptor */
23760 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
23761 rtx fn_reg = gen_reg_rtx (Pmode);
23762 rtx toc_reg = gen_reg_rtx (Pmode);
23764 /* Macro to shorten the code expansions below. */
23765 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23767 m_tramp = replace_equiv_address (m_tramp, addr);
23769 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
23770 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23771 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23772 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23773 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23779 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23782 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23783 LCT_NORMAL, VOIDmode, 4,
23785 GEN_INT (rs6000_trampoline_size ()), SImode,
23793 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
23794 identifier as an argument, so the front end shouldn't look it up. */
23797 rs6000_attribute_takes_identifier_p (const_tree attr_id)
23799 return is_attribute_p ("altivec", attr_id);
23802 /* Handle the "altivec" attribute. The attribute may have
23803 arguments as follows:
23805 __attribute__((altivec(vector__)))
23806 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23807 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23809 and may appear more than once (e.g., 'vector bool char') in a
23810 given declaration. */
23813 rs6000_handle_altivec_attribute (tree *node,
23814 tree name ATTRIBUTE_UNUSED,
23816 int flags ATTRIBUTE_UNUSED,
23817 bool *no_add_attrs)
23819 tree type = *node, result = NULL_TREE;
23820 enum machine_mode mode;
23823 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23824 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23825 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23828 while (POINTER_TYPE_P (type)
23829 || TREE_CODE (type) == FUNCTION_TYPE
23830 || TREE_CODE (type) == METHOD_TYPE
23831 || TREE_CODE (type) == ARRAY_TYPE)
23832 type = TREE_TYPE (type);
23834 mode = TYPE_MODE (type);
23836 /* Check for invalid AltiVec type qualifiers. */
23837 if (type == long_double_type_node)
23838 error ("use of %<long double%> in AltiVec types is invalid");
23839 else if (type == boolean_type_node)
23840 error ("use of boolean types in AltiVec types is invalid");
23841 else if (TREE_CODE (type) == COMPLEX_TYPE)
23842 error ("use of %<complex%> in AltiVec types is invalid");
23843 else if (DECIMAL_FLOAT_MODE_P (mode))
23844 error ("use of decimal floating point types in AltiVec types is invalid");
23845 else if (!TARGET_VSX)
23847 if (type == long_unsigned_type_node || type == long_integer_type_node)
23850 error ("use of %<long%> in AltiVec types is invalid for "
23851 "64-bit code without -mvsx");
23852 else if (rs6000_warn_altivec_long)
23853 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23856 else if (type == long_long_unsigned_type_node
23857 || type == long_long_integer_type_node)
23858 error ("use of %<long long%> in AltiVec types is invalid without "
23860 else if (type == double_type_node)
23861 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23864 switch (altivec_type)
23867 unsigned_p = TYPE_UNSIGNED (type);
23871 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
23874 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
23877 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
23880 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
23882 case SFmode: result = V4SF_type_node; break;
23883 case DFmode: result = V2DF_type_node; break;
23884 /* If the user says 'vector int bool', we may be handed the 'bool'
23885 attribute _before_ the 'vector' attribute, and so select the
23886 proper type in the 'b' case below. */
23887 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
23888 case V2DImode: case V2DFmode:
23896 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
23897 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
23898 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
23899 case QImode: case V16QImode: result = bool_V16QI_type_node;
23906 case V8HImode: result = pixel_V8HI_type_node;
23912 /* Propagate qualifiers attached to the element type
23913 onto the vector type. */
23914 if (result && result != type && TYPE_QUALS (type))
23915 result = build_qualified_type (result, TYPE_QUALS (type));
23917 *no_add_attrs = true; /* No need to hang on to the attribute. */
23920 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
23925 /* AltiVec defines four built-in scalar types that serve as vector
23926 elements; we must teach the compiler how to mangle them. */
23928 static const char *
23929 rs6000_mangle_type (const_tree type)
23931 type = TYPE_MAIN_VARIANT (type);
23933 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
23934 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
23937 if (type == bool_char_type_node) return "U6__boolc";
23938 if (type == bool_short_type_node) return "U6__bools";
23939 if (type == pixel_type_node) return "u7__pixel";
23940 if (type == bool_int_type_node) return "U6__booli";
23941 if (type == bool_long_type_node) return "U6__booll";
23943 /* Mangle IBM extended float long double as `g' (__float128) on
23944 powerpc*-linux where long-double-64 previously was the default. */
23945 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
23947 && TARGET_LONG_DOUBLE_128
23948 && !TARGET_IEEEQUAD)
23951 /* For all other types, use normal C++ mangling. */
23955 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23956 struct attribute_spec.handler. */
23959 rs6000_handle_longcall_attribute (tree *node, tree name,
23960 tree args ATTRIBUTE_UNUSED,
23961 int flags ATTRIBUTE_UNUSED,
23962 bool *no_add_attrs)
23964 if (TREE_CODE (*node) != FUNCTION_TYPE
23965 && TREE_CODE (*node) != FIELD_DECL
23966 && TREE_CODE (*node) != TYPE_DECL)
23968 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23970 *no_add_attrs = true;
23976 /* Set longcall attributes on all functions declared when
23977 rs6000_default_long_calls is true. */
23979 rs6000_set_default_type_attributes (tree type)
23981 if (rs6000_default_long_calls
23982 && (TREE_CODE (type) == FUNCTION_TYPE
23983 || TREE_CODE (type) == METHOD_TYPE))
23984 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23986 TYPE_ATTRIBUTES (type));
23989 darwin_set_default_type_attributes (type);
23993 /* Return a reference suitable for calling a function with the
23994 longcall attribute. */
23997 rs6000_longcall_ref (rtx call_ref)
23999 const char *call_name;
24002 if (GET_CODE (call_ref) != SYMBOL_REF)
24005 /* System V adds '.' to the internal name, so skip them. */
24006 call_name = XSTR (call_ref, 0);
24007 if (*call_name == '.')
24009 while (*call_name == '.')
24012 node = get_identifier (call_name);
24013 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24016 return force_reg (Pmode, call_ref);
24019 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24020 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24023 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24024 struct attribute_spec.handler. */
24026 rs6000_handle_struct_attribute (tree *node, tree name,
24027 tree args ATTRIBUTE_UNUSED,
24028 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24031 if (DECL_P (*node))
24033 if (TREE_CODE (*node) == TYPE_DECL)
24034 type = &TREE_TYPE (*node);
24039 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24040 || TREE_CODE (*type) == UNION_TYPE)))
24042 warning (OPT_Wattributes, "%qE attribute ignored", name);
24043 *no_add_attrs = true;
24046 else if ((is_attribute_p ("ms_struct", name)
24047 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24048 || ((is_attribute_p ("gcc_struct", name)
24049 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24051 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24053 *no_add_attrs = true;
24060 rs6000_ms_bitfield_layout_p (const_tree record_type)
24062 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24063 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24064 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24067 #ifdef USING_ELFOS_H
24069 /* A get_unnamed_section callback, used for switching to toc_section. */
24072 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24074 if (DEFAULT_ABI == ABI_AIX
24075 && TARGET_MINIMAL_TOC
24076 && !TARGET_RELOCATABLE)
24078 if (!toc_initialized)
24080 toc_initialized = 1;
24081 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24082 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24083 fprintf (asm_out_file, "\t.tc ");
24084 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24085 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24086 fprintf (asm_out_file, "\n");
24088 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24089 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24090 fprintf (asm_out_file, " = .+32768\n");
24093 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24095 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24096 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24099 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24100 if (!toc_initialized)
24102 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24103 fprintf (asm_out_file, " = .+32768\n");
24104 toc_initialized = 1;
24109 /* Implement TARGET_ASM_INIT_SECTIONS. */
24112 rs6000_elf_asm_init_sections (void)
24115 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24118 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24119 SDATA2_SECTION_ASM_OP);
24122 /* Implement TARGET_SELECT_RTX_SECTION. */
24125 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24126 unsigned HOST_WIDE_INT align)
24128 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24129 return toc_section;
24131 return default_elf_select_rtx_section (mode, x, align);
24134 /* For a SYMBOL_REF, set generic flags and then perform some
24135 target-specific processing.
24137 When the AIX ABI is requested on a non-AIX system, replace the
24138 function name with the real name (with a leading .) rather than the
24139 function descriptor name. This saves a lot of overriding code to
24140 read the prefixes. */
24143 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24145 default_encode_section_info (decl, rtl, first);
24148 && TREE_CODE (decl) == FUNCTION_DECL
24150 && DEFAULT_ABI == ABI_AIX)
24152 rtx sym_ref = XEXP (rtl, 0);
24153 size_t len = strlen (XSTR (sym_ref, 0));
24154 char *str = XALLOCAVEC (char, len + 2);
24156 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24157 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24162 compare_section_name (const char *section, const char *templ)
24166 len = strlen (templ);
24167 return (strncmp (section, templ, len) == 0
24168 && (section[len] == 0 || section[len] == '.'));
24172 rs6000_elf_in_small_data_p (const_tree decl)
24174 if (rs6000_sdata == SDATA_NONE)
24177 /* We want to merge strings, so we never consider them small data. */
24178 if (TREE_CODE (decl) == STRING_CST)
24181 /* Functions are never in the small data area. */
24182 if (TREE_CODE (decl) == FUNCTION_DECL)
24185 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24187 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24188 if (compare_section_name (section, ".sdata")
24189 || compare_section_name (section, ".sdata2")
24190 || compare_section_name (section, ".gnu.linkonce.s")
24191 || compare_section_name (section, ".sbss")
24192 || compare_section_name (section, ".sbss2")
24193 || compare_section_name (section, ".gnu.linkonce.sb")
24194 || strcmp (section, ".PPC.EMB.sdata0") == 0
24195 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24200 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24203 && (unsigned HOST_WIDE_INT) size <= g_switch_value
24204 /* If it's not public, and we're not going to reference it there,
24205 there's no need to put it in the small data section. */
24206 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24213 #endif /* USING_ELFOS_H */
24215 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24218 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24220 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24223 /* Return a REG that occurs in ADDR with coefficient 1.
24224 ADDR can be effectively incremented by incrementing REG.
24226 r0 is special and we must not select it as an address
24227 register by this routine since our caller will try to
24228 increment the returned register via an "la" instruction. */
24231 find_addr_reg (rtx addr)
24233 while (GET_CODE (addr) == PLUS)
24235 if (GET_CODE (XEXP (addr, 0)) == REG
24236 && REGNO (XEXP (addr, 0)) != 0)
24237 addr = XEXP (addr, 0);
24238 else if (GET_CODE (XEXP (addr, 1)) == REG
24239 && REGNO (XEXP (addr, 1)) != 0)
24240 addr = XEXP (addr, 1);
24241 else if (CONSTANT_P (XEXP (addr, 0)))
24242 addr = XEXP (addr, 1);
24243 else if (CONSTANT_P (XEXP (addr, 1)))
24244 addr = XEXP (addr, 0);
24246 gcc_unreachable ();
24248 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
24253 rs6000_fatal_bad_address (rtx op)
24255 fatal_insn ("bad address", op);
24260 static tree branch_island_list = 0;
24262 /* Remember to generate a branch island for far calls to the given
24266 add_compiler_branch_island (tree label_name, tree function_name,
24269 tree branch_island = build_tree_list (function_name, label_name);
24270 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
24271 TREE_CHAIN (branch_island) = branch_island_list;
24272 branch_island_list = branch_island;
24275 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
24276 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
24277 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
24278 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
24280 /* Generate far-jump branch islands for everything on the
24281 branch_island_list. Invoked immediately after the last instruction
24282 of the epilogue has been emitted; the branch-islands must be
24283 appended to, and contiguous with, the function body. Mach-O stubs
24284 are generated in machopic_output_stub(). */
24287 macho_branch_islands (void)
24290 tree branch_island;
24292 for (branch_island = branch_island_list;
24294 branch_island = TREE_CHAIN (branch_island))
24296 const char *label =
24297 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
24299 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
24300 char name_buf[512];
24301 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
24302 if (name[0] == '*' || name[0] == '&')
24303 strcpy (name_buf, name+1);
24307 strcpy (name_buf+1, name);
24309 strcpy (tmp_buf, "\n");
24310 strcat (tmp_buf, label);
24311 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24312 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24313 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
24314 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24317 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
24318 strcat (tmp_buf, label);
24319 strcat (tmp_buf, "_pic\n");
24320 strcat (tmp_buf, label);
24321 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
24323 strcat (tmp_buf, "\taddis r11,r11,ha16(");
24324 strcat (tmp_buf, name_buf);
24325 strcat (tmp_buf, " - ");
24326 strcat (tmp_buf, label);
24327 strcat (tmp_buf, "_pic)\n");
24329 strcat (tmp_buf, "\tmtlr r0\n");
24331 strcat (tmp_buf, "\taddi r12,r11,lo16(");
24332 strcat (tmp_buf, name_buf);
24333 strcat (tmp_buf, " - ");
24334 strcat (tmp_buf, label);
24335 strcat (tmp_buf, "_pic)\n");
24337 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
24341 strcat (tmp_buf, ":\nlis r12,hi16(");
24342 strcat (tmp_buf, name_buf);
24343 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
24344 strcat (tmp_buf, name_buf);
24345 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
24347 output_asm_insn (tmp_buf, 0);
24348 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24349 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24350 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
24351 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24354 branch_island_list = 0;
24357 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
24358 already there or not. */
24361 no_previous_def (tree function_name)
24363 tree branch_island;
24364 for (branch_island = branch_island_list;
24366 branch_island = TREE_CHAIN (branch_island))
24367 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
24372 /* GET_PREV_LABEL gets the label name from the previous definition of
24376 get_prev_label (tree function_name)
24378 tree branch_island;
24379 for (branch_island = branch_island_list;
24381 branch_island = TREE_CHAIN (branch_island))
24382 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
24383 return BRANCH_ISLAND_LABEL_NAME (branch_island);
24387 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
24388 #define DARWIN_LINKER_GENERATES_ISLANDS 0
24391 /* KEXTs still need branch islands. */
24392 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
24393 || flag_mkernel || flag_apple_kext)
24395 /* INSN is either a function call or a millicode call. It may have an
24396 unconditional jump in its delay slot.
24398 CALL_DEST is the routine we are calling. */
24401 output_call (rtx insn, rtx *operands, int dest_operand_number,
24402 int cookie_operand_number)
24404 static char buf[256];
24405 if (DARWIN_GENERATE_ISLANDS
24406 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
24407 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
24410 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
24412 if (no_previous_def (funname))
24414 rtx label_rtx = gen_label_rtx ();
24415 char *label_buf, temp_buf[256];
24416 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
24417 CODE_LABEL_NUMBER (label_rtx));
24418 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
24419 labelname = get_identifier (label_buf);
24420 add_compiler_branch_island (labelname, funname, insn_line (insn));
24423 labelname = get_prev_label (funname);
24425 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
24426 instruction will reach 'foo', otherwise link as 'bl L42'".
24427 "L42" should be a 'branch island', that will do a far jump to
24428 'foo'. Branch islands are generated in
24429 macho_branch_islands(). */
24430 sprintf (buf, "jbsr %%z%d,%.246s",
24431 dest_operand_number, IDENTIFIER_POINTER (labelname));
24434 sprintf (buf, "bl %%z%d", dest_operand_number);
24438 /* Generate PIC and indirect symbol stubs. */
24441 machopic_output_stub (FILE *file, const char *symb, const char *stub)
24443 unsigned int length;
24444 char *symbol_name, *lazy_ptr_name;
24445 char *local_label_0;
24446 static int label = 0;
24448 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
24449 symb = (*targetm.strip_name_encoding) (symb);
24452 length = strlen (symb);
24453 symbol_name = XALLOCAVEC (char, length + 32);
24454 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
24456 lazy_ptr_name = XALLOCAVEC (char, length + 32);
24457 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
24460 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
24462 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
24466 fprintf (file, "\t.align 5\n");
24468 fprintf (file, "%s:\n", stub);
24469 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24472 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
24473 sprintf (local_label_0, "\"L%011d$spb\"", label);
24475 fprintf (file, "\tmflr r0\n");
24476 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
24477 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
24478 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
24479 lazy_ptr_name, local_label_0);
24480 fprintf (file, "\tmtlr r0\n");
24481 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
24482 (TARGET_64BIT ? "ldu" : "lwzu"),
24483 lazy_ptr_name, local_label_0);
24484 fprintf (file, "\tmtctr r12\n");
24485 fprintf (file, "\tbctr\n");
24489 fprintf (file, "\t.align 4\n");
24491 fprintf (file, "%s:\n", stub);
24492 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24494 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
24495 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
24496 (TARGET_64BIT ? "ldu" : "lwzu"),
24498 fprintf (file, "\tmtctr r12\n");
24499 fprintf (file, "\tbctr\n");
24502 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
24503 fprintf (file, "%s:\n", lazy_ptr_name);
24504 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24505 fprintf (file, "%sdyld_stub_binding_helper\n",
24506 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
24509 /* Legitimize PIC addresses. If the address is already
24510 position-independent, we return ORIG. Newly generated
24511 position-independent addresses go into a reg. This is REG if non
24512 zero, otherwise we allocate register(s) as necessary. */
24514 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
24517 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
24522 if (reg == NULL && ! reload_in_progress && ! reload_completed)
24523 reg = gen_reg_rtx (Pmode);
24525 if (GET_CODE (orig) == CONST)
24529 if (GET_CODE (XEXP (orig, 0)) == PLUS
24530 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
24533 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
24535 /* Use a different reg for the intermediate value, as
24536 it will be marked UNCHANGING. */
24537 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
24538 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
24541 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
24544 if (GET_CODE (offset) == CONST_INT)
24546 if (SMALL_INT (offset))
24547 return plus_constant (base, INTVAL (offset));
24548 else if (! reload_in_progress && ! reload_completed)
24549 offset = force_reg (Pmode, offset);
24552 rtx mem = force_const_mem (Pmode, orig);
24553 return machopic_legitimize_pic_address (mem, Pmode, reg);
24556 return gen_rtx_PLUS (Pmode, base, offset);
24559 /* Fall back on generic machopic code. */
24560 return machopic_legitimize_pic_address (orig, mode, reg);
24563 /* Output a .machine directive for the Darwin assembler, and call
24564 the generic start_file routine. */
24567 rs6000_darwin_file_start (void)
24569 static const struct
24575 { "ppc64", "ppc64", MASK_64BIT },
24576 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
24577 { "power4", "ppc970", 0 },
24578 { "G5", "ppc970", 0 },
24579 { "7450", "ppc7450", 0 },
24580 { "7400", "ppc7400", MASK_ALTIVEC },
24581 { "G4", "ppc7400", 0 },
24582 { "750", "ppc750", 0 },
24583 { "740", "ppc750", 0 },
24584 { "G3", "ppc750", 0 },
24585 { "604e", "ppc604e", 0 },
24586 { "604", "ppc604", 0 },
24587 { "603e", "ppc603", 0 },
24588 { "603", "ppc603", 0 },
24589 { "601", "ppc601", 0 },
24590 { NULL, "ppc", 0 } };
24591 const char *cpu_id = "";
24594 rs6000_file_start ();
24595 darwin_file_start ();
24597 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
24598 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
24599 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
24600 && rs6000_select[i].string[0] != '\0')
24601 cpu_id = rs6000_select[i].string;
24603 /* Look through the mapping array. Pick the first name that either
24604 matches the argument, has a bit set in IF_SET that is also set
24605 in the target flags, or has a NULL name. */
24608 while (mapping[i].arg != NULL
24609 && strcmp (mapping[i].arg, cpu_id) != 0
24610 && (mapping[i].if_set & target_flags) == 0)
24613 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
24616 #endif /* TARGET_MACHO */
24620 rs6000_elf_reloc_rw_mask (void)
24624 else if (DEFAULT_ABI == ABI_AIX)
24630 /* Record an element in the table of global constructors. SYMBOL is
24631 a SYMBOL_REF of the function to be called; PRIORITY is a number
24632 between 0 and MAX_INIT_PRIORITY.
24634 This differs from default_named_section_asm_out_constructor in
24635 that we have special handling for -mrelocatable. */
24638 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
24640 const char *section = ".ctors";
24643 if (priority != DEFAULT_INIT_PRIORITY)
24645 sprintf (buf, ".ctors.%.5u",
24646 /* Invert the numbering so the linker puts us in the proper
24647 order; constructors are run from right to left, and the
24648 linker sorts in increasing order. */
24649 MAX_INIT_PRIORITY - priority);
24653 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24654 assemble_align (POINTER_SIZE);
24656 if (TARGET_RELOCATABLE)
24658 fputs ("\t.long (", asm_out_file);
24659 output_addr_const (asm_out_file, symbol);
24660 fputs (")@fixup\n", asm_out_file);
24663 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24667 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
24669 const char *section = ".dtors";
24672 if (priority != DEFAULT_INIT_PRIORITY)
24674 sprintf (buf, ".dtors.%.5u",
24675 /* Invert the numbering so the linker puts us in the proper
24676 order; constructors are run from right to left, and the
24677 linker sorts in increasing order. */
24678 MAX_INIT_PRIORITY - priority);
24682 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24683 assemble_align (POINTER_SIZE);
24685 if (TARGET_RELOCATABLE)
24687 fputs ("\t.long (", asm_out_file);
24688 output_addr_const (asm_out_file, symbol);
24689 fputs (")@fixup\n", asm_out_file);
24692 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24696 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
24700 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
24701 ASM_OUTPUT_LABEL (file, name);
24702 fputs (DOUBLE_INT_ASM_OP, file);
24703 rs6000_output_function_entry (file, name);
24704 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
24707 fputs ("\t.size\t", file);
24708 assemble_name (file, name);
24709 fputs (",24\n\t.type\t.", file);
24710 assemble_name (file, name);
24711 fputs (",@function\n", file);
24712 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
24714 fputs ("\t.globl\t.", file);
24715 assemble_name (file, name);
24720 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24721 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24722 rs6000_output_function_entry (file, name);
24723 fputs (":\n", file);
24727 if (TARGET_RELOCATABLE
24728 && !TARGET_SECURE_PLT
24729 && (get_pool_size () != 0 || crtl->profile)
24734 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
24736 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
24737 fprintf (file, "\t.long ");
24738 assemble_name (file, buf);
24740 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
24741 assemble_name (file, buf);
24745 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24746 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24748 if (DEFAULT_ABI == ABI_AIX)
24750 const char *desc_name, *orig_name;
24752 orig_name = (*targetm.strip_name_encoding) (name);
24753 desc_name = orig_name;
24754 while (*desc_name == '.')
24757 if (TREE_PUBLIC (decl))
24758 fprintf (file, "\t.globl %s\n", desc_name);
24760 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24761 fprintf (file, "%s:\n", desc_name);
24762 fprintf (file, "\t.long %s\n", orig_name);
24763 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
24764 if (DEFAULT_ABI == ABI_AIX)
24765 fputs ("\t.long 0\n", file);
24766 fprintf (file, "\t.previous\n");
24768 ASM_OUTPUT_LABEL (file, name);
24772 rs6000_elf_end_indicate_exec_stack (void)
24775 file_end_indicate_exec_stack ();
24781 rs6000_xcoff_asm_output_anchor (rtx symbol)
24785 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24786 SYMBOL_REF_BLOCK_OFFSET (symbol));
24787 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24791 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24793 fputs (GLOBAL_ASM_OP, stream);
24794 RS6000_OUTPUT_BASENAME (stream, name);
24795 putc ('\n', stream);
24798 /* A get_unnamed_decl callback, used for read-only sections. PTR
24799 points to the section string variable. */
24802 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24804 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24805 *(const char *const *) directive,
24806 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24809 /* Likewise for read-write sections. */
24812 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24814 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24815 *(const char *const *) directive,
24816 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24819 /* A get_unnamed_section callback, used for switching to toc_section. */
24822 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24824 if (TARGET_MINIMAL_TOC)
24826 /* toc_section is always selected at least once from
24827 rs6000_xcoff_file_start, so this is guaranteed to
24828 always be defined once and only once in each file. */
24829 if (!toc_initialized)
24831 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24832 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24833 toc_initialized = 1;
24835 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
24836 (TARGET_32BIT ? "" : ",3"));
24839 fputs ("\t.toc\n", asm_out_file);
24842 /* Implement TARGET_ASM_INIT_SECTIONS. */
24845 rs6000_xcoff_asm_init_sections (void)
24847 read_only_data_section
24848 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24849 &xcoff_read_only_section_name);
24851 private_data_section
24852 = get_unnamed_section (SECTION_WRITE,
24853 rs6000_xcoff_output_readwrite_section_asm_op,
24854 &xcoff_private_data_section_name);
24856 read_only_private_data_section
24857 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24858 &xcoff_private_data_section_name);
24861 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
24863 readonly_data_section = read_only_data_section;
24864 exception_section = data_section;
24868 rs6000_xcoff_reloc_rw_mask (void)
24874 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
24875 tree decl ATTRIBUTE_UNUSED)
24878 static const char * const suffix[3] = { "PR", "RO", "RW" };
24880 if (flags & SECTION_CODE)
24882 else if (flags & SECTION_WRITE)
24887 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
24888 (flags & SECTION_CODE) ? "." : "",
24889 name, suffix[smclass], flags & SECTION_ENTSIZE);
24893 rs6000_xcoff_select_section (tree decl, int reloc,
24894 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24896 if (decl_readonly_section (decl, reloc))
24898 if (TREE_PUBLIC (decl))
24899 return read_only_data_section;
24901 return read_only_private_data_section;
24905 if (TREE_PUBLIC (decl))
24906 return data_section;
24908 return private_data_section;
24913 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
24917 /* Use select_section for private and uninitialized data. */
24918 if (!TREE_PUBLIC (decl)
24919 || DECL_COMMON (decl)
24920 || DECL_INITIAL (decl) == NULL_TREE
24921 || DECL_INITIAL (decl) == error_mark_node
24922 || (flag_zero_initialized_in_bss
24923 && initializer_zerop (DECL_INITIAL (decl))))
24926 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
24927 name = (*targetm.strip_name_encoding) (name);
24928 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
24931 /* Select section for constant in constant pool.
24933 On RS/6000, all constants are in the private read-only data area.
24934 However, if this is being placed in the TOC it must be output as a
24938 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
24939 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24941 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24942 return toc_section;
24944 return read_only_private_data_section;
24947 /* Remove any trailing [DS] or the like from the symbol name. */
24949 static const char *
24950 rs6000_xcoff_strip_name_encoding (const char *name)
24955 len = strlen (name);
24956 if (name[len - 1] == ']')
24957 return ggc_alloc_string (name, len - 4);
24962 /* Section attributes. AIX is always PIC. */
24964 static unsigned int
24965 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24967 unsigned int align;
24968 unsigned int flags = default_section_type_flags (decl, name, reloc);
24970 /* Align to at least UNIT size. */
24971 if (flags & SECTION_CODE)
24972 align = MIN_UNITS_PER_WORD;
24974 /* Increase alignment of large objects if not already stricter. */
24975 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24976 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24977 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24979 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24982 /* Output at beginning of assembler file.
24984 Initialize the section names for the RS/6000 at this point.
24986 Specify filename, including full path, to assembler.
24988 We want to go into the TOC section so at least one .toc will be emitted.
24989 Also, in order to output proper .bs/.es pairs, we need at least one static
24990 [RW] section emitted.
24992 Finally, declare mcount when profiling to make the assembler happy. */
24995 rs6000_xcoff_file_start (void)
24997 rs6000_gen_section_name (&xcoff_bss_section_name,
24998 main_input_filename, ".bss_");
24999 rs6000_gen_section_name (&xcoff_private_data_section_name,
25000 main_input_filename, ".rw_");
25001 rs6000_gen_section_name (&xcoff_read_only_section_name,
25002 main_input_filename, ".ro_");
25004 fputs ("\t.file\t", asm_out_file);
25005 output_quoted_string (asm_out_file, main_input_filename);
25006 fputc ('\n', asm_out_file);
25007 if (write_symbols != NO_DEBUG)
25008 switch_to_section (private_data_section);
25009 switch_to_section (text_section);
25011 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25012 rs6000_file_start ();
25015 /* Output at end of assembler file.
25016 On the RS/6000, referencing data should automatically pull in text. */
25019 rs6000_xcoff_file_end (void)
25021 switch_to_section (text_section);
25022 fputs ("_section_.text:\n", asm_out_file);
25023 switch_to_section (data_section);
25024 fputs (TARGET_32BIT
25025 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25028 #endif /* TARGET_XCOFF */
25030 /* Compute a (partial) cost for rtx X. Return true if the complete
25031 cost has been computed, and false if subexpressions should be
25032 scanned. In either case, *TOTAL contains the cost result. */
25035 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25038 enum machine_mode mode = GET_MODE (x);
25042 /* On the RS/6000, if it is valid in the insn, it is free. */
25044 if (((outer_code == SET
25045 || outer_code == PLUS
25046 || outer_code == MINUS)
25047 && (satisfies_constraint_I (x)
25048 || satisfies_constraint_L (x)))
25049 || (outer_code == AND
25050 && (satisfies_constraint_K (x)
25052 ? satisfies_constraint_L (x)
25053 : satisfies_constraint_J (x))
25054 || mask_operand (x, mode)
25056 && mask64_operand (x, DImode))))
25057 || ((outer_code == IOR || outer_code == XOR)
25058 && (satisfies_constraint_K (x)
25060 ? satisfies_constraint_L (x)
25061 : satisfies_constraint_J (x))))
25062 || outer_code == ASHIFT
25063 || outer_code == ASHIFTRT
25064 || outer_code == LSHIFTRT
25065 || outer_code == ROTATE
25066 || outer_code == ROTATERT
25067 || outer_code == ZERO_EXTRACT
25068 || (outer_code == MULT
25069 && satisfies_constraint_I (x))
25070 || ((outer_code == DIV || outer_code == UDIV
25071 || outer_code == MOD || outer_code == UMOD)
25072 && exact_log2 (INTVAL (x)) >= 0)
25073 || (outer_code == COMPARE
25074 && (satisfies_constraint_I (x)
25075 || satisfies_constraint_K (x)))
25076 || (outer_code == EQ
25077 && (satisfies_constraint_I (x)
25078 || satisfies_constraint_K (x)
25080 ? satisfies_constraint_L (x)
25081 : satisfies_constraint_J (x))))
25082 || (outer_code == GTU
25083 && satisfies_constraint_I (x))
25084 || (outer_code == LTU
25085 && satisfies_constraint_P (x)))
25090 else if ((outer_code == PLUS
25091 && reg_or_add_cint_operand (x, VOIDmode))
25092 || (outer_code == MINUS
25093 && reg_or_sub_cint_operand (x, VOIDmode))
25094 || ((outer_code == SET
25095 || outer_code == IOR
25096 || outer_code == XOR)
25098 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25100 *total = COSTS_N_INSNS (1);
25106 if (mode == DImode && code == CONST_DOUBLE)
25108 if ((outer_code == IOR || outer_code == XOR)
25109 && CONST_DOUBLE_HIGH (x) == 0
25110 && (CONST_DOUBLE_LOW (x)
25111 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25116 else if ((outer_code == AND && and64_2_operand (x, DImode))
25117 || ((outer_code == SET
25118 || outer_code == IOR
25119 || outer_code == XOR)
25120 && CONST_DOUBLE_HIGH (x) == 0))
25122 *total = COSTS_N_INSNS (1);
25132 /* When optimizing for size, MEM should be slightly more expensive
25133 than generating address, e.g., (plus (reg) (const)).
25134 L1 cache latency is about two instructions. */
25135 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25143 if (mode == DFmode)
25145 if (GET_CODE (XEXP (x, 0)) == MULT)
25147 /* FNMA accounted in outer NEG. */
25148 if (outer_code == NEG)
25149 *total = rs6000_cost->dmul - rs6000_cost->fp;
25151 *total = rs6000_cost->dmul;
25154 *total = rs6000_cost->fp;
25156 else if (mode == SFmode)
25158 /* FNMA accounted in outer NEG. */
25159 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25162 *total = rs6000_cost->fp;
25165 *total = COSTS_N_INSNS (1);
25169 if (mode == DFmode)
25171 if (GET_CODE (XEXP (x, 0)) == MULT
25172 || GET_CODE (XEXP (x, 1)) == MULT)
25174 /* FNMA accounted in outer NEG. */
25175 if (outer_code == NEG)
25176 *total = rs6000_cost->dmul - rs6000_cost->fp;
25178 *total = rs6000_cost->dmul;
25181 *total = rs6000_cost->fp;
25183 else if (mode == SFmode)
25185 /* FNMA accounted in outer NEG. */
25186 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25189 *total = rs6000_cost->fp;
25192 *total = COSTS_N_INSNS (1);
25196 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25197 && satisfies_constraint_I (XEXP (x, 1)))
25199 if (INTVAL (XEXP (x, 1)) >= -256
25200 && INTVAL (XEXP (x, 1)) <= 255)
25201 *total = rs6000_cost->mulsi_const9;
25203 *total = rs6000_cost->mulsi_const;
25205 /* FMA accounted in outer PLUS/MINUS. */
25206 else if ((mode == DFmode || mode == SFmode)
25207 && (outer_code == PLUS || outer_code == MINUS))
25209 else if (mode == DFmode)
25210 *total = rs6000_cost->dmul;
25211 else if (mode == SFmode)
25212 *total = rs6000_cost->fp;
25213 else if (mode == DImode)
25214 *total = rs6000_cost->muldi;
25216 *total = rs6000_cost->mulsi;
25221 if (FLOAT_MODE_P (mode))
25223 *total = mode == DFmode ? rs6000_cost->ddiv
25224 : rs6000_cost->sdiv;
25231 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25232 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25234 if (code == DIV || code == MOD)
25236 *total = COSTS_N_INSNS (2);
25239 *total = COSTS_N_INSNS (1);
25243 if (GET_MODE (XEXP (x, 1)) == DImode)
25244 *total = rs6000_cost->divdi;
25246 *total = rs6000_cost->divsi;
25248 /* Add in shift and subtract for MOD. */
25249 if (code == MOD || code == UMOD)
25250 *total += COSTS_N_INSNS (2);
25255 *total = COSTS_N_INSNS (4);
25259 *total = COSTS_N_INSNS (6);
25263 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
25275 *total = COSTS_N_INSNS (1);
25283 /* Handle mul_highpart. */
25284 if (outer_code == TRUNCATE
25285 && GET_CODE (XEXP (x, 0)) == MULT)
25287 if (mode == DImode)
25288 *total = rs6000_cost->muldi;
25290 *total = rs6000_cost->mulsi;
25293 else if (outer_code == AND)
25296 *total = COSTS_N_INSNS (1);
25301 if (GET_CODE (XEXP (x, 0)) == MEM)
25304 *total = COSTS_N_INSNS (1);
25310 if (!FLOAT_MODE_P (mode))
25312 *total = COSTS_N_INSNS (1);
25318 case UNSIGNED_FLOAT:
25321 case FLOAT_TRUNCATE:
25322 *total = rs6000_cost->fp;
25326 if (mode == DFmode)
25329 *total = rs6000_cost->fp;
25333 switch (XINT (x, 1))
25336 *total = rs6000_cost->fp;
25348 *total = COSTS_N_INSNS (1);
25351 else if (FLOAT_MODE_P (mode)
25352 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
25354 *total = rs6000_cost->fp;
25362 /* Carry bit requires mode == Pmode.
25363 NEG or PLUS already counted so only add one. */
25365 && (outer_code == NEG || outer_code == PLUS))
25367 *total = COSTS_N_INSNS (1);
25370 if (outer_code == SET)
25372 if (XEXP (x, 1) == const0_rtx)
25374 if (TARGET_ISEL && !TARGET_MFCRF)
25375 *total = COSTS_N_INSNS (8);
25377 *total = COSTS_N_INSNS (2);
25380 else if (mode == Pmode)
25382 *total = COSTS_N_INSNS (3);
25391 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
25393 if (TARGET_ISEL && !TARGET_MFCRF)
25394 *total = COSTS_N_INSNS (8);
25396 *total = COSTS_N_INSNS (2);
25400 if (outer_code == COMPARE)
25414 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
25417 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
25420 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
25423 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
25424 "total = %d, speed = %s, x:\n",
25425 ret ? "complete" : "scan inner",
25426 GET_RTX_NAME (code),
25427 GET_RTX_NAME (outer_code),
25429 speed ? "true" : "false");
25436 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
25439 rs6000_debug_address_cost (rtx x, bool speed)
25441 int ret = TARGET_ADDRESS_COST (x, speed);
25443 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
25444 ret, speed ? "true" : "false");
25451 /* A C expression returning the cost of moving data from a register of class
25452 CLASS1 to one of CLASS2. */
25455 rs6000_register_move_cost (enum machine_mode mode,
25456 enum reg_class from, enum reg_class to)
25460 /* Moves from/to GENERAL_REGS. */
25461 if (reg_classes_intersect_p (to, GENERAL_REGS)
25462 || reg_classes_intersect_p (from, GENERAL_REGS))
25464 if (! reg_classes_intersect_p (to, GENERAL_REGS))
25467 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
25468 ret = (rs6000_memory_move_cost (mode, from, 0)
25469 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
25471 /* It's more expensive to move CR_REGS than CR0_REGS because of the
25473 else if (from == CR_REGS)
25476 /* Power6 has slower LR/CTR moves so make them more expensive than
25477 memory in order to bias spills to memory .*/
25478 else if (rs6000_cpu == PROCESSOR_POWER6
25479 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
25480 ret = 6 * hard_regno_nregs[0][mode];
25483 /* A move will cost one instruction per GPR moved. */
25484 ret = 2 * hard_regno_nregs[0][mode];
25487 /* If we have VSX, we can easily move between FPR or Altivec registers. */
25488 else if (VECTOR_UNIT_VSX_P (mode)
25489 && reg_classes_intersect_p (to, VSX_REGS)
25490 && reg_classes_intersect_p (from, VSX_REGS))
25491 ret = 2 * hard_regno_nregs[32][mode];
25493 /* Moving between two similar registers is just one instruction. */
25494 else if (reg_classes_intersect_p (to, from))
25495 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
25497 /* Everything else has to go through GENERAL_REGS. */
25499 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
25500 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
25502 if (TARGET_DEBUG_COST)
25504 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
25505 ret, GET_MODE_NAME (mode), reg_class_names[from],
25506 reg_class_names[to]);
25511 /* A C expressions returning the cost of moving data of MODE from a register to
25515 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
25516 int in ATTRIBUTE_UNUSED)
25520 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
25521 ret = 4 * hard_regno_nregs[0][mode];
25522 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
25523 ret = 4 * hard_regno_nregs[32][mode];
25524 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
25525 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
25527 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
25529 if (TARGET_DEBUG_COST)
25531 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
25532 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
25537 /* Returns a code for a target-specific builtin that implements
25538 reciprocal of the function, or NULL_TREE if not available. */
25541 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
25542 bool sqrt ATTRIBUTE_UNUSED)
25544 if (optimize_insn_for_size_p ())
25550 case VSX_BUILTIN_XVSQRTDP:
25551 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
25554 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
25556 case VSX_BUILTIN_XVSQRTSP:
25557 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
25560 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
25569 case BUILT_IN_SQRT:
25570 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
25573 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
25575 case BUILT_IN_SQRTF:
25576 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
25579 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
25586 /* Load up a constant. If the mode is a vector mode, splat the value across
25587 all of the vector elements. */
25590 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
25594 if (mode == SFmode || mode == DFmode)
25596 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
25597 reg = force_reg (mode, d);
25599 else if (mode == V4SFmode)
25601 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
25602 rtvec v = gen_rtvec (4, d, d, d, d);
25603 reg = gen_reg_rtx (mode);
25604 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
25606 else if (mode == V2DFmode)
25608 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
25609 rtvec v = gen_rtvec (2, d, d);
25610 reg = gen_reg_rtx (mode);
25611 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
25614 gcc_unreachable ();
25619 /* Generate a FMADD instruction:
25620 dst = (m1 * m2) + a
25622 generating different RTL based on the fused multiply/add switch. */
25625 rs6000_emit_madd (rtx dst, rtx m1, rtx m2, rtx a)
25627 enum machine_mode mode = GET_MODE (dst);
25629 if (!TARGET_FUSED_MADD)
25631 /* For the simple ops, use the generator function, rather than assuming
25632 that the RTL is standard. */
25633 enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code;
25634 enum insn_code acode = optab_handler (add_optab, mode)->insn_code;
25635 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25636 gen_2arg_fn_t gen_add = (gen_2arg_fn_t) GEN_FCN (acode);
25637 rtx mreg = gen_reg_rtx (mode);
25639 gcc_assert (mcode != CODE_FOR_nothing && acode != CODE_FOR_nothing);
25640 emit_insn (gen_mul (mreg, m1, m2));
25641 emit_insn (gen_add (dst, mreg, a));
25645 emit_insn (gen_rtx_SET (VOIDmode, dst,
25646 gen_rtx_PLUS (mode,
25647 gen_rtx_MULT (mode, m1, m2),
25651 /* Generate a FMSUB instruction:
25652 dst = (m1 * m2) - a
25654 generating different RTL based on the fused multiply/add switch. */
25657 rs6000_emit_msub (rtx dst, rtx m1, rtx m2, rtx a)
25659 enum machine_mode mode = GET_MODE (dst);
25661 if (!TARGET_FUSED_MADD
25662 || (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (V4SFmode)))
25664 /* For the simple ops, use the generator function, rather than assuming
25665 that the RTL is standard. */
25666 enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code;
25667 enum insn_code scode = optab_handler (add_optab, mode)->insn_code;
25668 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25669 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
25670 rtx mreg = gen_reg_rtx (mode);
25672 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
25673 emit_insn (gen_mul (mreg, m1, m2));
25674 emit_insn (gen_sub (dst, mreg, a));
25678 emit_insn (gen_rtx_SET (VOIDmode, dst,
25679 gen_rtx_MINUS (mode,
25680 gen_rtx_MULT (mode, m1, m2),
25684 /* Generate a FNMSUB instruction:
25685 dst = - ((m1 * m2) - a)
25687 Which is equivalent to (except in the prescence of -0.0):
25688 dst = a - (m1 * m2)
25690 generating different RTL based on the fast-math and fused multiply/add
25694 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
25696 enum machine_mode mode = GET_MODE (dst);
25698 if (!TARGET_FUSED_MADD)
25700 /* For the simple ops, use the generator function, rather than assuming
25701 that the RTL is standard. */
25702 enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code;
25703 enum insn_code scode = optab_handler (sub_optab, mode)->insn_code;
25704 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25705 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
25706 rtx mreg = gen_reg_rtx (mode);
25708 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
25709 emit_insn (gen_mul (mreg, m1, m2));
25710 emit_insn (gen_sub (dst, a, mreg));
25715 rtx m = gen_rtx_MULT (mode, m1, m2);
25717 if (!HONOR_SIGNED_ZEROS (mode))
25718 emit_insn (gen_rtx_SET (VOIDmode, dst, gen_rtx_MINUS (mode, a, m)));
25721 emit_insn (gen_rtx_SET (VOIDmode, dst,
25723 gen_rtx_MINUS (mode, m, a))));
25727 /* Newton-Raphson approximation of floating point divide with just 2 passes
25728 (either single precision floating point, or newer machines with higher
25729 accuracy estimates). Support both scalar and vector divide. Assumes no
25730 trapping math and finite arguments. */
25733 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
25735 enum machine_mode mode = GET_MODE (dst);
25736 rtx x0, e0, e1, y1, u0, v0;
25737 enum insn_code code = optab_handler (smul_optab, mode)->insn_code;
25738 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25739 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
25741 gcc_assert (code != CODE_FOR_nothing);
25743 /* x0 = 1./d estimate */
25744 x0 = gen_reg_rtx (mode);
25745 emit_insn (gen_rtx_SET (VOIDmode, x0,
25746 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
25749 e0 = gen_reg_rtx (mode);
25750 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
25752 e1 = gen_reg_rtx (mode);
25753 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
25755 y1 = gen_reg_rtx (mode);
25756 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
25758 u0 = gen_reg_rtx (mode);
25759 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
25761 v0 = gen_reg_rtx (mode);
25762 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
25764 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
25767 /* Newton-Raphson approximation of floating point divide that has a low
25768 precision estimate. Assumes no trapping math and finite arguments. */
25771 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
25773 enum machine_mode mode = GET_MODE (dst);
25774 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
25775 enum insn_code code = optab_handler (smul_optab, mode)->insn_code;
25776 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25778 gcc_assert (code != CODE_FOR_nothing);
25780 one = rs6000_load_constant_and_splat (mode, dconst1);
25782 /* x0 = 1./d estimate */
25783 x0 = gen_reg_rtx (mode);
25784 emit_insn (gen_rtx_SET (VOIDmode, x0,
25785 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
25788 e0 = gen_reg_rtx (mode);
25789 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
25791 y1 = gen_reg_rtx (mode);
25792 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
25794 e1 = gen_reg_rtx (mode);
25795 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
25797 y2 = gen_reg_rtx (mode);
25798 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
25800 e2 = gen_reg_rtx (mode);
25801 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
25803 y3 = gen_reg_rtx (mode);
25804 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
25806 u0 = gen_reg_rtx (mode);
25807 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
25809 v0 = gen_reg_rtx (mode);
25810 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
25812 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
25815 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
25816 add a reg_note saying that this was a division. Support both scalar and
25817 vector divide. Assumes no trapping math and finite arguments. */
25820 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
25822 enum machine_mode mode = GET_MODE (dst);
25824 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
25825 rs6000_emit_swdiv_high_precision (dst, n, d);
25827 rs6000_emit_swdiv_low_precision (dst, n, d);
25830 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
25833 /* Newton-Raphson approximation of single/double-precision floating point
25834 rsqrt. Assumes no trapping math and finite arguments. */
25837 rs6000_emit_swrsqrt (rtx dst, rtx src)
25839 enum machine_mode mode = GET_MODE (src);
25840 rtx x0 = gen_reg_rtx (mode);
25841 rtx y = gen_reg_rtx (mode);
25842 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
25843 REAL_VALUE_TYPE dconst3_2;
25846 enum insn_code code = optab_handler (smul_optab, mode)->insn_code;
25847 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25849 gcc_assert (code != CODE_FOR_nothing);
25851 /* Load up the constant 1.5 either as a scalar, or as a vector. */
25852 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
25853 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
25855 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
25857 /* x0 = rsqrt estimate */
25858 emit_insn (gen_rtx_SET (VOIDmode, x0,
25859 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
25862 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
25863 rs6000_emit_msub (y, src, halfthree, src);
25865 for (i = 0; i < passes; i++)
25867 rtx x1 = gen_reg_rtx (mode);
25868 rtx u = gen_reg_rtx (mode);
25869 rtx v = gen_reg_rtx (mode);
25871 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
25872 emit_insn (gen_mul (u, x0, x0));
25873 rs6000_emit_nmsub (v, y, u, halfthree);
25874 emit_insn (gen_mul (x1, x0, v));
25878 emit_move_insn (dst, x0);
25882 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
25883 (Power7) targets. DST is the target, and SRC is the argument operand. */
25886 rs6000_emit_popcount (rtx dst, rtx src)
25888 enum machine_mode mode = GET_MODE (dst);
25891 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
25892 if (TARGET_POPCNTD)
25894 if (mode == SImode)
25895 emit_insn (gen_popcntwsi2 (dst, src));
25897 emit_insn (gen_popcntddi2 (dst, src));
25901 tmp1 = gen_reg_rtx (mode);
25903 if (mode == SImode)
25905 emit_insn (gen_popcntbsi2 (tmp1, src));
25906 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
25908 tmp2 = force_reg (SImode, tmp2);
25909 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
25913 emit_insn (gen_popcntbdi2 (tmp1, src));
25914 tmp2 = expand_mult (DImode, tmp1,
25915 GEN_INT ((HOST_WIDE_INT)
25916 0x01010101 << 32 | 0x01010101),
25918 tmp2 = force_reg (DImode, tmp2);
25919 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
25924 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25925 target, and SRC is the argument operand. */
25928 rs6000_emit_parity (rtx dst, rtx src)
25930 enum machine_mode mode = GET_MODE (dst);
25933 tmp = gen_reg_rtx (mode);
25934 if (mode == SImode)
25936 /* Is mult+shift >= shift+xor+shift+xor? */
25937 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
25939 rtx tmp1, tmp2, tmp3, tmp4;
25941 tmp1 = gen_reg_rtx (SImode);
25942 emit_insn (gen_popcntbsi2 (tmp1, src));
25944 tmp2 = gen_reg_rtx (SImode);
25945 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
25946 tmp3 = gen_reg_rtx (SImode);
25947 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
25949 tmp4 = gen_reg_rtx (SImode);
25950 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
25951 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
25954 rs6000_emit_popcount (tmp, src);
25955 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
25959 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25960 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
25962 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
25964 tmp1 = gen_reg_rtx (DImode);
25965 emit_insn (gen_popcntbdi2 (tmp1, src));
25967 tmp2 = gen_reg_rtx (DImode);
25968 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
25969 tmp3 = gen_reg_rtx (DImode);
25970 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
25972 tmp4 = gen_reg_rtx (DImode);
25973 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
25974 tmp5 = gen_reg_rtx (DImode);
25975 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
25977 tmp6 = gen_reg_rtx (DImode);
25978 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
25979 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
25982 rs6000_emit_popcount (tmp, src);
25983 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
25987 /* Return an RTX representing where to find the function value of a
25988 function returning MODE. */
25990 rs6000_complex_function_value (enum machine_mode mode)
25992 unsigned int regno;
25994 enum machine_mode inner = GET_MODE_INNER (mode);
25995 unsigned int inner_bytes = GET_MODE_SIZE (inner);
25997 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25998 regno = FP_ARG_RETURN;
26001 regno = GP_ARG_RETURN;
26003 /* 32-bit is OK since it'll go in r3/r4. */
26004 if (TARGET_32BIT && inner_bytes >= 4)
26005 return gen_rtx_REG (mode, regno);
26008 if (inner_bytes >= 8)
26009 return gen_rtx_REG (mode, regno);
26011 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26013 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26014 GEN_INT (inner_bytes));
26015 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26018 /* Target hook for TARGET_FUNCTION_VALUE.
26020 On the SPE, both FPs and vectors are returned in r3.
26022 On RS/6000 an integer value is in r3 and a floating-point value is in
26023 fp1, unless -msoft-float. */
26026 rs6000_function_value (const_tree valtype,
26027 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26028 bool outgoing ATTRIBUTE_UNUSED)
26030 enum machine_mode mode;
26031 unsigned int regno;
26033 /* Special handling for structs in darwin64. */
26034 if (rs6000_darwin64_abi
26035 && TYPE_MODE (valtype) == BLKmode
26036 && TREE_CODE (valtype) == RECORD_TYPE
26037 && int_size_in_bytes (valtype) > 0)
26039 CUMULATIVE_ARGS valcum;
26043 valcum.fregno = FP_ARG_MIN_REG;
26044 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26045 /* Do a trial code generation as if this were going to be passed as
26046 an argument; if any part goes in memory, we return NULL. */
26047 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
26050 /* Otherwise fall through to standard ABI rules. */
26053 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26055 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26056 return gen_rtx_PARALLEL (DImode,
26058 gen_rtx_EXPR_LIST (VOIDmode,
26059 gen_rtx_REG (SImode, GP_ARG_RETURN),
26061 gen_rtx_EXPR_LIST (VOIDmode,
26062 gen_rtx_REG (SImode,
26063 GP_ARG_RETURN + 1),
26066 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26068 return gen_rtx_PARALLEL (DCmode,
26070 gen_rtx_EXPR_LIST (VOIDmode,
26071 gen_rtx_REG (SImode, GP_ARG_RETURN),
26073 gen_rtx_EXPR_LIST (VOIDmode,
26074 gen_rtx_REG (SImode,
26075 GP_ARG_RETURN + 1),
26077 gen_rtx_EXPR_LIST (VOIDmode,
26078 gen_rtx_REG (SImode,
26079 GP_ARG_RETURN + 2),
26081 gen_rtx_EXPR_LIST (VOIDmode,
26082 gen_rtx_REG (SImode,
26083 GP_ARG_RETURN + 3),
26087 mode = TYPE_MODE (valtype);
26088 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26089 || POINTER_TYPE_P (valtype))
26090 mode = TARGET_32BIT ? SImode : DImode;
26092 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26093 /* _Decimal128 must use an even/odd register pair. */
26094 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26095 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26096 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26097 regno = FP_ARG_RETURN;
26098 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26099 && targetm.calls.split_complex_arg)
26100 return rs6000_complex_function_value (mode);
26101 else if (TREE_CODE (valtype) == VECTOR_TYPE
26102 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26103 && ALTIVEC_VECTOR_MODE (mode))
26104 regno = ALTIVEC_ARG_RETURN;
26105 else if (TREE_CODE (valtype) == VECTOR_TYPE
26106 && TARGET_VSX && TARGET_ALTIVEC_ABI
26107 && VSX_VECTOR_MODE (mode))
26108 regno = ALTIVEC_ARG_RETURN;
26109 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26110 && (mode == DFmode || mode == DCmode
26111 || mode == TFmode || mode == TCmode))
26112 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26114 regno = GP_ARG_RETURN;
26116 return gen_rtx_REG (mode, regno);
26119 /* Define how to find the value returned by a library function
26120 assuming the value has mode MODE. */
26122 rs6000_libcall_value (enum machine_mode mode)
26124 unsigned int regno;
26126 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26128 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26129 return gen_rtx_PARALLEL (DImode,
26131 gen_rtx_EXPR_LIST (VOIDmode,
26132 gen_rtx_REG (SImode, GP_ARG_RETURN),
26134 gen_rtx_EXPR_LIST (VOIDmode,
26135 gen_rtx_REG (SImode,
26136 GP_ARG_RETURN + 1),
26140 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26141 /* _Decimal128 must use an even/odd register pair. */
26142 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26143 else if (SCALAR_FLOAT_MODE_P (mode)
26144 && TARGET_HARD_FLOAT && TARGET_FPRS
26145 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26146 regno = FP_ARG_RETURN;
26147 else if (ALTIVEC_VECTOR_MODE (mode)
26148 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26149 regno = ALTIVEC_ARG_RETURN;
26150 else if (VSX_VECTOR_MODE (mode)
26151 && TARGET_VSX && TARGET_ALTIVEC_ABI)
26152 regno = ALTIVEC_ARG_RETURN;
26153 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26154 return rs6000_complex_function_value (mode);
26155 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26156 && (mode == DFmode || mode == DCmode
26157 || mode == TFmode || mode == TCmode))
26158 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26160 regno = GP_ARG_RETURN;
26162 return gen_rtx_REG (mode, regno);
26166 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26167 Frame pointer elimination is automatically handled.
26169 For the RS/6000, if frame pointer elimination is being done, we would like
26170 to convert ap into fp, not sp.
26172 We need r30 if -mminimal-toc was specified, and there are constant pool
26176 rs6000_can_eliminate (const int from, const int to)
26178 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26179 ? ! frame_pointer_needed
26180 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26181 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26185 /* Define the offset between two registers, FROM to be eliminated and its
26186 replacement TO, at the start of a routine. */
26188 rs6000_initial_elimination_offset (int from, int to)
26190 rs6000_stack_t *info = rs6000_stack_info ();
26191 HOST_WIDE_INT offset;
26193 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26194 offset = info->push_p ? 0 : -info->total_size;
26195 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26197 offset = info->push_p ? 0 : -info->total_size;
26198 if (FRAME_GROWS_DOWNWARD)
26199 offset += info->fixed_size + info->vars_size + info->parm_size;
26201 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26202 offset = FRAME_GROWS_DOWNWARD
26203 ? info->fixed_size + info->vars_size + info->parm_size
26205 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26206 offset = info->total_size;
26207 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26208 offset = info->push_p ? info->total_size : 0;
26209 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26212 gcc_unreachable ();
26218 rs6000_dwarf_register_span (rtx reg)
26222 unsigned regno = REGNO (reg);
26223 enum machine_mode mode = GET_MODE (reg);
26227 && (SPE_VECTOR_MODE (GET_MODE (reg))
26228 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26229 && mode != SFmode && mode != SDmode && mode != SCmode)))
26234 regno = REGNO (reg);
26236 /* The duality of the SPE register size wreaks all kinds of havoc.
26237 This is a way of distinguishing r0 in 32-bits from r0 in
26239 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26240 gcc_assert (words <= 4);
26241 for (i = 0; i < words; i++, regno++)
26243 if (BYTES_BIG_ENDIAN)
26245 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26246 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
26250 parts[2 * i] = gen_rtx_REG (SImode, regno);
26251 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
26255 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
26258 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26261 rs6000_init_dwarf_reg_sizes_extra (tree address)
26266 enum machine_mode mode = TYPE_MODE (char_type_node);
26267 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
26268 rtx mem = gen_rtx_MEM (BLKmode, addr);
26269 rtx value = gen_int_mode (4, mode);
26271 for (i = 1201; i < 1232; i++)
26273 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
26274 HOST_WIDE_INT offset
26275 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
26277 emit_move_insn (adjust_address (mem, mode, offset), value);
26282 /* Map internal gcc register numbers to DWARF2 register numbers. */
26285 rs6000_dbx_register_number (unsigned int regno)
26287 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
26289 if (regno == MQ_REGNO)
26291 if (regno == LR_REGNO)
26293 if (regno == CTR_REGNO)
26295 if (CR_REGNO_P (regno))
26296 return regno - CR0_REGNO + 86;
26297 if (regno == CA_REGNO)
26298 return 101; /* XER */
26299 if (ALTIVEC_REGNO_P (regno))
26300 return regno - FIRST_ALTIVEC_REGNO + 1124;
26301 if (regno == VRSAVE_REGNO)
26303 if (regno == VSCR_REGNO)
26305 if (regno == SPE_ACC_REGNO)
26307 if (regno == SPEFSCR_REGNO)
26309 /* SPE high reg number. We get these values of regno from
26310 rs6000_dwarf_register_span. */
26311 gcc_assert (regno >= 1200 && regno < 1232);
26315 /* target hook eh_return_filter_mode */
26316 static enum machine_mode
26317 rs6000_eh_return_filter_mode (void)
26319 return TARGET_32BIT ? SImode : word_mode;
26322 /* Target hook for scalar_mode_supported_p. */
26324 rs6000_scalar_mode_supported_p (enum machine_mode mode)
26326 if (DECIMAL_FLOAT_MODE_P (mode))
26327 return default_decimal_float_supported_p ();
26329 return default_scalar_mode_supported_p (mode);
26332 /* Target hook for vector_mode_supported_p. */
26334 rs6000_vector_mode_supported_p (enum machine_mode mode)
26337 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
26340 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
26343 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
26350 /* Target hook for invalid_arg_for_unprototyped_fn. */
26351 static const char *
26352 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
26354 return (!rs6000_darwin64_abi
26356 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
26357 && (funcdecl == NULL_TREE
26358 || (TREE_CODE (funcdecl) == FUNCTION_DECL
26359 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
26360 ? N_("AltiVec argument passed to unprototyped function")
26364 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
26365 setup by using __stack_chk_fail_local hidden function instead of
26366 calling __stack_chk_fail directly. Otherwise it is better to call
26367 __stack_chk_fail directly. */
26370 rs6000_stack_protect_fail (void)
26372 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
26373 ? default_hidden_stack_protect_fail ()
26374 : default_external_stack_protect_fail ();
26378 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
26379 int num_operands ATTRIBUTE_UNUSED)
26381 if (rs6000_warn_cell_microcode)
26384 int insn_code_number = recog_memoized (insn);
26385 location_t location = locator_location (INSN_LOCATOR (insn));
26387 /* Punt on insns we cannot recognize. */
26388 if (insn_code_number < 0)
26391 temp = get_insn_template (insn_code_number, insn);
26393 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
26394 warning_at (location, OPT_mwarn_cell_microcode,
26395 "emitting microcode insn %s\t[%s] #%d",
26396 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
26397 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
26398 warning_at (location, OPT_mwarn_cell_microcode,
26399 "emitting conditional microcode insn %s\t[%s] #%d",
26400 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
26404 #include "gt-rs6000.h"