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 POWER4 and POWER5 processors. */
843 struct processor_costs power4_cost = {
844 COSTS_N_INSNS (3), /* mulsi */
845 COSTS_N_INSNS (2), /* mulsi_const */
846 COSTS_N_INSNS (2), /* mulsi_const9 */
847 COSTS_N_INSNS (4), /* muldi */
848 COSTS_N_INSNS (18), /* divsi */
849 COSTS_N_INSNS (34), /* divdi */
850 COSTS_N_INSNS (3), /* fp */
851 COSTS_N_INSNS (3), /* dmul */
852 COSTS_N_INSNS (17), /* sdiv */
853 COSTS_N_INSNS (17), /* ddiv */
854 128, /* cache line size */
857 8, /* prefetch streams /*/
860 /* Instruction costs on POWER6 processors. */
862 struct processor_costs power6_cost = {
863 COSTS_N_INSNS (8), /* mulsi */
864 COSTS_N_INSNS (8), /* mulsi_const */
865 COSTS_N_INSNS (8), /* mulsi_const9 */
866 COSTS_N_INSNS (8), /* muldi */
867 COSTS_N_INSNS (22), /* divsi */
868 COSTS_N_INSNS (28), /* divdi */
869 COSTS_N_INSNS (3), /* fp */
870 COSTS_N_INSNS (3), /* dmul */
871 COSTS_N_INSNS (13), /* sdiv */
872 COSTS_N_INSNS (16), /* ddiv */
873 128, /* cache line size */
876 16, /* prefetch streams */
879 /* Instruction costs on POWER7 processors. */
881 struct processor_costs power7_cost = {
882 COSTS_N_INSNS (2), /* mulsi */
883 COSTS_N_INSNS (2), /* mulsi_const */
884 COSTS_N_INSNS (2), /* mulsi_const9 */
885 COSTS_N_INSNS (2), /* muldi */
886 COSTS_N_INSNS (18), /* divsi */
887 COSTS_N_INSNS (34), /* 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 12, /* prefetch streams */
898 /* Instruction costs on POWER A2 processors. */
900 struct processor_costs ppca2_cost = {
901 COSTS_N_INSNS (16), /* mulsi */
902 COSTS_N_INSNS (16), /* mulsi_const */
903 COSTS_N_INSNS (16), /* mulsi_const9 */
904 COSTS_N_INSNS (16), /* muldi */
905 COSTS_N_INSNS (22), /* divsi */
906 COSTS_N_INSNS (28), /* divdi */
907 COSTS_N_INSNS (3), /* fp */
908 COSTS_N_INSNS (3), /* dmul */
909 COSTS_N_INSNS (59), /* sdiv */
910 COSTS_N_INSNS (72), /* ddiv */
914 16, /* prefetch streams */
918 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
919 #undef RS6000_BUILTIN
920 #undef RS6000_BUILTIN_EQUATE
921 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
922 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
924 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
926 #include "rs6000-builtin.def"
929 #undef RS6000_BUILTIN
930 #undef RS6000_BUILTIN_EQUATE
933 static bool rs6000_function_ok_for_sibcall (tree, tree);
934 static const char *rs6000_invalid_within_doloop (const_rtx);
935 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
936 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
937 static rtx rs6000_generate_compare (rtx, enum machine_mode);
938 static void rs6000_emit_stack_tie (void);
939 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
940 static bool spe_func_has_64bit_regs_p (void);
941 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
943 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
944 static unsigned rs6000_hash_constant (rtx);
945 static unsigned toc_hash_function (const void *);
946 static int toc_hash_eq (const void *, const void *);
947 static bool reg_offset_addressing_ok_p (enum machine_mode);
948 static bool virtual_stack_registers_memory_p (rtx);
949 static bool constant_pool_expr_p (rtx);
950 static bool legitimate_small_data_p (enum machine_mode, rtx);
951 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
952 static struct machine_function * rs6000_init_machine_status (void);
953 static bool rs6000_assemble_integer (rtx, unsigned int, int);
954 static bool no_global_regs_above (int, bool);
955 #ifdef HAVE_GAS_HIDDEN
956 static void rs6000_assemble_visibility (tree, int);
958 static int rs6000_ra_ever_killed (void);
959 static bool rs6000_attribute_takes_identifier_p (const_tree);
960 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
961 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
962 static bool rs6000_ms_bitfield_layout_p (const_tree);
963 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
964 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
965 static const char *rs6000_mangle_type (const_tree);
966 static void rs6000_set_default_type_attributes (tree);
967 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
968 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
969 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
970 enum machine_mode, bool, bool, bool);
971 static bool rs6000_reg_live_or_pic_offset_p (int);
972 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
973 static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
974 static void rs6000_restore_saved_cr (rtx, int);
975 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
976 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
977 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
979 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
980 static bool rs6000_return_in_memory (const_tree, const_tree);
981 static rtx rs6000_function_value (const_tree, const_tree, bool);
982 static void rs6000_file_start (void);
984 static int rs6000_elf_reloc_rw_mask (void);
985 static void rs6000_elf_asm_out_constructor (rtx, int);
986 static void rs6000_elf_asm_out_destructor (rtx, int);
987 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
988 static void rs6000_elf_asm_init_sections (void);
989 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
990 unsigned HOST_WIDE_INT);
991 static void rs6000_elf_encode_section_info (tree, rtx, int)
994 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
995 static void rs6000_alloc_sdmode_stack_slot (void);
996 static void rs6000_instantiate_decls (void);
998 static void rs6000_xcoff_asm_output_anchor (rtx);
999 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
1000 static void rs6000_xcoff_asm_init_sections (void);
1001 static int rs6000_xcoff_reloc_rw_mask (void);
1002 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
1003 static section *rs6000_xcoff_select_section (tree, int,
1004 unsigned HOST_WIDE_INT);
1005 static void rs6000_xcoff_unique_section (tree, int);
1006 static section *rs6000_xcoff_select_rtx_section
1007 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
1008 static const char * rs6000_xcoff_strip_name_encoding (const char *);
1009 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
1010 static void rs6000_xcoff_file_start (void);
1011 static void rs6000_xcoff_file_end (void);
1013 static int rs6000_variable_issue (FILE *, int, rtx, int);
1014 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
1015 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
1016 static int rs6000_debug_address_cost (rtx, bool);
1017 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
1018 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
1019 static void rs6000_sched_init (FILE *, int, int);
1020 static bool is_microcoded_insn (rtx);
1021 static bool is_nonpipeline_insn (rtx);
1022 static bool is_cracked_insn (rtx);
1023 static bool is_branch_slot_insn (rtx);
1024 static bool is_load_insn (rtx);
1025 static rtx get_store_dest (rtx pat);
1026 static bool is_store_insn (rtx);
1027 static bool set_to_load_agen (rtx,rtx);
1028 static bool adjacent_mem_locations (rtx,rtx);
1029 static int rs6000_adjust_priority (rtx, int);
1030 static int rs6000_issue_rate (void);
1031 static bool rs6000_is_costly_dependence (dep_t, int, int);
1032 static rtx get_next_active_insn (rtx, rtx);
1033 static bool insn_terminates_group_p (rtx , enum group_termination);
1034 static bool insn_must_be_first_in_group (rtx);
1035 static bool insn_must_be_last_in_group (rtx);
1036 static bool is_costly_group (rtx *, rtx);
1037 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
1038 static int redefine_groups (FILE *, int, rtx, rtx);
1039 static int pad_groups (FILE *, int, rtx, rtx);
1040 static void rs6000_sched_finish (FILE *, int);
1041 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
1042 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
1043 static int rs6000_use_sched_lookahead (void);
1044 static int rs6000_use_sched_lookahead_guard (rtx);
1045 static void * rs6000_alloc_sched_context (void);
1046 static void rs6000_init_sched_context (void *, bool);
1047 static void rs6000_set_sched_context (void *);
1048 static void rs6000_free_sched_context (void *);
1049 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
1050 static tree rs6000_builtin_mask_for_load (void);
1051 static tree rs6000_builtin_mul_widen_even (tree);
1052 static tree rs6000_builtin_mul_widen_odd (tree);
1053 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
1054 static tree rs6000_builtin_vec_perm (tree, tree *);
1055 static bool rs6000_builtin_support_vector_misalignment (enum
1060 static void def_builtin (int, const char *, tree, int);
1061 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1062 static void rs6000_init_builtins (void);
1063 static tree rs6000_builtin_decl (unsigned, bool);
1065 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1066 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1067 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1068 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1069 static void altivec_init_builtins (void);
1070 static unsigned builtin_hash_function (const void *);
1071 static int builtin_hash_eq (const void *, const void *);
1072 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1073 enum machine_mode, enum machine_mode,
1074 enum rs6000_builtins, const char *name);
1075 static void rs6000_common_init_builtins (void);
1076 static void rs6000_init_libfuncs (void);
1078 static void paired_init_builtins (void);
1079 static rtx paired_expand_builtin (tree, rtx, bool *);
1080 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1081 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1082 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1084 static void enable_mask_for_builtins (struct builtin_description *, int,
1085 enum rs6000_builtins,
1086 enum rs6000_builtins);
1087 static void spe_init_builtins (void);
1088 static rtx spe_expand_builtin (tree, rtx, bool *);
1089 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1090 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1091 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1092 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1093 static rs6000_stack_t *rs6000_stack_info (void);
1094 static void debug_stack_info (rs6000_stack_t *);
1096 static rtx altivec_expand_builtin (tree, rtx, bool *);
1097 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1098 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1099 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1100 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1101 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1102 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1103 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1104 static rtx altivec_expand_vec_set_builtin (tree);
1105 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1106 static int get_element_number (tree, tree);
1107 static bool rs6000_handle_option (size_t, const char *, int);
1108 static void rs6000_parse_tls_size_option (void);
1109 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1110 static int first_altivec_reg_to_save (void);
1111 static unsigned int compute_vrsave_mask (void);
1112 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1113 static void is_altivec_return_reg (rtx, void *);
1114 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1115 int easy_vector_constant (rtx, enum machine_mode);
1116 static rtx rs6000_dwarf_register_span (rtx);
1117 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1118 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1119 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1120 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1121 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1122 static rtx rs6000_delegitimize_address (rtx);
1123 static rtx rs6000_tls_get_addr (void);
1124 static rtx rs6000_got_sym (void);
1125 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1126 static const char *rs6000_get_some_local_dynamic_name (void);
1127 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1128 static rtx rs6000_complex_function_value (enum machine_mode);
1129 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
1130 enum machine_mode, tree);
1131 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1133 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1134 tree, HOST_WIDE_INT);
1135 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1138 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1139 const_tree, HOST_WIDE_INT,
1141 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
1142 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
1143 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1144 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1145 enum machine_mode, tree,
1147 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1149 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1151 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1153 static void macho_branch_islands (void);
1154 static int no_previous_def (tree function_name);
1155 static tree get_prev_label (tree function_name);
1156 static void rs6000_darwin_file_start (void);
1159 static tree rs6000_build_builtin_va_list (void);
1160 static void rs6000_va_start (tree, rtx);
1161 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1162 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1163 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1164 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1165 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1166 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1168 static tree rs6000_stack_protect_fail (void);
1170 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1173 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1176 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1178 = rs6000_legitimize_reload_address;
1180 static bool rs6000_mode_dependent_address_p (const_rtx);
1181 static bool rs6000_mode_dependent_address (const_rtx);
1182 static bool rs6000_debug_mode_dependent_address (const_rtx);
1183 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1184 = rs6000_mode_dependent_address;
1186 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1187 enum machine_mode, rtx);
1188 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1191 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1192 enum machine_mode, rtx)
1193 = rs6000_secondary_reload_class;
1195 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1196 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1198 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1199 = rs6000_preferred_reload_class;
1201 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1204 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1208 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1210 = rs6000_secondary_memory_needed;
1212 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1215 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1219 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1222 = rs6000_cannot_change_mode_class;
1224 static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class,
1226 struct secondary_reload_info *);
1228 static const enum reg_class *rs6000_ira_cover_classes (void);
1230 const int INSN_NOT_AVAILABLE = -1;
1231 static enum machine_mode rs6000_eh_return_filter_mode (void);
1232 static bool rs6000_can_eliminate (const int, const int);
1233 static void rs6000_trampoline_init (rtx, tree, rtx);
1235 /* Hash table stuff for keeping track of TOC entries. */
1237 struct GTY(()) toc_hash_struct
1239 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1240 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1242 enum machine_mode key_mode;
1246 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1248 /* Hash table to keep track of the argument types for builtin functions. */
1250 struct GTY(()) builtin_hash_struct
1253 enum machine_mode mode[4]; /* return value + 3 arguments. */
1254 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1257 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1259 /* Default register names. */
1260 char rs6000_reg_names[][8] =
1262 "0", "1", "2", "3", "4", "5", "6", "7",
1263 "8", "9", "10", "11", "12", "13", "14", "15",
1264 "16", "17", "18", "19", "20", "21", "22", "23",
1265 "24", "25", "26", "27", "28", "29", "30", "31",
1266 "0", "1", "2", "3", "4", "5", "6", "7",
1267 "8", "9", "10", "11", "12", "13", "14", "15",
1268 "16", "17", "18", "19", "20", "21", "22", "23",
1269 "24", "25", "26", "27", "28", "29", "30", "31",
1270 "mq", "lr", "ctr","ap",
1271 "0", "1", "2", "3", "4", "5", "6", "7",
1273 /* AltiVec registers. */
1274 "0", "1", "2", "3", "4", "5", "6", "7",
1275 "8", "9", "10", "11", "12", "13", "14", "15",
1276 "16", "17", "18", "19", "20", "21", "22", "23",
1277 "24", "25", "26", "27", "28", "29", "30", "31",
1279 /* SPE registers. */
1280 "spe_acc", "spefscr",
1281 /* Soft frame pointer. */
1285 #ifdef TARGET_REGNAMES
1286 static const char alt_reg_names[][8] =
1288 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1289 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1290 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1291 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1292 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1293 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1294 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1295 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1296 "mq", "lr", "ctr", "ap",
1297 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1299 /* AltiVec registers. */
1300 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1301 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1302 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1303 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1305 /* SPE registers. */
1306 "spe_acc", "spefscr",
1307 /* Soft frame pointer. */
1312 /* Table of valid machine attributes. */
1314 static const struct attribute_spec rs6000_attribute_table[] =
1316 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1317 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1318 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1319 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1320 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1321 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1322 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1323 SUBTARGET_ATTRIBUTE_TABLE,
1325 { NULL, 0, 0, false, false, false, NULL }
1328 #ifndef MASK_STRICT_ALIGN
1329 #define MASK_STRICT_ALIGN 0
1331 #ifndef TARGET_PROFILE_KERNEL
1332 #define TARGET_PROFILE_KERNEL 0
1335 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1336 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1338 /* Initialize the GCC target structure. */
1339 #undef TARGET_ATTRIBUTE_TABLE
1340 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1341 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1342 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1343 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1344 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1346 #undef TARGET_ASM_ALIGNED_DI_OP
1347 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1349 /* Default unaligned ops are only provided for ELF. Find the ops needed
1350 for non-ELF systems. */
1351 #ifndef OBJECT_FORMAT_ELF
1353 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1355 #undef TARGET_ASM_UNALIGNED_HI_OP
1356 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1357 #undef TARGET_ASM_UNALIGNED_SI_OP
1358 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1359 #undef TARGET_ASM_UNALIGNED_DI_OP
1360 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1363 #undef TARGET_ASM_UNALIGNED_HI_OP
1364 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1365 #undef TARGET_ASM_UNALIGNED_SI_OP
1366 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1367 #undef TARGET_ASM_UNALIGNED_DI_OP
1368 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1369 #undef TARGET_ASM_ALIGNED_DI_OP
1370 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1374 /* This hook deals with fixups for relocatable code and DI-mode objects
1376 #undef TARGET_ASM_INTEGER
1377 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1379 #ifdef HAVE_GAS_HIDDEN
1380 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1381 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1384 #undef TARGET_HAVE_TLS
1385 #define TARGET_HAVE_TLS HAVE_AS_TLS
1387 #undef TARGET_CANNOT_FORCE_CONST_MEM
1388 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1390 #undef TARGET_DELEGITIMIZE_ADDRESS
1391 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1393 #undef TARGET_ASM_FUNCTION_PROLOGUE
1394 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1395 #undef TARGET_ASM_FUNCTION_EPILOGUE
1396 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1398 #undef TARGET_LEGITIMIZE_ADDRESS
1399 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1401 #undef TARGET_SCHED_VARIABLE_ISSUE
1402 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1404 #undef TARGET_SCHED_ISSUE_RATE
1405 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1406 #undef TARGET_SCHED_ADJUST_COST
1407 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1408 #undef TARGET_SCHED_ADJUST_PRIORITY
1409 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1410 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1411 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1412 #undef TARGET_SCHED_INIT
1413 #define TARGET_SCHED_INIT rs6000_sched_init
1414 #undef TARGET_SCHED_FINISH
1415 #define TARGET_SCHED_FINISH rs6000_sched_finish
1416 #undef TARGET_SCHED_REORDER
1417 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1418 #undef TARGET_SCHED_REORDER2
1419 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1421 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1422 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1424 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1425 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1427 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1428 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1429 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1430 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1431 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1432 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1433 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1434 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1436 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1437 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1438 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1439 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1440 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1441 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1442 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1443 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1444 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1445 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1446 #undef TARGET_SUPPORT_VECTOR_MISALIGNMENT
1447 #define TARGET_SUPPORT_VECTOR_MISALIGNMENT \
1448 rs6000_builtin_support_vector_misalignment
1449 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1450 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1452 #undef TARGET_INIT_BUILTINS
1453 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1454 #undef TARGET_BUILTIN_DECL
1455 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1457 #undef TARGET_EXPAND_BUILTIN
1458 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1460 #undef TARGET_MANGLE_TYPE
1461 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1463 #undef TARGET_INIT_LIBFUNCS
1464 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1467 #undef TARGET_BINDS_LOCAL_P
1468 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1471 #undef TARGET_MS_BITFIELD_LAYOUT_P
1472 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1474 #undef TARGET_ASM_OUTPUT_MI_THUNK
1475 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1477 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1478 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1480 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1481 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1483 #undef TARGET_INVALID_WITHIN_DOLOOP
1484 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1486 #undef TARGET_RTX_COSTS
1487 #define TARGET_RTX_COSTS rs6000_rtx_costs
1488 #undef TARGET_ADDRESS_COST
1489 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1491 #undef TARGET_DWARF_REGISTER_SPAN
1492 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1494 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1495 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1497 /* On rs6000, function arguments are promoted, as are function return
1499 #undef TARGET_PROMOTE_FUNCTION_MODE
1500 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1502 #undef TARGET_RETURN_IN_MEMORY
1503 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1505 #undef TARGET_SETUP_INCOMING_VARARGS
1506 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1508 /* Always strict argument naming on rs6000. */
1509 #undef TARGET_STRICT_ARGUMENT_NAMING
1510 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1511 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1512 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1513 #undef TARGET_SPLIT_COMPLEX_ARG
1514 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1515 #undef TARGET_MUST_PASS_IN_STACK
1516 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1517 #undef TARGET_PASS_BY_REFERENCE
1518 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1519 #undef TARGET_ARG_PARTIAL_BYTES
1520 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1522 #undef TARGET_BUILD_BUILTIN_VA_LIST
1523 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1525 #undef TARGET_EXPAND_BUILTIN_VA_START
1526 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1528 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1529 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1531 #undef TARGET_EH_RETURN_FILTER_MODE
1532 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1534 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1535 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1537 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1538 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1540 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1541 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1543 #undef TARGET_HANDLE_OPTION
1544 #define TARGET_HANDLE_OPTION rs6000_handle_option
1546 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1547 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1548 rs6000_builtin_vectorized_function
1550 #undef TARGET_DEFAULT_TARGET_FLAGS
1551 #define TARGET_DEFAULT_TARGET_FLAGS \
1554 #undef TARGET_STACK_PROTECT_FAIL
1555 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1557 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1558 The PowerPC architecture requires only weak consistency among
1559 processors--that is, memory accesses between processors need not be
1560 sequentially consistent and memory accesses among processors can occur
1561 in any order. The ability to order memory accesses weakly provides
1562 opportunities for more efficient use of the system bus. Unless a
1563 dependency exists, the 604e allows read operations to precede store
1565 #undef TARGET_RELAXED_ORDERING
1566 #define TARGET_RELAXED_ORDERING true
1569 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1570 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1573 /* Use a 32-bit anchor range. This leads to sequences like:
1575 addis tmp,anchor,high
1578 where tmp itself acts as an anchor, and can be shared between
1579 accesses to the same 64k page. */
1580 #undef TARGET_MIN_ANCHOR_OFFSET
1581 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1582 #undef TARGET_MAX_ANCHOR_OFFSET
1583 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1584 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1585 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1587 #undef TARGET_BUILTIN_RECIPROCAL
1588 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1590 #undef TARGET_EXPAND_TO_RTL_HOOK
1591 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1593 #undef TARGET_INSTANTIATE_DECLS
1594 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1596 #undef TARGET_SECONDARY_RELOAD
1597 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1599 #undef TARGET_IRA_COVER_CLASSES
1600 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1602 #undef TARGET_LEGITIMATE_ADDRESS_P
1603 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1605 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1606 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1608 #undef TARGET_CAN_ELIMINATE
1609 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1611 #undef TARGET_TRAMPOLINE_INIT
1612 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1614 #undef TARGET_FUNCTION_VALUE
1615 #define TARGET_FUNCTION_VALUE rs6000_function_value
1617 struct gcc_target targetm = TARGET_INITIALIZER;
1619 /* Return number of consecutive hard regs needed starting at reg REGNO
1620 to hold something of mode MODE.
1621 This is ordinarily the length in words of a value of mode MODE
1622 but can be less for certain modes in special long registers.
1624 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1625 scalar instructions. The upper 32 bits are only available to the
1628 POWER and PowerPC GPRs hold 32 bits worth;
1629 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1632 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1634 unsigned HOST_WIDE_INT reg_size;
1636 if (FP_REGNO_P (regno))
1637 reg_size = (VECTOR_MEM_VSX_P (mode)
1638 ? UNITS_PER_VSX_WORD
1639 : UNITS_PER_FP_WORD);
1641 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1642 reg_size = UNITS_PER_SPE_WORD;
1644 else if (ALTIVEC_REGNO_P (regno))
1645 reg_size = UNITS_PER_ALTIVEC_WORD;
1647 /* The value returned for SCmode in the E500 double case is 2 for
1648 ABI compatibility; storing an SCmode value in a single register
1649 would require function_arg and rs6000_spe_function_arg to handle
1650 SCmode so as to pass the value correctly in a pair of
1652 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1653 && !DECIMAL_FLOAT_MODE_P (mode))
1654 reg_size = UNITS_PER_FP_WORD;
1657 reg_size = UNITS_PER_WORD;
1659 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1662 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1665 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1667 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1669 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1670 implementations. Don't allow an item to be split between a FP register
1671 and an Altivec register. */
1672 if (VECTOR_MEM_VSX_P (mode))
1674 if (FP_REGNO_P (regno))
1675 return FP_REGNO_P (last_regno);
1677 if (ALTIVEC_REGNO_P (regno))
1678 return ALTIVEC_REGNO_P (last_regno);
1681 /* The GPRs can hold any mode, but values bigger than one register
1682 cannot go past R31. */
1683 if (INT_REGNO_P (regno))
1684 return INT_REGNO_P (last_regno);
1686 /* The float registers (except for VSX vector modes) can only hold floating
1687 modes and DImode. This excludes the 32-bit decimal float mode for
1689 if (FP_REGNO_P (regno))
1691 if (SCALAR_FLOAT_MODE_P (mode)
1692 && (mode != TDmode || (regno % 2) == 0)
1693 && FP_REGNO_P (last_regno))
1696 if (GET_MODE_CLASS (mode) == MODE_INT
1697 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1700 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1701 && PAIRED_VECTOR_MODE (mode))
1707 /* The CR register can only hold CC modes. */
1708 if (CR_REGNO_P (regno))
1709 return GET_MODE_CLASS (mode) == MODE_CC;
1711 if (CA_REGNO_P (regno))
1712 return mode == BImode;
1714 /* AltiVec only in AldyVec registers. */
1715 if (ALTIVEC_REGNO_P (regno))
1716 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1718 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1719 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1722 /* We cannot put TImode anywhere except general register and it must be able
1723 to fit within the register set. In the future, allow TImode in the
1724 Altivec or VSX registers. */
1726 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1729 /* Print interesting facts about registers. */
1731 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1735 for (r = first_regno; r <= last_regno; ++r)
1737 const char *comma = "";
1740 if (first_regno == last_regno)
1741 fprintf (stderr, "%s:\t", reg_name);
1743 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1746 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1747 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1751 fprintf (stderr, ",\n\t");
1756 if (rs6000_hard_regno_nregs[m][r] > 1)
1757 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1758 rs6000_hard_regno_nregs[m][r]);
1760 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1765 if (call_used_regs[r])
1769 fprintf (stderr, ",\n\t");
1774 len += fprintf (stderr, "%s%s", comma, "call-used");
1782 fprintf (stderr, ",\n\t");
1787 len += fprintf (stderr, "%s%s", comma, "fixed");
1793 fprintf (stderr, ",\n\t");
1797 fprintf (stderr, "%sregno = %d\n", comma, r);
1801 /* Print various interesting information with -mdebug=reg. */
1803 rs6000_debug_reg_global (void)
1805 const char *nl = (const char *)0;
1807 char costly_num[20];
1809 const char *costly_str;
1810 const char *nop_str;
1812 /* Map enum rs6000_vector to string. */
1813 static const char *rs6000_debug_vector_unit[] = {
1822 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1823 LAST_VIRTUAL_REGISTER);
1824 rs6000_debug_reg_print (0, 31, "gr");
1825 rs6000_debug_reg_print (32, 63, "fp");
1826 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1829 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1830 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1831 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1832 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1833 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
1834 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1835 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1836 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1837 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1841 "d reg_class = %s\n"
1842 "f reg_class = %s\n"
1843 "v reg_class = %s\n"
1844 "wa reg_class = %s\n"
1845 "wd reg_class = %s\n"
1846 "wf reg_class = %s\n"
1847 "ws reg_class = %s\n\n",
1848 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1849 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1850 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1851 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1852 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1853 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1854 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1856 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1857 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1860 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1862 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1863 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1869 if (rs6000_recip_control)
1871 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
1873 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1874 if (rs6000_recip_bits[m])
1877 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1879 (RS6000_RECIP_AUTO_RE_P (m)
1881 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
1882 (RS6000_RECIP_AUTO_RSQRTE_P (m)
1884 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
1887 fputs ("\n", stderr);
1890 switch (rs6000_sched_costly_dep)
1892 case max_dep_latency:
1893 costly_str = "max_dep_latency";
1897 costly_str = "no_dep_costly";
1900 case all_deps_costly:
1901 costly_str = "all_deps_costly";
1904 case true_store_to_load_dep_costly:
1905 costly_str = "true_store_to_load_dep_costly";
1908 case store_to_load_dep_costly:
1909 costly_str = "store_to_load_dep_costly";
1913 costly_str = costly_num;
1914 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1918 switch (rs6000_sched_insert_nops)
1920 case sched_finish_regroup_exact:
1921 nop_str = "sched_finish_regroup_exact";
1924 case sched_finish_pad_groups:
1925 nop_str = "sched_finish_pad_groups";
1928 case sched_finish_none:
1929 nop_str = "sched_finish_none";
1934 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1939 "always_hint = %s\n"
1940 "align_branch_targets = %s\n"
1941 "sched_restricted_insns_priority = %d\n"
1942 "sched_costly_dep = %s\n"
1943 "sched_insert_nops = %s\n\n",
1944 rs6000_always_hint ? "true" : "false",
1945 rs6000_align_branch_targets ? "true" : "false",
1946 (int)rs6000_sched_restricted_insns_priority,
1947 costly_str, nop_str);
1950 /* Initialize the various global tables that are based on register size. */
1952 rs6000_init_hard_regno_mode_ok (void)
1958 /* Precalculate REGNO_REG_CLASS. */
1959 rs6000_regno_regclass[0] = GENERAL_REGS;
1960 for (r = 1; r < 32; ++r)
1961 rs6000_regno_regclass[r] = BASE_REGS;
1963 for (r = 32; r < 64; ++r)
1964 rs6000_regno_regclass[r] = FLOAT_REGS;
1966 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1967 rs6000_regno_regclass[r] = NO_REGS;
1969 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
1970 rs6000_regno_regclass[r] = ALTIVEC_REGS;
1972 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
1973 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
1974 rs6000_regno_regclass[r] = CR_REGS;
1976 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
1977 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
1978 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
1979 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
1980 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
1981 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
1982 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
1983 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
1984 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
1985 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
1987 /* Precalculate vector information, this must be set up before the
1988 rs6000_hard_regno_nregs_internal below. */
1989 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1991 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
1992 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
1993 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
1996 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
1997 rs6000_constraints[c] = NO_REGS;
1999 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2000 believes it can use native alignment or still uses 128-bit alignment. */
2001 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2012 /* V2DF mode, VSX only. */
2015 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2016 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2017 rs6000_vector_align[V2DFmode] = align64;
2020 /* V4SF mode, either VSX or Altivec. */
2023 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2024 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2025 rs6000_vector_align[V4SFmode] = align32;
2027 else if (TARGET_ALTIVEC)
2029 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2030 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2031 rs6000_vector_align[V4SFmode] = align32;
2034 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2038 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2039 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2040 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2041 rs6000_vector_align[V4SImode] = align32;
2042 rs6000_vector_align[V8HImode] = align32;
2043 rs6000_vector_align[V16QImode] = align32;
2047 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2048 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2049 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2053 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2054 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2055 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2059 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2060 Altivec doesn't have 64-bit support. */
2063 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2064 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2065 rs6000_vector_align[V2DImode] = align64;
2068 /* DFmode, see if we want to use the VSX unit. */
2069 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2071 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2072 rs6000_vector_mem[DFmode]
2073 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2074 rs6000_vector_align[DFmode] = align64;
2077 /* TODO add SPE and paired floating point vector support. */
2079 /* Register class constaints for the constraints that depend on compile
2081 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2082 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2084 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2085 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2089 /* At present, we just use VSX_REGS, but we have different constraints
2090 based on the use, in case we want to fine tune the default register
2091 class used. wa = any VSX register, wf = register class to use for
2092 V4SF, wd = register class to use for V2DF, and ws = register classs to
2093 use for DF scalars. */
2094 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2095 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2096 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2097 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2103 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2105 /* Set up the reload helper functions. */
2106 if (TARGET_VSX || TARGET_ALTIVEC)
2110 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2111 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2112 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2113 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2114 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2115 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2116 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2117 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2118 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2119 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2120 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2121 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2125 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2126 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2127 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2128 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2129 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2130 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2131 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2132 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2133 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2134 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2135 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2136 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2140 /* Precalculate HARD_REGNO_NREGS. */
2141 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2142 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2143 rs6000_hard_regno_nregs[m][r]
2144 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2146 /* Precalculate HARD_REGNO_MODE_OK. */
2147 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2148 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2149 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2150 rs6000_hard_regno_mode_ok_p[m][r] = true;
2152 /* Precalculate CLASS_MAX_NREGS sizes. */
2153 for (c = 0; c < LIM_REG_CLASSES; ++c)
2157 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2158 reg_size = UNITS_PER_VSX_WORD;
2160 else if (c == ALTIVEC_REGS)
2161 reg_size = UNITS_PER_ALTIVEC_WORD;
2163 else if (c == FLOAT_REGS)
2164 reg_size = UNITS_PER_FP_WORD;
2167 reg_size = UNITS_PER_WORD;
2169 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2170 rs6000_class_max_nregs[m][c]
2171 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2174 if (TARGET_E500_DOUBLE)
2175 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2177 /* Calculate which modes to automatically generate code to use a the
2178 reciprocal divide and square root instructions. In the future, possibly
2179 automatically generate the instructions even if the user did not specify
2180 -mrecip. The older machines double precision reciprocal sqrt estimate is
2181 not accurate enough. */
2182 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2184 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2186 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2187 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2188 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2189 if (VECTOR_UNIT_VSX_P (V2DFmode))
2190 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2192 if (TARGET_FRSQRTES)
2193 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2195 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2196 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2197 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2198 if (VECTOR_UNIT_VSX_P (V2DFmode))
2199 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2201 if (rs6000_recip_control)
2203 if (!TARGET_FUSED_MADD)
2204 warning (0, "-mrecip requires -mfused-madd");
2205 if (!flag_finite_math_only)
2206 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2207 if (flag_trapping_math)
2208 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2209 if (!flag_reciprocal_math)
2210 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2211 if (TARGET_FUSED_MADD && flag_finite_math_only && !flag_trapping_math
2212 && flag_reciprocal_math)
2214 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2215 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2216 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2218 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2219 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2220 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2222 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2223 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2224 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2226 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2227 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2228 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2230 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2231 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2232 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2234 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2235 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2236 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2238 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2239 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2240 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2242 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2243 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2244 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2248 if (TARGET_DEBUG_REG)
2249 rs6000_debug_reg_global ();
2251 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2253 "SImode variable mult cost = %d\n"
2254 "SImode constant mult cost = %d\n"
2255 "SImode short constant mult cost = %d\n"
2256 "DImode multipliciation cost = %d\n"
2257 "SImode division cost = %d\n"
2258 "DImode division cost = %d\n"
2259 "Simple fp operation cost = %d\n"
2260 "DFmode multiplication cost = %d\n"
2261 "SFmode division cost = %d\n"
2262 "DFmode division cost = %d\n"
2263 "cache line size = %d\n"
2264 "l1 cache size = %d\n"
2265 "l2 cache size = %d\n"
2266 "simultaneous prefetches = %d\n"
2269 rs6000_cost->mulsi_const,
2270 rs6000_cost->mulsi_const9,
2278 rs6000_cost->cache_line_size,
2279 rs6000_cost->l1_cache_size,
2280 rs6000_cost->l2_cache_size,
2281 rs6000_cost->simultaneous_prefetches);
2285 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2288 darwin_rs6000_override_options (void)
2290 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2292 rs6000_altivec_abi = 1;
2293 TARGET_ALTIVEC_VRSAVE = 1;
2294 if (DEFAULT_ABI == ABI_DARWIN)
2296 if (MACHO_DYNAMIC_NO_PIC_P)
2299 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2302 else if (flag_pic == 1)
2307 if (TARGET_64BIT && ! TARGET_POWERPC64)
2309 target_flags |= MASK_POWERPC64;
2310 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2314 rs6000_default_long_calls = 1;
2315 target_flags |= MASK_SOFT_FLOAT;
2318 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2320 if (!flag_mkernel && !flag_apple_kext
2322 && ! (target_flags_explicit & MASK_ALTIVEC))
2323 target_flags |= MASK_ALTIVEC;
2325 /* Unless the user (not the configurer) has explicitly overridden
2326 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2327 G4 unless targetting the kernel. */
2330 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2331 && ! (target_flags_explicit & MASK_ALTIVEC)
2332 && ! rs6000_select[1].string)
2334 target_flags |= MASK_ALTIVEC;
2339 /* If not otherwise specified by a target, make 'long double' equivalent to
2342 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2343 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2346 /* Override command line options. Mostly we process the processor
2347 type and sometimes adjust other TARGET_ options. */
2350 rs6000_override_options (const char *default_cpu)
2353 struct rs6000_cpu_select *ptr;
2356 /* Simplifications for entries below. */
2359 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2360 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2363 /* This table occasionally claims that a processor does not support
2364 a particular feature even though it does, but the feature is slower
2365 than the alternative. Thus, it shouldn't be relied on as a
2366 complete description of the processor's support.
2368 Please keep this list in order, and don't forget to update the
2369 documentation in invoke.texi when adding a new processor or
2373 const char *const name; /* Canonical processor name. */
2374 const enum processor_type processor; /* Processor type enum value. */
2375 const int target_enable; /* Target flags to enable. */
2376 } const processor_target_table[]
2377 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2378 {"403", PROCESSOR_PPC403,
2379 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2380 {"405", PROCESSOR_PPC405,
2381 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2382 {"405fp", PROCESSOR_PPC405,
2383 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2384 {"440", PROCESSOR_PPC440,
2385 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2386 {"440fp", PROCESSOR_PPC440,
2387 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2388 {"464", PROCESSOR_PPC440,
2389 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2390 {"464fp", PROCESSOR_PPC440,
2391 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2392 {"476", PROCESSOR_PPC476,
2393 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2394 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2395 {"476fp", PROCESSOR_PPC476,
2396 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2397 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2398 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2399 {"601", PROCESSOR_PPC601,
2400 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2401 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2402 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2403 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2404 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2405 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2406 {"620", PROCESSOR_PPC620,
2407 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2408 {"630", PROCESSOR_PPC630,
2409 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2410 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2411 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2412 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2413 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2414 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2415 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2416 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2417 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2419 /* 8548 has a dummy entry for now. */
2420 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2422 {"a2", PROCESSOR_PPCA2,
2423 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2424 | MASK_CMPB | MASK_NO_UPDATE },
2425 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2426 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2427 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2429 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2430 | MASK_PPC_GFXOPT | MASK_ISEL},
2431 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2432 {"970", PROCESSOR_POWER4,
2433 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2434 {"cell", PROCESSOR_CELL,
2435 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2436 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2437 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2438 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2439 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2440 {"G5", PROCESSOR_POWER4,
2441 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2442 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2443 {"power2", PROCESSOR_POWER,
2444 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2445 {"power3", PROCESSOR_PPC630,
2446 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2447 {"power4", PROCESSOR_POWER4,
2448 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2450 {"power5", PROCESSOR_POWER5,
2451 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2452 | MASK_MFCRF | MASK_POPCNTB},
2453 {"power5+", PROCESSOR_POWER5,
2454 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2455 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2456 {"power6", PROCESSOR_POWER6,
2457 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2458 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2459 | MASK_RECIP_PRECISION},
2460 {"power6x", PROCESSOR_POWER6,
2461 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2462 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2463 | MASK_MFPGPR | MASK_RECIP_PRECISION},
2464 {"power7", PROCESSOR_POWER7,
2465 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2466 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2467 | MASK_VSX| MASK_RECIP_PRECISION}, /* Don't add MASK_ISEL by default */
2468 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2469 {"powerpc64", PROCESSOR_POWERPC64,
2470 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2471 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2472 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2473 {"rios2", PROCESSOR_RIOS2,
2474 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2475 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2476 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2477 {"rs64", PROCESSOR_RS64A,
2478 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2481 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2483 /* Some OSs don't support saving the high part of 64-bit registers on
2484 context switch. Other OSs don't support saving Altivec registers.
2485 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2486 settings; if the user wants either, the user must explicitly specify
2487 them and we won't interfere with the user's specification. */
2490 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2491 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2492 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2493 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2494 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2495 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
2496 | MASK_RECIP_PRECISION)
2499 /* Masks for instructions set at various powerpc ISAs. */
2501 ISA_2_1_MASKS = MASK_MFCRF,
2502 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB | MASK_FPRND),
2504 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and
2505 don't add ALTIVEC, since in general it isn't a win on power6. */
2506 ISA_2_5_MASKS = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
2509 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
2510 altivec is a win so enable it. */
2511 ISA_2_6_MASKS = (ISA_2_5_MASKS | MASK_ALTIVEC | MASK_POPCNTD
2512 | MASK_VSX | MASK_RECIP_PRECISION)
2515 /* Numerous experiment shows that IRA based loop pressure
2516 calculation works better for RTL loop invariant motion on targets
2517 with enough (>= 32) registers. It is an expensive optimization.
2518 So it is on only for peak performance. */
2520 flag_ira_loop_pressure = 1;
2522 /* Set the pointer size. */
2525 rs6000_pmode = (int)DImode;
2526 rs6000_pointer_size = 64;
2530 rs6000_pmode = (int)SImode;
2531 rs6000_pointer_size = 32;
2534 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2535 #ifdef OS_MISSING_POWERPC64
2536 if (OS_MISSING_POWERPC64)
2537 set_masks &= ~MASK_POWERPC64;
2539 #ifdef OS_MISSING_ALTIVEC
2540 if (OS_MISSING_ALTIVEC)
2541 set_masks &= ~MASK_ALTIVEC;
2544 /* Don't override by the processor default if given explicitly. */
2545 set_masks &= ~target_flags_explicit;
2547 /* Identify the processor type. */
2548 rs6000_select[0].string = default_cpu;
2549 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2551 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2553 ptr = &rs6000_select[i];
2554 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2556 for (j = 0; j < ptt_size; j++)
2557 if (! strcmp (ptr->string, processor_target_table[j].name))
2559 if (ptr->set_tune_p)
2560 rs6000_cpu = processor_target_table[j].processor;
2562 if (ptr->set_arch_p)
2564 target_flags &= ~set_masks;
2565 target_flags |= (processor_target_table[j].target_enable
2572 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2576 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2577 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2580 error ("AltiVec not supported in this target");
2582 error ("Spe not supported in this target");
2585 /* Disable Cell microcode if we are optimizing for the Cell
2586 and not optimizing for size. */
2587 if (rs6000_gen_cell_microcode == -1)
2588 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2591 /* If we are optimizing big endian systems for space and it's OK to
2592 use instructions that would be microcoded on the Cell, use the
2593 load/store multiple and string instructions. */
2594 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2595 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2597 /* Don't allow -mmultiple or -mstring on little endian systems
2598 unless the cpu is a 750, because the hardware doesn't support the
2599 instructions used in little endian mode, and causes an alignment
2600 trap. The 750 does not cause an alignment trap (except when the
2601 target is unaligned). */
2603 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2605 if (TARGET_MULTIPLE)
2607 target_flags &= ~MASK_MULTIPLE;
2608 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2609 warning (0, "-mmultiple is not supported on little endian systems");
2614 target_flags &= ~MASK_STRING;
2615 if ((target_flags_explicit & MASK_STRING) != 0)
2616 warning (0, "-mstring is not supported on little endian systems");
2620 /* Add some warnings for VSX. */
2623 const char *msg = NULL;
2624 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2625 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2627 if (target_flags_explicit & MASK_VSX)
2628 msg = N_("-mvsx requires hardware floating point");
2630 target_flags &= ~ MASK_VSX;
2632 else if (TARGET_PAIRED_FLOAT)
2633 msg = N_("-mvsx and -mpaired are incompatible");
2634 /* The hardware will allow VSX and little endian, but until we make sure
2635 things like vector select, etc. work don't allow VSX on little endian
2636 systems at this point. */
2637 else if (!BYTES_BIG_ENDIAN)
2638 msg = N_("-mvsx used with little endian code");
2639 else if (TARGET_AVOID_XFORM > 0)
2640 msg = N_("-mvsx needs indexed addressing");
2641 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2643 if (target_flags_explicit & MASK_VSX)
2644 msg = N_("-mvsx and -mno-altivec are incompatible");
2646 msg = N_("-mno-altivec disables vsx");
2652 target_flags &= ~ MASK_VSX;
2656 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2657 unless the user explicitly used the -mno-<option> to disable the code. */
2659 target_flags |= (ISA_2_6_MASKS & (target_flags_explicit & ~ISA_2_6_MASKS));
2660 else if (TARGET_DFP)
2661 target_flags |= (ISA_2_5_MASKS & (target_flags_explicit & ~ISA_2_5_MASKS));
2662 else if (TARGET_ALTIVEC)
2663 target_flags |= (MASK_PPC_GFXOPT & (target_flags_explicit & ~MASK_PPC_GFXOPT));
2665 /* Set debug flags */
2666 if (rs6000_debug_name)
2668 if (! strcmp (rs6000_debug_name, "all"))
2669 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2670 = rs6000_debug_addr = rs6000_debug_cost = 1;
2671 else if (! strcmp (rs6000_debug_name, "stack"))
2672 rs6000_debug_stack = 1;
2673 else if (! strcmp (rs6000_debug_name, "arg"))
2674 rs6000_debug_arg = 1;
2675 else if (! strcmp (rs6000_debug_name, "reg"))
2676 rs6000_debug_reg = 1;
2677 else if (! strcmp (rs6000_debug_name, "addr"))
2678 rs6000_debug_addr = 1;
2679 else if (! strcmp (rs6000_debug_name, "cost"))
2680 rs6000_debug_cost = 1;
2682 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2684 /* If the appropriate debug option is enabled, replace the target hooks
2685 with debug versions that call the real version and then prints
2686 debugging information. */
2687 if (TARGET_DEBUG_COST)
2689 targetm.rtx_costs = rs6000_debug_rtx_costs;
2690 targetm.address_cost = rs6000_debug_address_cost;
2691 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2694 if (TARGET_DEBUG_ADDR)
2696 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2697 targetm.legitimize_address = rs6000_debug_legitimize_address;
2698 rs6000_secondary_reload_class_ptr
2699 = rs6000_debug_secondary_reload_class;
2700 rs6000_secondary_memory_needed_ptr
2701 = rs6000_debug_secondary_memory_needed;
2702 rs6000_cannot_change_mode_class_ptr
2703 = rs6000_debug_cannot_change_mode_class;
2704 rs6000_preferred_reload_class_ptr
2705 = rs6000_debug_preferred_reload_class;
2706 rs6000_legitimize_reload_address_ptr
2707 = rs6000_debug_legitimize_reload_address;
2708 rs6000_mode_dependent_address_ptr
2709 = rs6000_debug_mode_dependent_address;
2713 if (rs6000_traceback_name)
2715 if (! strncmp (rs6000_traceback_name, "full", 4))
2716 rs6000_traceback = traceback_full;
2717 else if (! strncmp (rs6000_traceback_name, "part", 4))
2718 rs6000_traceback = traceback_part;
2719 else if (! strncmp (rs6000_traceback_name, "no", 2))
2720 rs6000_traceback = traceback_none;
2722 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2723 rs6000_traceback_name);
2726 if (!rs6000_explicit_options.long_double)
2727 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2729 #ifndef POWERPC_LINUX
2730 if (!rs6000_explicit_options.ieee)
2731 rs6000_ieeequad = 1;
2734 /* Enable Altivec ABI for AIX -maltivec. */
2735 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2736 rs6000_altivec_abi = 1;
2738 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2739 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2740 be explicitly overridden in either case. */
2743 if (!rs6000_explicit_options.altivec_abi
2744 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2745 rs6000_altivec_abi = 1;
2747 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2748 if (!rs6000_explicit_options.vrsave)
2749 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2752 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2753 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2755 rs6000_darwin64_abi = 1;
2757 darwin_one_byte_bool = 1;
2759 /* Default to natural alignment, for better performance. */
2760 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2763 /* Place FP constants in the constant pool instead of TOC
2764 if section anchors enabled. */
2765 if (flag_section_anchors)
2766 TARGET_NO_FP_IN_TOC = 1;
2768 /* Handle -mtls-size option. */
2769 rs6000_parse_tls_size_option ();
2771 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2772 SUBTARGET_OVERRIDE_OPTIONS;
2774 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2775 SUBSUBTARGET_OVERRIDE_OPTIONS;
2777 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2778 SUB3TARGET_OVERRIDE_OPTIONS;
2781 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2782 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2784 /* The e500 and e500mc do not have string instructions, and we set
2785 MASK_STRING above when optimizing for size. */
2786 if ((target_flags & MASK_STRING) != 0)
2787 target_flags = target_flags & ~MASK_STRING;
2789 else if (rs6000_select[1].string != NULL)
2791 /* For the powerpc-eabispe configuration, we set all these by
2792 default, so let's unset them if we manually set another
2793 CPU that is not the E500. */
2794 if (!rs6000_explicit_options.spe_abi)
2796 if (!rs6000_explicit_options.spe)
2798 if (!rs6000_explicit_options.float_gprs)
2799 rs6000_float_gprs = 0;
2800 if (!(target_flags_explicit & MASK_ISEL))
2801 target_flags &= ~MASK_ISEL;
2804 /* Detect invalid option combinations with E500. */
2807 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2808 && rs6000_cpu != PROCESSOR_POWER5
2809 && rs6000_cpu != PROCESSOR_POWER6
2810 && rs6000_cpu != PROCESSOR_POWER7
2811 && rs6000_cpu != PROCESSOR_PPCA2
2812 && rs6000_cpu != PROCESSOR_CELL);
2813 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2814 || rs6000_cpu == PROCESSOR_POWER5
2815 || rs6000_cpu == PROCESSOR_POWER7);
2816 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2817 || rs6000_cpu == PROCESSOR_POWER5
2818 || rs6000_cpu == PROCESSOR_POWER6
2819 || rs6000_cpu == PROCESSOR_POWER7
2820 || rs6000_cpu == PROCESSOR_PPCE500MC
2821 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2823 /* Allow debug switches to override the above settings. */
2824 if (TARGET_ALWAYS_HINT > 0)
2825 rs6000_always_hint = TARGET_ALWAYS_HINT;
2827 if (TARGET_SCHED_GROUPS > 0)
2828 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2830 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2831 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2833 rs6000_sched_restricted_insns_priority
2834 = (rs6000_sched_groups ? 1 : 0);
2836 /* Handle -msched-costly-dep option. */
2837 rs6000_sched_costly_dep
2838 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2840 if (rs6000_sched_costly_dep_str)
2842 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2843 rs6000_sched_costly_dep = no_dep_costly;
2844 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2845 rs6000_sched_costly_dep = all_deps_costly;
2846 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2847 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2848 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2849 rs6000_sched_costly_dep = store_to_load_dep_costly;
2851 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2852 atoi (rs6000_sched_costly_dep_str));
2855 /* Handle -minsert-sched-nops option. */
2856 rs6000_sched_insert_nops
2857 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2859 if (rs6000_sched_insert_nops_str)
2861 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2862 rs6000_sched_insert_nops = sched_finish_none;
2863 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2864 rs6000_sched_insert_nops = sched_finish_pad_groups;
2865 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2866 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2868 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2869 atoi (rs6000_sched_insert_nops_str));
2872 #ifdef TARGET_REGNAMES
2873 /* If the user desires alternate register names, copy in the
2874 alternate names now. */
2875 if (TARGET_REGNAMES)
2876 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2879 /* Set aix_struct_return last, after the ABI is determined.
2880 If -maix-struct-return or -msvr4-struct-return was explicitly
2881 used, don't override with the ABI default. */
2882 if (!rs6000_explicit_options.aix_struct_ret)
2883 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2885 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2886 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2889 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2891 /* We can only guarantee the availability of DI pseudo-ops when
2892 assembling for 64-bit targets. */
2895 targetm.asm_out.aligned_op.di = NULL;
2896 targetm.asm_out.unaligned_op.di = NULL;
2899 /* Set branch target alignment, if not optimizing for size. */
2902 /* Cell wants to be aligned 8byte for dual issue. */
2903 if (rs6000_cpu == PROCESSOR_CELL)
2905 if (align_functions <= 0)
2906 align_functions = 8;
2907 if (align_jumps <= 0)
2909 if (align_loops <= 0)
2912 if (rs6000_align_branch_targets)
2914 if (align_functions <= 0)
2915 align_functions = 16;
2916 if (align_jumps <= 0)
2918 if (align_loops <= 0)
2921 if (align_jumps_max_skip <= 0)
2922 align_jumps_max_skip = 15;
2923 if (align_loops_max_skip <= 0)
2924 align_loops_max_skip = 15;
2927 /* Arrange to save and restore machine status around nested functions. */
2928 init_machine_status = rs6000_init_machine_status;
2930 /* We should always be splitting complex arguments, but we can't break
2931 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2932 if (DEFAULT_ABI != ABI_AIX)
2933 targetm.calls.split_complex_arg = NULL;
2935 /* Initialize rs6000_cost with the appropriate target costs. */
2937 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2941 case PROCESSOR_RIOS1:
2942 rs6000_cost = &rios1_cost;
2945 case PROCESSOR_RIOS2:
2946 rs6000_cost = &rios2_cost;
2949 case PROCESSOR_RS64A:
2950 rs6000_cost = &rs64a_cost;
2953 case PROCESSOR_MPCCORE:
2954 rs6000_cost = &mpccore_cost;
2957 case PROCESSOR_PPC403:
2958 rs6000_cost = &ppc403_cost;
2961 case PROCESSOR_PPC405:
2962 rs6000_cost = &ppc405_cost;
2965 case PROCESSOR_PPC440:
2966 rs6000_cost = &ppc440_cost;
2969 case PROCESSOR_PPC476:
2970 rs6000_cost = &ppc476_cost;
2973 case PROCESSOR_PPC601:
2974 rs6000_cost = &ppc601_cost;
2977 case PROCESSOR_PPC603:
2978 rs6000_cost = &ppc603_cost;
2981 case PROCESSOR_PPC604:
2982 rs6000_cost = &ppc604_cost;
2985 case PROCESSOR_PPC604e:
2986 rs6000_cost = &ppc604e_cost;
2989 case PROCESSOR_PPC620:
2990 rs6000_cost = &ppc620_cost;
2993 case PROCESSOR_PPC630:
2994 rs6000_cost = &ppc630_cost;
2997 case PROCESSOR_CELL:
2998 rs6000_cost = &ppccell_cost;
3001 case PROCESSOR_PPC750:
3002 case PROCESSOR_PPC7400:
3003 rs6000_cost = &ppc750_cost;
3006 case PROCESSOR_PPC7450:
3007 rs6000_cost = &ppc7450_cost;
3010 case PROCESSOR_PPC8540:
3011 rs6000_cost = &ppc8540_cost;
3014 case PROCESSOR_PPCE300C2:
3015 case PROCESSOR_PPCE300C3:
3016 rs6000_cost = &ppce300c2c3_cost;
3019 case PROCESSOR_PPCE500MC:
3020 rs6000_cost = &ppce500mc_cost;
3023 case PROCESSOR_PPCE500MC64:
3024 rs6000_cost = &ppce500mc64_cost;
3027 case PROCESSOR_POWER4:
3028 case PROCESSOR_POWER5:
3029 rs6000_cost = &power4_cost;
3032 case PROCESSOR_POWER6:
3033 rs6000_cost = &power6_cost;
3036 case PROCESSOR_POWER7:
3037 rs6000_cost = &power7_cost;
3040 case PROCESSOR_PPCA2:
3041 rs6000_cost = &ppca2_cost;
3048 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
3049 set_param_value ("simultaneous-prefetches",
3050 rs6000_cost->simultaneous_prefetches);
3051 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
3052 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
3053 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
3054 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
3055 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
3056 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
3058 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
3059 can be optimized to ap = __builtin_next_arg (0). */
3060 if (DEFAULT_ABI != ABI_V4)
3061 targetm.expand_builtin_va_start = NULL;
3063 /* Set up single/double float flags.
3064 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3065 then set both flags. */
3066 if (TARGET_HARD_FLOAT && TARGET_FPRS
3067 && rs6000_single_float == 0 && rs6000_double_float == 0)
3068 rs6000_single_float = rs6000_double_float = 1;
3070 /* Reset single and double FP flags if target is E500. */
3073 rs6000_single_float = rs6000_double_float = 0;
3074 if (TARGET_E500_SINGLE)
3075 rs6000_single_float = 1;
3076 if (TARGET_E500_DOUBLE)
3077 rs6000_single_float = rs6000_double_float = 1;
3080 /* If not explicitly specified via option, decide whether to generate indexed
3081 load/store instructions. */
3082 if (TARGET_AVOID_XFORM == -1)
3083 /* Avoid indexed addressing when targeting Power6 in order to avoid
3084 the DERAT mispredict penalty. */
3085 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
3087 /* Set the -mrecip options. */
3088 if (rs6000_recip_name)
3090 char *p = ASTRDUP (rs6000_recip_name);
3092 unsigned int mask, i;
3095 while ((q = strtok (p, ",")) != NULL)
3106 if (!strcmp (q, "default"))
3107 mask = ((TARGET_RECIP_PRECISION)
3108 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3111 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3112 if (!strcmp (q, recip_options[i].string))
3114 mask = recip_options[i].mask;
3118 if (i == ARRAY_SIZE (recip_options))
3120 error ("Unknown option for -mrecip=%s", q);
3127 rs6000_recip_control &= ~mask;
3129 rs6000_recip_control |= mask;
3133 rs6000_init_hard_regno_mode_ok ();
3136 /* Implement targetm.vectorize.builtin_mask_for_load. */
3138 rs6000_builtin_mask_for_load (void)
3140 if (TARGET_ALTIVEC || TARGET_VSX)
3141 return altivec_builtin_mask_for_load;
3146 /* Implement targetm.vectorize.builtin_conversion.
3147 Returns a decl of a function that implements conversion of an integer vector
3148 into a floating-point vector, or vice-versa. DEST_TYPE is the
3149 destination type and SRC_TYPE the source type of the conversion.
3150 Return NULL_TREE if it is not available. */
3152 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3154 enum tree_code code = (enum tree_code) tcode;
3158 case FIX_TRUNC_EXPR:
3159 switch (TYPE_MODE (dest_type))
3162 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3165 return TYPE_UNSIGNED (dest_type)
3166 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3167 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3170 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3173 return TYPE_UNSIGNED (dest_type)
3174 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3175 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3182 switch (TYPE_MODE (src_type))
3185 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3188 return TYPE_UNSIGNED (src_type)
3189 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3190 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3193 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3196 return TYPE_UNSIGNED (src_type)
3197 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3198 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3209 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3211 rs6000_builtin_mul_widen_even (tree type)
3213 if (!TARGET_ALTIVEC)
3216 switch (TYPE_MODE (type))
3219 return TYPE_UNSIGNED (type)
3220 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3221 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3224 return TYPE_UNSIGNED (type)
3225 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3226 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3232 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3234 rs6000_builtin_mul_widen_odd (tree type)
3236 if (!TARGET_ALTIVEC)
3239 switch (TYPE_MODE (type))
3242 return TYPE_UNSIGNED (type)
3243 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3244 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3247 return TYPE_UNSIGNED (type)
3248 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3249 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3256 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3257 after applying N number of iterations. This routine does not determine
3258 how may iterations are required to reach desired alignment. */
3261 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3268 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3271 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3281 /* Assuming that all other types are naturally aligned. CHECKME! */
3286 /* Return true if the vector misalignment factor is supported by the
3289 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3296 /* Return if movmisalign pattern is not supported for this mode. */
3297 if (optab_handler (movmisalign_optab, mode)->insn_code ==
3301 if (misalignment == -1)
3303 /* misalignment factor is unknown at compile time but we know
3304 it's word aligned. */
3305 if (rs6000_vector_alignment_reachable (type, is_packed))
3309 /* VSX supports word-aligned vector. */
3310 if (misalignment % 4 == 0)
3316 /* Implement targetm.vectorize.builtin_vec_perm. */
3318 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3320 tree inner_type = TREE_TYPE (type);
3321 bool uns_p = TYPE_UNSIGNED (inner_type);
3324 *mask_element_type = unsigned_char_type_node;
3326 switch (TYPE_MODE (type))
3330 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3331 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3336 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3337 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3342 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3343 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3347 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3351 if (!TARGET_ALLOW_DF_PERMUTE)
3354 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3358 if (!TARGET_ALLOW_DF_PERMUTE)
3362 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3363 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3374 /* Handle generic options of the form -mfoo=yes/no.
3375 NAME is the option name.
3376 VALUE is the option value.
3377 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3378 whether the option value is 'yes' or 'no' respectively. */
3380 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3384 else if (!strcmp (value, "yes"))
3386 else if (!strcmp (value, "no"))
3389 error ("unknown -m%s= option specified: '%s'", name, value);
3392 /* Validate and record the size specified with the -mtls-size option. */
3395 rs6000_parse_tls_size_option (void)
3397 if (rs6000_tls_size_string == 0)
3399 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3400 rs6000_tls_size = 16;
3401 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3402 rs6000_tls_size = 32;
3403 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3404 rs6000_tls_size = 64;
3406 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3410 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3412 if (DEFAULT_ABI == ABI_DARWIN)
3413 /* The Darwin libraries never set errno, so we might as well
3414 avoid calling them when that's the only reason we would. */
3415 flag_errno_math = 0;
3417 /* Double growth factor to counter reduced min jump length. */
3418 set_param_value ("max-grow-copy-bb-insns", 16);
3420 /* Enable section anchors by default.
3421 Skip section anchors for Objective C and Objective C++
3422 until front-ends fixed. */
3423 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3424 flag_section_anchors = 2;
3427 static enum fpu_type_t
3428 rs6000_parse_fpu_option (const char *option)
3430 if (!strcmp("none", option)) return FPU_NONE;
3431 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3432 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3433 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3434 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3435 error("unknown value %s for -mfpu", option);
3439 /* Returns a function decl for a vectorized version of the builtin function
3440 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3441 if it is not available. */
3444 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3447 enum machine_mode in_mode, out_mode;
3450 if (TREE_CODE (type_out) != VECTOR_TYPE
3451 || TREE_CODE (type_in) != VECTOR_TYPE
3452 || !TARGET_VECTORIZE_BUILTINS)
3455 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3456 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3457 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3458 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3460 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3462 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3465 case BUILT_IN_COPYSIGN:
3466 if (VECTOR_UNIT_VSX_P (V2DFmode)
3467 && out_mode == DFmode && out_n == 2
3468 && in_mode == DFmode && in_n == 2)
3469 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3471 case BUILT_IN_COPYSIGNF:
3472 if (out_mode != SFmode || out_n != 4
3473 || in_mode != SFmode || in_n != 4)
3475 if (VECTOR_UNIT_VSX_P (V4SFmode))
3476 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3477 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3478 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3481 if (VECTOR_UNIT_VSX_P (V2DFmode)
3482 && out_mode == DFmode && out_n == 2
3483 && in_mode == DFmode && in_n == 2)
3484 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3486 case BUILT_IN_SQRTF:
3487 if (VECTOR_UNIT_VSX_P (V4SFmode)
3488 && out_mode == SFmode && out_n == 4
3489 && in_mode == SFmode && in_n == 4)
3490 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3493 if (VECTOR_UNIT_VSX_P (V2DFmode)
3494 && out_mode == DFmode && out_n == 2
3495 && in_mode == DFmode && in_n == 2)
3496 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3498 case BUILT_IN_CEILF:
3499 if (out_mode != SFmode || out_n != 4
3500 || in_mode != SFmode || in_n != 4)
3502 if (VECTOR_UNIT_VSX_P (V4SFmode))
3503 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3504 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3505 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3507 case BUILT_IN_FLOOR:
3508 if (VECTOR_UNIT_VSX_P (V2DFmode)
3509 && out_mode == DFmode && out_n == 2
3510 && in_mode == DFmode && in_n == 2)
3511 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3513 case BUILT_IN_FLOORF:
3514 if (out_mode != SFmode || out_n != 4
3515 || in_mode != SFmode || in_n != 4)
3517 if (VECTOR_UNIT_VSX_P (V4SFmode))
3518 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3519 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3520 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3522 case BUILT_IN_TRUNC:
3523 if (VECTOR_UNIT_VSX_P (V2DFmode)
3524 && out_mode == DFmode && out_n == 2
3525 && in_mode == DFmode && in_n == 2)
3526 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3528 case BUILT_IN_TRUNCF:
3529 if (out_mode != SFmode || out_n != 4
3530 || in_mode != SFmode || in_n != 4)
3532 if (VECTOR_UNIT_VSX_P (V4SFmode))
3533 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3534 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3535 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3537 case BUILT_IN_NEARBYINT:
3538 if (VECTOR_UNIT_VSX_P (V2DFmode)
3539 && flag_unsafe_math_optimizations
3540 && out_mode == DFmode && out_n == 2
3541 && in_mode == DFmode && in_n == 2)
3542 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3544 case BUILT_IN_NEARBYINTF:
3545 if (VECTOR_UNIT_VSX_P (V4SFmode)
3546 && flag_unsafe_math_optimizations
3547 && out_mode == SFmode && out_n == 4
3548 && in_mode == SFmode && in_n == 4)
3549 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3552 if (VECTOR_UNIT_VSX_P (V2DFmode)
3553 && !flag_trapping_math
3554 && out_mode == DFmode && out_n == 2
3555 && in_mode == DFmode && in_n == 2)
3556 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3558 case BUILT_IN_RINTF:
3559 if (VECTOR_UNIT_VSX_P (V4SFmode)
3560 && !flag_trapping_math
3561 && out_mode == SFmode && out_n == 4
3562 && in_mode == SFmode && in_n == 4)
3563 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3570 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3572 enum rs6000_builtins fn
3573 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
3576 case RS6000_BUILTIN_RSQRTF:
3577 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3578 && out_mode == SFmode && out_n == 4
3579 && in_mode == SFmode && in_n == 4)
3580 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
3582 case RS6000_BUILTIN_RSQRT:
3583 if (VECTOR_UNIT_VSX_P (V2DFmode)
3584 && out_mode == DFmode && out_n == 2
3585 && in_mode == DFmode && in_n == 2)
3586 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
3588 case RS6000_BUILTIN_RECIPF:
3589 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3590 && out_mode == SFmode && out_n == 4
3591 && in_mode == SFmode && in_n == 4)
3592 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
3594 case RS6000_BUILTIN_RECIP:
3595 if (VECTOR_UNIT_VSX_P (V2DFmode)
3596 && out_mode == DFmode && out_n == 2
3597 && in_mode == DFmode && in_n == 2)
3598 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
3609 /* Implement TARGET_HANDLE_OPTION. */
3612 rs6000_handle_option (size_t code, const char *arg, int value)
3614 enum fpu_type_t fpu_type = FPU_NONE;
3620 target_flags &= ~(MASK_POWER | MASK_POWER2
3621 | MASK_MULTIPLE | MASK_STRING);
3622 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3623 | MASK_MULTIPLE | MASK_STRING);
3625 case OPT_mno_powerpc:
3626 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3627 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3628 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3629 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3632 target_flags &= ~MASK_MINIMAL_TOC;
3633 TARGET_NO_FP_IN_TOC = 0;
3634 TARGET_NO_SUM_IN_TOC = 0;
3635 target_flags_explicit |= MASK_MINIMAL_TOC;
3636 #ifdef TARGET_USES_SYSV4_OPT
3637 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3638 just the same as -mminimal-toc. */
3639 target_flags |= MASK_MINIMAL_TOC;
3640 target_flags_explicit |= MASK_MINIMAL_TOC;
3644 #ifdef TARGET_USES_SYSV4_OPT
3646 /* Make -mtoc behave like -mminimal-toc. */
3647 target_flags |= MASK_MINIMAL_TOC;
3648 target_flags_explicit |= MASK_MINIMAL_TOC;
3652 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
3654 if (strcmp (arg, "small") == 0)
3655 cmodel = CMODEL_SMALL;
3656 else if (strcmp (arg, "large") == 0)
3657 cmodel = CMODEL_LARGE;
3660 error ("invalid option for -mcmodel: '%s'", arg);
3663 rs6000_explicit_options.cmodel = true;
3666 #ifdef TARGET_USES_AIX64_OPT
3671 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3672 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3673 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3676 #ifdef TARGET_USES_AIX64_OPT
3681 target_flags &= ~MASK_POWERPC64;
3682 target_flags_explicit |= MASK_POWERPC64;
3685 case OPT_minsert_sched_nops_:
3686 rs6000_sched_insert_nops_str = arg;
3689 case OPT_mminimal_toc:
3692 TARGET_NO_FP_IN_TOC = 0;
3693 TARGET_NO_SUM_IN_TOC = 0;
3700 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3701 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3708 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3709 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3713 case OPT_mpowerpc_gpopt:
3714 case OPT_mpowerpc_gfxopt:
3717 target_flags |= MASK_POWERPC;
3718 target_flags_explicit |= MASK_POWERPC;
3722 case OPT_maix_struct_return:
3723 case OPT_msvr4_struct_return:
3724 rs6000_explicit_options.aix_struct_ret = true;
3728 rs6000_explicit_options.vrsave = true;
3729 TARGET_ALTIVEC_VRSAVE = value;
3733 rs6000_explicit_options.vrsave = true;
3734 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3738 target_flags_explicit |= MASK_ISEL;
3740 rs6000_parse_yes_no_option ("isel", arg, &isel);
3742 target_flags |= MASK_ISEL;
3744 target_flags &= ~MASK_ISEL;
3748 rs6000_explicit_options.spe = true;
3753 rs6000_explicit_options.spe = true;
3754 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3758 rs6000_debug_name = arg;
3761 #ifdef TARGET_USES_SYSV4_OPT
3763 rs6000_abi_name = arg;
3767 rs6000_sdata_name = arg;
3770 case OPT_mtls_size_:
3771 rs6000_tls_size_string = arg;
3774 case OPT_mrelocatable:
3777 target_flags |= MASK_MINIMAL_TOC;
3778 target_flags_explicit |= MASK_MINIMAL_TOC;
3779 TARGET_NO_FP_IN_TOC = 1;
3783 case OPT_mrelocatable_lib:
3786 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3787 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3788 TARGET_NO_FP_IN_TOC = 1;
3792 target_flags &= ~MASK_RELOCATABLE;
3793 target_flags_explicit |= MASK_RELOCATABLE;
3799 if (!strcmp (arg, "altivec"))
3801 rs6000_explicit_options.altivec_abi = true;
3802 rs6000_altivec_abi = 1;
3804 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3807 else if (! strcmp (arg, "no-altivec"))
3809 rs6000_explicit_options.altivec_abi = true;
3810 rs6000_altivec_abi = 0;
3812 else if (! strcmp (arg, "spe"))
3814 rs6000_explicit_options.spe_abi = true;
3816 rs6000_altivec_abi = 0;
3817 if (!TARGET_SPE_ABI)
3818 error ("not configured for ABI: '%s'", arg);
3820 else if (! strcmp (arg, "no-spe"))
3822 rs6000_explicit_options.spe_abi = true;
3826 /* These are here for testing during development only, do not
3827 document in the manual please. */
3828 else if (! strcmp (arg, "d64"))
3830 rs6000_darwin64_abi = 1;
3831 warning (0, "Using darwin64 ABI");
3833 else if (! strcmp (arg, "d32"))
3835 rs6000_darwin64_abi = 0;
3836 warning (0, "Using old darwin ABI");
3839 else if (! strcmp (arg, "ibmlongdouble"))
3841 rs6000_explicit_options.ieee = true;
3842 rs6000_ieeequad = 0;
3843 warning (0, "Using IBM extended precision long double");
3845 else if (! strcmp (arg, "ieeelongdouble"))
3847 rs6000_explicit_options.ieee = true;
3848 rs6000_ieeequad = 1;
3849 warning (0, "Using IEEE extended precision long double");
3854 error ("unknown ABI specified: '%s'", arg);
3860 rs6000_select[1].string = arg;
3864 rs6000_select[2].string = arg;
3867 case OPT_mtraceback_:
3868 rs6000_traceback_name = arg;
3871 case OPT_mfloat_gprs_:
3872 rs6000_explicit_options.float_gprs = true;
3873 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3874 rs6000_float_gprs = 1;
3875 else if (! strcmp (arg, "double"))
3876 rs6000_float_gprs = 2;
3877 else if (! strcmp (arg, "no"))
3878 rs6000_float_gprs = 0;
3881 error ("invalid option for -mfloat-gprs: '%s'", arg);
3886 case OPT_mlong_double_:
3887 rs6000_explicit_options.long_double = true;
3888 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3889 if (value != 64 && value != 128)
3891 error ("Unknown switch -mlong-double-%s", arg);
3892 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3896 rs6000_long_double_type_size = value;
3899 case OPT_msched_costly_dep_:
3900 rs6000_sched_costly_dep_str = arg;
3904 rs6000_explicit_options.alignment = true;
3905 if (! strcmp (arg, "power"))
3907 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3908 some C library functions, so warn about it. The flag may be
3909 useful for performance studies from time to time though, so
3910 don't disable it entirely. */
3911 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3912 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3913 " it is incompatible with the installed C and C++ libraries");
3914 rs6000_alignment_flags = MASK_ALIGN_POWER;
3916 else if (! strcmp (arg, "natural"))
3917 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3920 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3925 case OPT_msingle_float:
3926 if (!TARGET_SINGLE_FPU)
3927 warning (0, "-msingle-float option equivalent to -mhard-float");
3928 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3929 rs6000_double_float = 0;
3930 target_flags &= ~MASK_SOFT_FLOAT;
3931 target_flags_explicit |= MASK_SOFT_FLOAT;
3934 case OPT_mdouble_float:
3935 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3936 rs6000_single_float = 1;
3937 target_flags &= ~MASK_SOFT_FLOAT;
3938 target_flags_explicit |= MASK_SOFT_FLOAT;
3941 case OPT_msimple_fpu:
3942 if (!TARGET_SINGLE_FPU)
3943 warning (0, "-msimple-fpu option ignored");
3946 case OPT_mhard_float:
3947 /* -mhard_float implies -msingle-float and -mdouble-float. */
3948 rs6000_single_float = rs6000_double_float = 1;
3951 case OPT_msoft_float:
3952 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3953 rs6000_single_float = rs6000_double_float = 0;
3957 fpu_type = rs6000_parse_fpu_option(arg);
3958 if (fpu_type != FPU_NONE)
3959 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3961 target_flags &= ~MASK_SOFT_FLOAT;
3962 target_flags_explicit |= MASK_SOFT_FLOAT;
3963 rs6000_xilinx_fpu = 1;
3964 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3965 rs6000_single_float = 1;
3966 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3967 rs6000_single_float = rs6000_double_float = 1;
3968 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3969 rs6000_simple_fpu = 1;
3973 /* -mfpu=none is equivalent to -msoft-float */
3974 target_flags |= MASK_SOFT_FLOAT;
3975 target_flags_explicit |= MASK_SOFT_FLOAT;
3976 rs6000_single_float = rs6000_double_float = 0;
3980 rs6000_recip_name = (value) ? "default" : "none";
3984 rs6000_recip_name = arg;
3990 /* Do anything needed at the start of the asm file. */
3993 rs6000_file_start (void)
3997 const char *start = buffer;
3998 struct rs6000_cpu_select *ptr;
3999 const char *default_cpu = TARGET_CPU_DEFAULT;
4000 FILE *file = asm_out_file;
4002 default_file_start ();
4004 #ifdef TARGET_BI_ARCH
4005 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4009 if (flag_verbose_asm)
4011 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4012 rs6000_select[0].string = default_cpu;
4014 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4016 ptr = &rs6000_select[i];
4017 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4019 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4024 if (PPC405_ERRATUM77)
4026 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4030 #ifdef USING_ELFOS_H
4031 switch (rs6000_sdata)
4033 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4034 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4035 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4036 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4039 if (rs6000_sdata && g_switch_value)
4041 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
4051 #ifdef HAVE_AS_GNU_ATTRIBUTE
4052 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
4054 fprintf (file, "\t.gnu_attribute 4, %d\n",
4055 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
4056 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
4058 fprintf (file, "\t.gnu_attribute 8, %d\n",
4059 (TARGET_ALTIVEC_ABI ? 2
4060 : TARGET_SPE_ABI ? 3
4062 fprintf (file, "\t.gnu_attribute 12, %d\n",
4063 aix_struct_return ? 2 : 1);
4068 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4070 switch_to_section (toc_section);
4071 switch_to_section (text_section);
4076 /* Return nonzero if this function is known to have a null epilogue. */
4079 direct_return (void)
4081 if (reload_completed)
4083 rs6000_stack_t *info = rs6000_stack_info ();
4085 if (info->first_gp_reg_save == 32
4086 && info->first_fp_reg_save == 64
4087 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4088 && ! info->lr_save_p
4089 && ! info->cr_save_p
4090 && info->vrsave_mask == 0
4098 /* Return the number of instructions it takes to form a constant in an
4099 integer register. */
4102 num_insns_constant_wide (HOST_WIDE_INT value)
4104 /* signed constant loadable with {cal|addi} */
4105 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4108 /* constant loadable with {cau|addis} */
4109 else if ((value & 0xffff) == 0
4110 && (value >> 31 == -1 || value >> 31 == 0))
4113 #if HOST_BITS_PER_WIDE_INT == 64
4114 else if (TARGET_POWERPC64)
4116 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4117 HOST_WIDE_INT high = value >> 31;
4119 if (high == 0 || high == -1)
4125 return num_insns_constant_wide (high) + 1;
4127 return num_insns_constant_wide (low) + 1;
4129 return (num_insns_constant_wide (high)
4130 + num_insns_constant_wide (low) + 1);
4139 num_insns_constant (rtx op, enum machine_mode mode)
4141 HOST_WIDE_INT low, high;
4143 switch (GET_CODE (op))
4146 #if HOST_BITS_PER_WIDE_INT == 64
4147 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4148 && mask64_operand (op, mode))
4152 return num_insns_constant_wide (INTVAL (op));
4155 if (mode == SFmode || mode == SDmode)
4160 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4161 if (DECIMAL_FLOAT_MODE_P (mode))
4162 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4164 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4165 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4168 if (mode == VOIDmode || mode == DImode)
4170 high = CONST_DOUBLE_HIGH (op);
4171 low = CONST_DOUBLE_LOW (op);
4178 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4179 if (DECIMAL_FLOAT_MODE_P (mode))
4180 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4182 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4183 high = l[WORDS_BIG_ENDIAN == 0];
4184 low = l[WORDS_BIG_ENDIAN != 0];
4188 return (num_insns_constant_wide (low)
4189 + num_insns_constant_wide (high));
4192 if ((high == 0 && low >= 0)
4193 || (high == -1 && low < 0))
4194 return num_insns_constant_wide (low);
4196 else if (mask64_operand (op, mode))
4200 return num_insns_constant_wide (high) + 1;
4203 return (num_insns_constant_wide (high)
4204 + num_insns_constant_wide (low) + 1);
4212 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4213 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4214 corresponding element of the vector, but for V4SFmode and V2SFmode,
4215 the corresponding "float" is interpreted as an SImode integer. */
4218 const_vector_elt_as_int (rtx op, unsigned int elt)
4220 rtx tmp = CONST_VECTOR_ELT (op, elt);
4221 if (GET_MODE (op) == V4SFmode
4222 || GET_MODE (op) == V2SFmode)
4223 tmp = gen_lowpart (SImode, tmp);
4224 return INTVAL (tmp);
4227 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4228 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4229 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4230 all items are set to the same value and contain COPIES replicas of the
4231 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4232 operand and the others are set to the value of the operand's msb. */
4235 vspltis_constant (rtx op, unsigned step, unsigned copies)
4237 enum machine_mode mode = GET_MODE (op);
4238 enum machine_mode inner = GET_MODE_INNER (mode);
4241 unsigned nunits = GET_MODE_NUNITS (mode);
4242 unsigned bitsize = GET_MODE_BITSIZE (inner);
4243 unsigned mask = GET_MODE_MASK (inner);
4245 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
4246 HOST_WIDE_INT splat_val = val;
4247 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
4249 /* Construct the value to be splatted, if possible. If not, return 0. */
4250 for (i = 2; i <= copies; i *= 2)
4252 HOST_WIDE_INT small_val;
4254 small_val = splat_val >> bitsize;
4256 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4258 splat_val = small_val;
4261 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4262 if (EASY_VECTOR_15 (splat_val))
4265 /* Also check if we can splat, and then add the result to itself. Do so if
4266 the value is positive, of if the splat instruction is using OP's mode;
4267 for splat_val < 0, the splat and the add should use the same mode. */
4268 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4269 && (splat_val >= 0 || (step == 1 && copies == 1)))
4272 /* Also check if are loading up the most significant bit which can be done by
4273 loading up -1 and shifting the value left by -1. */
4274 else if (EASY_VECTOR_MSB (splat_val, inner))
4280 /* Check if VAL is present in every STEP-th element, and the
4281 other elements are filled with its most significant bit. */
4282 for (i = 0; i < nunits - 1; ++i)
4284 HOST_WIDE_INT desired_val;
4285 if (((i + 1) & (step - 1)) == 0)
4288 desired_val = msb_val;
4290 if (desired_val != const_vector_elt_as_int (op, i))
4298 /* Return true if OP is of the given MODE and can be synthesized
4299 with a vspltisb, vspltish or vspltisw. */
4302 easy_altivec_constant (rtx op, enum machine_mode mode)
4304 unsigned step, copies;
4306 if (mode == VOIDmode)
4307 mode = GET_MODE (op);
4308 else if (mode != GET_MODE (op))
4311 /* Start with a vspltisw. */
4312 step = GET_MODE_NUNITS (mode) / 4;
4315 if (vspltis_constant (op, step, copies))
4318 /* Then try with a vspltish. */
4324 if (vspltis_constant (op, step, copies))
4327 /* And finally a vspltisb. */
4333 if (vspltis_constant (op, step, copies))
4339 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4340 result is OP. Abort if it is not possible. */
4343 gen_easy_altivec_constant (rtx op)
4345 enum machine_mode mode = GET_MODE (op);
4346 int nunits = GET_MODE_NUNITS (mode);
4347 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4348 unsigned step = nunits / 4;
4349 unsigned copies = 1;
4351 /* Start with a vspltisw. */
4352 if (vspltis_constant (op, step, copies))
4353 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4355 /* Then try with a vspltish. */
4361 if (vspltis_constant (op, step, copies))
4362 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4364 /* And finally a vspltisb. */
4370 if (vspltis_constant (op, step, copies))
4371 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4377 output_vec_const_move (rtx *operands)
4380 enum machine_mode mode;
4385 mode = GET_MODE (dest);
4387 if (TARGET_VSX && zero_constant (vec, mode))
4388 return "xxlxor %x0,%x0,%x0";
4393 if (zero_constant (vec, mode))
4394 return "vxor %0,%0,%0";
4396 splat_vec = gen_easy_altivec_constant (vec);
4397 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4398 operands[1] = XEXP (splat_vec, 0);
4399 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4402 switch (GET_MODE (splat_vec))
4405 return "vspltisw %0,%1";
4408 return "vspltish %0,%1";
4411 return "vspltisb %0,%1";
4418 gcc_assert (TARGET_SPE);
4420 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4421 pattern of V1DI, V4HI, and V2SF.
4423 FIXME: We should probably return # and add post reload
4424 splitters for these, but this way is so easy ;-). */
4425 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4426 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4427 operands[1] = CONST_VECTOR_ELT (vec, 0);
4428 operands[2] = CONST_VECTOR_ELT (vec, 1);
4430 return "li %0,%1\n\tevmergelo %0,%0,%0";
4432 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4435 /* Initialize TARGET of vector PAIRED to VALS. */
4438 paired_expand_vector_init (rtx target, rtx vals)
4440 enum machine_mode mode = GET_MODE (target);
4441 int n_elts = GET_MODE_NUNITS (mode);
4443 rtx x, new_rtx, tmp, constant_op, op1, op2;
4446 for (i = 0; i < n_elts; ++i)
4448 x = XVECEXP (vals, 0, i);
4449 if (!CONSTANT_P (x))
4454 /* Load from constant pool. */
4455 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4461 /* The vector is initialized only with non-constants. */
4462 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4463 XVECEXP (vals, 0, 1));
4465 emit_move_insn (target, new_rtx);
4469 /* One field is non-constant and the other one is a constant. Load the
4470 constant from the constant pool and use ps_merge instruction to
4471 construct the whole vector. */
4472 op1 = XVECEXP (vals, 0, 0);
4473 op2 = XVECEXP (vals, 0, 1);
4475 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4477 tmp = gen_reg_rtx (GET_MODE (constant_op));
4478 emit_move_insn (tmp, constant_op);
4480 if (CONSTANT_P (op1))
4481 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4483 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4485 emit_move_insn (target, new_rtx);
4489 paired_expand_vector_move (rtx operands[])
4491 rtx op0 = operands[0], op1 = operands[1];
4493 emit_move_insn (op0, op1);
4496 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4497 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4498 operands for the relation operation COND. This is a recursive
4502 paired_emit_vector_compare (enum rtx_code rcode,
4503 rtx dest, rtx op0, rtx op1,
4504 rtx cc_op0, rtx cc_op1)
4506 rtx tmp = gen_reg_rtx (V2SFmode);
4509 gcc_assert (TARGET_PAIRED_FLOAT);
4510 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4516 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4520 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4521 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4525 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4528 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4531 tmp1 = gen_reg_rtx (V2SFmode);
4532 max = gen_reg_rtx (V2SFmode);
4533 min = gen_reg_rtx (V2SFmode);
4534 gen_reg_rtx (V2SFmode);
4536 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4537 emit_insn (gen_selv2sf4
4538 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4539 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4540 emit_insn (gen_selv2sf4
4541 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4542 emit_insn (gen_subv2sf3 (tmp1, min, max));
4543 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4546 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4549 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4552 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4555 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4558 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4567 /* Emit vector conditional expression.
4568 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4569 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4572 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4573 rtx cond, rtx cc_op0, rtx cc_op1)
4575 enum rtx_code rcode = GET_CODE (cond);
4577 if (!TARGET_PAIRED_FLOAT)
4580 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4585 /* Initialize vector TARGET to VALS. */
4588 rs6000_expand_vector_init (rtx target, rtx vals)
4590 enum machine_mode mode = GET_MODE (target);
4591 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4592 int n_elts = GET_MODE_NUNITS (mode);
4593 int n_var = 0, one_var = -1;
4594 bool all_same = true, all_const_zero = true;
4598 for (i = 0; i < n_elts; ++i)
4600 x = XVECEXP (vals, 0, i);
4601 if (!CONSTANT_P (x))
4602 ++n_var, one_var = i;
4603 else if (x != CONST0_RTX (inner_mode))
4604 all_const_zero = false;
4606 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4612 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4613 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4614 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4616 /* Zero register. */
4617 emit_insn (gen_rtx_SET (VOIDmode, target,
4618 gen_rtx_XOR (mode, target, target)));
4621 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4623 /* Splat immediate. */
4624 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4629 /* Load from constant pool. */
4630 emit_move_insn (target, const_vec);
4635 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4636 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4640 rtx element = XVECEXP (vals, 0, 0);
4641 if (mode == V2DFmode)
4642 emit_insn (gen_vsx_splat_v2df (target, element));
4644 emit_insn (gen_vsx_splat_v2di (target, element));
4648 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4649 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4650 if (mode == V2DFmode)
4651 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4653 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4658 /* With single precision floating point on VSX, know that internally single
4659 precision is actually represented as a double, and either make 2 V2DF
4660 vectors, and convert these vectors to single precision, or do one
4661 conversion, and splat the result to the other elements. */
4662 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4666 rtx freg = gen_reg_rtx (V4SFmode);
4667 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4669 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4670 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4674 rtx dbl_even = gen_reg_rtx (V2DFmode);
4675 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4676 rtx flt_even = gen_reg_rtx (V4SFmode);
4677 rtx flt_odd = gen_reg_rtx (V4SFmode);
4679 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4680 copy_to_reg (XVECEXP (vals, 0, 0)),
4681 copy_to_reg (XVECEXP (vals, 0, 1))));
4682 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4683 copy_to_reg (XVECEXP (vals, 0, 2)),
4684 copy_to_reg (XVECEXP (vals, 0, 3))));
4685 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4686 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4687 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4692 /* Store value to stack temp. Load vector element. Splat. However, splat
4693 of 64-bit items is not supported on Altivec. */
4694 if (all_same && GET_MODE_SIZE (mode) <= 4)
4696 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4697 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4698 XVECEXP (vals, 0, 0));
4699 x = gen_rtx_UNSPEC (VOIDmode,
4700 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4701 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4703 gen_rtx_SET (VOIDmode,
4706 x = gen_rtx_VEC_SELECT (inner_mode, target,
4707 gen_rtx_PARALLEL (VOIDmode,
4708 gen_rtvec (1, const0_rtx)));
4709 emit_insn (gen_rtx_SET (VOIDmode, target,
4710 gen_rtx_VEC_DUPLICATE (mode, x)));
4714 /* One field is non-constant. Load constant then overwrite
4718 rtx copy = copy_rtx (vals);
4720 /* Load constant part of vector, substitute neighboring value for
4722 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4723 rs6000_expand_vector_init (target, copy);
4725 /* Insert variable. */
4726 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4730 /* Construct the vector in memory one field at a time
4731 and load the whole vector. */
4732 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4733 for (i = 0; i < n_elts; i++)
4734 emit_move_insn (adjust_address_nv (mem, inner_mode,
4735 i * GET_MODE_SIZE (inner_mode)),
4736 XVECEXP (vals, 0, i));
4737 emit_move_insn (target, mem);
4740 /* Set field ELT of TARGET to VAL. */
4743 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4745 enum machine_mode mode = GET_MODE (target);
4746 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4747 rtx reg = gen_reg_rtx (mode);
4749 int width = GET_MODE_SIZE (inner_mode);
4752 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4754 rtx (*set_func) (rtx, rtx, rtx, rtx)
4755 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4756 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4760 /* Load single variable value. */
4761 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4762 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4763 x = gen_rtx_UNSPEC (VOIDmode,
4764 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4765 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4767 gen_rtx_SET (VOIDmode,
4771 /* Linear sequence. */
4772 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4773 for (i = 0; i < 16; ++i)
4774 XVECEXP (mask, 0, i) = GEN_INT (i);
4776 /* Set permute mask to insert element into target. */
4777 for (i = 0; i < width; ++i)
4778 XVECEXP (mask, 0, elt*width + i)
4779 = GEN_INT (i + 0x10);
4780 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4781 x = gen_rtx_UNSPEC (mode,
4782 gen_rtvec (3, target, reg,
4783 force_reg (V16QImode, x)),
4785 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4788 /* Extract field ELT from VEC into TARGET. */
4791 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4793 enum machine_mode mode = GET_MODE (vec);
4794 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4797 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4799 rtx (*extract_func) (rtx, rtx, rtx)
4800 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4801 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4805 /* Allocate mode-sized buffer. */
4806 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4808 /* Add offset to field within buffer matching vector element. */
4809 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4811 /* Store single field into mode-sized buffer. */
4812 x = gen_rtx_UNSPEC (VOIDmode,
4813 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4814 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4816 gen_rtx_SET (VOIDmode,
4819 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4822 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4823 implement ANDing by the mask IN. */
4825 build_mask64_2_operands (rtx in, rtx *out)
4827 #if HOST_BITS_PER_WIDE_INT >= 64
4828 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4831 gcc_assert (GET_CODE (in) == CONST_INT);
4836 /* Assume c initially something like 0x00fff000000fffff. The idea
4837 is to rotate the word so that the middle ^^^^^^ group of zeros
4838 is at the MS end and can be cleared with an rldicl mask. We then
4839 rotate back and clear off the MS ^^ group of zeros with a
4841 c = ~c; /* c == 0xff000ffffff00000 */
4842 lsb = c & -c; /* lsb == 0x0000000000100000 */
4843 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4844 c = ~c; /* c == 0x00fff000000fffff */
4845 c &= -lsb; /* c == 0x00fff00000000000 */
4846 lsb = c & -c; /* lsb == 0x0000100000000000 */
4847 c = ~c; /* c == 0xff000fffffffffff */
4848 c &= -lsb; /* c == 0xff00000000000000 */
4850 while ((lsb >>= 1) != 0)
4851 shift++; /* shift == 44 on exit from loop */
4852 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4853 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4854 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4858 /* Assume c initially something like 0xff000f0000000000. The idea
4859 is to rotate the word so that the ^^^ middle group of zeros
4860 is at the LS end and can be cleared with an rldicr mask. We then
4861 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4863 lsb = c & -c; /* lsb == 0x0000010000000000 */
4864 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4865 c = ~c; /* c == 0x00fff0ffffffffff */
4866 c &= -lsb; /* c == 0x00fff00000000000 */
4867 lsb = c & -c; /* lsb == 0x0000100000000000 */
4868 c = ~c; /* c == 0xff000fffffffffff */
4869 c &= -lsb; /* c == 0xff00000000000000 */
4871 while ((lsb >>= 1) != 0)
4872 shift++; /* shift == 44 on exit from loop */
4873 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4874 m1 >>= shift; /* m1 == 0x0000000000000fff */
4875 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4878 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4879 masks will be all 1's. We are guaranteed more than one transition. */
4880 out[0] = GEN_INT (64 - shift);
4881 out[1] = GEN_INT (m1);
4882 out[2] = GEN_INT (shift);
4883 out[3] = GEN_INT (m2);
4891 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4894 invalid_e500_subreg (rtx op, enum machine_mode mode)
4896 if (TARGET_E500_DOUBLE)
4898 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4899 subreg:TI and reg:TF. Decimal float modes are like integer
4900 modes (only low part of each register used) for this
4902 if (GET_CODE (op) == SUBREG
4903 && (mode == SImode || mode == DImode || mode == TImode
4904 || mode == DDmode || mode == TDmode)
4905 && REG_P (SUBREG_REG (op))
4906 && (GET_MODE (SUBREG_REG (op)) == DFmode
4907 || GET_MODE (SUBREG_REG (op)) == TFmode))
4910 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4912 if (GET_CODE (op) == SUBREG
4913 && (mode == DFmode || mode == TFmode)
4914 && REG_P (SUBREG_REG (op))
4915 && (GET_MODE (SUBREG_REG (op)) == DImode
4916 || GET_MODE (SUBREG_REG (op)) == TImode
4917 || GET_MODE (SUBREG_REG (op)) == DDmode
4918 || GET_MODE (SUBREG_REG (op)) == TDmode))
4923 && GET_CODE (op) == SUBREG
4925 && REG_P (SUBREG_REG (op))
4926 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4932 /* AIX increases natural record alignment to doubleword if the first
4933 field is an FP double while the FP fields remain word aligned. */
4936 rs6000_special_round_type_align (tree type, unsigned int computed,
4937 unsigned int specified)
4939 unsigned int align = MAX (computed, specified);
4940 tree field = TYPE_FIELDS (type);
4942 /* Skip all non field decls */
4943 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4944 field = TREE_CHAIN (field);
4946 if (field != NULL && field != type)
4948 type = TREE_TYPE (field);
4949 while (TREE_CODE (type) == ARRAY_TYPE)
4950 type = TREE_TYPE (type);
4952 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4953 align = MAX (align, 64);
4959 /* Darwin increases record alignment to the natural alignment of
4963 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4964 unsigned int specified)
4966 unsigned int align = MAX (computed, specified);
4968 if (TYPE_PACKED (type))
4971 /* Find the first field, looking down into aggregates. */
4973 tree field = TYPE_FIELDS (type);
4974 /* Skip all non field decls */
4975 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4976 field = TREE_CHAIN (field);
4979 /* A packed field does not contribute any extra alignment. */
4980 if (DECL_PACKED (field))
4982 type = TREE_TYPE (field);
4983 while (TREE_CODE (type) == ARRAY_TYPE)
4984 type = TREE_TYPE (type);
4985 } while (AGGREGATE_TYPE_P (type));
4987 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
4988 align = MAX (align, TYPE_ALIGN (type));
4993 /* Return 1 for an operand in small memory on V.4/eabi. */
4996 small_data_operand (rtx op ATTRIBUTE_UNUSED,
4997 enum machine_mode mode ATTRIBUTE_UNUSED)
5002 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5005 if (DEFAULT_ABI != ABI_V4)
5008 /* Vector and float memory instructions have a limited offset on the
5009 SPE, so using a vector or float variable directly as an operand is
5012 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5015 if (GET_CODE (op) == SYMBOL_REF)
5018 else if (GET_CODE (op) != CONST
5019 || GET_CODE (XEXP (op, 0)) != PLUS
5020 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5021 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5026 rtx sum = XEXP (op, 0);
5027 HOST_WIDE_INT summand;
5029 /* We have to be careful here, because it is the referenced address
5030 that must be 32k from _SDA_BASE_, not just the symbol. */
5031 summand = INTVAL (XEXP (sum, 1));
5032 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
5035 sym_ref = XEXP (sum, 0);
5038 return SYMBOL_REF_SMALL_P (sym_ref);
5044 /* Return true if either operand is a general purpose register. */
5047 gpr_or_gpr_p (rtx op0, rtx op1)
5049 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5050 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5054 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5057 reg_offset_addressing_ok_p (enum machine_mode mode)
5067 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5068 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5076 /* Paired vector modes. Only reg+reg addressing is valid. */
5077 if (TARGET_PAIRED_FLOAT)
5089 virtual_stack_registers_memory_p (rtx op)
5093 if (GET_CODE (op) == REG)
5094 regnum = REGNO (op);
5096 else if (GET_CODE (op) == PLUS
5097 && GET_CODE (XEXP (op, 0)) == REG
5098 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5099 regnum = REGNO (XEXP (op, 0));
5104 return (regnum >= FIRST_VIRTUAL_REGISTER
5105 && regnum <= LAST_VIRTUAL_REGISTER);
5109 constant_pool_expr_p (rtx op)
5113 split_const (op, &base, &offset);
5114 return (GET_CODE (base) == SYMBOL_REF
5115 && CONSTANT_POOL_ADDRESS_P (base)
5116 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5119 static rtx tocrel_base, tocrel_offset;
5122 toc_relative_expr_p (rtx op)
5124 if (GET_CODE (op) != CONST)
5127 split_const (op, &tocrel_base, &tocrel_offset);
5128 return (GET_CODE (tocrel_base) == UNSPEC
5129 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5133 legitimate_constant_pool_address_p (const_rtx x, bool strict)
5136 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5137 && GET_CODE (XEXP (x, 0)) == REG
5138 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5139 || ((TARGET_MINIMAL_TOC
5140 || TARGET_CMODEL != CMODEL_SMALL)
5141 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5142 && toc_relative_expr_p (XEXP (x, 1)));
5146 legitimate_small_data_p (enum machine_mode mode, rtx x)
5148 return (DEFAULT_ABI == ABI_V4
5149 && !flag_pic && !TARGET_TOC
5150 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5151 && small_data_operand (x, mode));
5154 /* SPE offset addressing is limited to 5-bits worth of double words. */
5155 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5158 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5160 unsigned HOST_WIDE_INT offset, extra;
5162 if (GET_CODE (x) != PLUS)
5164 if (GET_CODE (XEXP (x, 0)) != REG)
5166 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5168 if (!reg_offset_addressing_ok_p (mode))
5169 return virtual_stack_registers_memory_p (x);
5170 if (legitimate_constant_pool_address_p (x, strict))
5172 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5175 offset = INTVAL (XEXP (x, 1));
5183 /* SPE vector modes. */
5184 return SPE_CONST_OFFSET_OK (offset);
5187 if (TARGET_E500_DOUBLE)
5188 return SPE_CONST_OFFSET_OK (offset);
5190 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5192 if (VECTOR_MEM_VSX_P (DFmode))
5197 /* On e500v2, we may have:
5199 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5201 Which gets addressed with evldd instructions. */
5202 if (TARGET_E500_DOUBLE)
5203 return SPE_CONST_OFFSET_OK (offset);
5205 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5207 else if (offset & 3)
5212 if (TARGET_E500_DOUBLE)
5213 return (SPE_CONST_OFFSET_OK (offset)
5214 && SPE_CONST_OFFSET_OK (offset + 8));
5218 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5220 else if (offset & 3)
5231 return (offset < 0x10000) && (offset + extra < 0x10000);
5235 legitimate_indexed_address_p (rtx x, int strict)
5239 if (GET_CODE (x) != PLUS)
5245 /* Recognize the rtl generated by reload which we know will later be
5246 replaced with proper base and index regs. */
5248 && reload_in_progress
5249 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5253 return (REG_P (op0) && REG_P (op1)
5254 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5255 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5256 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5257 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5261 avoiding_indexed_address_p (enum machine_mode mode)
5263 /* Avoid indexed addressing for modes that have non-indexed
5264 load/store instruction forms. */
5265 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5269 legitimate_indirect_address_p (rtx x, int strict)
5271 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5275 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5277 if (!TARGET_MACHO || !flag_pic
5278 || mode != SImode || GET_CODE (x) != MEM)
5282 if (GET_CODE (x) != LO_SUM)
5284 if (GET_CODE (XEXP (x, 0)) != REG)
5286 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5290 return CONSTANT_P (x);
5294 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5296 if (GET_CODE (x) != LO_SUM)
5298 if (GET_CODE (XEXP (x, 0)) != REG)
5300 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5302 /* Restrict addressing for DI because of our SUBREG hackery. */
5303 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5304 || mode == DDmode || mode == TDmode
5309 if (TARGET_ELF || TARGET_MACHO)
5311 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5315 if (GET_MODE_NUNITS (mode) != 1)
5317 if (GET_MODE_BITSIZE (mode) > 64
5318 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5319 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5320 && (mode == DFmode || mode == DDmode))))
5323 return CONSTANT_P (x);
5330 /* Try machine-dependent ways of modifying an illegitimate address
5331 to be legitimate. If we find one, return the new, valid address.
5332 This is used from only one place: `memory_address' in explow.c.
5334 OLDX is the address as it was before break_out_memory_refs was
5335 called. In some cases it is useful to look at this to decide what
5338 It is always safe for this function to do nothing. It exists to
5339 recognize opportunities to optimize the output.
5341 On RS/6000, first check for the sum of a register with a constant
5342 integer that is out of range. If so, generate code to add the
5343 constant with the low-order 16 bits masked to the register and force
5344 this result into another register (this can be done with `cau').
5345 Then generate an address of REG+(CONST&0xffff), allowing for the
5346 possibility of bit 16 being a one.
5348 Then check for the sum of a register and something not constant, try to
5349 load the other things into a register and return the sum. */
5352 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5353 enum machine_mode mode)
5355 unsigned int extra = 0;
5357 if (!reg_offset_addressing_ok_p (mode))
5359 if (virtual_stack_registers_memory_p (x))
5362 /* In theory we should not be seeing addresses of the form reg+0,
5363 but just in case it is generated, optimize it away. */
5364 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5365 return force_reg (Pmode, XEXP (x, 0));
5367 /* Make sure both operands are registers. */
5368 else if (GET_CODE (x) == PLUS)
5369 return gen_rtx_PLUS (Pmode,
5370 force_reg (Pmode, XEXP (x, 0)),
5371 force_reg (Pmode, XEXP (x, 1)));
5373 return force_reg (Pmode, x);
5375 if (GET_CODE (x) == SYMBOL_REF)
5377 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5379 return rs6000_legitimize_tls_address (x, model);
5389 if (!TARGET_POWERPC64)
5397 extra = TARGET_POWERPC64 ? 8 : 12;
5403 if (GET_CODE (x) == PLUS
5404 && GET_CODE (XEXP (x, 0)) == REG
5405 && GET_CODE (XEXP (x, 1)) == CONST_INT
5406 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5408 && !((TARGET_POWERPC64
5409 && (mode == DImode || mode == TImode)
5410 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5411 || SPE_VECTOR_MODE (mode)
5412 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5413 || mode == DImode || mode == DDmode
5414 || mode == TDmode))))
5416 HOST_WIDE_INT high_int, low_int;
5418 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5419 if (low_int >= 0x8000 - extra)
5421 high_int = INTVAL (XEXP (x, 1)) - low_int;
5422 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5423 GEN_INT (high_int)), 0);
5424 return plus_constant (sum, low_int);
5426 else if (GET_CODE (x) == PLUS
5427 && GET_CODE (XEXP (x, 0)) == REG
5428 && GET_CODE (XEXP (x, 1)) != CONST_INT
5429 && GET_MODE_NUNITS (mode) == 1
5430 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5432 || ((mode != DImode && mode != DFmode && mode != DDmode)
5433 || (TARGET_E500_DOUBLE && mode != DDmode)))
5434 && (TARGET_POWERPC64 || mode != DImode)
5435 && !avoiding_indexed_address_p (mode)
5440 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5441 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5443 else if (SPE_VECTOR_MODE (mode)
5444 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5445 || mode == DDmode || mode == TDmode
5446 || mode == DImode)))
5450 /* We accept [reg + reg] and [reg + OFFSET]. */
5452 if (GET_CODE (x) == PLUS)
5454 rtx op1 = XEXP (x, 0);
5455 rtx op2 = XEXP (x, 1);
5458 op1 = force_reg (Pmode, op1);
5460 if (GET_CODE (op2) != REG
5461 && (GET_CODE (op2) != CONST_INT
5462 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5463 || (GET_MODE_SIZE (mode) > 8
5464 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5465 op2 = force_reg (Pmode, op2);
5467 /* We can't always do [reg + reg] for these, because [reg +
5468 reg + offset] is not a legitimate addressing mode. */
5469 y = gen_rtx_PLUS (Pmode, op1, op2);
5471 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5472 return force_reg (Pmode, y);
5477 return force_reg (Pmode, x);
5483 && GET_CODE (x) != CONST_INT
5484 && GET_CODE (x) != CONST_DOUBLE
5486 && GET_MODE_NUNITS (mode) == 1
5487 && (GET_MODE_BITSIZE (mode) <= 32
5488 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5489 && (mode == DFmode || mode == DDmode))))
5491 rtx reg = gen_reg_rtx (Pmode);
5492 emit_insn (gen_elf_high (reg, x));
5493 return gen_rtx_LO_SUM (Pmode, reg, x);
5495 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5498 && ! MACHO_DYNAMIC_NO_PIC_P
5500 && GET_CODE (x) != CONST_INT
5501 && GET_CODE (x) != CONST_DOUBLE
5503 && GET_MODE_NUNITS (mode) == 1
5504 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5505 || (mode != DFmode && mode != DDmode))
5509 rtx reg = gen_reg_rtx (Pmode);
5510 emit_insn (gen_macho_high (reg, x));
5511 return gen_rtx_LO_SUM (Pmode, reg, x);
5514 && GET_CODE (x) == SYMBOL_REF
5515 && constant_pool_expr_p (x)
5516 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5518 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5519 return create_TOC_reference (x, reg);
5525 /* Debug version of rs6000_legitimize_address. */
5527 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5533 ret = rs6000_legitimize_address (x, oldx, mode);
5534 insns = get_insns ();
5540 "\nrs6000_legitimize_address: mode %s, old code %s, "
5541 "new code %s, modified\n",
5542 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5543 GET_RTX_NAME (GET_CODE (ret)));
5545 fprintf (stderr, "Original address:\n");
5548 fprintf (stderr, "oldx:\n");
5551 fprintf (stderr, "New address:\n");
5556 fprintf (stderr, "Insns added:\n");
5557 debug_rtx_list (insns, 20);
5563 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5564 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5575 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5576 We need to emit DTP-relative relocations. */
5579 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5584 fputs ("\t.long\t", file);
5587 fputs (DOUBLE_INT_ASM_OP, file);
5592 output_addr_const (file, x);
5593 fputs ("@dtprel+0x8000", file);
5596 /* In the name of slightly smaller debug output, and to cater to
5597 general assembler lossage, recognize various UNSPEC sequences
5598 and turn them back into a direct symbol reference. */
5601 rs6000_delegitimize_address (rtx orig_x)
5605 orig_x = delegitimize_mem_from_attrs (orig_x);
5610 if ((GET_CODE (x) == PLUS
5611 || GET_CODE (x) == LO_SUM)
5612 && GET_CODE (XEXP (x, 0)) == REG
5613 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5614 || TARGET_MINIMAL_TOC
5615 || TARGET_CMODEL != CMODEL_SMALL)
5616 && GET_CODE (XEXP (x, 1)) == CONST)
5618 y = XEXP (XEXP (x, 1), 0);
5619 if (GET_CODE (y) == UNSPEC
5620 && XINT (y, 1) == UNSPEC_TOCREL)
5622 y = XVECEXP (y, 0, 0);
5623 if (!MEM_P (orig_x))
5626 return replace_equiv_address_nv (orig_x, y);
5631 && GET_CODE (orig_x) == LO_SUM
5632 && GET_CODE (XEXP (x, 1)) == CONST)
5634 y = XEXP (XEXP (x, 1), 0);
5635 if (GET_CODE (y) == UNSPEC
5636 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5637 return XVECEXP (y, 0, 0);
5643 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5645 static GTY(()) rtx rs6000_tls_symbol;
5647 rs6000_tls_get_addr (void)
5649 if (!rs6000_tls_symbol)
5650 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5652 return rs6000_tls_symbol;
5655 /* Construct the SYMBOL_REF for TLS GOT references. */
5657 static GTY(()) rtx rs6000_got_symbol;
5659 rs6000_got_sym (void)
5661 if (!rs6000_got_symbol)
5663 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5664 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5665 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5668 return rs6000_got_symbol;
5671 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5672 this (thread-local) address. */
5675 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5679 dest = gen_reg_rtx (Pmode);
5680 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5686 tlsreg = gen_rtx_REG (Pmode, 13);
5687 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5691 tlsreg = gen_rtx_REG (Pmode, 2);
5692 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5696 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5700 tmp = gen_reg_rtx (Pmode);
5703 tlsreg = gen_rtx_REG (Pmode, 13);
5704 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5708 tlsreg = gen_rtx_REG (Pmode, 2);
5709 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5713 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5715 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5720 rtx r3, got, tga, tmp1, tmp2, call_insn;
5722 /* We currently use relocations like @got@tlsgd for tls, which
5723 means the linker will handle allocation of tls entries, placing
5724 them in the .got section. So use a pointer to the .got section,
5725 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5726 or to secondary GOT sections used by 32-bit -fPIC. */
5728 got = gen_rtx_REG (Pmode, 2);
5732 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5735 rtx gsym = rs6000_got_sym ();
5736 got = gen_reg_rtx (Pmode);
5738 rs6000_emit_move (got, gsym, Pmode);
5743 tmp1 = gen_reg_rtx (Pmode);
5744 tmp2 = gen_reg_rtx (Pmode);
5745 mem = gen_const_mem (Pmode, tmp1);
5746 lab = gen_label_rtx ();
5747 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
5748 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
5749 emit_move_insn (tmp2, mem);
5750 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
5751 set_unique_reg_note (last, REG_EQUAL, gsym);
5756 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5758 r3 = gen_rtx_REG (Pmode, 3);
5759 tga = rs6000_tls_get_addr ();
5760 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
5762 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5763 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5764 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5765 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5766 else if (DEFAULT_ABI == ABI_V4)
5767 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5770 call_insn = last_call_insn ();
5771 PATTERN (call_insn) = insn;
5772 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5773 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5774 pic_offset_table_rtx);
5776 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5778 r3 = gen_rtx_REG (Pmode, 3);
5779 tga = rs6000_tls_get_addr ();
5780 tmp1 = gen_reg_rtx (Pmode);
5781 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
5783 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5784 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5785 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5786 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5787 else if (DEFAULT_ABI == ABI_V4)
5788 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5791 call_insn = last_call_insn ();
5792 PATTERN (call_insn) = insn;
5793 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5794 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5795 pic_offset_table_rtx);
5797 if (rs6000_tls_size == 16)
5800 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5802 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5804 else if (rs6000_tls_size == 32)
5806 tmp2 = gen_reg_rtx (Pmode);
5808 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5810 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5813 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5815 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5819 tmp2 = gen_reg_rtx (Pmode);
5821 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5823 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5825 insn = gen_rtx_SET (Pmode, dest,
5826 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5832 /* IE, or 64-bit offset LE. */
5833 tmp2 = gen_reg_rtx (Pmode);
5835 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5837 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5840 insn = gen_tls_tls_64 (dest, tmp2, addr);
5842 insn = gen_tls_tls_32 (dest, tmp2, addr);
5850 /* Return 1 if X contains a thread-local symbol. */
5853 rs6000_tls_referenced_p (rtx x)
5855 if (! TARGET_HAVE_TLS)
5858 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5861 /* Return 1 if *X is a thread-local symbol. This is the same as
5862 rs6000_tls_symbol_ref except for the type of the unused argument. */
5865 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5867 return RS6000_SYMBOL_REF_TLS_P (*x);
5870 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5871 replace the input X, or the original X if no replacement is called for.
5872 The output parameter *WIN is 1 if the calling macro should goto WIN,
5875 For RS/6000, we wish to handle large displacements off a base
5876 register by splitting the addend across an addiu/addis and the mem insn.
5877 This cuts number of extra insns needed from 3 to 1.
5879 On Darwin, we use this to generate code for floating point constants.
5880 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5881 The Darwin code is inside #if TARGET_MACHO because only then are the
5882 machopic_* functions defined. */
5884 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5885 int opnum, int type,
5886 int ind_levels ATTRIBUTE_UNUSED, int *win)
5888 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5890 /* We must recognize output that we have already generated ourselves. */
5891 if (GET_CODE (x) == PLUS
5892 && GET_CODE (XEXP (x, 0)) == PLUS
5893 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5894 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5895 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5897 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5898 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5899 opnum, (enum reload_type)type);
5905 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5906 && GET_CODE (x) == LO_SUM
5907 && GET_CODE (XEXP (x, 0)) == PLUS
5908 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5909 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5910 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5911 && machopic_operand_p (XEXP (x, 1)))
5913 /* Result of previous invocation of this function on Darwin
5914 floating point constant. */
5915 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5916 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5917 opnum, (enum reload_type)type);
5923 if (TARGET_CMODEL != CMODEL_SMALL
5924 && GET_CODE (x) == LO_SUM
5925 && GET_CODE (XEXP (x, 0)) == PLUS
5926 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5927 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
5928 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5929 && GET_CODE (XEXP (x, 1)) == CONST
5930 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
5931 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
5932 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
5934 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5935 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5936 opnum, (enum reload_type) type);
5941 /* Force ld/std non-word aligned offset into base register by wrapping
5943 if (GET_CODE (x) == PLUS
5944 && GET_CODE (XEXP (x, 0)) == REG
5945 && REGNO (XEXP (x, 0)) < 32
5946 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5947 && GET_CODE (XEXP (x, 1)) == CONST_INT
5949 && (INTVAL (XEXP (x, 1)) & 3) != 0
5950 && VECTOR_MEM_NONE_P (mode)
5951 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5952 && TARGET_POWERPC64)
5954 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5955 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5956 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5957 opnum, (enum reload_type) type);
5962 if (GET_CODE (x) == PLUS
5963 && GET_CODE (XEXP (x, 0)) == REG
5964 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5965 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5966 && GET_CODE (XEXP (x, 1)) == CONST_INT
5968 && !SPE_VECTOR_MODE (mode)
5969 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5970 || mode == DDmode || mode == TDmode
5972 && VECTOR_MEM_NONE_P (mode))
5974 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5975 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5977 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5979 /* Check for 32-bit overflow. */
5980 if (high + low != val)
5986 /* Reload the high part into a base reg; leave the low part
5987 in the mem directly. */
5989 x = gen_rtx_PLUS (GET_MODE (x),
5990 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5994 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5995 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5996 opnum, (enum reload_type)type);
6001 if (GET_CODE (x) == SYMBOL_REF
6003 && VECTOR_MEM_NONE_P (mode)
6004 && !SPE_VECTOR_MODE (mode)
6006 && DEFAULT_ABI == ABI_DARWIN
6007 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6009 && DEFAULT_ABI == ABI_V4
6012 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6013 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6017 && (mode != DImode || TARGET_POWERPC64)
6018 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6019 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6024 rtx offset = machopic_gen_offset (x);
6025 x = gen_rtx_LO_SUM (GET_MODE (x),
6026 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6027 gen_rtx_HIGH (Pmode, offset)), offset);
6031 x = gen_rtx_LO_SUM (GET_MODE (x),
6032 gen_rtx_HIGH (Pmode, x), x);
6034 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6035 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6036 opnum, (enum reload_type)type);
6041 /* Reload an offset address wrapped by an AND that represents the
6042 masking of the lower bits. Strip the outer AND and let reload
6043 convert the offset address into an indirect address. For VSX,
6044 force reload to create the address with an AND in a separate
6045 register, because we can't guarantee an altivec register will
6047 if (VECTOR_MEM_ALTIVEC_P (mode)
6048 && GET_CODE (x) == AND
6049 && GET_CODE (XEXP (x, 0)) == PLUS
6050 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6051 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6052 && GET_CODE (XEXP (x, 1)) == CONST_INT
6053 && INTVAL (XEXP (x, 1)) == -16)
6062 && GET_CODE (x) == SYMBOL_REF
6063 && constant_pool_expr_p (x)
6064 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6066 x = create_TOC_reference (x, NULL_RTX);
6067 if (TARGET_CMODEL != CMODEL_SMALL)
6068 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6069 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6070 opnum, (enum reload_type) type);
6078 /* Debug version of rs6000_legitimize_reload_address. */
6080 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6081 int opnum, int type,
6082 int ind_levels, int *win)
6084 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6087 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6088 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6089 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6093 fprintf (stderr, "Same address returned\n");
6095 fprintf (stderr, "NULL returned\n");
6098 fprintf (stderr, "New address:\n");
6105 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6106 that is a valid memory address for an instruction.
6107 The MODE argument is the machine mode for the MEM expression
6108 that wants to use this address.
6110 On the RS/6000, there are four valid address: a SYMBOL_REF that
6111 refers to a constant pool entry of an address (or the sum of it
6112 plus a constant), a short (16-bit signed) constant plus a register,
6113 the sum of two registers, or a register indirect, possibly with an
6114 auto-increment. For DFmode, DDmode and DImode with a constant plus
6115 register, we must ensure that both words are addressable or PowerPC64
6116 with offset word aligned.
6118 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6119 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6120 because adjacent memory cells are accessed by adding word-sized offsets
6121 during assembly output. */
6123 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6125 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6127 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6128 if (VECTOR_MEM_ALTIVEC_P (mode)
6129 && GET_CODE (x) == AND
6130 && GET_CODE (XEXP (x, 1)) == CONST_INT
6131 && INTVAL (XEXP (x, 1)) == -16)
6134 if (RS6000_SYMBOL_REF_TLS_P (x))
6136 if (legitimate_indirect_address_p (x, reg_ok_strict))
6138 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6139 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6140 && !SPE_VECTOR_MODE (mode)
6143 /* Restrict addressing for DI because of our SUBREG hackery. */
6144 && !(TARGET_E500_DOUBLE
6145 && (mode == DFmode || mode == DDmode || mode == DImode))
6147 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6149 if (virtual_stack_registers_memory_p (x))
6151 if (reg_offset_p && legitimate_small_data_p (mode, x))
6153 if (reg_offset_p && legitimate_constant_pool_address_p (x, reg_ok_strict))
6155 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6158 && GET_CODE (x) == PLUS
6159 && GET_CODE (XEXP (x, 0)) == REG
6160 && (XEXP (x, 0) == virtual_stack_vars_rtx
6161 || XEXP (x, 0) == arg_pointer_rtx)
6162 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6164 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6169 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6171 || (mode != DFmode && mode != DDmode)
6172 || (TARGET_E500_DOUBLE && mode != DDmode))
6173 && (TARGET_POWERPC64 || mode != DImode)
6174 && !avoiding_indexed_address_p (mode)
6175 && legitimate_indexed_address_p (x, reg_ok_strict))
6177 if (GET_CODE (x) == PRE_MODIFY
6181 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6183 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6184 && (TARGET_POWERPC64 || mode != DImode)
6185 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6186 && !SPE_VECTOR_MODE (mode)
6187 /* Restrict addressing for DI because of our SUBREG hackery. */
6188 && !(TARGET_E500_DOUBLE
6189 && (mode == DFmode || mode == DDmode || mode == DImode))
6191 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6192 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6193 || (!avoiding_indexed_address_p (mode)
6194 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6195 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6197 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6202 /* Debug version of rs6000_legitimate_address_p. */
6204 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6207 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6209 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6210 "strict = %d, code = %s\n",
6211 ret ? "true" : "false",
6212 GET_MODE_NAME (mode),
6214 GET_RTX_NAME (GET_CODE (x)));
6220 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6223 rs6000_mode_dependent_address_p (const_rtx addr)
6225 return rs6000_mode_dependent_address_ptr (addr);
6228 /* Go to LABEL if ADDR (a legitimate address expression)
6229 has an effect that depends on the machine mode it is used for.
6231 On the RS/6000 this is true of all integral offsets (since AltiVec
6232 and VSX modes don't allow them) or is a pre-increment or decrement.
6234 ??? Except that due to conceptual problems in offsettable_address_p
6235 we can't really report the problems of integral offsets. So leave
6236 this assuming that the adjustable offset must be valid for the
6237 sub-words of a TFmode operand, which is what we had before. */
6240 rs6000_mode_dependent_address (const_rtx addr)
6242 switch (GET_CODE (addr))
6245 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6246 is considered a legitimate address before reload, so there
6247 are no offset restrictions in that case. Note that this
6248 condition is safe in strict mode because any address involving
6249 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6250 been rejected as illegitimate. */
6251 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6252 && XEXP (addr, 0) != arg_pointer_rtx
6253 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6255 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6256 return val + 12 + 0x8000 >= 0x10000;
6261 /* Anything in the constant pool is sufficiently aligned that
6262 all bytes have the same high part address. */
6263 return !legitimate_constant_pool_address_p (addr, false);
6265 /* Auto-increment cases are now treated generically in recog.c. */
6267 return TARGET_UPDATE;
6269 /* AND is only allowed in Altivec loads. */
6280 /* Debug version of rs6000_mode_dependent_address. */
6282 rs6000_debug_mode_dependent_address (const_rtx addr)
6284 bool ret = rs6000_mode_dependent_address (addr);
6286 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6287 ret ? "true" : "false");
6293 /* Implement FIND_BASE_TERM. */
6296 rs6000_find_base_term (rtx op)
6300 split_const (op, &base, &offset);
6301 if (GET_CODE (base) == UNSPEC)
6302 switch (XINT (base, 1))
6305 case UNSPEC_MACHOPIC_OFFSET:
6306 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6307 for aliasing purposes. */
6308 return XVECEXP (base, 0, 0);
6314 /* More elaborate version of recog's offsettable_memref_p predicate
6315 that works around the ??? note of rs6000_mode_dependent_address.
6316 In particular it accepts
6318 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6320 in 32-bit mode, that the recog predicate rejects. */
6323 rs6000_offsettable_memref_p (rtx op)
6328 /* First mimic offsettable_memref_p. */
6329 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6332 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6333 the latter predicate knows nothing about the mode of the memory
6334 reference and, therefore, assumes that it is the largest supported
6335 mode (TFmode). As a consequence, legitimate offsettable memory
6336 references are rejected. rs6000_legitimate_offset_address_p contains
6337 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6338 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6341 /* Change register usage conditional on target flags. */
6343 rs6000_conditional_register_usage (void)
6347 /* Set MQ register fixed (already call_used) if not POWER
6348 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6353 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6355 fixed_regs[13] = call_used_regs[13]
6356 = call_really_used_regs[13] = 1;
6358 /* Conditionally disable FPRs. */
6359 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6360 for (i = 32; i < 64; i++)
6361 fixed_regs[i] = call_used_regs[i]
6362 = call_really_used_regs[i] = 1;
6364 /* The TOC register is not killed across calls in a way that is
6365 visible to the compiler. */
6366 if (DEFAULT_ABI == ABI_AIX)
6367 call_really_used_regs[2] = 0;
6369 if (DEFAULT_ABI == ABI_V4
6370 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6372 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6374 if (DEFAULT_ABI == ABI_V4
6375 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6377 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6378 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6379 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6381 if (DEFAULT_ABI == ABI_DARWIN
6382 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6383 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6384 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6385 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6387 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6388 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6389 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6393 global_regs[SPEFSCR_REGNO] = 1;
6394 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6395 registers in prologues and epilogues. We no longer use r14
6396 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6397 pool for link-compatibility with older versions of GCC. Once
6398 "old" code has died out, we can return r14 to the allocation
6401 = call_used_regs[14]
6402 = call_really_used_regs[14] = 1;
6405 if (!TARGET_ALTIVEC && !TARGET_VSX)
6407 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6408 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6409 call_really_used_regs[VRSAVE_REGNO] = 1;
6412 if (TARGET_ALTIVEC || TARGET_VSX)
6413 global_regs[VSCR_REGNO] = 1;
6415 if (TARGET_ALTIVEC_ABI)
6417 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6418 call_used_regs[i] = call_really_used_regs[i] = 1;
6420 /* AIX reserves VR20:31 in non-extended ABI mode. */
6422 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6423 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6427 /* Try to output insns to set TARGET equal to the constant C if it can
6428 be done in less than N insns. Do all computations in MODE.
6429 Returns the place where the output has been placed if it can be
6430 done and the insns have been emitted. If it would take more than N
6431 insns, zero is returned and no insns and emitted. */
6434 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6435 rtx source, int n ATTRIBUTE_UNUSED)
6437 rtx result, insn, set;
6438 HOST_WIDE_INT c0, c1;
6445 dest = gen_reg_rtx (mode);
6446 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6450 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6452 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6453 GEN_INT (INTVAL (source)
6454 & (~ (HOST_WIDE_INT) 0xffff))));
6455 emit_insn (gen_rtx_SET (VOIDmode, dest,
6456 gen_rtx_IOR (SImode, copy_rtx (result),
6457 GEN_INT (INTVAL (source) & 0xffff))));
6462 switch (GET_CODE (source))
6465 c0 = INTVAL (source);
6470 #if HOST_BITS_PER_WIDE_INT >= 64
6471 c0 = CONST_DOUBLE_LOW (source);
6474 c0 = CONST_DOUBLE_LOW (source);
6475 c1 = CONST_DOUBLE_HIGH (source);
6483 result = rs6000_emit_set_long_const (dest, c0, c1);
6490 insn = get_last_insn ();
6491 set = single_set (insn);
6492 if (! CONSTANT_P (SET_SRC (set)))
6493 set_unique_reg_note (insn, REG_EQUAL, source);
6498 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6499 fall back to a straight forward decomposition. We do this to avoid
6500 exponential run times encountered when looking for longer sequences
6501 with rs6000_emit_set_const. */
6503 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6505 if (!TARGET_POWERPC64)
6507 rtx operand1, operand2;
6509 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6511 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6513 emit_move_insn (operand1, GEN_INT (c1));
6514 emit_move_insn (operand2, GEN_INT (c2));
6518 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6521 ud2 = (c1 & 0xffff0000) >> 16;
6522 #if HOST_BITS_PER_WIDE_INT >= 64
6526 ud4 = (c2 & 0xffff0000) >> 16;
6528 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6529 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6532 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6534 emit_move_insn (dest, GEN_INT (ud1));
6537 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6538 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6541 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6544 emit_move_insn (dest, GEN_INT (ud2 << 16));
6546 emit_move_insn (copy_rtx (dest),
6547 gen_rtx_IOR (DImode, copy_rtx (dest),
6550 else if (ud3 == 0 && ud4 == 0)
6552 gcc_assert (ud2 & 0x8000);
6553 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6556 emit_move_insn (copy_rtx (dest),
6557 gen_rtx_IOR (DImode, copy_rtx (dest),
6559 emit_move_insn (copy_rtx (dest),
6560 gen_rtx_ZERO_EXTEND (DImode,
6561 gen_lowpart (SImode,
6564 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6565 || (ud4 == 0 && ! (ud3 & 0x8000)))
6568 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6571 emit_move_insn (dest, GEN_INT (ud3 << 16));
6574 emit_move_insn (copy_rtx (dest),
6575 gen_rtx_IOR (DImode, copy_rtx (dest),
6577 emit_move_insn (copy_rtx (dest),
6578 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6581 emit_move_insn (copy_rtx (dest),
6582 gen_rtx_IOR (DImode, copy_rtx (dest),
6588 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6591 emit_move_insn (dest, GEN_INT (ud4 << 16));
6594 emit_move_insn (copy_rtx (dest),
6595 gen_rtx_IOR (DImode, copy_rtx (dest),
6598 emit_move_insn (copy_rtx (dest),
6599 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6602 emit_move_insn (copy_rtx (dest),
6603 gen_rtx_IOR (DImode, copy_rtx (dest),
6604 GEN_INT (ud2 << 16)));
6606 emit_move_insn (copy_rtx (dest),
6607 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6613 /* Helper for the following. Get rid of [r+r] memory refs
6614 in cases where it won't work (TImode, TFmode, TDmode). */
6617 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6619 if (reload_in_progress)
6622 if (GET_CODE (operands[0]) == MEM
6623 && GET_CODE (XEXP (operands[0], 0)) != REG
6624 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), false))
6626 = replace_equiv_address (operands[0],
6627 copy_addr_to_reg (XEXP (operands[0], 0)));
6629 if (GET_CODE (operands[1]) == MEM
6630 && GET_CODE (XEXP (operands[1], 0)) != REG
6631 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), false))
6633 = replace_equiv_address (operands[1],
6634 copy_addr_to_reg (XEXP (operands[1], 0)));
6637 /* Emit a move from SOURCE to DEST in mode MODE. */
6639 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6643 operands[1] = source;
6645 if (TARGET_DEBUG_ADDR)
6648 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6649 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6650 GET_MODE_NAME (mode),
6653 can_create_pseudo_p ());
6655 fprintf (stderr, "source:\n");
6659 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6660 if (GET_CODE (operands[1]) == CONST_DOUBLE
6661 && ! FLOAT_MODE_P (mode)
6662 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6664 /* FIXME. This should never happen. */
6665 /* Since it seems that it does, do the safe thing and convert
6667 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6669 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6670 || FLOAT_MODE_P (mode)
6671 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6672 || CONST_DOUBLE_LOW (operands[1]) < 0)
6673 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6674 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6676 /* Check if GCC is setting up a block move that will end up using FP
6677 registers as temporaries. We must make sure this is acceptable. */
6678 if (GET_CODE (operands[0]) == MEM
6679 && GET_CODE (operands[1]) == MEM
6681 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6682 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6683 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6684 ? 32 : MEM_ALIGN (operands[0])))
6685 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6687 : MEM_ALIGN (operands[1]))))
6688 && ! MEM_VOLATILE_P (operands [0])
6689 && ! MEM_VOLATILE_P (operands [1]))
6691 emit_move_insn (adjust_address (operands[0], SImode, 0),
6692 adjust_address (operands[1], SImode, 0));
6693 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6694 adjust_address (copy_rtx (operands[1]), SImode, 4));
6698 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6699 && !gpc_reg_operand (operands[1], mode))
6700 operands[1] = force_reg (mode, operands[1]);
6702 if (mode == SFmode && ! TARGET_POWERPC
6703 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6704 && GET_CODE (operands[0]) == MEM)
6708 if (reload_in_progress || reload_completed)
6709 regnum = true_regnum (operands[1]);
6710 else if (GET_CODE (operands[1]) == REG)
6711 regnum = REGNO (operands[1]);
6715 /* If operands[1] is a register, on POWER it may have
6716 double-precision data in it, so truncate it to single
6718 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6721 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6722 : gen_reg_rtx (mode));
6723 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6724 operands[1] = newreg;
6728 /* Recognize the case where operand[1] is a reference to thread-local
6729 data and load its address to a register. */
6730 if (rs6000_tls_referenced_p (operands[1]))
6732 enum tls_model model;
6733 rtx tmp = operands[1];
6736 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6738 addend = XEXP (XEXP (tmp, 0), 1);
6739 tmp = XEXP (XEXP (tmp, 0), 0);
6742 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6743 model = SYMBOL_REF_TLS_MODEL (tmp);
6744 gcc_assert (model != 0);
6746 tmp = rs6000_legitimize_tls_address (tmp, model);
6749 tmp = gen_rtx_PLUS (mode, tmp, addend);
6750 tmp = force_operand (tmp, operands[0]);
6755 /* Handle the case where reload calls us with an invalid address. */
6756 if (reload_in_progress && mode == Pmode
6757 && (! general_operand (operands[1], mode)
6758 || ! nonimmediate_operand (operands[0], mode)))
6761 /* 128-bit constant floating-point values on Darwin should really be
6762 loaded as two parts. */
6763 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6764 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6766 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6767 know how to get a DFmode SUBREG of a TFmode. */
6768 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6769 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6770 simplify_gen_subreg (imode, operands[1], mode, 0),
6772 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6773 GET_MODE_SIZE (imode)),
6774 simplify_gen_subreg (imode, operands[1], mode,
6775 GET_MODE_SIZE (imode)),
6780 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6781 cfun->machine->sdmode_stack_slot =
6782 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6784 if (reload_in_progress
6786 && MEM_P (operands[0])
6787 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6788 && REG_P (operands[1]))
6790 if (FP_REGNO_P (REGNO (operands[1])))
6792 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6793 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6794 emit_insn (gen_movsd_store (mem, operands[1]));
6796 else if (INT_REGNO_P (REGNO (operands[1])))
6798 rtx mem = adjust_address_nv (operands[0], mode, 4);
6799 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6800 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6806 if (reload_in_progress
6808 && REG_P (operands[0])
6809 && MEM_P (operands[1])
6810 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6812 if (FP_REGNO_P (REGNO (operands[0])))
6814 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6815 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6816 emit_insn (gen_movsd_load (operands[0], mem));
6818 else if (INT_REGNO_P (REGNO (operands[0])))
6820 rtx mem = adjust_address_nv (operands[1], mode, 4);
6821 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6822 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6829 /* FIXME: In the long term, this switch statement should go away
6830 and be replaced by a sequence of tests based on things like
6836 if (CONSTANT_P (operands[1])
6837 && GET_CODE (operands[1]) != CONST_INT)
6838 operands[1] = force_const_mem (mode, operands[1]);
6843 rs6000_eliminate_indexed_memrefs (operands);
6850 if (CONSTANT_P (operands[1])
6851 && ! easy_fp_constant (operands[1], mode))
6852 operands[1] = force_const_mem (mode, operands[1]);
6865 if (CONSTANT_P (operands[1])
6866 && !easy_vector_constant (operands[1], mode))
6867 operands[1] = force_const_mem (mode, operands[1]);
6872 /* Use default pattern for address of ELF small data */
6875 && DEFAULT_ABI == ABI_V4
6876 && (GET_CODE (operands[1]) == SYMBOL_REF
6877 || GET_CODE (operands[1]) == CONST)
6878 && small_data_operand (operands[1], mode))
6880 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6884 if (DEFAULT_ABI == ABI_V4
6885 && mode == Pmode && mode == SImode
6886 && flag_pic == 1 && got_operand (operands[1], mode))
6888 emit_insn (gen_movsi_got (operands[0], operands[1]));
6892 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6896 && CONSTANT_P (operands[1])
6897 && GET_CODE (operands[1]) != HIGH
6898 && GET_CODE (operands[1]) != CONST_INT)
6900 rtx target = (!can_create_pseudo_p ()
6902 : gen_reg_rtx (mode));
6904 /* If this is a function address on -mcall-aixdesc,
6905 convert it to the address of the descriptor. */
6906 if (DEFAULT_ABI == ABI_AIX
6907 && GET_CODE (operands[1]) == SYMBOL_REF
6908 && XSTR (operands[1], 0)[0] == '.')
6910 const char *name = XSTR (operands[1], 0);
6912 while (*name == '.')
6914 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6915 CONSTANT_POOL_ADDRESS_P (new_ref)
6916 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6917 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6918 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6919 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6920 operands[1] = new_ref;
6923 if (DEFAULT_ABI == ABI_DARWIN)
6926 if (MACHO_DYNAMIC_NO_PIC_P)
6928 /* Take care of any required data indirection. */
6929 operands[1] = rs6000_machopic_legitimize_pic_address (
6930 operands[1], mode, operands[0]);
6931 if (operands[0] != operands[1])
6932 emit_insn (gen_rtx_SET (VOIDmode,
6933 operands[0], operands[1]));
6937 emit_insn (gen_macho_high (target, operands[1]));
6938 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6942 emit_insn (gen_elf_high (target, operands[1]));
6943 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6947 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6948 and we have put it in the TOC, we just need to make a TOC-relative
6951 && GET_CODE (operands[1]) == SYMBOL_REF
6952 && constant_pool_expr_p (operands[1])
6953 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6954 get_pool_mode (operands[1])))
6957 if (TARGET_CMODEL != CMODEL_SMALL)
6959 if (can_create_pseudo_p ())
6960 reg = gen_reg_rtx (Pmode);
6964 operands[1] = create_TOC_reference (operands[1], reg);
6966 else if (mode == Pmode
6967 && CONSTANT_P (operands[1])
6968 && ((GET_CODE (operands[1]) != CONST_INT
6969 && ! easy_fp_constant (operands[1], mode))
6970 || (GET_CODE (operands[1]) == CONST_INT
6971 && (num_insns_constant (operands[1], mode)
6972 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
6973 || (GET_CODE (operands[0]) == REG
6974 && FP_REGNO_P (REGNO (operands[0]))))
6975 && GET_CODE (operands[1]) != HIGH
6976 && ! legitimate_constant_pool_address_p (operands[1], false)
6977 && ! toc_relative_expr_p (operands[1])
6978 && (TARGET_CMODEL == CMODEL_SMALL
6979 || can_create_pseudo_p ()
6980 || (REG_P (operands[0])
6981 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
6985 /* Darwin uses a special PIC legitimizer. */
6986 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
6989 rs6000_machopic_legitimize_pic_address (operands[1], mode,
6991 if (operands[0] != operands[1])
6992 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6997 /* If we are to limit the number of things we put in the TOC and
6998 this is a symbol plus a constant we can add in one insn,
6999 just put the symbol in the TOC and add the constant. Don't do
7000 this if reload is in progress. */
7001 if (GET_CODE (operands[1]) == CONST
7002 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7003 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7004 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7005 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7006 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7007 && ! side_effects_p (operands[0]))
7010 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7011 rtx other = XEXP (XEXP (operands[1], 0), 1);
7013 sym = force_reg (mode, sym);
7014 emit_insn (gen_add3_insn (operands[0], sym, other));
7018 operands[1] = force_const_mem (mode, operands[1]);
7021 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7022 && constant_pool_expr_p (XEXP (operands[1], 0))
7023 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7024 get_pool_constant (XEXP (operands[1], 0)),
7025 get_pool_mode (XEXP (operands[1], 0))))
7029 if (TARGET_CMODEL != CMODEL_SMALL)
7031 if (can_create_pseudo_p ())
7032 reg = gen_reg_rtx (Pmode);
7036 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7037 operands[1] = gen_const_mem (mode, tocref);
7038 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7044 rs6000_eliminate_indexed_memrefs (operands);
7048 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7050 gen_rtx_SET (VOIDmode,
7051 operands[0], operands[1]),
7052 gen_rtx_CLOBBER (VOIDmode,
7053 gen_rtx_SCRATCH (SImode)))));
7059 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7062 /* Above, we may have called force_const_mem which may have returned
7063 an invalid address. If we can, fix this up; otherwise, reload will
7064 have to deal with it. */
7065 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7066 operands[1] = validize_mem (operands[1]);
7069 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7072 /* Nonzero if we can use a floating-point register to pass this arg. */
7073 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7074 (SCALAR_FLOAT_MODE_P (MODE) \
7075 && (CUM)->fregno <= FP_ARG_MAX_REG \
7076 && TARGET_HARD_FLOAT && TARGET_FPRS)
7078 /* Nonzero if we can use an AltiVec register to pass this arg. */
7079 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7080 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7081 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7082 && TARGET_ALTIVEC_ABI \
7085 /* Return a nonzero value to say to return the function value in
7086 memory, just as large structures are always returned. TYPE will be
7087 the data type of the value, and FNTYPE will be the type of the
7088 function doing the returning, or @code{NULL} for libcalls.
7090 The AIX ABI for the RS/6000 specifies that all structures are
7091 returned in memory. The Darwin ABI does the same. The SVR4 ABI
7092 specifies that structures <= 8 bytes are returned in r3/r4, but a
7093 draft put them in memory, and GCC used to implement the draft
7094 instead of the final standard. Therefore, aix_struct_return
7095 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7096 compatibility can change DRAFT_V4_STRUCT_RET to override the
7097 default, and -m switches get the final word. See
7098 rs6000_override_options for more details.
7100 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7101 long double support is enabled. These values are returned in memory.
7103 int_size_in_bytes returns -1 for variable size objects, which go in
7104 memory always. The cast to unsigned makes -1 > 8. */
7107 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7109 /* In the darwin64 abi, try to use registers for larger structs
7111 if (rs6000_darwin64_abi
7112 && TREE_CODE (type) == RECORD_TYPE
7113 && int_size_in_bytes (type) > 0)
7115 CUMULATIVE_ARGS valcum;
7119 valcum.fregno = FP_ARG_MIN_REG;
7120 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7121 /* Do a trial code generation as if this were going to be passed
7122 as an argument; if any part goes in memory, we return NULL. */
7123 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
7126 /* Otherwise fall through to more conventional ABI rules. */
7129 if (AGGREGATE_TYPE_P (type)
7130 && (aix_struct_return
7131 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7134 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7135 modes only exist for GCC vector types if -maltivec. */
7136 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7137 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7140 /* Return synthetic vectors in memory. */
7141 if (TREE_CODE (type) == VECTOR_TYPE
7142 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7144 static bool warned_for_return_big_vectors = false;
7145 if (!warned_for_return_big_vectors)
7147 warning (0, "GCC vector returned by reference: "
7148 "non-standard ABI extension with no compatibility guarantee");
7149 warned_for_return_big_vectors = true;
7154 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7160 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7161 for a call to a function whose data type is FNTYPE.
7162 For a library call, FNTYPE is 0.
7164 For incoming args we set the number of arguments in the prototype large
7165 so we never return a PARALLEL. */
7168 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7169 rtx libname ATTRIBUTE_UNUSED, int incoming,
7170 int libcall, int n_named_args)
7172 static CUMULATIVE_ARGS zero_cumulative;
7174 *cum = zero_cumulative;
7176 cum->fregno = FP_ARG_MIN_REG;
7177 cum->vregno = ALTIVEC_ARG_MIN_REG;
7178 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7179 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7180 ? CALL_LIBCALL : CALL_NORMAL);
7181 cum->sysv_gregno = GP_ARG_MIN_REG;
7182 cum->stdarg = fntype
7183 && (TYPE_ARG_TYPES (fntype) != 0
7184 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
7185 != void_type_node));
7187 cum->nargs_prototype = 0;
7188 if (incoming || cum->prototype)
7189 cum->nargs_prototype = n_named_args;
7191 /* Check for a longcall attribute. */
7192 if ((!fntype && rs6000_default_long_calls)
7194 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7195 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7196 cum->call_cookie |= CALL_LONG;
7198 if (TARGET_DEBUG_ARG)
7200 fprintf (stderr, "\ninit_cumulative_args:");
7203 tree ret_type = TREE_TYPE (fntype);
7204 fprintf (stderr, " ret code = %s,",
7205 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7208 if (cum->call_cookie & CALL_LONG)
7209 fprintf (stderr, " longcall,");
7211 fprintf (stderr, " proto = %d, nargs = %d\n",
7212 cum->prototype, cum->nargs_prototype);
7217 && TARGET_ALTIVEC_ABI
7218 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7220 error ("cannot return value in vector register because"
7221 " altivec instructions are disabled, use -maltivec"
7226 /* Return true if TYPE must be passed on the stack and not in registers. */
7229 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7231 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7232 return must_pass_in_stack_var_size (mode, type);
7234 return must_pass_in_stack_var_size_or_pad (mode, type);
7237 /* If defined, a C expression which determines whether, and in which
7238 direction, to pad out an argument with extra space. The value
7239 should be of type `enum direction': either `upward' to pad above
7240 the argument, `downward' to pad below, or `none' to inhibit
7243 For the AIX ABI structs are always stored left shifted in their
7247 function_arg_padding (enum machine_mode mode, const_tree type)
7249 #ifndef AGGREGATE_PADDING_FIXED
7250 #define AGGREGATE_PADDING_FIXED 0
7252 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7253 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7256 if (!AGGREGATE_PADDING_FIXED)
7258 /* GCC used to pass structures of the same size as integer types as
7259 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7260 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7261 passed padded downward, except that -mstrict-align further
7262 muddied the water in that multi-component structures of 2 and 4
7263 bytes in size were passed padded upward.
7265 The following arranges for best compatibility with previous
7266 versions of gcc, but removes the -mstrict-align dependency. */
7267 if (BYTES_BIG_ENDIAN)
7269 HOST_WIDE_INT size = 0;
7271 if (mode == BLKmode)
7273 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7274 size = int_size_in_bytes (type);
7277 size = GET_MODE_SIZE (mode);
7279 if (size == 1 || size == 2 || size == 4)
7285 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7287 if (type != 0 && AGGREGATE_TYPE_P (type))
7291 /* Fall back to the default. */
7292 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7295 /* If defined, a C expression that gives the alignment boundary, in bits,
7296 of an argument with the specified mode and type. If it is not defined,
7297 PARM_BOUNDARY is used for all arguments.
7299 V.4 wants long longs and doubles to be double word aligned. Just
7300 testing the mode size is a boneheaded way to do this as it means
7301 that other types such as complex int are also double word aligned.
7302 However, we're stuck with this because changing the ABI might break
7303 existing library interfaces.
7305 Doubleword align SPE vectors.
7306 Quadword align Altivec vectors.
7307 Quadword align large synthetic vector types. */
7310 function_arg_boundary (enum machine_mode mode, tree type)
7312 if (DEFAULT_ABI == ABI_V4
7313 && (GET_MODE_SIZE (mode) == 8
7314 || (TARGET_HARD_FLOAT
7316 && (mode == TFmode || mode == TDmode))))
7318 else if (SPE_VECTOR_MODE (mode)
7319 || (type && TREE_CODE (type) == VECTOR_TYPE
7320 && int_size_in_bytes (type) >= 8
7321 && int_size_in_bytes (type) < 16))
7323 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
7324 || (type && TREE_CODE (type) == VECTOR_TYPE
7325 && int_size_in_bytes (type) >= 16))
7327 else if (rs6000_darwin64_abi && mode == BLKmode
7328 && type && TYPE_ALIGN (type) > 64)
7331 return PARM_BOUNDARY;
7334 /* For a function parm of MODE and TYPE, return the starting word in
7335 the parameter area. NWORDS of the parameter area are already used. */
7338 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
7341 unsigned int parm_offset;
7343 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7344 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7345 return nwords + (-(parm_offset + nwords) & align);
7348 /* Compute the size (in words) of a function argument. */
7350 static unsigned long
7351 rs6000_arg_size (enum machine_mode mode, tree type)
7355 if (mode != BLKmode)
7356 size = GET_MODE_SIZE (mode);
7358 size = int_size_in_bytes (type);
7361 return (size + 3) >> 2;
7363 return (size + 7) >> 3;
7366 /* Use this to flush pending int fields. */
7369 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7370 HOST_WIDE_INT bitpos)
7372 unsigned int startbit, endbit;
7373 int intregs, intoffset;
7374 enum machine_mode mode;
7376 if (cum->intoffset == -1)
7379 intoffset = cum->intoffset;
7380 cum->intoffset = -1;
7382 if (intoffset % BITS_PER_WORD != 0)
7384 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7386 if (mode == BLKmode)
7388 /* We couldn't find an appropriate mode, which happens,
7389 e.g., in packed structs when there are 3 bytes to load.
7390 Back intoffset back to the beginning of the word in this
7392 intoffset = intoffset & -BITS_PER_WORD;
7396 startbit = intoffset & -BITS_PER_WORD;
7397 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7398 intregs = (endbit - startbit) / BITS_PER_WORD;
7399 cum->words += intregs;
7402 /* The darwin64 ABI calls for us to recurse down through structs,
7403 looking for elements passed in registers. Unfortunately, we have
7404 to track int register count here also because of misalignments
7405 in powerpc alignment mode. */
7408 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7410 HOST_WIDE_INT startbitpos)
7414 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7415 if (TREE_CODE (f) == FIELD_DECL)
7417 HOST_WIDE_INT bitpos = startbitpos;
7418 tree ftype = TREE_TYPE (f);
7419 enum machine_mode mode;
7420 if (ftype == error_mark_node)
7422 mode = TYPE_MODE (ftype);
7424 if (DECL_SIZE (f) != 0
7425 && host_integerp (bit_position (f), 1))
7426 bitpos += int_bit_position (f);
7428 /* ??? FIXME: else assume zero offset. */
7430 if (TREE_CODE (ftype) == RECORD_TYPE)
7431 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7432 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7434 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7435 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7436 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7438 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7440 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7444 else if (cum->intoffset == -1)
7445 cum->intoffset = bitpos;
7449 /* Update the data in CUM to advance over an argument
7450 of mode MODE and data type TYPE.
7451 (TYPE is null for libcalls where that information may not be available.)
7453 Note that for args passed by reference, function_arg will be called
7454 with MODE and TYPE set to that of the pointer to the arg, not the arg
7458 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7459 tree type, int named, int depth)
7463 /* Only tick off an argument if we're not recursing. */
7465 cum->nargs_prototype--;
7467 if (TARGET_ALTIVEC_ABI
7468 && (ALTIVEC_VECTOR_MODE (mode)
7469 || VSX_VECTOR_MODE (mode)
7470 || (type && TREE_CODE (type) == VECTOR_TYPE
7471 && int_size_in_bytes (type) == 16)))
7475 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7478 if (!TARGET_ALTIVEC)
7479 error ("cannot pass argument in vector register because"
7480 " altivec instructions are disabled, use -maltivec"
7483 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7484 even if it is going to be passed in a vector register.
7485 Darwin does the same for variable-argument functions. */
7486 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7487 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7497 /* Vector parameters must be 16-byte aligned. This places
7498 them at 2 mod 4 in terms of words in 32-bit mode, since
7499 the parameter save area starts at offset 24 from the
7500 stack. In 64-bit mode, they just have to start on an
7501 even word, since the parameter save area is 16-byte
7502 aligned. Space for GPRs is reserved even if the argument
7503 will be passed in memory. */
7505 align = (2 - cum->words) & 3;
7507 align = cum->words & 1;
7508 cum->words += align + rs6000_arg_size (mode, type);
7510 if (TARGET_DEBUG_ARG)
7512 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7514 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7515 cum->nargs_prototype, cum->prototype,
7516 GET_MODE_NAME (mode));
7520 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7522 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7525 else if (rs6000_darwin64_abi
7527 && TREE_CODE (type) == RECORD_TYPE
7528 && (size = int_size_in_bytes (type)) > 0)
7530 /* Variable sized types have size == -1 and are
7531 treated as if consisting entirely of ints.
7532 Pad to 16 byte boundary if needed. */
7533 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7534 && (cum->words % 2) != 0)
7536 /* For varargs, we can just go up by the size of the struct. */
7538 cum->words += (size + 7) / 8;
7541 /* It is tempting to say int register count just goes up by
7542 sizeof(type)/8, but this is wrong in a case such as
7543 { int; double; int; } [powerpc alignment]. We have to
7544 grovel through the fields for these too. */
7546 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7547 rs6000_darwin64_record_arg_advance_flush (cum,
7548 size * BITS_PER_UNIT);
7551 else if (DEFAULT_ABI == ABI_V4)
7553 if (TARGET_HARD_FLOAT && TARGET_FPRS
7554 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7555 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7556 || (mode == TFmode && !TARGET_IEEEQUAD)
7557 || mode == SDmode || mode == DDmode || mode == TDmode))
7559 /* _Decimal128 must use an even/odd register pair. This assumes
7560 that the register number is odd when fregno is odd. */
7561 if (mode == TDmode && (cum->fregno % 2) == 1)
7564 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7565 <= FP_ARG_V4_MAX_REG)
7566 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7569 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7570 if (mode == DFmode || mode == TFmode
7571 || mode == DDmode || mode == TDmode)
7572 cum->words += cum->words & 1;
7573 cum->words += rs6000_arg_size (mode, type);
7578 int n_words = rs6000_arg_size (mode, type);
7579 int gregno = cum->sysv_gregno;
7581 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7582 (r7,r8) or (r9,r10). As does any other 2 word item such
7583 as complex int due to a historical mistake. */
7585 gregno += (1 - gregno) & 1;
7587 /* Multi-reg args are not split between registers and stack. */
7588 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7590 /* Long long and SPE vectors are aligned on the stack.
7591 So are other 2 word items such as complex int due to
7592 a historical mistake. */
7594 cum->words += cum->words & 1;
7595 cum->words += n_words;
7598 /* Note: continuing to accumulate gregno past when we've started
7599 spilling to the stack indicates the fact that we've started
7600 spilling to the stack to expand_builtin_saveregs. */
7601 cum->sysv_gregno = gregno + n_words;
7604 if (TARGET_DEBUG_ARG)
7606 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7607 cum->words, cum->fregno);
7608 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7609 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7610 fprintf (stderr, "mode = %4s, named = %d\n",
7611 GET_MODE_NAME (mode), named);
7616 int n_words = rs6000_arg_size (mode, type);
7617 int start_words = cum->words;
7618 int align_words = rs6000_parm_start (mode, type, start_words);
7620 cum->words = align_words + n_words;
7622 if (SCALAR_FLOAT_MODE_P (mode)
7623 && TARGET_HARD_FLOAT && TARGET_FPRS)
7625 /* _Decimal128 must be passed in an even/odd float register pair.
7626 This assumes that the register number is odd when fregno is
7628 if (mode == TDmode && (cum->fregno % 2) == 1)
7630 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7633 if (TARGET_DEBUG_ARG)
7635 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7636 cum->words, cum->fregno);
7637 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7638 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7639 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7640 named, align_words - start_words, depth);
7646 spe_build_register_parallel (enum machine_mode mode, int gregno)
7653 r1 = gen_rtx_REG (DImode, gregno);
7654 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7655 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7659 r1 = gen_rtx_REG (DImode, gregno);
7660 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7661 r3 = gen_rtx_REG (DImode, gregno + 2);
7662 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7663 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7666 r1 = gen_rtx_REG (DImode, gregno);
7667 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7668 r3 = gen_rtx_REG (DImode, gregno + 2);
7669 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7670 r5 = gen_rtx_REG (DImode, gregno + 4);
7671 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7672 r7 = gen_rtx_REG (DImode, gregno + 6);
7673 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7674 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7681 /* Determine where to put a SIMD argument on the SPE. */
7683 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7686 int gregno = cum->sysv_gregno;
7688 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7689 are passed and returned in a pair of GPRs for ABI compatibility. */
7690 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7691 || mode == DCmode || mode == TCmode))
7693 int n_words = rs6000_arg_size (mode, type);
7695 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7697 gregno += (1 - gregno) & 1;
7699 /* Multi-reg args are not split between registers and stack. */
7700 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7703 return spe_build_register_parallel (mode, gregno);
7707 int n_words = rs6000_arg_size (mode, type);
7709 /* SPE vectors are put in odd registers. */
7710 if (n_words == 2 && (gregno & 1) == 0)
7713 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7716 enum machine_mode m = SImode;
7718 r1 = gen_rtx_REG (m, gregno);
7719 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7720 r2 = gen_rtx_REG (m, gregno + 1);
7721 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7722 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7729 if (gregno <= GP_ARG_MAX_REG)
7730 return gen_rtx_REG (mode, gregno);
7736 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7737 structure between cum->intoffset and bitpos to integer registers. */
7740 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7741 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7743 enum machine_mode mode;
7745 unsigned int startbit, endbit;
7746 int this_regno, intregs, intoffset;
7749 if (cum->intoffset == -1)
7752 intoffset = cum->intoffset;
7753 cum->intoffset = -1;
7755 /* If this is the trailing part of a word, try to only load that
7756 much into the register. Otherwise load the whole register. Note
7757 that in the latter case we may pick up unwanted bits. It's not a
7758 problem at the moment but may wish to revisit. */
7760 if (intoffset % BITS_PER_WORD != 0)
7762 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7764 if (mode == BLKmode)
7766 /* We couldn't find an appropriate mode, which happens,
7767 e.g., in packed structs when there are 3 bytes to load.
7768 Back intoffset back to the beginning of the word in this
7770 intoffset = intoffset & -BITS_PER_WORD;
7777 startbit = intoffset & -BITS_PER_WORD;
7778 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7779 intregs = (endbit - startbit) / BITS_PER_WORD;
7780 this_regno = cum->words + intoffset / BITS_PER_WORD;
7782 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7785 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7789 intoffset /= BITS_PER_UNIT;
7792 regno = GP_ARG_MIN_REG + this_regno;
7793 reg = gen_rtx_REG (mode, regno);
7795 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7798 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7802 while (intregs > 0);
7805 /* Recursive workhorse for the following. */
7808 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7809 HOST_WIDE_INT startbitpos, rtx rvec[],
7814 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7815 if (TREE_CODE (f) == FIELD_DECL)
7817 HOST_WIDE_INT bitpos = startbitpos;
7818 tree ftype = TREE_TYPE (f);
7819 enum machine_mode mode;
7820 if (ftype == error_mark_node)
7822 mode = TYPE_MODE (ftype);
7824 if (DECL_SIZE (f) != 0
7825 && host_integerp (bit_position (f), 1))
7826 bitpos += int_bit_position (f);
7828 /* ??? FIXME: else assume zero offset. */
7830 if (TREE_CODE (ftype) == RECORD_TYPE)
7831 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7832 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7837 case SCmode: mode = SFmode; break;
7838 case DCmode: mode = DFmode; break;
7839 case TCmode: mode = TFmode; break;
7843 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7845 = gen_rtx_EXPR_LIST (VOIDmode,
7846 gen_rtx_REG (mode, cum->fregno++),
7847 GEN_INT (bitpos / BITS_PER_UNIT));
7848 if (mode == TFmode || mode == TDmode)
7851 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7853 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7855 = gen_rtx_EXPR_LIST (VOIDmode,
7856 gen_rtx_REG (mode, cum->vregno++),
7857 GEN_INT (bitpos / BITS_PER_UNIT));
7859 else if (cum->intoffset == -1)
7860 cum->intoffset = bitpos;
7864 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7865 the register(s) to be used for each field and subfield of a struct
7866 being passed by value, along with the offset of where the
7867 register's value may be found in the block. FP fields go in FP
7868 register, vector fields go in vector registers, and everything
7869 else goes in int registers, packed as in memory.
7871 This code is also used for function return values. RETVAL indicates
7872 whether this is the case.
7874 Much of this is taken from the SPARC V9 port, which has a similar
7875 calling convention. */
7878 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7879 int named, bool retval)
7881 rtx rvec[FIRST_PSEUDO_REGISTER];
7882 int k = 1, kbase = 1;
7883 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7884 /* This is a copy; modifications are not visible to our caller. */
7885 CUMULATIVE_ARGS copy_cum = *orig_cum;
7886 CUMULATIVE_ARGS *cum = ©_cum;
7888 /* Pad to 16 byte boundary if needed. */
7889 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7890 && (cum->words % 2) != 0)
7897 /* Put entries into rvec[] for individual FP and vector fields, and
7898 for the chunks of memory that go in int regs. Note we start at
7899 element 1; 0 is reserved for an indication of using memory, and
7900 may or may not be filled in below. */
7901 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7902 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7904 /* If any part of the struct went on the stack put all of it there.
7905 This hack is because the generic code for
7906 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7907 parts of the struct are not at the beginning. */
7911 return NULL_RTX; /* doesn't go in registers at all */
7913 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7915 if (k > 1 || cum->use_stack)
7916 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7921 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7924 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7928 rtx rvec[GP_ARG_NUM_REG + 1];
7930 if (align_words >= GP_ARG_NUM_REG)
7933 n_units = rs6000_arg_size (mode, type);
7935 /* Optimize the simple case where the arg fits in one gpr, except in
7936 the case of BLKmode due to assign_parms assuming that registers are
7937 BITS_PER_WORD wide. */
7939 || (n_units == 1 && mode != BLKmode))
7940 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7943 if (align_words + n_units > GP_ARG_NUM_REG)
7944 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7945 using a magic NULL_RTX component.
7946 This is not strictly correct. Only some of the arg belongs in
7947 memory, not all of it. However, the normal scheme using
7948 function_arg_partial_nregs can result in unusual subregs, eg.
7949 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7950 store the whole arg to memory is often more efficient than code
7951 to store pieces, and we know that space is available in the right
7952 place for the whole arg. */
7953 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7958 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7959 rtx off = GEN_INT (i++ * 4);
7960 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7962 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7964 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7967 /* Determine where to put an argument to a function.
7968 Value is zero to push the argument on the stack,
7969 or a hard register in which to store the argument.
7971 MODE is the argument's machine mode.
7972 TYPE is the data type of the argument (as a tree).
7973 This is null for libcalls where that information may
7975 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7976 the preceding args and about the function being called. It is
7977 not modified in this routine.
7978 NAMED is nonzero if this argument is a named parameter
7979 (otherwise it is an extra parameter matching an ellipsis).
7981 On RS/6000 the first eight words of non-FP are normally in registers
7982 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7983 Under V.4, the first 8 FP args are in registers.
7985 If this is floating-point and no prototype is specified, we use
7986 both an FP and integer register (or possibly FP reg and stack). Library
7987 functions (when CALL_LIBCALL is set) always have the proper types for args,
7988 so we can pass the FP value just in one register. emit_library_function
7989 doesn't support PARALLEL anyway.
7991 Note that for args passed by reference, function_arg will be called
7992 with MODE and TYPE set to that of the pointer to the arg, not the arg
7996 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7997 tree type, int named)
7999 enum rs6000_abi abi = DEFAULT_ABI;
8001 /* Return a marker to indicate whether CR1 needs to set or clear the
8002 bit that V.4 uses to say fp args were passed in registers.
8003 Assume that we don't need the marker for software floating point,
8004 or compiler generated library calls. */
8005 if (mode == VOIDmode)
8008 && (cum->call_cookie & CALL_LIBCALL) == 0
8010 || (cum->nargs_prototype < 0
8011 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8013 /* For the SPE, we need to crxor CR6 always. */
8015 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8016 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8017 return GEN_INT (cum->call_cookie
8018 | ((cum->fregno == FP_ARG_MIN_REG)
8019 ? CALL_V4_SET_FP_ARGS
8020 : CALL_V4_CLEAR_FP_ARGS));
8023 return GEN_INT (cum->call_cookie);
8026 if (rs6000_darwin64_abi && mode == BLKmode
8027 && TREE_CODE (type) == RECORD_TYPE)
8029 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
8030 if (rslt != NULL_RTX)
8032 /* Else fall through to usual handling. */
8035 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8036 if (TARGET_64BIT && ! cum->prototype)
8038 /* Vector parameters get passed in vector register
8039 and also in GPRs or memory, in absence of prototype. */
8042 align_words = (cum->words + 1) & ~1;
8044 if (align_words >= GP_ARG_NUM_REG)
8050 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8052 return gen_rtx_PARALLEL (mode,
8054 gen_rtx_EXPR_LIST (VOIDmode,
8056 gen_rtx_EXPR_LIST (VOIDmode,
8057 gen_rtx_REG (mode, cum->vregno),
8061 return gen_rtx_REG (mode, cum->vregno);
8062 else if (TARGET_ALTIVEC_ABI
8063 && (ALTIVEC_VECTOR_MODE (mode)
8064 || VSX_VECTOR_MODE (mode)
8065 || (type && TREE_CODE (type) == VECTOR_TYPE
8066 && int_size_in_bytes (type) == 16)))
8068 if (named || abi == ABI_V4)
8072 /* Vector parameters to varargs functions under AIX or Darwin
8073 get passed in memory and possibly also in GPRs. */
8074 int align, align_words, n_words;
8075 enum machine_mode part_mode;
8077 /* Vector parameters must be 16-byte aligned. This places them at
8078 2 mod 4 in terms of words in 32-bit mode, since the parameter
8079 save area starts at offset 24 from the stack. In 64-bit mode,
8080 they just have to start on an even word, since the parameter
8081 save area is 16-byte aligned. */
8083 align = (2 - cum->words) & 3;
8085 align = cum->words & 1;
8086 align_words = cum->words + align;
8088 /* Out of registers? Memory, then. */
8089 if (align_words >= GP_ARG_NUM_REG)
8092 if (TARGET_32BIT && TARGET_POWERPC64)
8093 return rs6000_mixed_function_arg (mode, type, align_words);
8095 /* The vector value goes in GPRs. Only the part of the
8096 value in GPRs is reported here. */
8098 n_words = rs6000_arg_size (mode, type);
8099 if (align_words + n_words > GP_ARG_NUM_REG)
8100 /* Fortunately, there are only two possibilities, the value
8101 is either wholly in GPRs or half in GPRs and half not. */
8104 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8107 else if (TARGET_SPE_ABI && TARGET_SPE
8108 && (SPE_VECTOR_MODE (mode)
8109 || (TARGET_E500_DOUBLE && (mode == DFmode
8112 || mode == TCmode))))
8113 return rs6000_spe_function_arg (cum, mode, type);
8115 else if (abi == ABI_V4)
8117 if (TARGET_HARD_FLOAT && TARGET_FPRS
8118 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8119 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8120 || (mode == TFmode && !TARGET_IEEEQUAD)
8121 || mode == SDmode || mode == DDmode || mode == TDmode))
8123 /* _Decimal128 must use an even/odd register pair. This assumes
8124 that the register number is odd when fregno is odd. */
8125 if (mode == TDmode && (cum->fregno % 2) == 1)
8128 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8129 <= FP_ARG_V4_MAX_REG)
8130 return gen_rtx_REG (mode, cum->fregno);
8136 int n_words = rs6000_arg_size (mode, type);
8137 int gregno = cum->sysv_gregno;
8139 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8140 (r7,r8) or (r9,r10). As does any other 2 word item such
8141 as complex int due to a historical mistake. */
8143 gregno += (1 - gregno) & 1;
8145 /* Multi-reg args are not split between registers and stack. */
8146 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8149 if (TARGET_32BIT && TARGET_POWERPC64)
8150 return rs6000_mixed_function_arg (mode, type,
8151 gregno - GP_ARG_MIN_REG);
8152 return gen_rtx_REG (mode, gregno);
8157 int align_words = rs6000_parm_start (mode, type, cum->words);
8159 /* _Decimal128 must be passed in an even/odd float register pair.
8160 This assumes that the register number is odd when fregno is odd. */
8161 if (mode == TDmode && (cum->fregno % 2) == 1)
8164 if (USE_FP_FOR_ARG_P (cum, mode, type))
8166 rtx rvec[GP_ARG_NUM_REG + 1];
8170 enum machine_mode fmode = mode;
8171 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8173 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8175 /* Currently, we only ever need one reg here because complex
8176 doubles are split. */
8177 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8178 && (fmode == TFmode || fmode == TDmode));
8180 /* Long double or _Decimal128 split over regs and memory. */
8181 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8184 /* Do we also need to pass this arg in the parameter save
8187 && (cum->nargs_prototype <= 0
8188 || (DEFAULT_ABI == ABI_AIX
8190 && align_words >= GP_ARG_NUM_REG)));
8192 if (!needs_psave && mode == fmode)
8193 return gen_rtx_REG (fmode, cum->fregno);
8198 /* Describe the part that goes in gprs or the stack.
8199 This piece must come first, before the fprs. */
8200 if (align_words < GP_ARG_NUM_REG)
8202 unsigned long n_words = rs6000_arg_size (mode, type);
8204 if (align_words + n_words > GP_ARG_NUM_REG
8205 || (TARGET_32BIT && TARGET_POWERPC64))
8207 /* If this is partially on the stack, then we only
8208 include the portion actually in registers here. */
8209 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8212 if (align_words + n_words > GP_ARG_NUM_REG)
8213 /* Not all of the arg fits in gprs. Say that it
8214 goes in memory too, using a magic NULL_RTX
8215 component. Also see comment in
8216 rs6000_mixed_function_arg for why the normal
8217 function_arg_partial_nregs scheme doesn't work
8219 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8223 r = gen_rtx_REG (rmode,
8224 GP_ARG_MIN_REG + align_words);
8225 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8226 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8228 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8232 /* The whole arg fits in gprs. */
8233 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8234 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8238 /* It's entirely in memory. */
8239 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8242 /* Describe where this piece goes in the fprs. */
8243 r = gen_rtx_REG (fmode, cum->fregno);
8244 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8246 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8248 else if (align_words < GP_ARG_NUM_REG)
8250 if (TARGET_32BIT && TARGET_POWERPC64)
8251 return rs6000_mixed_function_arg (mode, type, align_words);
8253 if (mode == BLKmode)
8256 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8263 /* For an arg passed partly in registers and partly in memory, this is
8264 the number of bytes passed in registers. For args passed entirely in
8265 registers or entirely in memory, zero. When an arg is described by a
8266 PARALLEL, perhaps using more than one register type, this function
8267 returns the number of bytes used by the first element of the PARALLEL. */
8270 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8271 tree type, bool named)
8276 if (DEFAULT_ABI == ABI_V4)
8279 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8280 && cum->nargs_prototype >= 0)
8283 /* In this complicated case we just disable the partial_nregs code. */
8284 if (rs6000_darwin64_abi && mode == BLKmode
8285 && TREE_CODE (type) == RECORD_TYPE
8286 && int_size_in_bytes (type) > 0)
8289 align_words = rs6000_parm_start (mode, type, cum->words);
8291 if (USE_FP_FOR_ARG_P (cum, mode, type))
8293 /* If we are passing this arg in the fixed parameter save area
8294 (gprs or memory) as well as fprs, then this function should
8295 return the number of partial bytes passed in the parameter
8296 save area rather than partial bytes passed in fprs. */
8298 && (cum->nargs_prototype <= 0
8299 || (DEFAULT_ABI == ABI_AIX
8301 && align_words >= GP_ARG_NUM_REG)))
8303 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8304 > FP_ARG_MAX_REG + 1)
8305 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8306 else if (cum->nargs_prototype >= 0)
8310 if (align_words < GP_ARG_NUM_REG
8311 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8312 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8314 if (ret != 0 && TARGET_DEBUG_ARG)
8315 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8320 /* A C expression that indicates when an argument must be passed by
8321 reference. If nonzero for an argument, a copy of that argument is
8322 made in memory and a pointer to the argument is passed instead of
8323 the argument itself. The pointer is passed in whatever way is
8324 appropriate for passing a pointer to that type.
8326 Under V.4, aggregates and long double are passed by reference.
8328 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8329 reference unless the AltiVec vector extension ABI is in force.
8331 As an extension to all ABIs, variable sized types are passed by
8335 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
8336 enum machine_mode mode, const_tree type,
8337 bool named ATTRIBUTE_UNUSED)
8339 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8341 if (TARGET_DEBUG_ARG)
8342 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8349 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8351 if (TARGET_DEBUG_ARG)
8352 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8356 if (int_size_in_bytes (type) < 0)
8358 if (TARGET_DEBUG_ARG)
8359 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8363 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8364 modes only exist for GCC vector types if -maltivec. */
8365 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8367 if (TARGET_DEBUG_ARG)
8368 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8372 /* Pass synthetic vectors in memory. */
8373 if (TREE_CODE (type) == VECTOR_TYPE
8374 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8376 static bool warned_for_pass_big_vectors = false;
8377 if (TARGET_DEBUG_ARG)
8378 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8379 if (!warned_for_pass_big_vectors)
8381 warning (0, "GCC vector passed by reference: "
8382 "non-standard ABI extension with no compatibility guarantee");
8383 warned_for_pass_big_vectors = true;
8392 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8395 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8400 for (i = 0; i < nregs; i++)
8402 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8403 if (reload_completed)
8405 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8408 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8409 i * GET_MODE_SIZE (reg_mode));
8412 tem = replace_equiv_address (tem, XEXP (tem, 0));
8416 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8420 /* Perform any needed actions needed for a function that is receiving a
8421 variable number of arguments.
8425 MODE and TYPE are the mode and type of the current parameter.
8427 PRETEND_SIZE is a variable that should be set to the amount of stack
8428 that must be pushed by the prolog to pretend that our caller pushed
8431 Normally, this macro will push all remaining incoming registers on the
8432 stack and set PRETEND_SIZE to the length of the registers pushed. */
8435 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8436 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8439 CUMULATIVE_ARGS next_cum;
8440 int reg_size = TARGET_32BIT ? 4 : 8;
8441 rtx save_area = NULL_RTX, mem;
8442 int first_reg_offset;
8445 /* Skip the last named argument. */
8447 function_arg_advance (&next_cum, mode, type, 1, 0);
8449 if (DEFAULT_ABI == ABI_V4)
8451 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8455 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8456 HOST_WIDE_INT offset = 0;
8458 /* Try to optimize the size of the varargs save area.
8459 The ABI requires that ap.reg_save_area is doubleword
8460 aligned, but we don't need to allocate space for all
8461 the bytes, only those to which we actually will save
8463 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8464 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8465 if (TARGET_HARD_FLOAT && TARGET_FPRS
8466 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8467 && cfun->va_list_fpr_size)
8470 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8471 * UNITS_PER_FP_WORD;
8472 if (cfun->va_list_fpr_size
8473 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8474 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8476 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8477 * UNITS_PER_FP_WORD;
8481 offset = -((first_reg_offset * reg_size) & ~7);
8482 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8484 gpr_reg_num = cfun->va_list_gpr_size;
8485 if (reg_size == 4 && (first_reg_offset & 1))
8488 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8491 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8493 - (int) (GP_ARG_NUM_REG * reg_size);
8495 if (gpr_size + fpr_size)
8498 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8499 gcc_assert (GET_CODE (reg_save_area) == MEM);
8500 reg_save_area = XEXP (reg_save_area, 0);
8501 if (GET_CODE (reg_save_area) == PLUS)
8503 gcc_assert (XEXP (reg_save_area, 0)
8504 == virtual_stack_vars_rtx);
8505 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8506 offset += INTVAL (XEXP (reg_save_area, 1));
8509 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8512 cfun->machine->varargs_save_offset = offset;
8513 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8518 first_reg_offset = next_cum.words;
8519 save_area = virtual_incoming_args_rtx;
8521 if (targetm.calls.must_pass_in_stack (mode, type))
8522 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8525 set = get_varargs_alias_set ();
8526 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8527 && cfun->va_list_gpr_size)
8529 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8531 if (va_list_gpr_counter_field)
8533 /* V4 va_list_gpr_size counts number of registers needed. */
8534 if (nregs > cfun->va_list_gpr_size)
8535 nregs = cfun->va_list_gpr_size;
8539 /* char * va_list instead counts number of bytes needed. */
8540 if (nregs > cfun->va_list_gpr_size / reg_size)
8541 nregs = cfun->va_list_gpr_size / reg_size;
8544 mem = gen_rtx_MEM (BLKmode,
8545 plus_constant (save_area,
8546 first_reg_offset * reg_size));
8547 MEM_NOTRAP_P (mem) = 1;
8548 set_mem_alias_set (mem, set);
8549 set_mem_align (mem, BITS_PER_WORD);
8551 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8555 /* Save FP registers if needed. */
8556 if (DEFAULT_ABI == ABI_V4
8557 && TARGET_HARD_FLOAT && TARGET_FPRS
8559 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8560 && cfun->va_list_fpr_size)
8562 int fregno = next_cum.fregno, nregs;
8563 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8564 rtx lab = gen_label_rtx ();
8565 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8566 * UNITS_PER_FP_WORD);
8569 (gen_rtx_SET (VOIDmode,
8571 gen_rtx_IF_THEN_ELSE (VOIDmode,
8572 gen_rtx_NE (VOIDmode, cr1,
8574 gen_rtx_LABEL_REF (VOIDmode, lab),
8578 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8579 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8581 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8583 plus_constant (save_area, off));
8584 MEM_NOTRAP_P (mem) = 1;
8585 set_mem_alias_set (mem, set);
8586 set_mem_align (mem, GET_MODE_ALIGNMENT (
8587 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8588 ? DFmode : SFmode));
8589 emit_move_insn (mem, gen_rtx_REG (
8590 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8591 ? DFmode : SFmode, fregno));
8598 /* Create the va_list data type. */
8601 rs6000_build_builtin_va_list (void)
8603 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8605 /* For AIX, prefer 'char *' because that's what the system
8606 header files like. */
8607 if (DEFAULT_ABI != ABI_V4)
8608 return build_pointer_type (char_type_node);
8610 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8611 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8612 get_identifier ("__va_list_tag"), record);
8614 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8615 unsigned_char_type_node);
8616 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8617 unsigned_char_type_node);
8618 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8620 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8621 get_identifier ("reserved"), short_unsigned_type_node);
8622 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8623 get_identifier ("overflow_arg_area"),
8625 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8626 get_identifier ("reg_save_area"),
8629 va_list_gpr_counter_field = f_gpr;
8630 va_list_fpr_counter_field = f_fpr;
8632 DECL_FIELD_CONTEXT (f_gpr) = record;
8633 DECL_FIELD_CONTEXT (f_fpr) = record;
8634 DECL_FIELD_CONTEXT (f_res) = record;
8635 DECL_FIELD_CONTEXT (f_ovf) = record;
8636 DECL_FIELD_CONTEXT (f_sav) = record;
8638 TREE_CHAIN (record) = type_decl;
8639 TYPE_NAME (record) = type_decl;
8640 TYPE_FIELDS (record) = f_gpr;
8641 TREE_CHAIN (f_gpr) = f_fpr;
8642 TREE_CHAIN (f_fpr) = f_res;
8643 TREE_CHAIN (f_res) = f_ovf;
8644 TREE_CHAIN (f_ovf) = f_sav;
8646 layout_type (record);
8648 /* The correct type is an array type of one element. */
8649 return build_array_type (record, build_index_type (size_zero_node));
8652 /* Implement va_start. */
8655 rs6000_va_start (tree valist, rtx nextarg)
8657 HOST_WIDE_INT words, n_gpr, n_fpr;
8658 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8659 tree gpr, fpr, ovf, sav, t;
8661 /* Only SVR4 needs something special. */
8662 if (DEFAULT_ABI != ABI_V4)
8664 std_expand_builtin_va_start (valist, nextarg);
8668 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8669 f_fpr = TREE_CHAIN (f_gpr);
8670 f_res = TREE_CHAIN (f_fpr);
8671 f_ovf = TREE_CHAIN (f_res);
8672 f_sav = TREE_CHAIN (f_ovf);
8674 valist = build_va_arg_indirect_ref (valist);
8675 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8676 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8678 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8680 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8683 /* Count number of gp and fp argument registers used. */
8684 words = crtl->args.info.words;
8685 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8687 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8690 if (TARGET_DEBUG_ARG)
8691 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8692 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8693 words, n_gpr, n_fpr);
8695 if (cfun->va_list_gpr_size)
8697 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8698 build_int_cst (NULL_TREE, n_gpr));
8699 TREE_SIDE_EFFECTS (t) = 1;
8700 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8703 if (cfun->va_list_fpr_size)
8705 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8706 build_int_cst (NULL_TREE, n_fpr));
8707 TREE_SIDE_EFFECTS (t) = 1;
8708 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8711 /* Find the overflow area. */
8712 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8714 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8715 size_int (words * UNITS_PER_WORD));
8716 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8717 TREE_SIDE_EFFECTS (t) = 1;
8718 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8720 /* If there were no va_arg invocations, don't set up the register
8722 if (!cfun->va_list_gpr_size
8723 && !cfun->va_list_fpr_size
8724 && n_gpr < GP_ARG_NUM_REG
8725 && n_fpr < FP_ARG_V4_MAX_REG)
8728 /* Find the register save area. */
8729 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8730 if (cfun->machine->varargs_save_offset)
8731 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8732 size_int (cfun->machine->varargs_save_offset));
8733 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8734 TREE_SIDE_EFFECTS (t) = 1;
8735 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8738 /* Implement va_arg. */
8741 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8744 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8745 tree gpr, fpr, ovf, sav, reg, t, u;
8746 int size, rsize, n_reg, sav_ofs, sav_scale;
8747 tree lab_false, lab_over, addr;
8749 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8753 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8755 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8756 return build_va_arg_indirect_ref (t);
8759 if (DEFAULT_ABI != ABI_V4)
8761 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8763 tree elem_type = TREE_TYPE (type);
8764 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8765 int elem_size = GET_MODE_SIZE (elem_mode);
8767 if (elem_size < UNITS_PER_WORD)
8769 tree real_part, imag_part;
8770 gimple_seq post = NULL;
8772 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8774 /* Copy the value into a temporary, lest the formal temporary
8775 be reused out from under us. */
8776 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8777 gimple_seq_add_seq (pre_p, post);
8779 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8782 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8786 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8789 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8790 f_fpr = TREE_CHAIN (f_gpr);
8791 f_res = TREE_CHAIN (f_fpr);
8792 f_ovf = TREE_CHAIN (f_res);
8793 f_sav = TREE_CHAIN (f_ovf);
8795 valist = build_va_arg_indirect_ref (valist);
8796 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8797 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8799 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8801 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8804 size = int_size_in_bytes (type);
8805 rsize = (size + 3) / 4;
8808 if (TARGET_HARD_FLOAT && TARGET_FPRS
8809 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8810 || (TARGET_DOUBLE_FLOAT
8811 && (TYPE_MODE (type) == DFmode
8812 || TYPE_MODE (type) == TFmode
8813 || TYPE_MODE (type) == SDmode
8814 || TYPE_MODE (type) == DDmode
8815 || TYPE_MODE (type) == TDmode))))
8817 /* FP args go in FP registers, if present. */
8819 n_reg = (size + 7) / 8;
8820 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8821 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8822 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8827 /* Otherwise into GP registers. */
8836 /* Pull the value out of the saved registers.... */
8839 addr = create_tmp_var (ptr_type_node, "addr");
8841 /* AltiVec vectors never go in registers when -mabi=altivec. */
8842 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8846 lab_false = create_artificial_label (input_location);
8847 lab_over = create_artificial_label (input_location);
8849 /* Long long and SPE vectors are aligned in the registers.
8850 As are any other 2 gpr item such as complex int due to a
8851 historical mistake. */
8853 if (n_reg == 2 && reg == gpr)
8856 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8857 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8858 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8859 unshare_expr (reg), u);
8861 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8862 reg number is 0 for f1, so we want to make it odd. */
8863 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8865 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8866 build_int_cst (TREE_TYPE (reg), 1));
8867 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8870 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8871 t = build2 (GE_EXPR, boolean_type_node, u, t);
8872 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8873 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8874 gimplify_and_add (t, pre_p);
8878 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8880 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8881 build_int_cst (TREE_TYPE (reg), n_reg));
8882 u = fold_convert (sizetype, u);
8883 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8884 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8886 /* _Decimal32 varargs are located in the second word of the 64-bit
8887 FP register for 32-bit binaries. */
8888 if (!TARGET_POWERPC64
8889 && TARGET_HARD_FLOAT && TARGET_FPRS
8890 && TYPE_MODE (type) == SDmode)
8891 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8893 gimplify_assign (addr, t, pre_p);
8895 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8897 stmt = gimple_build_label (lab_false);
8898 gimple_seq_add_stmt (pre_p, stmt);
8900 if ((n_reg == 2 && !regalign) || n_reg > 2)
8902 /* Ensure that we don't find any more args in regs.
8903 Alignment has taken care of for special cases. */
8904 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8908 /* ... otherwise out of the overflow area. */
8910 /* Care for on-stack alignment if needed. */
8914 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8915 t = fold_convert (sizetype, t);
8916 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8918 t = fold_convert (TREE_TYPE (ovf), t);
8920 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8922 gimplify_assign (unshare_expr (addr), t, pre_p);
8924 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8925 gimplify_assign (unshare_expr (ovf), t, pre_p);
8929 stmt = gimple_build_label (lab_over);
8930 gimple_seq_add_stmt (pre_p, stmt);
8933 if (STRICT_ALIGNMENT
8934 && (TYPE_ALIGN (type)
8935 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8937 /* The value (of type complex double, for example) may not be
8938 aligned in memory in the saved registers, so copy via a
8939 temporary. (This is the same code as used for SPARC.) */
8940 tree tmp = create_tmp_var (type, "va_arg_tmp");
8941 tree dest_addr = build_fold_addr_expr (tmp);
8943 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8944 3, dest_addr, addr, size_int (rsize * 4));
8946 gimplify_and_add (copy, pre_p);
8950 addr = fold_convert (ptrtype, addr);
8951 return build_va_arg_indirect_ref (addr);
8957 def_builtin (int mask, const char *name, tree type, int code)
8959 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8962 if (rs6000_builtin_decls[code])
8963 fatal_error ("internal error: builtin function to %s already processed.",
8966 rs6000_builtin_decls[code] = t =
8967 add_builtin_function (name, type, code, BUILT_IN_MD,
8970 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
8971 switch (builtin_classify[code])
8976 /* assume builtin can do anything. */
8977 case RS6000_BTC_MISC:
8980 /* const function, function only depends on the inputs. */
8981 case RS6000_BTC_CONST:
8982 TREE_READONLY (t) = 1;
8983 TREE_NOTHROW (t) = 1;
8986 /* pure function, function can read global memory. */
8987 case RS6000_BTC_PURE:
8988 DECL_PURE_P (t) = 1;
8989 TREE_NOTHROW (t) = 1;
8992 /* Function is a math function. If rounding mode is on, then treat
8993 the function as not reading global memory, but it can have
8994 arbitrary side effects. If it is off, then assume the function is
8995 a const function. This mimics the ATTR_MATHFN_FPROUNDING
8996 attribute in builtin-attribute.def that is used for the math
8998 case RS6000_BTC_FP_PURE:
8999 TREE_NOTHROW (t) = 1;
9000 if (flag_rounding_math)
9002 DECL_PURE_P (t) = 1;
9003 DECL_IS_NOVOPS (t) = 1;
9006 TREE_READONLY (t) = 1;
9012 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9014 static const struct builtin_description bdesc_3arg[] =
9016 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9017 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9018 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9019 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9020 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9021 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9022 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9023 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9024 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9025 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9026 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9027 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9028 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9029 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9030 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9031 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9032 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9033 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9034 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9035 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9036 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9037 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9038 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9039 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9040 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9041 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9042 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9043 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9044 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9045 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9046 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9047 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9048 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9049 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9050 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9052 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9053 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9054 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9055 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9056 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9057 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9058 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9059 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9060 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9061 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9062 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9063 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9064 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9065 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9066 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9068 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9069 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9070 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9071 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9073 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9074 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9075 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9076 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9078 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9079 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9081 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9082 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9083 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9084 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9085 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9086 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9087 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9088 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9089 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9090 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9092 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9093 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9094 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9095 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9096 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9097 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9098 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9099 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9100 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9101 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9103 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9104 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9105 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9106 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9107 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9108 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9109 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9110 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9111 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9113 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9114 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9115 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9116 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9117 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9118 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9119 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9121 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9122 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9123 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9124 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9125 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9126 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9127 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9128 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9129 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9132 /* DST operations: void foo (void *, const int, const char). */
9134 static const struct builtin_description bdesc_dst[] =
9136 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9137 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9138 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9139 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9141 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9142 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9143 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9144 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9147 /* Simple binary operations: VECc = foo (VECa, VECb). */
9149 static struct builtin_description bdesc_2arg[] =
9151 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9152 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9153 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9154 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9155 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9156 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9157 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9158 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9159 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9160 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9161 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9162 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9163 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9164 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9165 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9166 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9167 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9168 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9169 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9170 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9171 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9172 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9173 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9174 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9175 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9176 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9177 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9178 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9179 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9180 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9181 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9182 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9183 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9184 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9185 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9186 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9187 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9188 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9189 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9190 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9191 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9192 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9193 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9194 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9195 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9196 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9197 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9198 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9199 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9200 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9201 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9202 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9203 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9204 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9205 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9206 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9207 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9208 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9209 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9210 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9211 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9212 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9213 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9214 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9215 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9216 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9217 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9218 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9219 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9220 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9221 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9222 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9223 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9224 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9225 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9226 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9227 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9228 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9229 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9230 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9231 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9232 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9233 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9234 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9235 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9236 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9237 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9238 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9239 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9240 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9241 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9242 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9243 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9244 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9245 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9246 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9247 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9248 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9249 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9250 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9251 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9252 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9253 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9254 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9255 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9256 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9257 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9258 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9259 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9260 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9261 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9262 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9263 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9264 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9265 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9266 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9267 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9269 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9270 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9271 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9272 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9273 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9274 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9275 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9276 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9277 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9278 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9279 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9280 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9282 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9283 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9284 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9285 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9286 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9287 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9288 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9289 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9290 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9291 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9292 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9293 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9295 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9296 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9297 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9298 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9299 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9300 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9302 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9303 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9304 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9305 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9306 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9307 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9308 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9309 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9310 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9311 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9312 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9313 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9315 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9316 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9317 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9318 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9319 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9320 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9321 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9322 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9323 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9324 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9325 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9326 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9327 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9328 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9329 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9330 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9331 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9332 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9333 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9334 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9335 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9336 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9337 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9338 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9339 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9340 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9341 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9342 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9343 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9344 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9345 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9346 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9347 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9348 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9349 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9350 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9351 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9352 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9353 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9354 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9355 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9356 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9357 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9358 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9359 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9360 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9361 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9362 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9363 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9364 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9365 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9366 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9367 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9368 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9369 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9370 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9371 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9372 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9373 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9374 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9375 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9376 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9377 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9378 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9379 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9380 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9381 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9382 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9383 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9384 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9385 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9386 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9387 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9388 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9389 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9390 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9391 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9392 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9393 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9394 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9395 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9396 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9397 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9398 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9399 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9400 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9401 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9402 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9403 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
9404 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9405 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9406 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9407 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9408 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9409 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9410 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9411 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9412 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9413 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9414 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9415 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9416 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9417 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9418 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9419 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9420 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9421 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9422 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9423 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9424 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9425 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9426 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9427 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9428 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9429 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9430 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9431 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9432 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9433 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9434 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9435 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9436 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9437 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9438 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9439 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9440 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9441 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9442 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9443 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9445 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9446 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9448 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9449 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9450 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9451 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9452 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9453 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9454 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9455 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9456 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9457 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9459 /* Place holder, leave as first spe builtin. */
9460 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9461 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9462 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9463 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9464 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9465 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9466 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9467 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9468 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9469 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9470 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9471 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9472 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9473 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9474 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9475 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9476 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9477 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9478 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9479 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9480 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9481 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9482 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9483 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9484 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9485 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9486 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9487 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9488 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9489 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9490 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9491 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9492 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9493 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9494 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9495 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9496 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9497 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9498 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9499 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9500 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9501 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9502 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9503 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9504 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9505 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9506 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9507 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9508 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9509 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9510 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9511 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9512 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9513 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9514 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9515 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9516 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9517 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9518 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9519 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9520 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9521 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9522 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9523 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9524 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9525 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9526 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9527 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9528 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9529 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9530 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9531 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9532 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9533 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9534 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9535 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9536 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9537 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9538 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9539 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9540 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9541 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9542 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9543 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9544 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9545 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9546 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9547 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9548 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9549 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9550 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9551 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9552 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9553 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9554 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9555 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9556 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9557 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9558 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9559 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9560 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9561 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9562 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9563 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9564 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9565 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9566 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9567 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9568 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9570 /* SPE binary operations expecting a 5-bit unsigned literal. */
9571 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9573 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9574 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9575 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9576 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9577 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9578 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9579 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9580 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9581 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9582 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9583 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9584 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9585 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9586 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9587 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9588 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9589 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9590 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9591 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9592 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9593 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9594 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9595 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9596 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9597 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9598 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9600 /* Place-holder. Leave as last binary SPE builtin. */
9601 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9604 /* AltiVec predicates. */
9606 struct builtin_description_predicates
9608 const unsigned int mask;
9609 const enum insn_code icode;
9610 const char *const name;
9611 const enum rs6000_builtins code;
9614 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9616 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9617 ALTIVEC_BUILTIN_VCMPBFP_P },
9618 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9619 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9620 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9621 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9622 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9623 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9624 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9625 ALTIVEC_BUILTIN_VCMPEQUW_P },
9626 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9627 ALTIVEC_BUILTIN_VCMPGTSW_P },
9628 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9629 ALTIVEC_BUILTIN_VCMPGTUW_P },
9630 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9631 ALTIVEC_BUILTIN_VCMPEQUH_P },
9632 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9633 ALTIVEC_BUILTIN_VCMPGTSH_P },
9634 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9635 ALTIVEC_BUILTIN_VCMPGTUH_P },
9636 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9637 ALTIVEC_BUILTIN_VCMPEQUB_P },
9638 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9639 ALTIVEC_BUILTIN_VCMPGTSB_P },
9640 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9641 ALTIVEC_BUILTIN_VCMPGTUB_P },
9643 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9644 VSX_BUILTIN_XVCMPEQSP_P },
9645 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9646 VSX_BUILTIN_XVCMPGESP_P },
9647 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9648 VSX_BUILTIN_XVCMPGTSP_P },
9649 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9650 VSX_BUILTIN_XVCMPEQDP_P },
9651 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9652 VSX_BUILTIN_XVCMPGEDP_P },
9653 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9654 VSX_BUILTIN_XVCMPGTDP_P },
9656 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9657 ALTIVEC_BUILTIN_VCMPEQ_P },
9658 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9659 ALTIVEC_BUILTIN_VCMPGT_P },
9660 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9661 ALTIVEC_BUILTIN_VCMPGE_P }
9664 /* SPE predicates. */
9665 static struct builtin_description bdesc_spe_predicates[] =
9667 /* Place-holder. Leave as first. */
9668 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9669 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9670 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9671 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9672 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9673 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9674 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9675 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9676 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9677 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9678 /* Place-holder. Leave as last. */
9679 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9682 /* SPE evsel predicates. */
9683 static struct builtin_description bdesc_spe_evsel[] =
9685 /* Place-holder. Leave as first. */
9686 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9687 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9688 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9689 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9690 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9691 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9692 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9693 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9694 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9695 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9696 /* Place-holder. Leave as last. */
9697 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9700 /* PAIRED predicates. */
9701 static const struct builtin_description bdesc_paired_preds[] =
9703 /* Place-holder. Leave as first. */
9704 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9705 /* Place-holder. Leave as last. */
9706 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9709 /* ABS* operations. */
9711 static const struct builtin_description bdesc_abs[] =
9713 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9714 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9715 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9716 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9717 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9718 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9719 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9720 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9721 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9722 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9723 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9726 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9729 static struct builtin_description bdesc_1arg[] =
9731 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9732 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9733 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9734 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9735 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9736 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9737 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9738 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
9739 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9740 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9741 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9742 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9743 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9744 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9745 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9746 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9747 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9748 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9750 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9751 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9752 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
9753 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9754 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9755 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9756 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9758 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9759 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9760 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
9761 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9762 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9763 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9764 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9766 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9767 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9768 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9769 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9770 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9771 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9773 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9774 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9775 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9776 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9777 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9778 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9780 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9781 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9782 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9783 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9785 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9786 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9787 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9788 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9789 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9790 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9791 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9792 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9793 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9795 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9796 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9797 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9798 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9799 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9800 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9801 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9802 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9803 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9805 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9806 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9807 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9808 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9809 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9811 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9812 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9813 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9814 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9815 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9816 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9817 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9818 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9819 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9820 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
9821 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9822 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9823 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9824 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9825 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9826 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9827 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9828 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9829 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9830 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9832 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9833 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9834 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9836 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9837 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9838 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9839 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9841 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9842 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9843 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9844 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9845 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9846 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9847 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9848 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9849 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9850 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9851 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9852 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9853 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9854 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9855 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9856 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9857 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9858 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9859 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9860 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9861 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9862 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9863 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9864 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9865 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9866 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9867 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9868 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9869 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9870 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9872 /* Place-holder. Leave as last unary SPE builtin. */
9873 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9875 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9876 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9877 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9878 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9879 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9883 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9886 tree arg0 = CALL_EXPR_ARG (exp, 0);
9887 rtx op0 = expand_normal (arg0);
9888 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9889 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9891 if (icode == CODE_FOR_nothing)
9892 /* Builtin not supported on this processor. */
9895 /* If we got invalid arguments bail out before generating bad rtl. */
9896 if (arg0 == error_mark_node)
9899 if (icode == CODE_FOR_altivec_vspltisb
9900 || icode == CODE_FOR_altivec_vspltish
9901 || icode == CODE_FOR_altivec_vspltisw
9902 || icode == CODE_FOR_spe_evsplatfi
9903 || icode == CODE_FOR_spe_evsplati)
9905 /* Only allow 5-bit *signed* literals. */
9906 if (GET_CODE (op0) != CONST_INT
9907 || INTVAL (op0) > 15
9908 || INTVAL (op0) < -16)
9910 error ("argument 1 must be a 5-bit signed literal");
9916 || GET_MODE (target) != tmode
9917 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9918 target = gen_reg_rtx (tmode);
9920 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9921 op0 = copy_to_mode_reg (mode0, op0);
9923 pat = GEN_FCN (icode) (target, op0);
9932 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9934 rtx pat, scratch1, scratch2;
9935 tree arg0 = CALL_EXPR_ARG (exp, 0);
9936 rtx op0 = expand_normal (arg0);
9937 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9938 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9940 /* If we have invalid arguments, bail out before generating bad rtl. */
9941 if (arg0 == error_mark_node)
9945 || GET_MODE (target) != tmode
9946 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9947 target = gen_reg_rtx (tmode);
9949 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9950 op0 = copy_to_mode_reg (mode0, op0);
9952 scratch1 = gen_reg_rtx (mode0);
9953 scratch2 = gen_reg_rtx (mode0);
9955 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9964 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
9967 tree arg0 = CALL_EXPR_ARG (exp, 0);
9968 tree arg1 = CALL_EXPR_ARG (exp, 1);
9969 rtx op0 = expand_normal (arg0);
9970 rtx op1 = expand_normal (arg1);
9971 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9972 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9973 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9975 if (icode == CODE_FOR_nothing)
9976 /* Builtin not supported on this processor. */
9979 /* If we got invalid arguments bail out before generating bad rtl. */
9980 if (arg0 == error_mark_node || arg1 == error_mark_node)
9983 if (icode == CODE_FOR_altivec_vcfux
9984 || icode == CODE_FOR_altivec_vcfsx
9985 || icode == CODE_FOR_altivec_vctsxs
9986 || icode == CODE_FOR_altivec_vctuxs
9987 || icode == CODE_FOR_altivec_vspltb
9988 || icode == CODE_FOR_altivec_vsplth
9989 || icode == CODE_FOR_altivec_vspltw
9990 || icode == CODE_FOR_spe_evaddiw
9991 || icode == CODE_FOR_spe_evldd
9992 || icode == CODE_FOR_spe_evldh
9993 || icode == CODE_FOR_spe_evldw
9994 || icode == CODE_FOR_spe_evlhhesplat
9995 || icode == CODE_FOR_spe_evlhhossplat
9996 || icode == CODE_FOR_spe_evlhhousplat
9997 || icode == CODE_FOR_spe_evlwhe
9998 || icode == CODE_FOR_spe_evlwhos
9999 || icode == CODE_FOR_spe_evlwhou
10000 || icode == CODE_FOR_spe_evlwhsplat
10001 || icode == CODE_FOR_spe_evlwwsplat
10002 || icode == CODE_FOR_spe_evrlwi
10003 || icode == CODE_FOR_spe_evslwi
10004 || icode == CODE_FOR_spe_evsrwis
10005 || icode == CODE_FOR_spe_evsubifw
10006 || icode == CODE_FOR_spe_evsrwiu)
10008 /* Only allow 5-bit unsigned literals. */
10010 if (TREE_CODE (arg1) != INTEGER_CST
10011 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10013 error ("argument 2 must be a 5-bit unsigned literal");
10019 || GET_MODE (target) != tmode
10020 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10021 target = gen_reg_rtx (tmode);
10023 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10024 op0 = copy_to_mode_reg (mode0, op0);
10025 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10026 op1 = copy_to_mode_reg (mode1, op1);
10028 pat = GEN_FCN (icode) (target, op0, op1);
10037 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10040 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10041 tree arg0 = CALL_EXPR_ARG (exp, 1);
10042 tree arg1 = CALL_EXPR_ARG (exp, 2);
10043 rtx op0 = expand_normal (arg0);
10044 rtx op1 = expand_normal (arg1);
10045 enum machine_mode tmode = SImode;
10046 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10047 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10050 if (TREE_CODE (cr6_form) != INTEGER_CST)
10052 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10056 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10058 gcc_assert (mode0 == mode1);
10060 /* If we have invalid arguments, bail out before generating bad rtl. */
10061 if (arg0 == error_mark_node || arg1 == error_mark_node)
10065 || GET_MODE (target) != tmode
10066 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10067 target = gen_reg_rtx (tmode);
10069 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10070 op0 = copy_to_mode_reg (mode0, op0);
10071 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10072 op1 = copy_to_mode_reg (mode1, op1);
10074 scratch = gen_reg_rtx (mode0);
10076 pat = GEN_FCN (icode) (scratch, op0, op1);
10081 /* The vec_any* and vec_all* predicates use the same opcodes for two
10082 different operations, but the bits in CR6 will be different
10083 depending on what information we want. So we have to play tricks
10084 with CR6 to get the right bits out.
10086 If you think this is disgusting, look at the specs for the
10087 AltiVec predicates. */
10089 switch (cr6_form_int)
10092 emit_insn (gen_cr6_test_for_zero (target));
10095 emit_insn (gen_cr6_test_for_zero_reverse (target));
10098 emit_insn (gen_cr6_test_for_lt (target));
10101 emit_insn (gen_cr6_test_for_lt_reverse (target));
10104 error ("argument 1 of __builtin_altivec_predicate is out of range");
10112 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10115 tree arg0 = CALL_EXPR_ARG (exp, 0);
10116 tree arg1 = CALL_EXPR_ARG (exp, 1);
10117 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10118 enum machine_mode mode0 = Pmode;
10119 enum machine_mode mode1 = Pmode;
10120 rtx op0 = expand_normal (arg0);
10121 rtx op1 = expand_normal (arg1);
10123 if (icode == CODE_FOR_nothing)
10124 /* Builtin not supported on this processor. */
10127 /* If we got invalid arguments bail out before generating bad rtl. */
10128 if (arg0 == error_mark_node || arg1 == error_mark_node)
10132 || GET_MODE (target) != tmode
10133 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10134 target = gen_reg_rtx (tmode);
10136 op1 = copy_to_mode_reg (mode1, op1);
10138 if (op0 == const0_rtx)
10140 addr = gen_rtx_MEM (tmode, op1);
10144 op0 = copy_to_mode_reg (mode0, op0);
10145 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10148 pat = GEN_FCN (icode) (target, addr);
10158 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10161 tree arg0 = CALL_EXPR_ARG (exp, 0);
10162 tree arg1 = CALL_EXPR_ARG (exp, 1);
10163 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10164 enum machine_mode mode0 = Pmode;
10165 enum machine_mode mode1 = Pmode;
10166 rtx op0 = expand_normal (arg0);
10167 rtx op1 = expand_normal (arg1);
10169 if (icode == CODE_FOR_nothing)
10170 /* Builtin not supported on this processor. */
10173 /* If we got invalid arguments bail out before generating bad rtl. */
10174 if (arg0 == error_mark_node || arg1 == error_mark_node)
10178 || GET_MODE (target) != tmode
10179 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10180 target = gen_reg_rtx (tmode);
10182 op1 = copy_to_mode_reg (mode1, op1);
10184 if (op0 == const0_rtx)
10186 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10190 op0 = copy_to_mode_reg (mode0, op0);
10191 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10194 pat = GEN_FCN (icode) (target, addr);
10204 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10206 tree arg0 = CALL_EXPR_ARG (exp, 0);
10207 tree arg1 = CALL_EXPR_ARG (exp, 1);
10208 tree arg2 = CALL_EXPR_ARG (exp, 2);
10209 rtx op0 = expand_normal (arg0);
10210 rtx op1 = expand_normal (arg1);
10211 rtx op2 = expand_normal (arg2);
10213 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10214 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10215 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10217 /* Invalid arguments. Bail before doing anything stoopid! */
10218 if (arg0 == error_mark_node
10219 || arg1 == error_mark_node
10220 || arg2 == error_mark_node)
10223 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10224 op0 = copy_to_mode_reg (mode2, op0);
10225 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10226 op1 = copy_to_mode_reg (mode0, op1);
10227 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10228 op2 = copy_to_mode_reg (mode1, op2);
10230 pat = GEN_FCN (icode) (op1, op2, op0);
10237 paired_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 tmode = insn_data[icode].operand[0].mode;
10247 enum machine_mode mode1 = Pmode;
10248 enum machine_mode mode2 = Pmode;
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[1].predicate) (op0, tmode))
10257 op0 = copy_to_mode_reg (tmode, op0);
10259 op2 = copy_to_mode_reg (mode2, op2);
10261 if (op1 == const0_rtx)
10263 addr = gen_rtx_MEM (tmode, op2);
10267 op1 = copy_to_mode_reg (mode1, op1);
10268 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10271 pat = GEN_FCN (icode) (addr, op0);
10278 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10280 tree arg0 = CALL_EXPR_ARG (exp, 0);
10281 tree arg1 = CALL_EXPR_ARG (exp, 1);
10282 tree arg2 = CALL_EXPR_ARG (exp, 2);
10283 rtx op0 = expand_normal (arg0);
10284 rtx op1 = expand_normal (arg1);
10285 rtx op2 = expand_normal (arg2);
10287 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10288 enum machine_mode mode1 = Pmode;
10289 enum machine_mode mode2 = Pmode;
10291 /* Invalid arguments. Bail before doing anything stoopid! */
10292 if (arg0 == error_mark_node
10293 || arg1 == error_mark_node
10294 || arg2 == error_mark_node)
10297 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10298 op0 = copy_to_mode_reg (tmode, op0);
10300 op2 = copy_to_mode_reg (mode2, op2);
10302 if (op1 == const0_rtx)
10304 addr = gen_rtx_MEM (tmode, op2);
10308 op1 = copy_to_mode_reg (mode1, op1);
10309 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10312 pat = GEN_FCN (icode) (addr, op0);
10319 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10322 tree arg0 = CALL_EXPR_ARG (exp, 0);
10323 tree arg1 = CALL_EXPR_ARG (exp, 1);
10324 tree arg2 = CALL_EXPR_ARG (exp, 2);
10325 rtx op0 = expand_normal (arg0);
10326 rtx op1 = expand_normal (arg1);
10327 rtx op2 = expand_normal (arg2);
10328 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10329 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10330 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10331 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10333 if (icode == CODE_FOR_nothing)
10334 /* Builtin not supported on this processor. */
10337 /* If we got invalid arguments bail out before generating bad rtl. */
10338 if (arg0 == error_mark_node
10339 || arg1 == error_mark_node
10340 || arg2 == error_mark_node)
10345 case CODE_FOR_altivec_vsldoi_v4sf:
10346 case CODE_FOR_altivec_vsldoi_v4si:
10347 case CODE_FOR_altivec_vsldoi_v8hi:
10348 case CODE_FOR_altivec_vsldoi_v16qi:
10349 /* Only allow 4-bit unsigned literals. */
10351 if (TREE_CODE (arg2) != INTEGER_CST
10352 || TREE_INT_CST_LOW (arg2) & ~0xf)
10354 error ("argument 3 must be a 4-bit unsigned literal");
10359 case CODE_FOR_vsx_xxpermdi_v2df:
10360 case CODE_FOR_vsx_xxpermdi_v2di:
10361 case CODE_FOR_vsx_xxsldwi_v16qi:
10362 case CODE_FOR_vsx_xxsldwi_v8hi:
10363 case CODE_FOR_vsx_xxsldwi_v4si:
10364 case CODE_FOR_vsx_xxsldwi_v4sf:
10365 case CODE_FOR_vsx_xxsldwi_v2di:
10366 case CODE_FOR_vsx_xxsldwi_v2df:
10367 /* Only allow 2-bit unsigned literals. */
10369 if (TREE_CODE (arg2) != INTEGER_CST
10370 || TREE_INT_CST_LOW (arg2) & ~0x3)
10372 error ("argument 3 must be a 2-bit unsigned literal");
10377 case CODE_FOR_vsx_set_v2df:
10378 case CODE_FOR_vsx_set_v2di:
10379 /* Only allow 1-bit unsigned literals. */
10381 if (TREE_CODE (arg2) != INTEGER_CST
10382 || TREE_INT_CST_LOW (arg2) & ~0x1)
10384 error ("argument 3 must be a 1-bit unsigned literal");
10394 || GET_MODE (target) != tmode
10395 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10396 target = gen_reg_rtx (tmode);
10398 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10399 op0 = copy_to_mode_reg (mode0, op0);
10400 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10401 op1 = copy_to_mode_reg (mode1, op1);
10402 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10403 op2 = copy_to_mode_reg (mode2, op2);
10405 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10406 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10408 pat = GEN_FCN (icode) (target, op0, op1, op2);
10416 /* Expand the lvx builtins. */
10418 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10420 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10421 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10423 enum machine_mode tmode, mode0;
10425 enum insn_code icode;
10429 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10430 icode = CODE_FOR_vector_load_v16qi;
10432 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10433 icode = CODE_FOR_vector_load_v8hi;
10435 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10436 icode = CODE_FOR_vector_load_v4si;
10438 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10439 icode = CODE_FOR_vector_load_v4sf;
10442 *expandedp = false;
10448 arg0 = CALL_EXPR_ARG (exp, 0);
10449 op0 = expand_normal (arg0);
10450 tmode = insn_data[icode].operand[0].mode;
10451 mode0 = insn_data[icode].operand[1].mode;
10454 || GET_MODE (target) != tmode
10455 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10456 target = gen_reg_rtx (tmode);
10458 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10459 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10461 pat = GEN_FCN (icode) (target, op0);
10468 /* Expand the stvx builtins. */
10470 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10473 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10474 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10476 enum machine_mode mode0, mode1;
10478 enum insn_code icode;
10482 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10483 icode = CODE_FOR_vector_store_v16qi;
10485 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10486 icode = CODE_FOR_vector_store_v8hi;
10488 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10489 icode = CODE_FOR_vector_store_v4si;
10491 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10492 icode = CODE_FOR_vector_store_v4sf;
10495 *expandedp = false;
10499 arg0 = CALL_EXPR_ARG (exp, 0);
10500 arg1 = CALL_EXPR_ARG (exp, 1);
10501 op0 = expand_normal (arg0);
10502 op1 = expand_normal (arg1);
10503 mode0 = insn_data[icode].operand[0].mode;
10504 mode1 = insn_data[icode].operand[1].mode;
10506 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10507 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10508 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10509 op1 = copy_to_mode_reg (mode1, op1);
10511 pat = GEN_FCN (icode) (op0, op1);
10519 /* Expand the dst builtins. */
10521 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10524 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10525 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10526 tree arg0, arg1, arg2;
10527 enum machine_mode mode0, mode1;
10528 rtx pat, op0, op1, op2;
10529 const struct builtin_description *d;
10532 *expandedp = false;
10534 /* Handle DST variants. */
10536 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10537 if (d->code == fcode)
10539 arg0 = CALL_EXPR_ARG (exp, 0);
10540 arg1 = CALL_EXPR_ARG (exp, 1);
10541 arg2 = CALL_EXPR_ARG (exp, 2);
10542 op0 = expand_normal (arg0);
10543 op1 = expand_normal (arg1);
10544 op2 = expand_normal (arg2);
10545 mode0 = insn_data[d->icode].operand[0].mode;
10546 mode1 = insn_data[d->icode].operand[1].mode;
10548 /* Invalid arguments, bail out before generating bad rtl. */
10549 if (arg0 == error_mark_node
10550 || arg1 == error_mark_node
10551 || arg2 == error_mark_node)
10556 if (TREE_CODE (arg2) != INTEGER_CST
10557 || TREE_INT_CST_LOW (arg2) & ~0x3)
10559 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10563 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10564 op0 = copy_to_mode_reg (Pmode, op0);
10565 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10566 op1 = copy_to_mode_reg (mode1, op1);
10568 pat = GEN_FCN (d->icode) (op0, op1, op2);
10578 /* Expand vec_init builtin. */
10580 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10582 enum machine_mode tmode = TYPE_MODE (type);
10583 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10584 int i, n_elt = GET_MODE_NUNITS (tmode);
10585 rtvec v = rtvec_alloc (n_elt);
10587 gcc_assert (VECTOR_MODE_P (tmode));
10588 gcc_assert (n_elt == call_expr_nargs (exp));
10590 for (i = 0; i < n_elt; ++i)
10592 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10593 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10596 if (!target || !register_operand (target, tmode))
10597 target = gen_reg_rtx (tmode);
10599 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10603 /* Return the integer constant in ARG. Constrain it to be in the range
10604 of the subparts of VEC_TYPE; issue an error if not. */
10607 get_element_number (tree vec_type, tree arg)
10609 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10611 if (!host_integerp (arg, 1)
10612 || (elt = tree_low_cst (arg, 1), elt > max))
10614 error ("selector must be an integer constant in the range 0..%wi", max);
10621 /* Expand vec_set builtin. */
10623 altivec_expand_vec_set_builtin (tree exp)
10625 enum machine_mode tmode, mode1;
10626 tree arg0, arg1, arg2;
10630 arg0 = CALL_EXPR_ARG (exp, 0);
10631 arg1 = CALL_EXPR_ARG (exp, 1);
10632 arg2 = CALL_EXPR_ARG (exp, 2);
10634 tmode = TYPE_MODE (TREE_TYPE (arg0));
10635 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10636 gcc_assert (VECTOR_MODE_P (tmode));
10638 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10639 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10640 elt = get_element_number (TREE_TYPE (arg0), arg2);
10642 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10643 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10645 op0 = force_reg (tmode, op0);
10646 op1 = force_reg (mode1, op1);
10648 rs6000_expand_vector_set (op0, op1, elt);
10653 /* Expand vec_ext builtin. */
10655 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10657 enum machine_mode tmode, mode0;
10662 arg0 = CALL_EXPR_ARG (exp, 0);
10663 arg1 = CALL_EXPR_ARG (exp, 1);
10665 op0 = expand_normal (arg0);
10666 elt = get_element_number (TREE_TYPE (arg0), arg1);
10668 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10669 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10670 gcc_assert (VECTOR_MODE_P (mode0));
10672 op0 = force_reg (mode0, op0);
10674 if (optimize || !target || !register_operand (target, tmode))
10675 target = gen_reg_rtx (tmode);
10677 rs6000_expand_vector_extract (target, op0, elt);
10682 /* Expand the builtin in EXP and store the result in TARGET. Store
10683 true in *EXPANDEDP if we found a builtin to expand. */
10685 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10687 const struct builtin_description *d;
10688 const struct builtin_description_predicates *dp;
10690 enum insn_code icode;
10691 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10694 enum machine_mode tmode, mode0;
10695 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10697 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10698 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10699 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10700 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10703 error ("unresolved overload for Altivec builtin %qF", fndecl);
10707 target = altivec_expand_ld_builtin (exp, target, expandedp);
10711 target = altivec_expand_st_builtin (exp, target, expandedp);
10715 target = altivec_expand_dst_builtin (exp, target, expandedp);
10723 case ALTIVEC_BUILTIN_STVX:
10724 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10725 case ALTIVEC_BUILTIN_STVEBX:
10726 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10727 case ALTIVEC_BUILTIN_STVEHX:
10728 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10729 case ALTIVEC_BUILTIN_STVEWX:
10730 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10731 case ALTIVEC_BUILTIN_STVXL:
10732 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10734 case ALTIVEC_BUILTIN_STVLX:
10735 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10736 case ALTIVEC_BUILTIN_STVLXL:
10737 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10738 case ALTIVEC_BUILTIN_STVRX:
10739 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10740 case ALTIVEC_BUILTIN_STVRXL:
10741 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10743 case ALTIVEC_BUILTIN_MFVSCR:
10744 icode = CODE_FOR_altivec_mfvscr;
10745 tmode = insn_data[icode].operand[0].mode;
10748 || GET_MODE (target) != tmode
10749 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10750 target = gen_reg_rtx (tmode);
10752 pat = GEN_FCN (icode) (target);
10758 case ALTIVEC_BUILTIN_MTVSCR:
10759 icode = CODE_FOR_altivec_mtvscr;
10760 arg0 = CALL_EXPR_ARG (exp, 0);
10761 op0 = expand_normal (arg0);
10762 mode0 = insn_data[icode].operand[0].mode;
10764 /* If we got invalid arguments bail out before generating bad rtl. */
10765 if (arg0 == error_mark_node)
10768 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10769 op0 = copy_to_mode_reg (mode0, op0);
10771 pat = GEN_FCN (icode) (op0);
10776 case ALTIVEC_BUILTIN_DSSALL:
10777 emit_insn (gen_altivec_dssall ());
10780 case ALTIVEC_BUILTIN_DSS:
10781 icode = CODE_FOR_altivec_dss;
10782 arg0 = CALL_EXPR_ARG (exp, 0);
10784 op0 = expand_normal (arg0);
10785 mode0 = insn_data[icode].operand[0].mode;
10787 /* If we got invalid arguments bail out before generating bad rtl. */
10788 if (arg0 == error_mark_node)
10791 if (TREE_CODE (arg0) != INTEGER_CST
10792 || TREE_INT_CST_LOW (arg0) & ~0x3)
10794 error ("argument to dss must be a 2-bit unsigned literal");
10798 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10799 op0 = copy_to_mode_reg (mode0, op0);
10801 emit_insn (gen_altivec_dss (op0));
10804 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10805 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10806 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10807 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10808 case VSX_BUILTIN_VEC_INIT_V2DF:
10809 case VSX_BUILTIN_VEC_INIT_V2DI:
10810 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10812 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10813 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10814 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10815 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10816 case VSX_BUILTIN_VEC_SET_V2DF:
10817 case VSX_BUILTIN_VEC_SET_V2DI:
10818 return altivec_expand_vec_set_builtin (exp);
10820 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10821 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10822 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10823 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10824 case VSX_BUILTIN_VEC_EXT_V2DF:
10825 case VSX_BUILTIN_VEC_EXT_V2DI:
10826 return altivec_expand_vec_ext_builtin (exp, target);
10830 /* Fall through. */
10833 /* Expand abs* operations. */
10835 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10836 if (d->code == fcode)
10837 return altivec_expand_abs_builtin (d->icode, exp, target);
10839 /* Expand the AltiVec predicates. */
10840 dp = bdesc_altivec_preds;
10841 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10842 if (dp->code == fcode)
10843 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10845 /* LV* are funky. We initialized them differently. */
10848 case ALTIVEC_BUILTIN_LVSL:
10849 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10850 exp, target, false);
10851 case ALTIVEC_BUILTIN_LVSR:
10852 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10853 exp, target, false);
10854 case ALTIVEC_BUILTIN_LVEBX:
10855 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10856 exp, target, false);
10857 case ALTIVEC_BUILTIN_LVEHX:
10858 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10859 exp, target, false);
10860 case ALTIVEC_BUILTIN_LVEWX:
10861 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10862 exp, target, false);
10863 case ALTIVEC_BUILTIN_LVXL:
10864 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10865 exp, target, false);
10866 case ALTIVEC_BUILTIN_LVX:
10867 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10868 exp, target, false);
10869 case ALTIVEC_BUILTIN_LVLX:
10870 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10871 exp, target, true);
10872 case ALTIVEC_BUILTIN_LVLXL:
10873 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10874 exp, target, true);
10875 case ALTIVEC_BUILTIN_LVRX:
10876 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10877 exp, target, true);
10878 case ALTIVEC_BUILTIN_LVRXL:
10879 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10880 exp, target, true);
10883 /* Fall through. */
10886 *expandedp = false;
10890 /* Expand the builtin in EXP and store the result in TARGET. Store
10891 true in *EXPANDEDP if we found a builtin to expand. */
10893 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10895 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10896 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10897 const struct builtin_description *d;
10904 case PAIRED_BUILTIN_STX:
10905 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10906 case PAIRED_BUILTIN_LX:
10907 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10910 /* Fall through. */
10913 /* Expand the paired predicates. */
10914 d = bdesc_paired_preds;
10915 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10916 if (d->code == fcode)
10917 return paired_expand_predicate_builtin (d->icode, exp, target);
10919 *expandedp = false;
10923 /* Binops that need to be initialized manually, but can be expanded
10924 automagically by rs6000_expand_binop_builtin. */
10925 static struct builtin_description bdesc_2arg_spe[] =
10927 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10928 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10929 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10930 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10931 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10932 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10933 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10934 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10935 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10936 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10937 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10938 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10939 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10940 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10941 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10942 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10943 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10944 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10945 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10946 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10947 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10948 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10951 /* Expand the builtin in EXP and store the result in TARGET. Store
10952 true in *EXPANDEDP if we found a builtin to expand.
10954 This expands the SPE builtins that are not simple unary and binary
10957 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10959 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10961 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10962 enum insn_code icode;
10963 enum machine_mode tmode, mode0;
10965 struct builtin_description *d;
10970 /* Syntax check for a 5-bit unsigned immediate. */
10973 case SPE_BUILTIN_EVSTDD:
10974 case SPE_BUILTIN_EVSTDH:
10975 case SPE_BUILTIN_EVSTDW:
10976 case SPE_BUILTIN_EVSTWHE:
10977 case SPE_BUILTIN_EVSTWHO:
10978 case SPE_BUILTIN_EVSTWWE:
10979 case SPE_BUILTIN_EVSTWWO:
10980 arg1 = CALL_EXPR_ARG (exp, 2);
10981 if (TREE_CODE (arg1) != INTEGER_CST
10982 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10984 error ("argument 2 must be a 5-bit unsigned literal");
10992 /* The evsplat*i instructions are not quite generic. */
10995 case SPE_BUILTIN_EVSPLATFI:
10996 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
10998 case SPE_BUILTIN_EVSPLATI:
10999 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11005 d = (struct builtin_description *) bdesc_2arg_spe;
11006 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11007 if (d->code == fcode)
11008 return rs6000_expand_binop_builtin (d->icode, exp, target);
11010 d = (struct builtin_description *) bdesc_spe_predicates;
11011 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11012 if (d->code == fcode)
11013 return spe_expand_predicate_builtin (d->icode, exp, target);
11015 d = (struct builtin_description *) bdesc_spe_evsel;
11016 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11017 if (d->code == fcode)
11018 return spe_expand_evsel_builtin (d->icode, exp, target);
11022 case SPE_BUILTIN_EVSTDDX:
11023 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11024 case SPE_BUILTIN_EVSTDHX:
11025 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11026 case SPE_BUILTIN_EVSTDWX:
11027 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11028 case SPE_BUILTIN_EVSTWHEX:
11029 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11030 case SPE_BUILTIN_EVSTWHOX:
11031 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11032 case SPE_BUILTIN_EVSTWWEX:
11033 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11034 case SPE_BUILTIN_EVSTWWOX:
11035 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11036 case SPE_BUILTIN_EVSTDD:
11037 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11038 case SPE_BUILTIN_EVSTDH:
11039 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11040 case SPE_BUILTIN_EVSTDW:
11041 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11042 case SPE_BUILTIN_EVSTWHE:
11043 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11044 case SPE_BUILTIN_EVSTWHO:
11045 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11046 case SPE_BUILTIN_EVSTWWE:
11047 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11048 case SPE_BUILTIN_EVSTWWO:
11049 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11050 case SPE_BUILTIN_MFSPEFSCR:
11051 icode = CODE_FOR_spe_mfspefscr;
11052 tmode = insn_data[icode].operand[0].mode;
11055 || GET_MODE (target) != tmode
11056 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11057 target = gen_reg_rtx (tmode);
11059 pat = GEN_FCN (icode) (target);
11064 case SPE_BUILTIN_MTSPEFSCR:
11065 icode = CODE_FOR_spe_mtspefscr;
11066 arg0 = CALL_EXPR_ARG (exp, 0);
11067 op0 = expand_normal (arg0);
11068 mode0 = insn_data[icode].operand[0].mode;
11070 if (arg0 == error_mark_node)
11073 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11074 op0 = copy_to_mode_reg (mode0, op0);
11076 pat = GEN_FCN (icode) (op0);
11084 *expandedp = false;
11089 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11091 rtx pat, scratch, tmp;
11092 tree form = CALL_EXPR_ARG (exp, 0);
11093 tree arg0 = CALL_EXPR_ARG (exp, 1);
11094 tree arg1 = CALL_EXPR_ARG (exp, 2);
11095 rtx op0 = expand_normal (arg0);
11096 rtx op1 = expand_normal (arg1);
11097 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11098 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11100 enum rtx_code code;
11102 if (TREE_CODE (form) != INTEGER_CST)
11104 error ("argument 1 of __builtin_paired_predicate must be a constant");
11108 form_int = TREE_INT_CST_LOW (form);
11110 gcc_assert (mode0 == mode1);
11112 if (arg0 == error_mark_node || arg1 == error_mark_node)
11116 || GET_MODE (target) != SImode
11117 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11118 target = gen_reg_rtx (SImode);
11119 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11120 op0 = copy_to_mode_reg (mode0, op0);
11121 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11122 op1 = copy_to_mode_reg (mode1, op1);
11124 scratch = gen_reg_rtx (CCFPmode);
11126 pat = GEN_FCN (icode) (scratch, op0, op1);
11148 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11151 error ("argument 1 of __builtin_paired_predicate is out of range");
11155 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11156 emit_move_insn (target, tmp);
11161 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11163 rtx pat, scratch, tmp;
11164 tree form = CALL_EXPR_ARG (exp, 0);
11165 tree arg0 = CALL_EXPR_ARG (exp, 1);
11166 tree arg1 = CALL_EXPR_ARG (exp, 2);
11167 rtx op0 = expand_normal (arg0);
11168 rtx op1 = expand_normal (arg1);
11169 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11170 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11172 enum rtx_code code;
11174 if (TREE_CODE (form) != INTEGER_CST)
11176 error ("argument 1 of __builtin_spe_predicate must be a constant");
11180 form_int = TREE_INT_CST_LOW (form);
11182 gcc_assert (mode0 == mode1);
11184 if (arg0 == error_mark_node || arg1 == error_mark_node)
11188 || GET_MODE (target) != SImode
11189 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11190 target = gen_reg_rtx (SImode);
11192 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11193 op0 = copy_to_mode_reg (mode0, op0);
11194 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11195 op1 = copy_to_mode_reg (mode1, op1);
11197 scratch = gen_reg_rtx (CCmode);
11199 pat = GEN_FCN (icode) (scratch, op0, op1);
11204 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11205 _lower_. We use one compare, but look in different bits of the
11206 CR for each variant.
11208 There are 2 elements in each SPE simd type (upper/lower). The CR
11209 bits are set as follows:
11211 BIT0 | BIT 1 | BIT 2 | BIT 3
11212 U | L | (U | L) | (U & L)
11214 So, for an "all" relationship, BIT 3 would be set.
11215 For an "any" relationship, BIT 2 would be set. Etc.
11217 Following traditional nomenclature, these bits map to:
11219 BIT0 | BIT 1 | BIT 2 | BIT 3
11222 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11227 /* All variant. OV bit. */
11229 /* We need to get to the OV bit, which is the ORDERED bit. We
11230 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11231 that's ugly and will make validate_condition_mode die.
11232 So let's just use another pattern. */
11233 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11235 /* Any variant. EQ bit. */
11239 /* Upper variant. LT bit. */
11243 /* Lower variant. GT bit. */
11248 error ("argument 1 of __builtin_spe_predicate is out of range");
11252 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11253 emit_move_insn (target, tmp);
11258 /* The evsel builtins look like this:
11260 e = __builtin_spe_evsel_OP (a, b, c, d);
11262 and work like this:
11264 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11265 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11269 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11272 tree arg0 = CALL_EXPR_ARG (exp, 0);
11273 tree arg1 = CALL_EXPR_ARG (exp, 1);
11274 tree arg2 = CALL_EXPR_ARG (exp, 2);
11275 tree arg3 = CALL_EXPR_ARG (exp, 3);
11276 rtx op0 = expand_normal (arg0);
11277 rtx op1 = expand_normal (arg1);
11278 rtx op2 = expand_normal (arg2);
11279 rtx op3 = expand_normal (arg3);
11280 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11281 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11283 gcc_assert (mode0 == mode1);
11285 if (arg0 == error_mark_node || arg1 == error_mark_node
11286 || arg2 == error_mark_node || arg3 == error_mark_node)
11290 || GET_MODE (target) != mode0
11291 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11292 target = gen_reg_rtx (mode0);
11294 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11295 op0 = copy_to_mode_reg (mode0, op0);
11296 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11297 op1 = copy_to_mode_reg (mode0, op1);
11298 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11299 op2 = copy_to_mode_reg (mode0, op2);
11300 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11301 op3 = copy_to_mode_reg (mode0, op3);
11303 /* Generate the compare. */
11304 scratch = gen_reg_rtx (CCmode);
11305 pat = GEN_FCN (icode) (scratch, op0, op1);
11310 if (mode0 == V2SImode)
11311 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11313 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11318 /* Expand an expression EXP that calls a built-in function,
11319 with result going to TARGET if that's convenient
11320 (and in mode MODE if that's convenient).
11321 SUBTARGET may be used as the target for computing one of EXP's operands.
11322 IGNORE is nonzero if the value is to be ignored. */
11325 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11326 enum machine_mode mode ATTRIBUTE_UNUSED,
11327 int ignore ATTRIBUTE_UNUSED)
11329 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11330 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11331 const struct builtin_description *d;
11338 case RS6000_BUILTIN_RECIP:
11339 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11341 case RS6000_BUILTIN_RECIPF:
11342 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11344 case RS6000_BUILTIN_RSQRTF:
11345 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11347 case RS6000_BUILTIN_RSQRT:
11348 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11350 case RS6000_BUILTIN_BSWAP_HI:
11351 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11353 case POWER7_BUILTIN_BPERMD:
11354 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11355 ? CODE_FOR_bpermd_di
11356 : CODE_FOR_bpermd_si), exp, target);
11358 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11359 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11361 int icode = (int) CODE_FOR_altivec_lvsr;
11362 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11363 enum machine_mode mode = insn_data[icode].operand[1].mode;
11367 gcc_assert (TARGET_ALTIVEC);
11369 arg = CALL_EXPR_ARG (exp, 0);
11370 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
11371 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11372 addr = memory_address (mode, op);
11373 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11377 /* For the load case need to negate the address. */
11378 op = gen_reg_rtx (GET_MODE (addr));
11379 emit_insn (gen_rtx_SET (VOIDmode, op,
11380 gen_rtx_NEG (GET_MODE (addr), addr)));
11382 op = gen_rtx_MEM (mode, op);
11385 || GET_MODE (target) != tmode
11386 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11387 target = gen_reg_rtx (tmode);
11389 /*pat = gen_altivec_lvsr (target, op);*/
11390 pat = GEN_FCN (icode) (target, op);
11398 case ALTIVEC_BUILTIN_VCFUX:
11399 case ALTIVEC_BUILTIN_VCFSX:
11400 case ALTIVEC_BUILTIN_VCTUXS:
11401 case ALTIVEC_BUILTIN_VCTSXS:
11402 /* FIXME: There's got to be a nicer way to handle this case than
11403 constructing a new CALL_EXPR. */
11404 if (call_expr_nargs (exp) == 1)
11406 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11407 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11415 if (TARGET_ALTIVEC)
11417 ret = altivec_expand_builtin (exp, target, &success);
11424 ret = spe_expand_builtin (exp, target, &success);
11429 if (TARGET_PAIRED_FLOAT)
11431 ret = paired_expand_builtin (exp, target, &success);
11437 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11439 /* Handle simple unary operations. */
11440 d = (struct builtin_description *) bdesc_1arg;
11441 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11442 if (d->code == fcode)
11443 return rs6000_expand_unop_builtin (d->icode, exp, target);
11445 /* Handle simple binary operations. */
11446 d = (struct builtin_description *) bdesc_2arg;
11447 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11448 if (d->code == fcode)
11449 return rs6000_expand_binop_builtin (d->icode, exp, target);
11451 /* Handle simple ternary operations. */
11453 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11454 if (d->code == fcode)
11455 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11457 gcc_unreachable ();
11461 rs6000_init_builtins (void)
11466 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11467 V2SF_type_node = build_vector_type (float_type_node, 2);
11468 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11469 V2DF_type_node = build_vector_type (double_type_node, 2);
11470 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11471 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11472 V4SF_type_node = build_vector_type (float_type_node, 4);
11473 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11474 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11476 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11477 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11478 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11479 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11481 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11482 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11483 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11484 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11486 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11487 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11488 'vector unsigned short'. */
11490 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11491 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11492 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11493 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11494 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11496 long_integer_type_internal_node = long_integer_type_node;
11497 long_unsigned_type_internal_node = long_unsigned_type_node;
11498 intQI_type_internal_node = intQI_type_node;
11499 uintQI_type_internal_node = unsigned_intQI_type_node;
11500 intHI_type_internal_node = intHI_type_node;
11501 uintHI_type_internal_node = unsigned_intHI_type_node;
11502 intSI_type_internal_node = intSI_type_node;
11503 uintSI_type_internal_node = unsigned_intSI_type_node;
11504 intDI_type_internal_node = intDI_type_node;
11505 uintDI_type_internal_node = unsigned_intDI_type_node;
11506 float_type_internal_node = float_type_node;
11507 double_type_internal_node = float_type_node;
11508 void_type_internal_node = void_type_node;
11510 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11512 builtin_mode_to_type[QImode][0] = integer_type_node;
11513 builtin_mode_to_type[HImode][0] = integer_type_node;
11514 builtin_mode_to_type[SImode][0] = intSI_type_node;
11515 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
11516 builtin_mode_to_type[DImode][0] = intDI_type_node;
11517 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
11518 builtin_mode_to_type[SFmode][0] = float_type_node;
11519 builtin_mode_to_type[DFmode][0] = double_type_node;
11520 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
11521 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
11522 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
11523 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
11524 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
11525 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
11526 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11527 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11528 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11529 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11530 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11531 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11532 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11534 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11535 get_identifier ("__bool char"),
11536 bool_char_type_node);
11537 TYPE_NAME (bool_char_type_node) = tdecl;
11538 (*lang_hooks.decls.pushdecl) (tdecl);
11539 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11540 get_identifier ("__bool short"),
11541 bool_short_type_node);
11542 TYPE_NAME (bool_short_type_node) = tdecl;
11543 (*lang_hooks.decls.pushdecl) (tdecl);
11544 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11545 get_identifier ("__bool int"),
11546 bool_int_type_node);
11547 TYPE_NAME (bool_int_type_node) = tdecl;
11548 (*lang_hooks.decls.pushdecl) (tdecl);
11549 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
11551 TYPE_NAME (pixel_type_node) = tdecl;
11552 (*lang_hooks.decls.pushdecl) (tdecl);
11554 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
11555 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11556 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11557 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11558 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11560 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11561 get_identifier ("__vector unsigned char"),
11562 unsigned_V16QI_type_node);
11563 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11564 (*lang_hooks.decls.pushdecl) (tdecl);
11565 tdecl = build_decl (BUILTINS_LOCATION,
11566 TYPE_DECL, get_identifier ("__vector signed char"),
11568 TYPE_NAME (V16QI_type_node) = tdecl;
11569 (*lang_hooks.decls.pushdecl) (tdecl);
11570 tdecl = build_decl (BUILTINS_LOCATION,
11571 TYPE_DECL, get_identifier ("__vector __bool char"),
11572 bool_V16QI_type_node);
11573 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11574 (*lang_hooks.decls.pushdecl) (tdecl);
11576 tdecl = build_decl (BUILTINS_LOCATION,
11577 TYPE_DECL, get_identifier ("__vector unsigned short"),
11578 unsigned_V8HI_type_node);
11579 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11580 (*lang_hooks.decls.pushdecl) (tdecl);
11581 tdecl = build_decl (BUILTINS_LOCATION,
11582 TYPE_DECL, get_identifier ("__vector signed short"),
11584 TYPE_NAME (V8HI_type_node) = tdecl;
11585 (*lang_hooks.decls.pushdecl) (tdecl);
11586 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11587 get_identifier ("__vector __bool short"),
11588 bool_V8HI_type_node);
11589 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11590 (*lang_hooks.decls.pushdecl) (tdecl);
11592 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11593 get_identifier ("__vector unsigned int"),
11594 unsigned_V4SI_type_node);
11595 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11596 (*lang_hooks.decls.pushdecl) (tdecl);
11597 tdecl = build_decl (BUILTINS_LOCATION,
11598 TYPE_DECL, get_identifier ("__vector signed int"),
11600 TYPE_NAME (V4SI_type_node) = tdecl;
11601 (*lang_hooks.decls.pushdecl) (tdecl);
11602 tdecl = build_decl (BUILTINS_LOCATION,
11603 TYPE_DECL, get_identifier ("__vector __bool int"),
11604 bool_V4SI_type_node);
11605 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11606 (*lang_hooks.decls.pushdecl) (tdecl);
11608 tdecl = build_decl (BUILTINS_LOCATION,
11609 TYPE_DECL, get_identifier ("__vector float"),
11611 TYPE_NAME (V4SF_type_node) = tdecl;
11612 (*lang_hooks.decls.pushdecl) (tdecl);
11613 tdecl = build_decl (BUILTINS_LOCATION,
11614 TYPE_DECL, get_identifier ("__vector __pixel"),
11615 pixel_V8HI_type_node);
11616 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11617 (*lang_hooks.decls.pushdecl) (tdecl);
11621 tdecl = build_decl (BUILTINS_LOCATION,
11622 TYPE_DECL, get_identifier ("__vector double"),
11624 TYPE_NAME (V2DF_type_node) = tdecl;
11625 (*lang_hooks.decls.pushdecl) (tdecl);
11627 tdecl = build_decl (BUILTINS_LOCATION,
11628 TYPE_DECL, get_identifier ("__vector long"),
11630 TYPE_NAME (V2DI_type_node) = tdecl;
11631 (*lang_hooks.decls.pushdecl) (tdecl);
11633 tdecl = build_decl (BUILTINS_LOCATION,
11634 TYPE_DECL, get_identifier ("__vector unsigned long"),
11635 unsigned_V2DI_type_node);
11636 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11637 (*lang_hooks.decls.pushdecl) (tdecl);
11639 tdecl = build_decl (BUILTINS_LOCATION,
11640 TYPE_DECL, get_identifier ("__vector __bool long"),
11641 bool_V2DI_type_node);
11642 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11643 (*lang_hooks.decls.pushdecl) (tdecl);
11646 if (TARGET_PAIRED_FLOAT)
11647 paired_init_builtins ();
11649 spe_init_builtins ();
11650 if (TARGET_ALTIVEC)
11651 altivec_init_builtins ();
11652 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11653 rs6000_common_init_builtins ();
11656 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11657 RS6000_BUILTIN_RECIP,
11658 "__builtin_recipdiv");
11659 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11660 RS6000_BUILTIN_RECIP);
11664 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11665 RS6000_BUILTIN_RECIPF,
11666 "__builtin_recipdivf");
11667 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11668 RS6000_BUILTIN_RECIPF);
11670 if (TARGET_FRSQRTE)
11672 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
11673 RS6000_BUILTIN_RSQRT,
11674 "__builtin_rsqrt");
11675 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
11676 RS6000_BUILTIN_RSQRT);
11678 if (TARGET_FRSQRTES)
11680 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11681 RS6000_BUILTIN_RSQRTF,
11682 "__builtin_rsqrtf");
11683 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11684 RS6000_BUILTIN_RSQRTF);
11686 if (TARGET_POPCNTD)
11688 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11689 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11690 POWER7_BUILTIN_BPERMD,
11691 "__builtin_bpermd");
11692 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11693 POWER7_BUILTIN_BPERMD);
11695 if (TARGET_POWERPC)
11697 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11698 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11699 unsigned_intHI_type_node,
11701 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11702 RS6000_BUILTIN_BSWAP_HI);
11706 /* AIX libm provides clog as __clog. */
11707 if (built_in_decls [BUILT_IN_CLOG])
11708 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11711 #ifdef SUBTARGET_INIT_BUILTINS
11712 SUBTARGET_INIT_BUILTINS;
11716 /* Returns the rs6000 builtin decl for CODE. */
11719 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
11721 if (code >= RS6000_BUILTIN_COUNT)
11722 return error_mark_node;
11724 return rs6000_builtin_decls[code];
11727 /* Search through a set of builtins and enable the mask bits.
11728 DESC is an array of builtins.
11729 SIZE is the total number of builtins.
11730 START is the builtin enum at which to start.
11731 END is the builtin enum at which to end. */
11733 enable_mask_for_builtins (struct builtin_description *desc, int size,
11734 enum rs6000_builtins start,
11735 enum rs6000_builtins end)
11739 for (i = 0; i < size; ++i)
11740 if (desc[i].code == start)
11746 for (; i < size; ++i)
11748 /* Flip all the bits on. */
11749 desc[i].mask = target_flags;
11750 if (desc[i].code == end)
11756 spe_init_builtins (void)
11758 tree endlink = void_list_node;
11759 tree puint_type_node = build_pointer_type (unsigned_type_node);
11760 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11761 struct builtin_description *d;
11764 tree v2si_ftype_4_v2si
11765 = build_function_type
11766 (opaque_V2SI_type_node,
11767 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11768 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11769 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11770 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11773 tree v2sf_ftype_4_v2sf
11774 = build_function_type
11775 (opaque_V2SF_type_node,
11776 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11777 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11778 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11779 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11782 tree int_ftype_int_v2si_v2si
11783 = build_function_type
11784 (integer_type_node,
11785 tree_cons (NULL_TREE, integer_type_node,
11786 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11787 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11790 tree int_ftype_int_v2sf_v2sf
11791 = build_function_type
11792 (integer_type_node,
11793 tree_cons (NULL_TREE, integer_type_node,
11794 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11795 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11798 tree void_ftype_v2si_puint_int
11799 = build_function_type (void_type_node,
11800 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11801 tree_cons (NULL_TREE, puint_type_node,
11802 tree_cons (NULL_TREE,
11806 tree void_ftype_v2si_puint_char
11807 = build_function_type (void_type_node,
11808 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11809 tree_cons (NULL_TREE, puint_type_node,
11810 tree_cons (NULL_TREE,
11814 tree void_ftype_v2si_pv2si_int
11815 = build_function_type (void_type_node,
11816 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11817 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11818 tree_cons (NULL_TREE,
11822 tree void_ftype_v2si_pv2si_char
11823 = build_function_type (void_type_node,
11824 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11825 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11826 tree_cons (NULL_TREE,
11830 tree void_ftype_int
11831 = build_function_type (void_type_node,
11832 tree_cons (NULL_TREE, integer_type_node, endlink));
11834 tree int_ftype_void
11835 = build_function_type (integer_type_node, endlink);
11837 tree v2si_ftype_pv2si_int
11838 = build_function_type (opaque_V2SI_type_node,
11839 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11840 tree_cons (NULL_TREE, integer_type_node,
11843 tree v2si_ftype_puint_int
11844 = build_function_type (opaque_V2SI_type_node,
11845 tree_cons (NULL_TREE, puint_type_node,
11846 tree_cons (NULL_TREE, integer_type_node,
11849 tree v2si_ftype_pushort_int
11850 = build_function_type (opaque_V2SI_type_node,
11851 tree_cons (NULL_TREE, pushort_type_node,
11852 tree_cons (NULL_TREE, integer_type_node,
11855 tree v2si_ftype_signed_char
11856 = build_function_type (opaque_V2SI_type_node,
11857 tree_cons (NULL_TREE, signed_char_type_node,
11860 /* The initialization of the simple binary and unary builtins is
11861 done in rs6000_common_init_builtins, but we have to enable the
11862 mask bits here manually because we have run out of `target_flags'
11863 bits. We really need to redesign this mask business. */
11865 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11866 ARRAY_SIZE (bdesc_2arg),
11867 SPE_BUILTIN_EVADDW,
11868 SPE_BUILTIN_EVXOR);
11869 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11870 ARRAY_SIZE (bdesc_1arg),
11872 SPE_BUILTIN_EVSUBFUSIAAW);
11873 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11874 ARRAY_SIZE (bdesc_spe_predicates),
11875 SPE_BUILTIN_EVCMPEQ,
11876 SPE_BUILTIN_EVFSTSTLT);
11877 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11878 ARRAY_SIZE (bdesc_spe_evsel),
11879 SPE_BUILTIN_EVSEL_CMPGTS,
11880 SPE_BUILTIN_EVSEL_FSTSTEQ);
11882 (*lang_hooks.decls.pushdecl)
11883 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11884 get_identifier ("__ev64_opaque__"),
11885 opaque_V2SI_type_node));
11887 /* Initialize irregular SPE builtins. */
11889 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11890 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11891 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11892 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11893 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11894 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11895 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11896 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11897 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11898 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11899 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11900 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11901 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11902 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11903 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11904 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11905 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11906 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11909 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11910 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11911 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11912 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11913 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11914 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11915 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11916 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11917 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11918 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11919 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11920 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11921 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11922 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11923 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11924 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11925 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11926 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11927 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11928 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11929 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11930 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11933 d = (struct builtin_description *) bdesc_spe_predicates;
11934 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11938 switch (insn_data[d->icode].operand[1].mode)
11941 type = int_ftype_int_v2si_v2si;
11944 type = int_ftype_int_v2sf_v2sf;
11947 gcc_unreachable ();
11950 def_builtin (d->mask, d->name, type, d->code);
11953 /* Evsel predicates. */
11954 d = (struct builtin_description *) bdesc_spe_evsel;
11955 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11959 switch (insn_data[d->icode].operand[1].mode)
11962 type = v2si_ftype_4_v2si;
11965 type = v2sf_ftype_4_v2sf;
11968 gcc_unreachable ();
11971 def_builtin (d->mask, d->name, type, d->code);
11976 paired_init_builtins (void)
11978 const struct builtin_description *d;
11980 tree endlink = void_list_node;
11982 tree int_ftype_int_v2sf_v2sf
11983 = build_function_type
11984 (integer_type_node,
11985 tree_cons (NULL_TREE, integer_type_node,
11986 tree_cons (NULL_TREE, V2SF_type_node,
11987 tree_cons (NULL_TREE, V2SF_type_node,
11989 tree pcfloat_type_node =
11990 build_pointer_type (build_qualified_type
11991 (float_type_node, TYPE_QUAL_CONST));
11993 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
11994 long_integer_type_node,
11997 tree void_ftype_v2sf_long_pcfloat =
11998 build_function_type_list (void_type_node,
12000 long_integer_type_node,
12005 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12006 PAIRED_BUILTIN_LX);
12009 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12010 PAIRED_BUILTIN_STX);
12013 d = bdesc_paired_preds;
12014 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12018 switch (insn_data[d->icode].operand[1].mode)
12021 type = int_ftype_int_v2sf_v2sf;
12024 gcc_unreachable ();
12027 def_builtin (d->mask, d->name, type, d->code);
12032 altivec_init_builtins (void)
12034 const struct builtin_description *d;
12035 const struct builtin_description_predicates *dp;
12039 tree pfloat_type_node = build_pointer_type (float_type_node);
12040 tree pint_type_node = build_pointer_type (integer_type_node);
12041 tree pshort_type_node = build_pointer_type (short_integer_type_node);
12042 tree pchar_type_node = build_pointer_type (char_type_node);
12044 tree pvoid_type_node = build_pointer_type (void_type_node);
12046 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
12047 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
12048 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
12049 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
12051 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
12053 tree int_ftype_opaque
12054 = build_function_type_list (integer_type_node,
12055 opaque_V4SI_type_node, NULL_TREE);
12056 tree opaque_ftype_opaque
12057 = build_function_type (integer_type_node,
12059 tree opaque_ftype_opaque_int
12060 = build_function_type_list (opaque_V4SI_type_node,
12061 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12062 tree opaque_ftype_opaque_opaque_int
12063 = build_function_type_list (opaque_V4SI_type_node,
12064 opaque_V4SI_type_node, opaque_V4SI_type_node,
12065 integer_type_node, NULL_TREE);
12066 tree int_ftype_int_opaque_opaque
12067 = build_function_type_list (integer_type_node,
12068 integer_type_node, opaque_V4SI_type_node,
12069 opaque_V4SI_type_node, NULL_TREE);
12070 tree int_ftype_int_v4si_v4si
12071 = build_function_type_list (integer_type_node,
12072 integer_type_node, V4SI_type_node,
12073 V4SI_type_node, NULL_TREE);
12074 tree v4sf_ftype_pcfloat
12075 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
12076 tree void_ftype_pfloat_v4sf
12077 = build_function_type_list (void_type_node,
12078 pfloat_type_node, V4SF_type_node, NULL_TREE);
12079 tree v4si_ftype_pcint
12080 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
12081 tree void_ftype_pint_v4si
12082 = build_function_type_list (void_type_node,
12083 pint_type_node, V4SI_type_node, NULL_TREE);
12084 tree v8hi_ftype_pcshort
12085 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
12086 tree void_ftype_pshort_v8hi
12087 = build_function_type_list (void_type_node,
12088 pshort_type_node, V8HI_type_node, NULL_TREE);
12089 tree v16qi_ftype_pcchar
12090 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
12091 tree void_ftype_pchar_v16qi
12092 = build_function_type_list (void_type_node,
12093 pchar_type_node, V16QI_type_node, NULL_TREE);
12094 tree void_ftype_v4si
12095 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12096 tree v8hi_ftype_void
12097 = build_function_type (V8HI_type_node, void_list_node);
12098 tree void_ftype_void
12099 = build_function_type (void_type_node, void_list_node);
12100 tree void_ftype_int
12101 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12103 tree opaque_ftype_long_pcvoid
12104 = build_function_type_list (opaque_V4SI_type_node,
12105 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12106 tree v16qi_ftype_long_pcvoid
12107 = build_function_type_list (V16QI_type_node,
12108 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12109 tree v8hi_ftype_long_pcvoid
12110 = build_function_type_list (V8HI_type_node,
12111 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12112 tree v4si_ftype_long_pcvoid
12113 = build_function_type_list (V4SI_type_node,
12114 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12116 tree void_ftype_opaque_long_pvoid
12117 = build_function_type_list (void_type_node,
12118 opaque_V4SI_type_node, long_integer_type_node,
12119 pvoid_type_node, NULL_TREE);
12120 tree void_ftype_v4si_long_pvoid
12121 = build_function_type_list (void_type_node,
12122 V4SI_type_node, long_integer_type_node,
12123 pvoid_type_node, NULL_TREE);
12124 tree void_ftype_v16qi_long_pvoid
12125 = build_function_type_list (void_type_node,
12126 V16QI_type_node, long_integer_type_node,
12127 pvoid_type_node, NULL_TREE);
12128 tree void_ftype_v8hi_long_pvoid
12129 = build_function_type_list (void_type_node,
12130 V8HI_type_node, long_integer_type_node,
12131 pvoid_type_node, NULL_TREE);
12132 tree int_ftype_int_v8hi_v8hi
12133 = build_function_type_list (integer_type_node,
12134 integer_type_node, V8HI_type_node,
12135 V8HI_type_node, NULL_TREE);
12136 tree int_ftype_int_v16qi_v16qi
12137 = build_function_type_list (integer_type_node,
12138 integer_type_node, V16QI_type_node,
12139 V16QI_type_node, NULL_TREE);
12140 tree int_ftype_int_v4sf_v4sf
12141 = build_function_type_list (integer_type_node,
12142 integer_type_node, V4SF_type_node,
12143 V4SF_type_node, NULL_TREE);
12144 tree int_ftype_int_v2df_v2df
12145 = build_function_type_list (integer_type_node,
12146 integer_type_node, V2DF_type_node,
12147 V2DF_type_node, NULL_TREE);
12148 tree v4si_ftype_v4si
12149 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12150 tree v8hi_ftype_v8hi
12151 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12152 tree v16qi_ftype_v16qi
12153 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12154 tree v4sf_ftype_v4sf
12155 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12156 tree v2df_ftype_v2df
12157 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12158 tree void_ftype_pcvoid_int_int
12159 = build_function_type_list (void_type_node,
12160 pcvoid_type_node, integer_type_node,
12161 integer_type_node, NULL_TREE);
12163 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
12164 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
12165 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
12166 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
12167 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
12168 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
12169 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
12170 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
12171 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
12172 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
12173 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
12174 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
12175 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
12176 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
12177 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
12178 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
12179 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12180 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12181 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12182 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12183 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12184 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12185 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12186 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12187 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12188 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12189 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12190 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12191 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12192 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12193 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12194 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12195 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12196 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12197 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12198 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12199 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12200 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12201 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12202 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12203 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12204 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12205 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12206 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12207 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12208 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12210 if (rs6000_cpu == PROCESSOR_CELL)
12212 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12213 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12214 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12215 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12217 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12218 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12219 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12220 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12222 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12223 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12224 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12225 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12227 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12228 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12229 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12230 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12232 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12233 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12234 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12236 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12237 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12238 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12239 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12240 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12241 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12242 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12243 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12244 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12245 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12246 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12247 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12249 /* Add the DST variants. */
12251 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12252 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12254 /* Initialize the predicates. */
12255 dp = bdesc_altivec_preds;
12256 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12258 enum machine_mode mode1;
12260 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12261 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12262 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12263 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12268 mode1 = insn_data[dp->icode].operand[1].mode;
12273 type = int_ftype_int_opaque_opaque;
12276 type = int_ftype_int_v4si_v4si;
12279 type = int_ftype_int_v8hi_v8hi;
12282 type = int_ftype_int_v16qi_v16qi;
12285 type = int_ftype_int_v4sf_v4sf;
12288 type = int_ftype_int_v2df_v2df;
12291 gcc_unreachable ();
12294 def_builtin (dp->mask, dp->name, type, dp->code);
12297 /* Initialize the abs* operators. */
12299 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12301 enum machine_mode mode0;
12304 mode0 = insn_data[d->icode].operand[0].mode;
12309 type = v4si_ftype_v4si;
12312 type = v8hi_ftype_v8hi;
12315 type = v16qi_ftype_v16qi;
12318 type = v4sf_ftype_v4sf;
12321 type = v2df_ftype_v2df;
12324 gcc_unreachable ();
12327 def_builtin (d->mask, d->name, type, d->code);
12330 if (TARGET_ALTIVEC)
12334 /* Initialize target builtin that implements
12335 targetm.vectorize.builtin_mask_for_load. */
12337 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12338 v16qi_ftype_long_pcvoid,
12339 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12340 BUILT_IN_MD, NULL, NULL_TREE);
12341 TREE_READONLY (decl) = 1;
12342 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12343 altivec_builtin_mask_for_load = decl;
12346 /* Access to the vec_init patterns. */
12347 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12348 integer_type_node, integer_type_node,
12349 integer_type_node, NULL_TREE);
12350 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12351 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12353 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12354 short_integer_type_node,
12355 short_integer_type_node,
12356 short_integer_type_node,
12357 short_integer_type_node,
12358 short_integer_type_node,
12359 short_integer_type_node,
12360 short_integer_type_node, NULL_TREE);
12361 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12362 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12364 ftype = build_function_type_list (V16QI_type_node, char_type_node,
12365 char_type_node, char_type_node,
12366 char_type_node, char_type_node,
12367 char_type_node, char_type_node,
12368 char_type_node, char_type_node,
12369 char_type_node, char_type_node,
12370 char_type_node, char_type_node,
12371 char_type_node, char_type_node,
12372 char_type_node, NULL_TREE);
12373 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
12374 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
12376 ftype = build_function_type_list (V4SF_type_node, float_type_node,
12377 float_type_node, float_type_node,
12378 float_type_node, NULL_TREE);
12379 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
12380 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12384 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12385 double_type_node, NULL_TREE);
12386 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12387 VSX_BUILTIN_VEC_INIT_V2DF);
12389 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12390 intDI_type_node, NULL_TREE);
12391 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12392 VSX_BUILTIN_VEC_INIT_V2DI);
12395 /* Access to the vec_set patterns. */
12396 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12398 integer_type_node, NULL_TREE);
12399 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12400 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12402 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12404 integer_type_node, NULL_TREE);
12405 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12406 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12408 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12410 integer_type_node, NULL_TREE);
12411 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12412 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12414 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12416 integer_type_node, NULL_TREE);
12417 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12418 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12422 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12424 integer_type_node, NULL_TREE);
12425 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12426 VSX_BUILTIN_VEC_SET_V2DF);
12428 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12430 integer_type_node, NULL_TREE);
12431 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12432 VSX_BUILTIN_VEC_SET_V2DI);
12435 /* Access to the vec_extract patterns. */
12436 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12437 integer_type_node, NULL_TREE);
12438 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12439 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12441 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12442 integer_type_node, NULL_TREE);
12443 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12444 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12446 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12447 integer_type_node, NULL_TREE);
12448 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12449 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12451 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12452 integer_type_node, NULL_TREE);
12453 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12454 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12458 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12459 integer_type_node, NULL_TREE);
12460 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12461 VSX_BUILTIN_VEC_EXT_V2DF);
12463 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12464 integer_type_node, NULL_TREE);
12465 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12466 VSX_BUILTIN_VEC_EXT_V2DI);
12470 /* Hash function for builtin functions with up to 3 arguments and a return
12473 builtin_hash_function (const void *hash_entry)
12477 const struct builtin_hash_struct *bh =
12478 (const struct builtin_hash_struct *) hash_entry;
12480 for (i = 0; i < 4; i++)
12482 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12483 ret = (ret * 2) + bh->uns_p[i];
12489 /* Compare builtin hash entries H1 and H2 for equivalence. */
12491 builtin_hash_eq (const void *h1, const void *h2)
12493 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12494 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
12496 return ((p1->mode[0] == p2->mode[0])
12497 && (p1->mode[1] == p2->mode[1])
12498 && (p1->mode[2] == p2->mode[2])
12499 && (p1->mode[3] == p2->mode[3])
12500 && (p1->uns_p[0] == p2->uns_p[0])
12501 && (p1->uns_p[1] == p2->uns_p[1])
12502 && (p1->uns_p[2] == p2->uns_p[2])
12503 && (p1->uns_p[3] == p2->uns_p[3]));
12506 /* Map types for builtin functions with an explicit return type and up to 3
12507 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12508 of the argument. */
12510 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
12511 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
12512 enum rs6000_builtins builtin, const char *name)
12514 struct builtin_hash_struct h;
12515 struct builtin_hash_struct *h2;
12519 tree ret_type = NULL_TREE;
12520 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
12523 /* Create builtin_hash_table. */
12524 if (builtin_hash_table == NULL)
12525 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
12526 builtin_hash_eq, NULL);
12528 h.type = NULL_TREE;
12529 h.mode[0] = mode_ret;
12530 h.mode[1] = mode_arg0;
12531 h.mode[2] = mode_arg1;
12532 h.mode[3] = mode_arg2;
12538 /* If the builtin is a type that produces unsigned results or takes unsigned
12539 arguments, and it is returned as a decl for the vectorizer (such as
12540 widening multiplies, permute), make sure the arguments and return value
12541 are type correct. */
12544 /* unsigned 2 argument functions. */
12545 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12546 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12547 case ALTIVEC_BUILTIN_VMULOUB_UNS:
12548 case ALTIVEC_BUILTIN_VMULOUH_UNS:
12554 /* unsigned 3 argument functions. */
12555 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
12556 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
12557 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
12558 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
12559 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
12560 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
12561 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
12562 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
12563 case VSX_BUILTIN_VPERM_16QI_UNS:
12564 case VSX_BUILTIN_VPERM_8HI_UNS:
12565 case VSX_BUILTIN_VPERM_4SI_UNS:
12566 case VSX_BUILTIN_VPERM_2DI_UNS:
12567 case VSX_BUILTIN_XXSEL_16QI_UNS:
12568 case VSX_BUILTIN_XXSEL_8HI_UNS:
12569 case VSX_BUILTIN_XXSEL_4SI_UNS:
12570 case VSX_BUILTIN_XXSEL_2DI_UNS:
12577 /* signed permute functions with unsigned char mask. */
12578 case ALTIVEC_BUILTIN_VPERM_16QI:
12579 case ALTIVEC_BUILTIN_VPERM_8HI:
12580 case ALTIVEC_BUILTIN_VPERM_4SI:
12581 case ALTIVEC_BUILTIN_VPERM_4SF:
12582 case ALTIVEC_BUILTIN_VPERM_2DI:
12583 case ALTIVEC_BUILTIN_VPERM_2DF:
12584 case VSX_BUILTIN_VPERM_16QI:
12585 case VSX_BUILTIN_VPERM_8HI:
12586 case VSX_BUILTIN_VPERM_4SI:
12587 case VSX_BUILTIN_VPERM_4SF:
12588 case VSX_BUILTIN_VPERM_2DI:
12589 case VSX_BUILTIN_VPERM_2DF:
12593 /* unsigned args, signed return. */
12594 case VSX_BUILTIN_XVCVUXDDP_UNS:
12595 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12599 /* signed args, unsigned return. */
12600 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12601 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12609 /* Figure out how many args are present. */
12610 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12614 fatal_error ("internal error: builtin function %s had no type", name);
12616 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12617 if (!ret_type && h.uns_p[0])
12618 ret_type = builtin_mode_to_type[h.mode[0]][0];
12621 fatal_error ("internal error: builtin function %s had an unexpected "
12622 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12624 for (i = 0; i < num_args; i++)
12626 int m = (int) h.mode[i+1];
12627 int uns_p = h.uns_p[i+1];
12629 arg_type[i] = builtin_mode_to_type[m][uns_p];
12630 if (!arg_type[i] && uns_p)
12631 arg_type[i] = builtin_mode_to_type[m][0];
12634 fatal_error ("internal error: builtin function %s, argument %d "
12635 "had unexpected argument type %s", name, i,
12636 GET_MODE_NAME (m));
12639 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12640 if (*found == NULL)
12642 h2 = ggc_alloc_builtin_hash_struct ();
12644 *found = (void *)h2;
12645 args = void_list_node;
12647 for (i = num_args - 1; i >= 0; i--)
12648 args = tree_cons (NULL_TREE, arg_type[i], args);
12650 h2->type = build_function_type (ret_type, args);
12653 return ((struct builtin_hash_struct *)(*found))->type;
12657 rs6000_common_init_builtins (void)
12659 const struct builtin_description *d;
12662 tree opaque_ftype_opaque = NULL_TREE;
12663 tree opaque_ftype_opaque_opaque = NULL_TREE;
12664 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12665 tree v2si_ftype_qi = NULL_TREE;
12666 tree v2si_ftype_v2si_qi = NULL_TREE;
12667 tree v2si_ftype_int_qi = NULL_TREE;
12669 if (!TARGET_PAIRED_FLOAT)
12671 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12672 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12675 /* Add the ternary operators. */
12677 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12680 int mask = d->mask;
12682 if ((mask != 0 && (mask & target_flags) == 0)
12683 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12686 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12687 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12688 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12689 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12691 if (! (type = opaque_ftype_opaque_opaque_opaque))
12692 type = opaque_ftype_opaque_opaque_opaque
12693 = build_function_type_list (opaque_V4SI_type_node,
12694 opaque_V4SI_type_node,
12695 opaque_V4SI_type_node,
12696 opaque_V4SI_type_node,
12701 enum insn_code icode = d->icode;
12702 if (d->name == 0 || icode == CODE_FOR_nothing)
12705 type = builtin_function_type (insn_data[icode].operand[0].mode,
12706 insn_data[icode].operand[1].mode,
12707 insn_data[icode].operand[2].mode,
12708 insn_data[icode].operand[3].mode,
12712 def_builtin (d->mask, d->name, type, d->code);
12715 /* Add the binary operators. */
12717 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12719 enum machine_mode mode0, mode1, mode2;
12721 int mask = d->mask;
12723 if ((mask != 0 && (mask & target_flags) == 0)
12724 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12727 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12728 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12729 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12730 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12732 if (! (type = opaque_ftype_opaque_opaque))
12733 type = opaque_ftype_opaque_opaque
12734 = build_function_type_list (opaque_V4SI_type_node,
12735 opaque_V4SI_type_node,
12736 opaque_V4SI_type_node,
12741 enum insn_code icode = d->icode;
12742 if (d->name == 0 || icode == CODE_FOR_nothing)
12745 mode0 = insn_data[icode].operand[0].mode;
12746 mode1 = insn_data[icode].operand[1].mode;
12747 mode2 = insn_data[icode].operand[2].mode;
12749 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12751 if (! (type = v2si_ftype_v2si_qi))
12752 type = v2si_ftype_v2si_qi
12753 = build_function_type_list (opaque_V2SI_type_node,
12754 opaque_V2SI_type_node,
12759 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12760 && mode2 == QImode)
12762 if (! (type = v2si_ftype_int_qi))
12763 type = v2si_ftype_int_qi
12764 = build_function_type_list (opaque_V2SI_type_node,
12771 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12775 def_builtin (d->mask, d->name, type, d->code);
12778 /* Add the simple unary operators. */
12779 d = (struct builtin_description *) bdesc_1arg;
12780 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12782 enum machine_mode mode0, mode1;
12784 int mask = d->mask;
12786 if ((mask != 0 && (mask & target_flags) == 0)
12787 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12790 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12791 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12792 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12793 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12795 if (! (type = opaque_ftype_opaque))
12796 type = opaque_ftype_opaque
12797 = build_function_type_list (opaque_V4SI_type_node,
12798 opaque_V4SI_type_node,
12803 enum insn_code icode = d->icode;
12804 if (d->name == 0 || icode == CODE_FOR_nothing)
12807 mode0 = insn_data[icode].operand[0].mode;
12808 mode1 = insn_data[icode].operand[1].mode;
12810 if (mode0 == V2SImode && mode1 == QImode)
12812 if (! (type = v2si_ftype_qi))
12813 type = v2si_ftype_qi
12814 = build_function_type_list (opaque_V2SI_type_node,
12820 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12824 def_builtin (d->mask, d->name, type, d->code);
12829 rs6000_init_libfuncs (void)
12831 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12832 && !TARGET_POWER2 && !TARGET_POWERPC)
12834 /* AIX library routines for float->int conversion. */
12835 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12836 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12837 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12838 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12841 if (!TARGET_IEEEQUAD)
12842 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12843 if (!TARGET_XL_COMPAT)
12845 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12846 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12847 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12848 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12850 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12852 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12853 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12854 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12855 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12856 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12857 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12858 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12860 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12861 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12862 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12863 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12864 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12865 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12866 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12867 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12870 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12871 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12875 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12876 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12877 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12878 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12882 /* 32-bit SVR4 quad floating point routines. */
12884 set_optab_libfunc (add_optab, TFmode, "_q_add");
12885 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12886 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12887 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12888 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12889 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12890 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12892 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12893 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12894 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12895 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12896 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12897 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12899 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12900 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12901 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12902 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12903 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12904 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12905 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12906 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12911 /* Expand a block clear operation, and return 1 if successful. Return 0
12912 if we should let the compiler generate normal code.
12914 operands[0] is the destination
12915 operands[1] is the length
12916 operands[3] is the alignment */
12919 expand_block_clear (rtx operands[])
12921 rtx orig_dest = operands[0];
12922 rtx bytes_rtx = operands[1];
12923 rtx align_rtx = operands[3];
12924 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12925 HOST_WIDE_INT align;
12926 HOST_WIDE_INT bytes;
12931 /* If this is not a fixed size move, just call memcpy */
12935 /* This must be a fixed size alignment */
12936 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12937 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12939 /* Anything to clear? */
12940 bytes = INTVAL (bytes_rtx);
12944 /* Use the builtin memset after a point, to avoid huge code bloat.
12945 When optimize_size, avoid any significant code bloat; calling
12946 memset is about 4 instructions, so allow for one instruction to
12947 load zero and three to do clearing. */
12948 if (TARGET_ALTIVEC && align >= 128)
12950 else if (TARGET_POWERPC64 && align >= 32)
12952 else if (TARGET_SPE && align >= 64)
12957 if (optimize_size && bytes > 3 * clear_step)
12959 if (! optimize_size && bytes > 8 * clear_step)
12962 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12964 enum machine_mode mode = BLKmode;
12967 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
12972 else if (bytes >= 8 && TARGET_SPE && align >= 64)
12977 else if (bytes >= 8 && TARGET_POWERPC64
12978 /* 64-bit loads and stores require word-aligned
12980 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12985 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12986 { /* move 4 bytes */
12990 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12991 { /* move 2 bytes */
12995 else /* move 1 byte at a time */
13001 dest = adjust_address (orig_dest, mode, offset);
13003 emit_move_insn (dest, CONST0_RTX (mode));
13010 /* Expand a block move operation, and return 1 if successful. Return 0
13011 if we should let the compiler generate normal code.
13013 operands[0] is the destination
13014 operands[1] is the source
13015 operands[2] is the length
13016 operands[3] is the alignment */
13018 #define MAX_MOVE_REG 4
13021 expand_block_move (rtx operands[])
13023 rtx orig_dest = operands[0];
13024 rtx orig_src = operands[1];
13025 rtx bytes_rtx = operands[2];
13026 rtx align_rtx = operands[3];
13027 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13032 rtx stores[MAX_MOVE_REG];
13035 /* If this is not a fixed size move, just call memcpy */
13039 /* This must be a fixed size alignment */
13040 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13041 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13043 /* Anything to move? */
13044 bytes = INTVAL (bytes_rtx);
13048 /* store_one_arg depends on expand_block_move to handle at least the size of
13049 reg_parm_stack_space. */
13050 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
13053 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13056 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13057 rtx (*mov) (rtx, rtx);
13059 enum machine_mode mode = BLKmode;
13062 /* Altivec first, since it will be faster than a string move
13063 when it applies, and usually not significantly larger. */
13064 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13068 gen_func.mov = gen_movv4si;
13070 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13074 gen_func.mov = gen_movv2si;
13076 else if (TARGET_STRING
13077 && bytes > 24 /* move up to 32 bytes at a time */
13083 && ! fixed_regs[10]
13084 && ! fixed_regs[11]
13085 && ! fixed_regs[12])
13087 move_bytes = (bytes > 32) ? 32 : bytes;
13088 gen_func.movmemsi = gen_movmemsi_8reg;
13090 else if (TARGET_STRING
13091 && bytes > 16 /* move up to 24 bytes at a time */
13097 && ! fixed_regs[10])
13099 move_bytes = (bytes > 24) ? 24 : bytes;
13100 gen_func.movmemsi = gen_movmemsi_6reg;
13102 else if (TARGET_STRING
13103 && bytes > 8 /* move up to 16 bytes at a time */
13107 && ! fixed_regs[8])
13109 move_bytes = (bytes > 16) ? 16 : bytes;
13110 gen_func.movmemsi = gen_movmemsi_4reg;
13112 else if (bytes >= 8 && TARGET_POWERPC64
13113 /* 64-bit loads and stores require word-aligned
13115 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13119 gen_func.mov = gen_movdi;
13121 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13122 { /* move up to 8 bytes at a time */
13123 move_bytes = (bytes > 8) ? 8 : bytes;
13124 gen_func.movmemsi = gen_movmemsi_2reg;
13126 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13127 { /* move 4 bytes */
13130 gen_func.mov = gen_movsi;
13132 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13133 { /* move 2 bytes */
13136 gen_func.mov = gen_movhi;
13138 else if (TARGET_STRING && bytes > 1)
13139 { /* move up to 4 bytes at a time */
13140 move_bytes = (bytes > 4) ? 4 : bytes;
13141 gen_func.movmemsi = gen_movmemsi_1reg;
13143 else /* move 1 byte at a time */
13147 gen_func.mov = gen_movqi;
13150 src = adjust_address (orig_src, mode, offset);
13151 dest = adjust_address (orig_dest, mode, offset);
13153 if (mode != BLKmode)
13155 rtx tmp_reg = gen_reg_rtx (mode);
13157 emit_insn ((*gen_func.mov) (tmp_reg, src));
13158 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13161 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13164 for (i = 0; i < num_reg; i++)
13165 emit_insn (stores[i]);
13169 if (mode == BLKmode)
13171 /* Move the address into scratch registers. The movmemsi
13172 patterns require zero offset. */
13173 if (!REG_P (XEXP (src, 0)))
13175 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13176 src = replace_equiv_address (src, src_reg);
13178 set_mem_size (src, GEN_INT (move_bytes));
13180 if (!REG_P (XEXP (dest, 0)))
13182 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13183 dest = replace_equiv_address (dest, dest_reg);
13185 set_mem_size (dest, GEN_INT (move_bytes));
13187 emit_insn ((*gen_func.movmemsi) (dest, src,
13188 GEN_INT (move_bytes & 31),
13197 /* Return a string to perform a load_multiple operation.
13198 operands[0] is the vector.
13199 operands[1] is the source address.
13200 operands[2] is the first destination register. */
13203 rs6000_output_load_multiple (rtx operands[3])
13205 /* We have to handle the case where the pseudo used to contain the address
13206 is assigned to one of the output registers. */
13208 int words = XVECLEN (operands[0], 0);
13211 if (XVECLEN (operands[0], 0) == 1)
13212 return "{l|lwz} %2,0(%1)";
13214 for (i = 0; i < words; i++)
13215 if (refers_to_regno_p (REGNO (operands[2]) + i,
13216 REGNO (operands[2]) + i + 1, operands[1], 0))
13220 xop[0] = GEN_INT (4 * (words-1));
13221 xop[1] = operands[1];
13222 xop[2] = operands[2];
13223 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13228 xop[0] = GEN_INT (4 * (words-1));
13229 xop[1] = operands[1];
13230 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13231 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);
13236 for (j = 0; j < words; j++)
13239 xop[0] = GEN_INT (j * 4);
13240 xop[1] = operands[1];
13241 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13242 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13244 xop[0] = GEN_INT (i * 4);
13245 xop[1] = operands[1];
13246 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13251 return "{lsi|lswi} %2,%1,%N0";
13255 /* A validation routine: say whether CODE, a condition code, and MODE
13256 match. The other alternatives either don't make sense or should
13257 never be generated. */
13260 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13262 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13263 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13264 && GET_MODE_CLASS (mode) == MODE_CC);
13266 /* These don't make sense. */
13267 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13268 || mode != CCUNSmode);
13270 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13271 || mode == CCUNSmode);
13273 gcc_assert (mode == CCFPmode
13274 || (code != ORDERED && code != UNORDERED
13275 && code != UNEQ && code != LTGT
13276 && code != UNGT && code != UNLT
13277 && code != UNGE && code != UNLE));
13279 /* These should never be generated except for
13280 flag_finite_math_only. */
13281 gcc_assert (mode != CCFPmode
13282 || flag_finite_math_only
13283 || (code != LE && code != GE
13284 && code != UNEQ && code != LTGT
13285 && code != UNGT && code != UNLT));
13287 /* These are invalid; the information is not there. */
13288 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13292 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13293 mask required to convert the result of a rotate insn into a shift
13294 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13297 includes_lshift_p (rtx shiftop, rtx andop)
13299 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13301 shift_mask <<= INTVAL (shiftop);
13303 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13306 /* Similar, but for right shift. */
13309 includes_rshift_p (rtx shiftop, rtx andop)
13311 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13313 shift_mask >>= INTVAL (shiftop);
13315 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13318 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13319 to perform a left shift. It must have exactly SHIFTOP least
13320 significant 0's, then one or more 1's, then zero or more 0's. */
13323 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13325 if (GET_CODE (andop) == CONST_INT)
13327 HOST_WIDE_INT c, lsb, shift_mask;
13329 c = INTVAL (andop);
13330 if (c == 0 || c == ~0)
13334 shift_mask <<= INTVAL (shiftop);
13336 /* Find the least significant one bit. */
13339 /* It must coincide with the LSB of the shift mask. */
13340 if (-lsb != shift_mask)
13343 /* Invert to look for the next transition (if any). */
13346 /* Remove the low group of ones (originally low group of zeros). */
13349 /* Again find the lsb, and check we have all 1's above. */
13353 else if (GET_CODE (andop) == CONST_DOUBLE
13354 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13356 HOST_WIDE_INT low, high, lsb;
13357 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13359 low = CONST_DOUBLE_LOW (andop);
13360 if (HOST_BITS_PER_WIDE_INT < 64)
13361 high = CONST_DOUBLE_HIGH (andop);
13363 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13364 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13367 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13369 shift_mask_high = ~0;
13370 if (INTVAL (shiftop) > 32)
13371 shift_mask_high <<= INTVAL (shiftop) - 32;
13373 lsb = high & -high;
13375 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13381 lsb = high & -high;
13382 return high == -lsb;
13385 shift_mask_low = ~0;
13386 shift_mask_low <<= INTVAL (shiftop);
13390 if (-lsb != shift_mask_low)
13393 if (HOST_BITS_PER_WIDE_INT < 64)
13398 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13400 lsb = high & -high;
13401 return high == -lsb;
13405 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13411 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13412 to perform a left shift. It must have SHIFTOP or more least
13413 significant 0's, with the remainder of the word 1's. */
13416 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13418 if (GET_CODE (andop) == CONST_INT)
13420 HOST_WIDE_INT c, lsb, shift_mask;
13423 shift_mask <<= INTVAL (shiftop);
13424 c = INTVAL (andop);
13426 /* Find the least significant one bit. */
13429 /* It must be covered by the shift mask.
13430 This test also rejects c == 0. */
13431 if ((lsb & shift_mask) == 0)
13434 /* Check we have all 1's above the transition, and reject all 1's. */
13435 return c == -lsb && lsb != 1;
13437 else if (GET_CODE (andop) == CONST_DOUBLE
13438 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13440 HOST_WIDE_INT low, lsb, shift_mask_low;
13442 low = CONST_DOUBLE_LOW (andop);
13444 if (HOST_BITS_PER_WIDE_INT < 64)
13446 HOST_WIDE_INT high, shift_mask_high;
13448 high = CONST_DOUBLE_HIGH (andop);
13452 shift_mask_high = ~0;
13453 if (INTVAL (shiftop) > 32)
13454 shift_mask_high <<= INTVAL (shiftop) - 32;
13456 lsb = high & -high;
13458 if ((lsb & shift_mask_high) == 0)
13461 return high == -lsb;
13467 shift_mask_low = ~0;
13468 shift_mask_low <<= INTVAL (shiftop);
13472 if ((lsb & shift_mask_low) == 0)
13475 return low == -lsb && lsb != 1;
13481 /* Return 1 if operands will generate a valid arguments to rlwimi
13482 instruction for insert with right shift in 64-bit mode. The mask may
13483 not start on the first bit or stop on the last bit because wrap-around
13484 effects of instruction do not correspond to semantics of RTL insn. */
13487 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13489 if (INTVAL (startop) > 32
13490 && INTVAL (startop) < 64
13491 && INTVAL (sizeop) > 1
13492 && INTVAL (sizeop) + INTVAL (startop) < 64
13493 && INTVAL (shiftop) > 0
13494 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13495 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
13501 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13502 for lfq and stfq insns iff the registers are hard registers. */
13505 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
13507 /* We might have been passed a SUBREG. */
13508 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
13511 /* We might have been passed non floating point registers. */
13512 if (!FP_REGNO_P (REGNO (reg1))
13513 || !FP_REGNO_P (REGNO (reg2)))
13516 return (REGNO (reg1) == REGNO (reg2) - 1);
13519 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13520 addr1 and addr2 must be in consecutive memory locations
13521 (addr2 == addr1 + 8). */
13524 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
13527 unsigned int reg1, reg2;
13528 int offset1, offset2;
13530 /* The mems cannot be volatile. */
13531 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
13534 addr1 = XEXP (mem1, 0);
13535 addr2 = XEXP (mem2, 0);
13537 /* Extract an offset (if used) from the first addr. */
13538 if (GET_CODE (addr1) == PLUS)
13540 /* If not a REG, return zero. */
13541 if (GET_CODE (XEXP (addr1, 0)) != REG)
13545 reg1 = REGNO (XEXP (addr1, 0));
13546 /* The offset must be constant! */
13547 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13549 offset1 = INTVAL (XEXP (addr1, 1));
13552 else if (GET_CODE (addr1) != REG)
13556 reg1 = REGNO (addr1);
13557 /* This was a simple (mem (reg)) expression. Offset is 0. */
13561 /* And now for the second addr. */
13562 if (GET_CODE (addr2) == PLUS)
13564 /* If not a REG, return zero. */
13565 if (GET_CODE (XEXP (addr2, 0)) != REG)
13569 reg2 = REGNO (XEXP (addr2, 0));
13570 /* The offset must be constant. */
13571 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
13573 offset2 = INTVAL (XEXP (addr2, 1));
13576 else if (GET_CODE (addr2) != REG)
13580 reg2 = REGNO (addr2);
13581 /* This was a simple (mem (reg)) expression. Offset is 0. */
13585 /* Both of these must have the same base register. */
13589 /* The offset for the second addr must be 8 more than the first addr. */
13590 if (offset2 != offset1 + 8)
13593 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13600 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13602 static bool eliminated = false;
13605 if (mode != SDmode)
13606 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13609 rtx mem = cfun->machine->sdmode_stack_slot;
13610 gcc_assert (mem != NULL_RTX);
13614 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13615 cfun->machine->sdmode_stack_slot = mem;
13621 if (TARGET_DEBUG_ADDR)
13623 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13624 GET_MODE_NAME (mode));
13626 fprintf (stderr, "\tNULL_RTX\n");
13635 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13637 /* Don't walk into types. */
13638 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13640 *walk_subtrees = 0;
13644 switch (TREE_CODE (*tp))
13653 case ALIGN_INDIRECT_REF:
13654 case MISALIGNED_INDIRECT_REF:
13655 case VIEW_CONVERT_EXPR:
13656 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13666 enum reload_reg_type {
13668 VECTOR_REGISTER_TYPE,
13669 OTHER_REGISTER_TYPE
13672 static enum reload_reg_type
13673 rs6000_reload_register_type (enum reg_class rclass)
13679 return GPR_REGISTER_TYPE;
13684 return VECTOR_REGISTER_TYPE;
13687 return OTHER_REGISTER_TYPE;
13691 /* Inform reload about cases where moving X with a mode MODE to a register in
13692 RCLASS requires an extra scratch or immediate register. Return the class
13693 needed for the immediate register.
13695 For VSX and Altivec, we may need a register to convert sp+offset into
13698 static enum reg_class
13699 rs6000_secondary_reload (bool in_p,
13701 enum reg_class rclass,
13702 enum machine_mode mode,
13703 secondary_reload_info *sri)
13705 enum reg_class ret = ALL_REGS;
13706 enum insn_code icode;
13707 bool default_p = false;
13709 sri->icode = CODE_FOR_nothing;
13711 /* Convert vector loads and stores into gprs to use an additional base
13713 icode = rs6000_vector_reload[mode][in_p != false];
13714 if (icode != CODE_FOR_nothing)
13717 sri->icode = CODE_FOR_nothing;
13718 sri->extra_cost = 0;
13720 if (GET_CODE (x) == MEM)
13722 rtx addr = XEXP (x, 0);
13724 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13725 an extra register in that case, but it would need an extra
13726 register if the addressing is reg+reg or (reg+reg)&(-16). */
13727 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13729 if (!legitimate_indirect_address_p (addr, false)
13730 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13732 sri->icode = icode;
13733 /* account for splitting the loads, and converting the
13734 address from reg+reg to reg. */
13735 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13736 + ((GET_CODE (addr) == AND) ? 1 : 0));
13739 /* Loads to and stores from vector registers can only do reg+reg
13740 addressing. Altivec registers can also do (reg+reg)&(-16). */
13741 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13742 || rclass == FLOAT_REGS || rclass == NO_REGS)
13744 if (!VECTOR_MEM_ALTIVEC_P (mode)
13745 && GET_CODE (addr) == AND
13746 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13747 && INTVAL (XEXP (addr, 1)) == -16
13748 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13749 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13751 sri->icode = icode;
13752 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13755 else if (!legitimate_indirect_address_p (addr, false)
13756 && (rclass == NO_REGS
13757 || !legitimate_indexed_address_p (addr, false)))
13759 sri->icode = icode;
13760 sri->extra_cost = 1;
13763 icode = CODE_FOR_nothing;
13765 /* Any other loads, including to pseudo registers which haven't been
13766 assigned to a register yet, default to require a scratch
13770 sri->icode = icode;
13771 sri->extra_cost = 2;
13774 else if (REG_P (x))
13776 int regno = true_regnum (x);
13778 icode = CODE_FOR_nothing;
13779 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13783 enum reg_class xclass = REGNO_REG_CLASS (regno);
13784 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13785 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13787 /* If memory is needed, use default_secondary_reload to create the
13789 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13802 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13804 gcc_assert (ret != ALL_REGS);
13806 if (TARGET_DEBUG_ADDR)
13809 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13811 reg_class_names[ret],
13812 in_p ? "true" : "false",
13813 reg_class_names[rclass],
13814 GET_MODE_NAME (mode));
13817 fprintf (stderr, ", default secondary reload");
13819 if (sri->icode != CODE_FOR_nothing)
13820 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13821 insn_data[sri->icode].name, sri->extra_cost);
13823 fprintf (stderr, "\n");
13831 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13832 to SP+reg addressing. */
13835 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13837 int regno = true_regnum (reg);
13838 enum machine_mode mode = GET_MODE (reg);
13839 enum reg_class rclass;
13841 rtx and_op2 = NULL_RTX;
13844 rtx scratch_or_premodify = scratch;
13848 if (TARGET_DEBUG_ADDR)
13850 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13851 store_p ? "store" : "load");
13852 fprintf (stderr, "reg:\n");
13854 fprintf (stderr, "mem:\n");
13856 fprintf (stderr, "scratch:\n");
13857 debug_rtx (scratch);
13860 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13861 gcc_assert (GET_CODE (mem) == MEM);
13862 rclass = REGNO_REG_CLASS (regno);
13863 addr = XEXP (mem, 0);
13867 /* GPRs can handle reg + small constant, all other addresses need to use
13868 the scratch register. */
13871 if (GET_CODE (addr) == AND)
13873 and_op2 = XEXP (addr, 1);
13874 addr = XEXP (addr, 0);
13877 if (GET_CODE (addr) == PRE_MODIFY)
13879 scratch_or_premodify = XEXP (addr, 0);
13880 gcc_assert (REG_P (scratch_or_premodify));
13881 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13882 addr = XEXP (addr, 1);
13885 if (GET_CODE (addr) == PLUS
13886 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13887 || and_op2 != NULL_RTX))
13889 addr_op1 = XEXP (addr, 0);
13890 addr_op2 = XEXP (addr, 1);
13891 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13893 if (!REG_P (addr_op2)
13894 && (GET_CODE (addr_op2) != CONST_INT
13895 || !satisfies_constraint_I (addr_op2)))
13897 if (TARGET_DEBUG_ADDR)
13900 "\nMove plus addr to register %s, mode = %s: ",
13901 rs6000_reg_names[REGNO (scratch)],
13902 GET_MODE_NAME (mode));
13903 debug_rtx (addr_op2);
13905 rs6000_emit_move (scratch, addr_op2, Pmode);
13906 addr_op2 = scratch;
13909 emit_insn (gen_rtx_SET (VOIDmode,
13910 scratch_or_premodify,
13911 gen_rtx_PLUS (Pmode,
13915 addr = scratch_or_premodify;
13916 scratch_or_premodify = scratch;
13918 else if (!legitimate_indirect_address_p (addr, false)
13919 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13921 if (TARGET_DEBUG_ADDR)
13923 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13924 rs6000_reg_names[REGNO (scratch_or_premodify)],
13925 GET_MODE_NAME (mode));
13928 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13929 addr = scratch_or_premodify;
13930 scratch_or_premodify = scratch;
13934 /* Float/Altivec registers can only handle reg+reg addressing. Move
13935 other addresses into a scratch register. */
13940 /* With float regs, we need to handle the AND ourselves, since we can't
13941 use the Altivec instruction with an implicit AND -16. Allow scalar
13942 loads to float registers to use reg+offset even if VSX. */
13943 if (GET_CODE (addr) == AND
13944 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13945 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13946 || INTVAL (XEXP (addr, 1)) != -16
13947 || !VECTOR_MEM_ALTIVEC_P (mode)))
13949 and_op2 = XEXP (addr, 1);
13950 addr = XEXP (addr, 0);
13953 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13954 as the address later. */
13955 if (GET_CODE (addr) == PRE_MODIFY
13956 && (!VECTOR_MEM_VSX_P (mode)
13957 || and_op2 != NULL_RTX
13958 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13960 scratch_or_premodify = XEXP (addr, 0);
13961 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13963 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13964 addr = XEXP (addr, 1);
13967 if (legitimate_indirect_address_p (addr, false) /* reg */
13968 || legitimate_indexed_address_p (addr, false) /* reg+reg */
13969 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
13970 || (GET_CODE (addr) == AND /* Altivec memory */
13971 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13972 && INTVAL (XEXP (addr, 1)) == -16
13973 && VECTOR_MEM_ALTIVEC_P (mode))
13974 || (rclass == FLOAT_REGS /* legacy float mem */
13975 && GET_MODE_SIZE (mode) == 8
13976 && and_op2 == NULL_RTX
13977 && scratch_or_premodify == scratch
13978 && rs6000_legitimate_offset_address_p (mode, addr, false)))
13981 else if (GET_CODE (addr) == PLUS)
13983 addr_op1 = XEXP (addr, 0);
13984 addr_op2 = XEXP (addr, 1);
13985 gcc_assert (REG_P (addr_op1));
13987 if (TARGET_DEBUG_ADDR)
13989 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
13990 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13991 debug_rtx (addr_op2);
13993 rs6000_emit_move (scratch, addr_op2, Pmode);
13994 emit_insn (gen_rtx_SET (VOIDmode,
13995 scratch_or_premodify,
13996 gen_rtx_PLUS (Pmode,
13999 addr = scratch_or_premodify;
14000 scratch_or_premodify = scratch;
14003 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14004 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14006 if (TARGET_DEBUG_ADDR)
14008 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14009 rs6000_reg_names[REGNO (scratch_or_premodify)],
14010 GET_MODE_NAME (mode));
14014 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14015 addr = scratch_or_premodify;
14016 scratch_or_premodify = scratch;
14020 gcc_unreachable ();
14025 gcc_unreachable ();
14028 /* If the original address involved a pre-modify that we couldn't use the VSX
14029 memory instruction with update, and we haven't taken care of already,
14030 store the address in the pre-modify register and use that as the
14032 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14034 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14035 addr = scratch_or_premodify;
14038 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14039 memory instruction, recreate the AND now, including the clobber which is
14040 generated by the general ANDSI3/ANDDI3 patterns for the
14041 andi. instruction. */
14042 if (and_op2 != NULL_RTX)
14044 if (! legitimate_indirect_address_p (addr, false))
14046 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14050 if (TARGET_DEBUG_ADDR)
14052 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14053 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14054 debug_rtx (and_op2);
14057 and_rtx = gen_rtx_SET (VOIDmode,
14059 gen_rtx_AND (Pmode,
14063 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14064 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14065 gen_rtvec (2, and_rtx, cc_clobber)));
14069 /* Adjust the address if it changed. */
14070 if (addr != XEXP (mem, 0))
14072 mem = change_address (mem, mode, addr);
14073 if (TARGET_DEBUG_ADDR)
14074 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14077 /* Now create the move. */
14079 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14081 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14086 /* Target hook to return the cover classes for Integrated Register Allocator.
14087 Cover classes is a set of non-intersected register classes covering all hard
14088 registers used for register allocation purpose. Any move between two
14089 registers of a cover class should be cheaper than load or store of the
14090 registers. The value is array of register classes with LIM_REG_CLASSES used
14093 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14094 account for the Altivec and Floating registers being subsets of the VSX
14095 register set under VSX, but distinct register sets on pre-VSX machines. */
14097 static const enum reg_class *
14098 rs6000_ira_cover_classes (void)
14100 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
14101 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
14103 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
14106 /* Allocate a 64-bit stack slot to be used for copying SDmode
14107 values through if this function has any SDmode references. */
14110 rs6000_alloc_sdmode_stack_slot (void)
14114 gimple_stmt_iterator gsi;
14116 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14119 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14121 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14124 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14125 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14131 /* Check for any SDmode parameters of the function. */
14132 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
14134 if (TREE_TYPE (t) == error_mark_node)
14137 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14138 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14140 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14141 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14149 rs6000_instantiate_decls (void)
14151 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14152 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14155 /* Given an rtx X being reloaded into a reg required to be
14156 in class CLASS, return the class of reg to actually use.
14157 In general this is just CLASS; but on some machines
14158 in some cases it is preferable to use a more restrictive class.
14160 On the RS/6000, we have to return NO_REGS when we want to reload a
14161 floating-point CONST_DOUBLE to force it to be copied to memory.
14163 We also don't want to reload integer values into floating-point
14164 registers if we can at all help it. In fact, this can
14165 cause reload to die, if it tries to generate a reload of CTR
14166 into a FP register and discovers it doesn't have the memory location
14169 ??? Would it be a good idea to have reload do the converse, that is
14170 try to reload floating modes into FP registers if possible?
14173 static enum reg_class
14174 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14176 enum machine_mode mode = GET_MODE (x);
14178 if (VECTOR_UNIT_VSX_P (mode)
14179 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14182 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14183 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14184 && easy_vector_constant (x, mode))
14185 return ALTIVEC_REGS;
14187 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14190 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14191 return GENERAL_REGS;
14193 /* For VSX, prefer the traditional registers for 64-bit values because we can
14194 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14195 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14196 prefer Altivec loads.. */
14197 if (rclass == VSX_REGS)
14199 if (GET_MODE_SIZE (mode) <= 8)
14202 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14203 return ALTIVEC_REGS;
14211 /* Debug version of rs6000_preferred_reload_class. */
14212 static enum reg_class
14213 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14215 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14218 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14220 reg_class_names[ret], reg_class_names[rclass],
14221 GET_MODE_NAME (GET_MODE (x)));
14227 /* If we are copying between FP or AltiVec registers and anything else, we need
14228 a memory location. The exception is when we are targeting ppc64 and the
14229 move to/from fpr to gpr instructions are available. Also, under VSX, you
14230 can copy vector registers from the FP register set to the Altivec register
14231 set and vice versa. */
14234 rs6000_secondary_memory_needed (enum reg_class class1,
14235 enum reg_class class2,
14236 enum machine_mode mode)
14238 if (class1 == class2)
14241 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14242 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14243 between these classes. But we need memory for other things that can go in
14244 FLOAT_REGS like SFmode. */
14246 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14247 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14248 || class1 == FLOAT_REGS))
14249 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14250 && class2 != FLOAT_REGS);
14252 if (class1 == VSX_REGS || class2 == VSX_REGS)
14255 if (class1 == FLOAT_REGS
14256 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14257 || ((mode != DFmode)
14258 && (mode != DDmode)
14259 && (mode != DImode))))
14262 if (class2 == FLOAT_REGS
14263 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14264 || ((mode != DFmode)
14265 && (mode != DDmode)
14266 && (mode != DImode))))
14269 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14275 /* Debug version of rs6000_secondary_memory_needed. */
14277 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14278 enum reg_class class2,
14279 enum machine_mode mode)
14281 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14284 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14285 "class2 = %s, mode = %s\n",
14286 ret ? "true" : "false", reg_class_names[class1],
14287 reg_class_names[class2], GET_MODE_NAME (mode));
14292 /* Return the register class of a scratch register needed to copy IN into
14293 or out of a register in RCLASS in MODE. If it can be done directly,
14294 NO_REGS is returned. */
14296 static enum reg_class
14297 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14302 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14304 && MACHOPIC_INDIRECT
14308 /* We cannot copy a symbolic operand directly into anything
14309 other than BASE_REGS for TARGET_ELF. So indicate that a
14310 register from BASE_REGS is needed as an intermediate
14313 On Darwin, pic addresses require a load from memory, which
14314 needs a base register. */
14315 if (rclass != BASE_REGS
14316 && (GET_CODE (in) == SYMBOL_REF
14317 || GET_CODE (in) == HIGH
14318 || GET_CODE (in) == LABEL_REF
14319 || GET_CODE (in) == CONST))
14323 if (GET_CODE (in) == REG)
14325 regno = REGNO (in);
14326 if (regno >= FIRST_PSEUDO_REGISTER)
14328 regno = true_regnum (in);
14329 if (regno >= FIRST_PSEUDO_REGISTER)
14333 else if (GET_CODE (in) == SUBREG)
14335 regno = true_regnum (in);
14336 if (regno >= FIRST_PSEUDO_REGISTER)
14342 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14344 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14345 || (regno >= 0 && INT_REGNO_P (regno)))
14348 /* Constants, memory, and FP registers can go into FP registers. */
14349 if ((regno == -1 || FP_REGNO_P (regno))
14350 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14351 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14353 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14356 && (regno == -1 || VSX_REGNO_P (regno))
14357 && VSX_REG_CLASS_P (rclass))
14360 /* Memory, and AltiVec registers can go into AltiVec registers. */
14361 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14362 && rclass == ALTIVEC_REGS)
14365 /* We can copy among the CR registers. */
14366 if ((rclass == CR_REGS || rclass == CR0_REGS)
14367 && regno >= 0 && CR_REGNO_P (regno))
14370 /* Otherwise, we need GENERAL_REGS. */
14371 return GENERAL_REGS;
14374 /* Debug version of rs6000_secondary_reload_class. */
14375 static enum reg_class
14376 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14377 enum machine_mode mode, rtx in)
14379 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14381 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14382 "mode = %s, input rtx:\n",
14383 reg_class_names[ret], reg_class_names[rclass],
14384 GET_MODE_NAME (mode));
14390 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14393 rs6000_cannot_change_mode_class (enum machine_mode from,
14394 enum machine_mode to,
14395 enum reg_class rclass)
14397 unsigned from_size = GET_MODE_SIZE (from);
14398 unsigned to_size = GET_MODE_SIZE (to);
14400 if (from_size != to_size)
14402 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14403 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14404 && reg_classes_intersect_p (xclass, rclass));
14407 if (TARGET_E500_DOUBLE
14408 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14409 || (((to) == TFmode) + ((from) == TFmode)) == 1
14410 || (((to) == DDmode) + ((from) == DDmode)) == 1
14411 || (((to) == TDmode) + ((from) == TDmode)) == 1
14412 || (((to) == DImode) + ((from) == DImode)) == 1))
14415 /* Since the VSX register set includes traditional floating point registers
14416 and altivec registers, just check for the size being different instead of
14417 trying to check whether the modes are vector modes. Otherwise it won't
14418 allow say DF and DI to change classes. */
14419 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14420 return (from_size != 8 && from_size != 16);
14422 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14423 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14426 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14427 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14433 /* Debug version of rs6000_cannot_change_mode_class. */
14435 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14436 enum machine_mode to,
14437 enum reg_class rclass)
14439 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
14442 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14443 "to = %s, rclass = %s\n",
14444 ret ? "true" : "false",
14445 GET_MODE_NAME (from), GET_MODE_NAME (to),
14446 reg_class_names[rclass]);
14451 /* Given a comparison operation, return the bit number in CCR to test. We
14452 know this is a valid comparison.
14454 SCC_P is 1 if this is for an scc. That means that %D will have been
14455 used instead of %C, so the bits will be in different places.
14457 Return -1 if OP isn't a valid comparison for some reason. */
14460 ccr_bit (rtx op, int scc_p)
14462 enum rtx_code code = GET_CODE (op);
14463 enum machine_mode cc_mode;
14468 if (!COMPARISON_P (op))
14471 reg = XEXP (op, 0);
14473 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14475 cc_mode = GET_MODE (reg);
14476 cc_regnum = REGNO (reg);
14477 base_bit = 4 * (cc_regnum - CR0_REGNO);
14479 validate_condition_mode (code, cc_mode);
14481 /* When generating a sCOND operation, only positive conditions are
14484 || code == EQ || code == GT || code == LT || code == UNORDERED
14485 || code == GTU || code == LTU);
14490 return scc_p ? base_bit + 3 : base_bit + 2;
14492 return base_bit + 2;
14493 case GT: case GTU: case UNLE:
14494 return base_bit + 1;
14495 case LT: case LTU: case UNGE:
14497 case ORDERED: case UNORDERED:
14498 return base_bit + 3;
14501 /* If scc, we will have done a cror to put the bit in the
14502 unordered position. So test that bit. For integer, this is ! LT
14503 unless this is an scc insn. */
14504 return scc_p ? base_bit + 3 : base_bit;
14507 return scc_p ? base_bit + 3 : base_bit + 1;
14510 gcc_unreachable ();
14514 /* Return the GOT register. */
14517 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
14519 /* The second flow pass currently (June 1999) can't update
14520 regs_ever_live without disturbing other parts of the compiler, so
14521 update it here to make the prolog/epilogue code happy. */
14522 if (!can_create_pseudo_p ()
14523 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
14524 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
14526 crtl->uses_pic_offset_table = 1;
14528 return pic_offset_table_rtx;
14531 /* Function to init struct machine_function.
14532 This will be called, via a pointer variable,
14533 from push_function_context. */
14535 static struct machine_function *
14536 rs6000_init_machine_status (void)
14538 return ggc_alloc_cleared_machine_function ();
14541 /* These macros test for integers and extract the low-order bits. */
14543 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
14544 && GET_MODE (X) == VOIDmode)
14546 #define INT_LOWPART(X) \
14547 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
14550 extract_MB (rtx op)
14553 unsigned long val = INT_LOWPART (op);
14555 /* If the high bit is zero, the value is the first 1 bit we find
14557 if ((val & 0x80000000) == 0)
14559 gcc_assert (val & 0xffffffff);
14562 while (((val <<= 1) & 0x80000000) == 0)
14567 /* If the high bit is set and the low bit is not, or the mask is all
14568 1's, the value is zero. */
14569 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14572 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14575 while (((val >>= 1) & 1) != 0)
14582 extract_ME (rtx op)
14585 unsigned long val = INT_LOWPART (op);
14587 /* If the low bit is zero, the value is the first 1 bit we find from
14589 if ((val & 1) == 0)
14591 gcc_assert (val & 0xffffffff);
14594 while (((val >>= 1) & 1) == 0)
14600 /* If the low bit is set and the high bit is not, or the mask is all
14601 1's, the value is 31. */
14602 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14605 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14608 while (((val <<= 1) & 0x80000000) != 0)
14614 /* Locate some local-dynamic symbol still in use by this function
14615 so that we can print its name in some tls_ld pattern. */
14617 static const char *
14618 rs6000_get_some_local_dynamic_name (void)
14622 if (cfun->machine->some_ld_name)
14623 return cfun->machine->some_ld_name;
14625 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14627 && for_each_rtx (&PATTERN (insn),
14628 rs6000_get_some_local_dynamic_name_1, 0))
14629 return cfun->machine->some_ld_name;
14631 gcc_unreachable ();
14634 /* Helper function for rs6000_get_some_local_dynamic_name. */
14637 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14641 if (GET_CODE (x) == SYMBOL_REF)
14643 const char *str = XSTR (x, 0);
14644 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14646 cfun->machine->some_ld_name = str;
14654 /* Write out a function code label. */
14657 rs6000_output_function_entry (FILE *file, const char *fname)
14659 if (fname[0] != '.')
14661 switch (DEFAULT_ABI)
14664 gcc_unreachable ();
14670 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14679 RS6000_OUTPUT_BASENAME (file, fname);
14682 /* Print an operand. Recognize special options, documented below. */
14685 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14686 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14688 #define SMALL_DATA_RELOC "sda21"
14689 #define SMALL_DATA_REG 0
14693 print_operand (FILE *file, rtx x, int code)
14697 unsigned HOST_WIDE_INT uval;
14702 /* Write out an instruction after the call which may be replaced
14703 with glue code by the loader. This depends on the AIX version. */
14704 asm_fprintf (file, RS6000_CALL_GLUE);
14707 /* %a is output_address. */
14710 /* If X is a constant integer whose low-order 5 bits are zero,
14711 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14712 in the AIX assembler where "sri" with a zero shift count
14713 writes a trash instruction. */
14714 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14721 /* If constant, low-order 16 bits of constant, unsigned.
14722 Otherwise, write normally. */
14724 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14726 print_operand (file, x, 0);
14730 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14731 for 64-bit mask direction. */
14732 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14735 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14739 /* X is a CR register. Print the number of the GT bit of the CR. */
14740 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14741 output_operand_lossage ("invalid %%c value");
14743 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14747 /* Like 'J' but get to the GT bit only. */
14748 gcc_assert (GET_CODE (x) == REG);
14750 /* Bit 1 is GT bit. */
14751 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14753 /* Add one for shift count in rlinm for scc. */
14754 fprintf (file, "%d", i + 1);
14758 /* X is a CR register. Print the number of the EQ bit of the CR */
14759 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14760 output_operand_lossage ("invalid %%E value");
14762 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14766 /* X is a CR register. Print the shift count needed to move it
14767 to the high-order four bits. */
14768 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14769 output_operand_lossage ("invalid %%f value");
14771 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14775 /* Similar, but print the count for the rotate in the opposite
14777 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14778 output_operand_lossage ("invalid %%F value");
14780 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14784 /* X is a constant integer. If it is negative, print "m",
14785 otherwise print "z". This is to make an aze or ame insn. */
14786 if (GET_CODE (x) != CONST_INT)
14787 output_operand_lossage ("invalid %%G value");
14788 else if (INTVAL (x) >= 0)
14795 /* If constant, output low-order five bits. Otherwise, write
14798 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14800 print_operand (file, x, 0);
14804 /* If constant, output low-order six bits. Otherwise, write
14807 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14809 print_operand (file, x, 0);
14813 /* Print `i' if this is a constant, else nothing. */
14819 /* Write the bit number in CCR for jump. */
14820 i = ccr_bit (x, 0);
14822 output_operand_lossage ("invalid %%j code");
14824 fprintf (file, "%d", i);
14828 /* Similar, but add one for shift count in rlinm for scc and pass
14829 scc flag to `ccr_bit'. */
14830 i = ccr_bit (x, 1);
14832 output_operand_lossage ("invalid %%J code");
14834 /* If we want bit 31, write a shift count of zero, not 32. */
14835 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14839 /* X must be a constant. Write the 1's complement of the
14842 output_operand_lossage ("invalid %%k value");
14844 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14848 /* X must be a symbolic constant on ELF. Write an
14849 expression suitable for an 'addi' that adds in the low 16
14850 bits of the MEM. */
14851 if (GET_CODE (x) == CONST)
14853 if (GET_CODE (XEXP (x, 0)) != PLUS
14854 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14855 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14856 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14857 output_operand_lossage ("invalid %%K value");
14859 print_operand_address (file, x);
14860 fputs ("@l", file);
14863 /* %l is output_asm_label. */
14866 /* Write second word of DImode or DFmode reference. Works on register
14867 or non-indexed memory only. */
14868 if (GET_CODE (x) == REG)
14869 fputs (reg_names[REGNO (x) + 1], file);
14870 else if (GET_CODE (x) == MEM)
14872 /* Handle possible auto-increment. Since it is pre-increment and
14873 we have already done it, we can just use an offset of word. */
14874 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14875 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14876 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14878 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14879 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14882 output_address (XEXP (adjust_address_nv (x, SImode,
14886 if (small_data_operand (x, GET_MODE (x)))
14887 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14888 reg_names[SMALL_DATA_REG]);
14893 /* MB value for a mask operand. */
14894 if (! mask_operand (x, SImode))
14895 output_operand_lossage ("invalid %%m value");
14897 fprintf (file, "%d", extract_MB (x));
14901 /* ME value for a mask operand. */
14902 if (! mask_operand (x, SImode))
14903 output_operand_lossage ("invalid %%M value");
14905 fprintf (file, "%d", extract_ME (x));
14908 /* %n outputs the negative of its operand. */
14911 /* Write the number of elements in the vector times 4. */
14912 if (GET_CODE (x) != PARALLEL)
14913 output_operand_lossage ("invalid %%N value");
14915 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14919 /* Similar, but subtract 1 first. */
14920 if (GET_CODE (x) != PARALLEL)
14921 output_operand_lossage ("invalid %%O value");
14923 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14927 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14929 || INT_LOWPART (x) < 0
14930 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14931 output_operand_lossage ("invalid %%p value");
14933 fprintf (file, "%d", i);
14937 /* The operand must be an indirect memory reference. The result
14938 is the register name. */
14939 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14940 || REGNO (XEXP (x, 0)) >= 32)
14941 output_operand_lossage ("invalid %%P value");
14943 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14947 /* This outputs the logical code corresponding to a boolean
14948 expression. The expression may have one or both operands
14949 negated (if one, only the first one). For condition register
14950 logical operations, it will also treat the negated
14951 CR codes as NOTs, but not handle NOTs of them. */
14953 const char *const *t = 0;
14955 enum rtx_code code = GET_CODE (x);
14956 static const char * const tbl[3][3] = {
14957 { "and", "andc", "nor" },
14958 { "or", "orc", "nand" },
14959 { "xor", "eqv", "xor" } };
14963 else if (code == IOR)
14965 else if (code == XOR)
14968 output_operand_lossage ("invalid %%q value");
14970 if (GET_CODE (XEXP (x, 0)) != NOT)
14974 if (GET_CODE (XEXP (x, 1)) == NOT)
14992 /* X is a CR register. Print the mask for `mtcrf'. */
14993 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14994 output_operand_lossage ("invalid %%R value");
14996 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15000 /* Low 5 bits of 32 - value */
15002 output_operand_lossage ("invalid %%s value");
15004 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15008 /* PowerPC64 mask position. All 0's is excluded.
15009 CONST_INT 32-bit mask is considered sign-extended so any
15010 transition must occur within the CONST_INT, not on the boundary. */
15011 if (! mask64_operand (x, DImode))
15012 output_operand_lossage ("invalid %%S value");
15014 uval = INT_LOWPART (x);
15016 if (uval & 1) /* Clear Left */
15018 #if HOST_BITS_PER_WIDE_INT > 64
15019 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15023 else /* Clear Right */
15026 #if HOST_BITS_PER_WIDE_INT > 64
15027 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15033 gcc_assert (i >= 0);
15034 fprintf (file, "%d", i);
15038 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15039 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15041 /* Bit 3 is OV bit. */
15042 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15044 /* If we want bit 31, write a shift count of zero, not 32. */
15045 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15049 /* Print the symbolic name of a branch target register. */
15050 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15051 && REGNO (x) != CTR_REGNO))
15052 output_operand_lossage ("invalid %%T value");
15053 else if (REGNO (x) == LR_REGNO)
15054 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15056 fputs ("ctr", file);
15060 /* High-order 16 bits of constant for use in unsigned operand. */
15062 output_operand_lossage ("invalid %%u value");
15064 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15065 (INT_LOWPART (x) >> 16) & 0xffff);
15069 /* High-order 16 bits of constant for use in signed operand. */
15071 output_operand_lossage ("invalid %%v value");
15073 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15074 (INT_LOWPART (x) >> 16) & 0xffff);
15078 /* Print `u' if this has an auto-increment or auto-decrement. */
15079 if (GET_CODE (x) == MEM
15080 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15081 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15082 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15087 /* Print the trap code for this operand. */
15088 switch (GET_CODE (x))
15091 fputs ("eq", file); /* 4 */
15094 fputs ("ne", file); /* 24 */
15097 fputs ("lt", file); /* 16 */
15100 fputs ("le", file); /* 20 */
15103 fputs ("gt", file); /* 8 */
15106 fputs ("ge", file); /* 12 */
15109 fputs ("llt", file); /* 2 */
15112 fputs ("lle", file); /* 6 */
15115 fputs ("lgt", file); /* 1 */
15118 fputs ("lge", file); /* 5 */
15121 gcc_unreachable ();
15126 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15129 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15130 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15132 print_operand (file, x, 0);
15136 /* MB value for a PowerPC64 rldic operand. */
15137 val = (GET_CODE (x) == CONST_INT
15138 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15143 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15144 if ((val <<= 1) < 0)
15147 #if HOST_BITS_PER_WIDE_INT == 32
15148 if (GET_CODE (x) == CONST_INT && i >= 0)
15149 i += 32; /* zero-extend high-part was all 0's */
15150 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15152 val = CONST_DOUBLE_LOW (x);
15158 for ( ; i < 64; i++)
15159 if ((val <<= 1) < 0)
15164 fprintf (file, "%d", i + 1);
15168 /* X is a FPR or Altivec register used in a VSX context. */
15169 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15170 output_operand_lossage ("invalid %%x value");
15173 int reg = REGNO (x);
15174 int vsx_reg = (FP_REGNO_P (reg)
15176 : reg - FIRST_ALTIVEC_REGNO + 32);
15178 #ifdef TARGET_REGNAMES
15179 if (TARGET_REGNAMES)
15180 fprintf (file, "%%vs%d", vsx_reg);
15183 fprintf (file, "%d", vsx_reg);
15188 if (GET_CODE (x) == MEM
15189 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15190 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15191 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15196 /* Like 'L', for third word of TImode */
15197 if (GET_CODE (x) == REG)
15198 fputs (reg_names[REGNO (x) + 2], file);
15199 else if (GET_CODE (x) == MEM)
15201 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15202 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15203 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15204 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15205 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15207 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15208 if (small_data_operand (x, GET_MODE (x)))
15209 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15210 reg_names[SMALL_DATA_REG]);
15215 /* X is a SYMBOL_REF. Write out the name preceded by a
15216 period and without any trailing data in brackets. Used for function
15217 names. If we are configured for System V (or the embedded ABI) on
15218 the PowerPC, do not emit the period, since those systems do not use
15219 TOCs and the like. */
15220 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15222 /* Mark the decl as referenced so that cgraph will output the
15224 if (SYMBOL_REF_DECL (x))
15225 mark_decl_referenced (SYMBOL_REF_DECL (x));
15227 /* For macho, check to see if we need a stub. */
15230 const char *name = XSTR (x, 0);
15232 if (MACHOPIC_INDIRECT
15233 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15234 name = machopic_indirection_name (x, /*stub_p=*/true);
15236 assemble_name (file, name);
15238 else if (!DOT_SYMBOLS)
15239 assemble_name (file, XSTR (x, 0));
15241 rs6000_output_function_entry (file, XSTR (x, 0));
15245 /* Like 'L', for last word of TImode. */
15246 if (GET_CODE (x) == REG)
15247 fputs (reg_names[REGNO (x) + 3], file);
15248 else if (GET_CODE (x) == MEM)
15250 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15251 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15252 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15253 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15254 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15256 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15257 if (small_data_operand (x, GET_MODE (x)))
15258 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15259 reg_names[SMALL_DATA_REG]);
15263 /* Print AltiVec or SPE memory operand. */
15268 gcc_assert (GET_CODE (x) == MEM);
15272 /* Ugly hack because %y is overloaded. */
15273 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15274 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15275 || GET_MODE (x) == TFmode
15276 || GET_MODE (x) == TImode))
15278 /* Handle [reg]. */
15279 if (GET_CODE (tmp) == REG)
15281 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15284 /* Handle [reg+UIMM]. */
15285 else if (GET_CODE (tmp) == PLUS &&
15286 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15290 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15292 x = INTVAL (XEXP (tmp, 1));
15293 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15297 /* Fall through. Must be [reg+reg]. */
15299 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15300 && GET_CODE (tmp) == AND
15301 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15302 && INTVAL (XEXP (tmp, 1)) == -16)
15303 tmp = XEXP (tmp, 0);
15304 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15305 && GET_CODE (tmp) == PRE_MODIFY)
15306 tmp = XEXP (tmp, 1);
15307 if (GET_CODE (tmp) == REG)
15308 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15311 if (!GET_CODE (tmp) == PLUS
15312 || !REG_P (XEXP (tmp, 0))
15313 || !REG_P (XEXP (tmp, 1)))
15315 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15319 if (REGNO (XEXP (tmp, 0)) == 0)
15320 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15321 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15323 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15324 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15330 if (GET_CODE (x) == REG)
15331 fprintf (file, "%s", reg_names[REGNO (x)]);
15332 else if (GET_CODE (x) == MEM)
15334 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15335 know the width from the mode. */
15336 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15337 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15338 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15339 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15340 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15341 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15342 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15343 output_address (XEXP (XEXP (x, 0), 1));
15345 output_address (XEXP (x, 0));
15348 output_addr_const (file, x);
15352 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15356 output_operand_lossage ("invalid %%xn code");
15360 /* Print the address of an operand. */
15363 print_operand_address (FILE *file, rtx x)
15365 if (GET_CODE (x) == REG)
15366 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15367 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15368 || GET_CODE (x) == LABEL_REF)
15370 output_addr_const (file, x);
15371 if (small_data_operand (x, GET_MODE (x)))
15372 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15373 reg_names[SMALL_DATA_REG]);
15375 gcc_assert (!TARGET_TOC);
15377 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15379 gcc_assert (REG_P (XEXP (x, 0)));
15380 if (REGNO (XEXP (x, 0)) == 0)
15381 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15382 reg_names[ REGNO (XEXP (x, 0)) ]);
15384 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15385 reg_names[ REGNO (XEXP (x, 1)) ]);
15387 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15388 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15389 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15391 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15392 && CONSTANT_P (XEXP (x, 1)))
15394 fprintf (file, "lo16(");
15395 output_addr_const (file, XEXP (x, 1));
15396 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15399 else if (legitimate_constant_pool_address_p (x, true))
15401 /* This hack along with a corresponding hack in
15402 rs6000_output_addr_const_extra arranges to output addends
15403 where the assembler expects to find them. eg.
15405 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
15406 without this hack would be output as "x@toc+8@l(9)". We
15407 want "x+8@toc@l(9)". */
15408 output_addr_const (file, tocrel_base);
15409 if (GET_CODE (x) == LO_SUM)
15410 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15412 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15415 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15416 && CONSTANT_P (XEXP (x, 1)))
15418 output_addr_const (file, XEXP (x, 1));
15419 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15423 gcc_unreachable ();
15426 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
15429 rs6000_output_addr_const_extra (FILE *file, rtx x)
15431 if (GET_CODE (x) == UNSPEC)
15432 switch (XINT (x, 1))
15434 case UNSPEC_TOCREL:
15435 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
15436 output_addr_const (file, XVECEXP (x, 0, 0));
15437 if (x == tocrel_base && tocrel_offset != const0_rtx)
15439 if (INTVAL (tocrel_offset) >= 0)
15440 fprintf (file, "+");
15441 output_addr_const (file, tocrel_offset);
15443 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
15446 assemble_name (file, toc_label_name);
15448 else if (TARGET_ELF)
15449 fputs ("@toc", file);
15453 case UNSPEC_MACHOPIC_OFFSET:
15454 output_addr_const (file, XVECEXP (x, 0, 0));
15456 machopic_output_function_base_name (file);
15463 /* Target hook for assembling integer objects. The PowerPC version has
15464 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15465 is defined. It also needs to handle DI-mode objects on 64-bit
15469 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15471 #ifdef RELOCATABLE_NEEDS_FIXUP
15472 /* Special handling for SI values. */
15473 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
15475 static int recurse = 0;
15477 /* For -mrelocatable, we mark all addresses that need to be fixed up
15478 in the .fixup section. */
15479 if (TARGET_RELOCATABLE
15480 && in_section != toc_section
15481 && in_section != text_section
15482 && !unlikely_text_section_p (in_section)
15484 && GET_CODE (x) != CONST_INT
15485 && GET_CODE (x) != CONST_DOUBLE
15491 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
15493 ASM_OUTPUT_LABEL (asm_out_file, buf);
15494 fprintf (asm_out_file, "\t.long\t(");
15495 output_addr_const (asm_out_file, x);
15496 fprintf (asm_out_file, ")@fixup\n");
15497 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
15498 ASM_OUTPUT_ALIGN (asm_out_file, 2);
15499 fprintf (asm_out_file, "\t.long\t");
15500 assemble_name (asm_out_file, buf);
15501 fprintf (asm_out_file, "\n\t.previous\n");
15505 /* Remove initial .'s to turn a -mcall-aixdesc function
15506 address into the address of the descriptor, not the function
15508 else if (GET_CODE (x) == SYMBOL_REF
15509 && XSTR (x, 0)[0] == '.'
15510 && DEFAULT_ABI == ABI_AIX)
15512 const char *name = XSTR (x, 0);
15513 while (*name == '.')
15516 fprintf (asm_out_file, "\t.long\t%s\n", name);
15520 #endif /* RELOCATABLE_NEEDS_FIXUP */
15521 return default_assemble_integer (x, size, aligned_p);
15524 #ifdef HAVE_GAS_HIDDEN
15525 /* Emit an assembler directive to set symbol visibility for DECL to
15526 VISIBILITY_TYPE. */
15529 rs6000_assemble_visibility (tree decl, int vis)
15531 /* Functions need to have their entry point symbol visibility set as
15532 well as their descriptor symbol visibility. */
15533 if (DEFAULT_ABI == ABI_AIX
15535 && TREE_CODE (decl) == FUNCTION_DECL)
15537 static const char * const visibility_types[] = {
15538 NULL, "internal", "hidden", "protected"
15541 const char *name, *type;
15543 name = ((* targetm.strip_name_encoding)
15544 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
15545 type = visibility_types[vis];
15547 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
15548 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
15551 default_assemble_visibility (decl, vis);
15556 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15558 /* Reversal of FP compares takes care -- an ordered compare
15559 becomes an unordered compare and vice versa. */
15560 if (mode == CCFPmode
15561 && (!flag_finite_math_only
15562 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15563 || code == UNEQ || code == LTGT))
15564 return reverse_condition_maybe_unordered (code);
15566 return reverse_condition (code);
15569 /* Generate a compare for CODE. Return a brand-new rtx that
15570 represents the result of the compare. */
15573 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15575 enum machine_mode comp_mode;
15576 rtx compare_result;
15577 enum rtx_code code = GET_CODE (cmp);
15578 rtx op0 = XEXP (cmp, 0);
15579 rtx op1 = XEXP (cmp, 1);
15581 if (FLOAT_MODE_P (mode))
15582 comp_mode = CCFPmode;
15583 else if (code == GTU || code == LTU
15584 || code == GEU || code == LEU)
15585 comp_mode = CCUNSmode;
15586 else if ((code == EQ || code == NE)
15587 && GET_CODE (op0) == SUBREG
15588 && GET_CODE (op1) == SUBREG
15589 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15590 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15591 /* These are unsigned values, perhaps there will be a later
15592 ordering compare that can be shared with this one.
15593 Unfortunately we cannot detect the signedness of the operands
15594 for non-subregs. */
15595 comp_mode = CCUNSmode;
15597 comp_mode = CCmode;
15599 /* First, the compare. */
15600 compare_result = gen_reg_rtx (comp_mode);
15602 /* E500 FP compare instructions on the GPRs. Yuck! */
15603 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15604 && FLOAT_MODE_P (mode))
15606 rtx cmp, or_result, compare_result2;
15607 enum machine_mode op_mode = GET_MODE (op0);
15609 if (op_mode == VOIDmode)
15610 op_mode = GET_MODE (op1);
15612 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15613 This explains the following mess. */
15617 case EQ: case UNEQ: case NE: case LTGT:
15621 cmp = (flag_finite_math_only && !flag_trapping_math)
15622 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15623 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15627 cmp = (flag_finite_math_only && !flag_trapping_math)
15628 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15629 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15633 cmp = (flag_finite_math_only && !flag_trapping_math)
15634 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15635 : gen_cmptfeq_gpr (compare_result, op0, op1);
15639 gcc_unreachable ();
15643 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15647 cmp = (flag_finite_math_only && !flag_trapping_math)
15648 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15649 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15653 cmp = (flag_finite_math_only && !flag_trapping_math)
15654 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15655 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15659 cmp = (flag_finite_math_only && !flag_trapping_math)
15660 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15661 : gen_cmptfgt_gpr (compare_result, op0, op1);
15665 gcc_unreachable ();
15669 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15673 cmp = (flag_finite_math_only && !flag_trapping_math)
15674 ? gen_tstsflt_gpr (compare_result, op0, op1)
15675 : gen_cmpsflt_gpr (compare_result, op0, op1);
15679 cmp = (flag_finite_math_only && !flag_trapping_math)
15680 ? gen_tstdflt_gpr (compare_result, op0, op1)
15681 : gen_cmpdflt_gpr (compare_result, op0, op1);
15685 cmp = (flag_finite_math_only && !flag_trapping_math)
15686 ? gen_tsttflt_gpr (compare_result, op0, op1)
15687 : gen_cmptflt_gpr (compare_result, op0, op1);
15691 gcc_unreachable ();
15695 gcc_unreachable ();
15698 /* Synthesize LE and GE from LT/GT || EQ. */
15699 if (code == LE || code == GE || code == LEU || code == GEU)
15705 case LE: code = LT; break;
15706 case GE: code = GT; break;
15707 case LEU: code = LT; break;
15708 case GEU: code = GT; break;
15709 default: gcc_unreachable ();
15712 compare_result2 = gen_reg_rtx (CCFPmode);
15718 cmp = (flag_finite_math_only && !flag_trapping_math)
15719 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15720 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15724 cmp = (flag_finite_math_only && !flag_trapping_math)
15725 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15726 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15730 cmp = (flag_finite_math_only && !flag_trapping_math)
15731 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15732 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15736 gcc_unreachable ();
15740 /* OR them together. */
15741 or_result = gen_reg_rtx (CCFPmode);
15742 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15744 compare_result = or_result;
15749 if (code == NE || code == LTGT)
15759 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15760 CLOBBERs to match cmptf_internal2 pattern. */
15761 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15762 && GET_MODE (op0) == TFmode
15763 && !TARGET_IEEEQUAD
15764 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15765 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15767 gen_rtx_SET (VOIDmode,
15769 gen_rtx_COMPARE (comp_mode, op0, op1)),
15770 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15771 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15772 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15773 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15774 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15775 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15776 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15777 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15778 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
15779 else if (GET_CODE (op1) == UNSPEC
15780 && XINT (op1, 1) == UNSPEC_SP_TEST)
15782 rtx op1b = XVECEXP (op1, 0, 0);
15783 comp_mode = CCEQmode;
15784 compare_result = gen_reg_rtx (CCEQmode);
15786 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15788 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15791 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15792 gen_rtx_COMPARE (comp_mode, op0, op1)));
15795 /* Some kinds of FP comparisons need an OR operation;
15796 under flag_finite_math_only we don't bother. */
15797 if (FLOAT_MODE_P (mode)
15798 && !flag_finite_math_only
15799 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15800 && (code == LE || code == GE
15801 || code == UNEQ || code == LTGT
15802 || code == UNGT || code == UNLT))
15804 enum rtx_code or1, or2;
15805 rtx or1_rtx, or2_rtx, compare2_rtx;
15806 rtx or_result = gen_reg_rtx (CCEQmode);
15810 case LE: or1 = LT; or2 = EQ; break;
15811 case GE: or1 = GT; or2 = EQ; break;
15812 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15813 case LTGT: or1 = LT; or2 = GT; break;
15814 case UNGT: or1 = UNORDERED; or2 = GT; break;
15815 case UNLT: or1 = UNORDERED; or2 = LT; break;
15816 default: gcc_unreachable ();
15818 validate_condition_mode (or1, comp_mode);
15819 validate_condition_mode (or2, comp_mode);
15820 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15821 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15822 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15823 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15825 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15827 compare_result = or_result;
15831 validate_condition_mode (code, GET_MODE (compare_result));
15833 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15837 /* Emit the RTL for an sCOND pattern. */
15840 rs6000_emit_sISEL (enum machine_mode mode, rtx operands[])
15843 enum machine_mode op_mode;
15844 enum rtx_code cond_code;
15845 rtx result = operands[0];
15847 condition_rtx = rs6000_generate_compare (operands[1], mode);
15848 cond_code = GET_CODE (condition_rtx);
15850 op_mode = GET_MODE (XEXP (operands[1], 0));
15851 if (op_mode == VOIDmode)
15852 op_mode = GET_MODE (XEXP (operands[1], 1));
15854 if (TARGET_POWERPC64 && GET_MODE (result) == DImode)
15856 PUT_MODE (condition_rtx, DImode);
15857 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15858 || cond_code == LTU)
15859 emit_insn (gen_isel_unsigned_di (result, condition_rtx,
15860 force_reg (DImode, const1_rtx),
15861 force_reg (DImode, const0_rtx),
15862 XEXP (condition_rtx, 0)));
15864 emit_insn (gen_isel_signed_di (result, condition_rtx,
15865 force_reg (DImode, const1_rtx),
15866 force_reg (DImode, const0_rtx),
15867 XEXP (condition_rtx, 0)));
15871 PUT_MODE (condition_rtx, SImode);
15872 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15873 || cond_code == LTU)
15874 emit_insn (gen_isel_unsigned_si (result, condition_rtx,
15875 force_reg (SImode, const1_rtx),
15876 force_reg (SImode, const0_rtx),
15877 XEXP (condition_rtx, 0)));
15879 emit_insn (gen_isel_signed_si (result, condition_rtx,
15880 force_reg (SImode, const1_rtx),
15881 force_reg (SImode, const0_rtx),
15882 XEXP (condition_rtx, 0)));
15887 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15890 enum machine_mode op_mode;
15891 enum rtx_code cond_code;
15892 rtx result = operands[0];
15894 if (TARGET_ISEL && (mode == SImode || mode == DImode))
15896 rs6000_emit_sISEL (mode, operands);
15900 condition_rtx = rs6000_generate_compare (operands[1], mode);
15901 cond_code = GET_CODE (condition_rtx);
15903 if (FLOAT_MODE_P (mode)
15904 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15908 PUT_MODE (condition_rtx, SImode);
15909 t = XEXP (condition_rtx, 0);
15911 gcc_assert (cond_code == NE || cond_code == EQ);
15913 if (cond_code == NE)
15914 emit_insn (gen_e500_flip_gt_bit (t, t));
15916 emit_insn (gen_move_from_CR_gt_bit (result, t));
15920 if (cond_code == NE
15921 || cond_code == GE || cond_code == LE
15922 || cond_code == GEU || cond_code == LEU
15923 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15925 rtx not_result = gen_reg_rtx (CCEQmode);
15926 rtx not_op, rev_cond_rtx;
15927 enum machine_mode cc_mode;
15929 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15931 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15932 SImode, XEXP (condition_rtx, 0), const0_rtx);
15933 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15934 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15935 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15938 op_mode = GET_MODE (XEXP (operands[1], 0));
15939 if (op_mode == VOIDmode)
15940 op_mode = GET_MODE (XEXP (operands[1], 1));
15942 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15944 PUT_MODE (condition_rtx, DImode);
15945 convert_move (result, condition_rtx, 0);
15949 PUT_MODE (condition_rtx, SImode);
15950 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15954 /* Emit a branch of kind CODE to location LOC. */
15957 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15959 rtx condition_rtx, loc_ref;
15961 condition_rtx = rs6000_generate_compare (operands[0], mode);
15962 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15963 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15964 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15965 loc_ref, pc_rtx)));
15968 /* Return the string to output a conditional branch to LABEL, which is
15969 the operand number of the label, or -1 if the branch is really a
15970 conditional return.
15972 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15973 condition code register and its mode specifies what kind of
15974 comparison we made.
15976 REVERSED is nonzero if we should reverse the sense of the comparison.
15978 INSN is the insn. */
15981 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
15983 static char string[64];
15984 enum rtx_code code = GET_CODE (op);
15985 rtx cc_reg = XEXP (op, 0);
15986 enum machine_mode mode = GET_MODE (cc_reg);
15987 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
15988 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
15989 int really_reversed = reversed ^ need_longbranch;
15995 validate_condition_mode (code, mode);
15997 /* Work out which way this really branches. We could use
15998 reverse_condition_maybe_unordered here always but this
15999 makes the resulting assembler clearer. */
16000 if (really_reversed)
16002 /* Reversal of FP compares takes care -- an ordered compare
16003 becomes an unordered compare and vice versa. */
16004 if (mode == CCFPmode)
16005 code = reverse_condition_maybe_unordered (code);
16007 code = reverse_condition (code);
16010 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16012 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16017 /* Opposite of GT. */
16026 gcc_unreachable ();
16032 /* Not all of these are actually distinct opcodes, but
16033 we distinguish them for clarity of the resulting assembler. */
16034 case NE: case LTGT:
16035 ccode = "ne"; break;
16036 case EQ: case UNEQ:
16037 ccode = "eq"; break;
16039 ccode = "ge"; break;
16040 case GT: case GTU: case UNGT:
16041 ccode = "gt"; break;
16043 ccode = "le"; break;
16044 case LT: case LTU: case UNLT:
16045 ccode = "lt"; break;
16046 case UNORDERED: ccode = "un"; break;
16047 case ORDERED: ccode = "nu"; break;
16048 case UNGE: ccode = "nl"; break;
16049 case UNLE: ccode = "ng"; break;
16051 gcc_unreachable ();
16054 /* Maybe we have a guess as to how likely the branch is.
16055 The old mnemonics don't have a way to specify this information. */
16057 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16058 if (note != NULL_RTX)
16060 /* PROB is the difference from 50%. */
16061 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16063 /* Only hint for highly probable/improbable branches on newer
16064 cpus as static prediction overrides processor dynamic
16065 prediction. For older cpus we may as well always hint, but
16066 assume not taken for branches that are very close to 50% as a
16067 mispredicted taken branch is more expensive than a
16068 mispredicted not-taken branch. */
16069 if (rs6000_always_hint
16070 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16071 && br_prob_note_reliable_p (note)))
16073 if (abs (prob) > REG_BR_PROB_BASE / 20
16074 && ((prob > 0) ^ need_longbranch))
16082 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16084 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16086 /* We need to escape any '%' characters in the reg_names string.
16087 Assume they'd only be the first character.... */
16088 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16090 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16094 /* If the branch distance was too far, we may have to use an
16095 unconditional branch to go the distance. */
16096 if (need_longbranch)
16097 s += sprintf (s, ",$+8\n\tb %s", label);
16099 s += sprintf (s, ",%s", label);
16105 /* Return the string to flip the GT bit on a CR. */
16107 output_e500_flip_gt_bit (rtx dst, rtx src)
16109 static char string[64];
16112 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16113 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16116 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16117 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16119 sprintf (string, "crnot %d,%d", a, b);
16123 /* Return insn for VSX or Altivec comparisons. */
16126 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16129 enum machine_mode mode = GET_MODE (op0);
16137 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16143 mask = gen_reg_rtx (mode);
16144 emit_insn (gen_rtx_SET (VOIDmode,
16146 gen_rtx_fmt_ee (code, mode, op0, op1)));
16153 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16154 DMODE is expected destination mode. This is a recursive function. */
16157 rs6000_emit_vector_compare (enum rtx_code rcode,
16159 enum machine_mode dmode)
16162 bool swap_operands = false;
16163 bool try_again = false;
16165 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16166 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16168 /* See if the comparison works as is. */
16169 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16177 swap_operands = true;
16182 swap_operands = true;
16190 /* Invert condition and try again.
16191 e.g., A != B becomes ~(A==B). */
16193 enum rtx_code rev_code;
16194 enum insn_code nor_code;
16197 rev_code = reverse_condition_maybe_unordered (rcode);
16198 if (rev_code == UNKNOWN)
16201 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
16202 if (nor_code == CODE_FOR_nothing)
16205 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16209 mask = gen_reg_rtx (dmode);
16210 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16218 /* Try GT/GTU/LT/LTU OR EQ */
16221 enum insn_code ior_code;
16222 enum rtx_code new_code;
16243 gcc_unreachable ();
16246 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
16247 if (ior_code == CODE_FOR_nothing)
16250 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16254 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16258 mask = gen_reg_rtx (dmode);
16259 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16277 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16282 /* You only get two chances. */
16286 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16287 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16288 operands for the relation operation COND. */
16291 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16292 rtx cond, rtx cc_op0, rtx cc_op1)
16294 enum machine_mode dest_mode = GET_MODE (dest);
16295 enum rtx_code rcode = GET_CODE (cond);
16296 enum machine_mode cc_mode = CCmode;
16300 bool invert_move = false;
16302 if (VECTOR_UNIT_NONE_P (dest_mode))
16307 /* Swap operands if we can, and fall back to doing the operation as
16308 specified, and doing a NOR to invert the test. */
16314 /* Invert condition and try again.
16315 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16316 invert_move = true;
16317 rcode = reverse_condition_maybe_unordered (rcode);
16318 if (rcode == UNKNOWN)
16322 /* Mark unsigned tests with CCUNSmode. */
16327 cc_mode = CCUNSmode;
16334 /* Get the vector mask for the given relational operations. */
16335 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16343 op_true = op_false;
16347 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
16348 emit_insn (gen_rtx_SET (VOIDmode,
16350 gen_rtx_IF_THEN_ELSE (dest_mode,
16357 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16358 operands of the last comparison is nonzero/true, FALSE_COND if it
16359 is zero/false. Return 0 if the hardware has no such operation. */
16362 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16364 enum rtx_code code = GET_CODE (op);
16365 rtx op0 = XEXP (op, 0);
16366 rtx op1 = XEXP (op, 1);
16367 REAL_VALUE_TYPE c1;
16368 enum machine_mode compare_mode = GET_MODE (op0);
16369 enum machine_mode result_mode = GET_MODE (dest);
16371 bool is_against_zero;
16373 /* These modes should always match. */
16374 if (GET_MODE (op1) != compare_mode
16375 /* In the isel case however, we can use a compare immediate, so
16376 op1 may be a small constant. */
16377 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16379 if (GET_MODE (true_cond) != result_mode)
16381 if (GET_MODE (false_cond) != result_mode)
16384 /* First, work out if the hardware can do this at all, or
16385 if it's too slow.... */
16386 if (!FLOAT_MODE_P (compare_mode))
16389 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16392 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16393 && SCALAR_FLOAT_MODE_P (compare_mode))
16396 is_against_zero = op1 == CONST0_RTX (compare_mode);
16398 /* A floating-point subtract might overflow, underflow, or produce
16399 an inexact result, thus changing the floating-point flags, so it
16400 can't be generated if we care about that. It's safe if one side
16401 of the construct is zero, since then no subtract will be
16403 if (SCALAR_FLOAT_MODE_P (compare_mode)
16404 && flag_trapping_math && ! is_against_zero)
16407 /* Eliminate half of the comparisons by switching operands, this
16408 makes the remaining code simpler. */
16409 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16410 || code == LTGT || code == LT || code == UNLE)
16412 code = reverse_condition_maybe_unordered (code);
16414 true_cond = false_cond;
16418 /* UNEQ and LTGT take four instructions for a comparison with zero,
16419 it'll probably be faster to use a branch here too. */
16420 if (code == UNEQ && HONOR_NANS (compare_mode))
16423 if (GET_CODE (op1) == CONST_DOUBLE)
16424 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16426 /* We're going to try to implement comparisons by performing
16427 a subtract, then comparing against zero. Unfortunately,
16428 Inf - Inf is NaN which is not zero, and so if we don't
16429 know that the operand is finite and the comparison
16430 would treat EQ different to UNORDERED, we can't do it. */
16431 if (HONOR_INFINITIES (compare_mode)
16432 && code != GT && code != UNGE
16433 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16434 /* Constructs of the form (a OP b ? a : b) are safe. */
16435 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16436 || (! rtx_equal_p (op0, true_cond)
16437 && ! rtx_equal_p (op1, true_cond))))
16440 /* At this point we know we can use fsel. */
16442 /* Reduce the comparison to a comparison against zero. */
16443 if (! is_against_zero)
16445 temp = gen_reg_rtx (compare_mode);
16446 emit_insn (gen_rtx_SET (VOIDmode, temp,
16447 gen_rtx_MINUS (compare_mode, op0, op1)));
16449 op1 = CONST0_RTX (compare_mode);
16452 /* If we don't care about NaNs we can reduce some of the comparisons
16453 down to faster ones. */
16454 if (! HONOR_NANS (compare_mode))
16460 true_cond = false_cond;
16473 /* Now, reduce everything down to a GE. */
16480 temp = gen_reg_rtx (compare_mode);
16481 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16486 temp = gen_reg_rtx (compare_mode);
16487 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
16492 temp = gen_reg_rtx (compare_mode);
16493 emit_insn (gen_rtx_SET (VOIDmode, temp,
16494 gen_rtx_NEG (compare_mode,
16495 gen_rtx_ABS (compare_mode, op0))));
16500 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16501 temp = gen_reg_rtx (result_mode);
16502 emit_insn (gen_rtx_SET (VOIDmode, temp,
16503 gen_rtx_IF_THEN_ELSE (result_mode,
16504 gen_rtx_GE (VOIDmode,
16506 true_cond, false_cond)));
16507 false_cond = true_cond;
16510 temp = gen_reg_rtx (compare_mode);
16511 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16516 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
16517 temp = gen_reg_rtx (result_mode);
16518 emit_insn (gen_rtx_SET (VOIDmode, temp,
16519 gen_rtx_IF_THEN_ELSE (result_mode,
16520 gen_rtx_GE (VOIDmode,
16522 true_cond, false_cond)));
16523 true_cond = false_cond;
16526 temp = gen_reg_rtx (compare_mode);
16527 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16532 gcc_unreachable ();
16535 emit_insn (gen_rtx_SET (VOIDmode, dest,
16536 gen_rtx_IF_THEN_ELSE (result_mode,
16537 gen_rtx_GE (VOIDmode,
16539 true_cond, false_cond)));
16543 /* Same as above, but for ints (isel). */
16546 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16548 rtx condition_rtx, cr;
16549 enum machine_mode mode = GET_MODE (dest);
16551 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
16554 /* We still have to do the compare, because isel doesn't do a
16555 compare, it just looks at the CRx bits set by a previous compare
16557 condition_rtx = rs6000_generate_compare (op, mode);
16558 cr = XEXP (condition_rtx, 0);
16560 if (mode == SImode)
16562 if (GET_MODE (cr) == CCmode)
16563 emit_insn (gen_isel_signed_si (dest, condition_rtx,
16564 true_cond, false_cond, cr));
16566 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
16567 true_cond, false_cond, cr));
16571 if (GET_MODE (cr) == CCmode)
16572 emit_insn (gen_isel_signed_di (dest, condition_rtx,
16573 true_cond, false_cond, cr));
16575 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
16576 true_cond, false_cond, cr));
16583 output_isel (rtx *operands)
16585 enum rtx_code code;
16587 code = GET_CODE (operands[1]);
16588 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
16590 PUT_CODE (operands[1], reverse_condition (code));
16591 return "isel %0,%3,%2,%j1";
16594 return "isel %0,%2,%3,%j1";
16598 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
16600 enum machine_mode mode = GET_MODE (op0);
16604 /* VSX/altivec have direct min/max insns. */
16605 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
16607 emit_insn (gen_rtx_SET (VOIDmode,
16609 gen_rtx_fmt_ee (code, mode, op0, op1)));
16613 if (code == SMAX || code == SMIN)
16618 if (code == SMAX || code == UMAX)
16619 target = emit_conditional_move (dest, c, op0, op1, mode,
16620 op0, op1, mode, 0);
16622 target = emit_conditional_move (dest, c, op0, op1, mode,
16623 op1, op0, mode, 0);
16624 gcc_assert (target);
16625 if (target != dest)
16626 emit_move_insn (dest, target);
16629 /* Emit instructions to perform a load-reserved/store-conditional operation.
16630 The operation performed is an atomic
16631 (set M (CODE:MODE M OP))
16632 If not NULL, BEFORE is atomically set to M before the operation, and
16633 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16634 If SYNC_P then a memory barrier is emitted before the operation.
16635 Either OP or M may be wrapped in a NOT operation. */
16638 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16639 rtx m, rtx op, rtx before_param, rtx after_param,
16642 enum machine_mode used_mode;
16643 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16646 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16647 rtx shift = NULL_RTX;
16650 emit_insn (gen_lwsync ());
16654 /* If this is smaller than SImode, we'll have to use SImode with
16656 if (mode == QImode || mode == HImode)
16660 if (MEM_ALIGN (used_m) >= 32)
16663 if (BYTES_BIG_ENDIAN)
16664 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16666 shift = GEN_INT (ishift);
16667 used_m = change_address (used_m, SImode, 0);
16671 rtx addrSI, aligned_addr;
16672 int shift_mask = mode == QImode ? 0x18 : 0x10;
16674 addrSI = gen_lowpart_common (SImode,
16675 force_reg (Pmode, XEXP (used_m, 0)));
16676 addrSI = force_reg (SImode, addrSI);
16677 shift = gen_reg_rtx (SImode);
16679 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16680 GEN_INT (shift_mask)));
16681 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16683 aligned_addr = expand_binop (Pmode, and_optab,
16685 GEN_INT (-4), NULL_RTX,
16686 1, OPTAB_LIB_WIDEN);
16687 used_m = change_address (used_m, SImode, aligned_addr);
16688 set_mem_align (used_m, 32);
16690 /* It's safe to keep the old alias set of USED_M, because
16691 the operation is atomic and only affects the original
16695 if (GET_CODE (op) == NOT)
16697 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16698 oldop = gen_rtx_NOT (SImode, oldop);
16701 oldop = lowpart_subreg (SImode, op, mode);
16707 newop = expand_binop (SImode, and_optab,
16708 oldop, GEN_INT (imask), NULL_RTX,
16709 1, OPTAB_LIB_WIDEN);
16710 emit_insn (gen_ashlsi3 (newop, newop, shift));
16713 case NOT: /* NAND */
16714 newop = expand_binop (SImode, ior_optab,
16715 oldop, GEN_INT (~imask), NULL_RTX,
16716 1, OPTAB_LIB_WIDEN);
16717 emit_insn (gen_rotlsi3 (newop, newop, shift));
16721 newop = expand_binop (SImode, ior_optab,
16722 oldop, GEN_INT (~imask), NULL_RTX,
16723 1, OPTAB_LIB_WIDEN);
16724 emit_insn (gen_rotlsi3 (newop, newop, shift));
16732 newop = expand_binop (SImode, and_optab,
16733 oldop, GEN_INT (imask), NULL_RTX,
16734 1, OPTAB_LIB_WIDEN);
16735 emit_insn (gen_ashlsi3 (newop, newop, shift));
16737 mask = gen_reg_rtx (SImode);
16738 emit_move_insn (mask, GEN_INT (imask));
16739 emit_insn (gen_ashlsi3 (mask, mask, shift));
16742 newop = gen_rtx_PLUS (SImode, m, newop);
16744 newop = gen_rtx_MINUS (SImode, m, newop);
16745 newop = gen_rtx_AND (SImode, newop, mask);
16746 newop = gen_rtx_IOR (SImode, newop,
16747 gen_rtx_AND (SImode,
16748 gen_rtx_NOT (SImode, mask),
16754 gcc_unreachable ();
16758 used_mode = SImode;
16759 before = gen_reg_rtx (used_mode);
16760 after = gen_reg_rtx (used_mode);
16765 before = before_param;
16766 after = after_param;
16768 if (before == NULL_RTX)
16769 before = gen_reg_rtx (used_mode);
16770 if (after == NULL_RTX)
16771 after = gen_reg_rtx (used_mode);
16774 if ((code == PLUS || code == MINUS)
16775 && used_mode != mode)
16776 the_op = op; /* Computed above. */
16777 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16778 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16779 else if (code == NOT)
16780 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16781 gen_rtx_NOT (used_mode, m),
16782 gen_rtx_NOT (used_mode, op));
16784 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16786 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16787 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16788 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16789 gen_rtx_UNSPEC (used_mode,
16790 gen_rtvec (1, the_op),
16792 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16794 if ((code == PLUS || code == MINUS) && used_mode != mode)
16795 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16796 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16798 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16799 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16801 /* Shift and mask the return values properly. */
16802 if (used_mode != mode && before_param)
16804 emit_insn (gen_lshrsi3 (before, before, shift));
16805 convert_move (before_param, before, 1);
16808 if (used_mode != mode && after_param)
16810 emit_insn (gen_lshrsi3 (after, after, shift));
16811 convert_move (after_param, after, 1);
16814 /* The previous sequence will end with a branch that's dependent on
16815 the conditional store, so placing an isync will ensure that no
16816 other instructions (especially, no load or store instructions)
16817 can start before the atomic operation completes. */
16819 emit_insn (gen_isync ());
16822 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16823 COND is true. Mark the jump as unlikely to be taken. */
16826 emit_unlikely_jump (rtx cond, rtx label)
16828 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16831 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16832 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16833 add_reg_note (x, REG_BR_PROB, very_unlikely);
16836 /* A subroutine of the atomic operation splitters. Emit a load-locked
16837 instruction in MODE. */
16840 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16842 rtx (*fn) (rtx, rtx) = NULL;
16843 if (mode == SImode)
16844 fn = gen_load_locked_si;
16845 else if (mode == DImode)
16846 fn = gen_load_locked_di;
16847 emit_insn (fn (reg, mem));
16850 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16851 instruction in MODE. */
16854 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16856 rtx (*fn) (rtx, rtx, rtx) = NULL;
16857 if (mode == SImode)
16858 fn = gen_store_conditional_si;
16859 else if (mode == DImode)
16860 fn = gen_store_conditional_di;
16862 /* Emit sync before stwcx. to address PPC405 Erratum. */
16863 if (PPC405_ERRATUM77)
16864 emit_insn (gen_memory_barrier ());
16866 emit_insn (fn (res, mem, val));
16869 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16870 to perform. MEM is the memory on which to operate. VAL is the second
16871 operand of the binary operator. BEFORE and AFTER are optional locations to
16872 return the value of MEM either before of after the operation. SCRATCH is
16873 a scratch register. */
16876 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16877 rtx before, rtx after, rtx scratch)
16879 enum machine_mode mode = GET_MODE (mem);
16880 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16882 emit_insn (gen_lwsync ());
16884 label = gen_label_rtx ();
16885 emit_label (label);
16886 label = gen_rtx_LABEL_REF (VOIDmode, label);
16888 if (before == NULL_RTX)
16890 emit_load_locked (mode, before, mem);
16893 x = gen_rtx_IOR (mode,
16894 gen_rtx_NOT (mode, before),
16895 gen_rtx_NOT (mode, val));
16896 else if (code == AND)
16897 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16899 x = gen_rtx_fmt_ee (code, mode, before, val);
16901 if (after != NULL_RTX)
16902 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16903 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16905 emit_store_conditional (mode, cond, mem, scratch);
16907 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16908 emit_unlikely_jump (x, label);
16910 emit_insn (gen_isync ());
16913 /* Expand an atomic compare and swap operation. MEM is the memory on which
16914 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16915 value to be stored. SCRATCH is a scratch GPR. */
16918 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16921 enum machine_mode mode = GET_MODE (mem);
16922 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16924 emit_insn (gen_lwsync ());
16926 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16927 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16928 emit_label (XEXP (label1, 0));
16930 emit_load_locked (mode, retval, mem);
16932 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16933 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16935 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16936 emit_unlikely_jump (x, label2);
16938 emit_move_insn (scratch, newval);
16939 emit_store_conditional (mode, cond, mem, scratch);
16941 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16942 emit_unlikely_jump (x, label1);
16944 emit_insn (gen_isync ());
16945 emit_label (XEXP (label2, 0));
16948 /* Expand an atomic test and set operation. MEM is the memory on which
16949 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16952 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16954 enum machine_mode mode = GET_MODE (mem);
16955 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16957 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16958 emit_label (XEXP (label, 0));
16960 emit_load_locked (mode, retval, mem);
16961 emit_move_insn (scratch, val);
16962 emit_store_conditional (mode, cond, mem, scratch);
16964 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16965 emit_unlikely_jump (x, label);
16967 emit_insn (gen_isync ());
16971 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
16973 enum machine_mode mode = GET_MODE (mem);
16974 rtx addrSI, align, wdst, shift, mask;
16975 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
16976 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16978 /* Shift amount for subword relative to aligned word. */
16979 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
16980 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
16981 shift = gen_reg_rtx (SImode);
16982 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16983 GEN_INT (shift_mask)));
16984 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16986 /* Shift and mask old value into position within word. */
16987 oldval = convert_modes (SImode, mode, oldval, 1);
16988 oldval = expand_binop (SImode, and_optab,
16989 oldval, GEN_INT (imask), NULL_RTX,
16990 1, OPTAB_LIB_WIDEN);
16991 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
16993 /* Shift and mask new value into position within word. */
16994 newval = convert_modes (SImode, mode, newval, 1);
16995 newval = expand_binop (SImode, and_optab,
16996 newval, GEN_INT (imask), NULL_RTX,
16997 1, OPTAB_LIB_WIDEN);
16998 emit_insn (gen_ashlsi3 (newval, newval, shift));
17000 /* Mask for insertion. */
17001 mask = gen_reg_rtx (SImode);
17002 emit_move_insn (mask, GEN_INT (imask));
17003 emit_insn (gen_ashlsi3 (mask, mask, shift));
17005 /* Address of aligned word containing subword. */
17006 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17007 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17008 mem = change_address (mem, SImode, align);
17009 set_mem_align (mem, 32);
17010 MEM_VOLATILE_P (mem) = 1;
17012 wdst = gen_reg_rtx (SImode);
17013 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17014 oldval, newval, mem));
17016 /* Shift the result back. */
17017 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17019 emit_move_insn (dst, gen_lowpart (mode, wdst));
17023 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17024 rtx oldval, rtx newval, rtx mem,
17027 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17029 emit_insn (gen_lwsync ());
17030 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17031 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17032 emit_label (XEXP (label1, 0));
17034 emit_load_locked (SImode, scratch, mem);
17036 /* Mask subword within loaded value for comparison with oldval.
17037 Use UNSPEC_AND to avoid clobber.*/
17038 emit_insn (gen_rtx_SET (SImode, dest,
17039 gen_rtx_UNSPEC (SImode,
17040 gen_rtvec (2, scratch, mask),
17043 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17044 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17046 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17047 emit_unlikely_jump (x, label2);
17049 /* Clear subword within loaded value for insertion of new value. */
17050 emit_insn (gen_rtx_SET (SImode, scratch,
17051 gen_rtx_AND (SImode,
17052 gen_rtx_NOT (SImode, mask), scratch)));
17053 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17054 emit_store_conditional (SImode, cond, mem, scratch);
17056 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17057 emit_unlikely_jump (x, label1);
17059 emit_insn (gen_isync ());
17060 emit_label (XEXP (label2, 0));
17064 /* Emit instructions to move SRC to DST. Called by splitters for
17065 multi-register moves. It will emit at most one instruction for
17066 each register that is accessed; that is, it won't emit li/lis pairs
17067 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17071 rs6000_split_multireg_move (rtx dst, rtx src)
17073 /* The register number of the first register being moved. */
17075 /* The mode that is to be moved. */
17076 enum machine_mode mode;
17077 /* The mode that the move is being done in, and its size. */
17078 enum machine_mode reg_mode;
17080 /* The number of registers that will be moved. */
17083 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17084 mode = GET_MODE (dst);
17085 nregs = hard_regno_nregs[reg][mode];
17086 if (FP_REGNO_P (reg))
17087 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17088 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17089 else if (ALTIVEC_REGNO_P (reg))
17090 reg_mode = V16QImode;
17091 else if (TARGET_E500_DOUBLE && mode == TFmode)
17094 reg_mode = word_mode;
17095 reg_mode_size = GET_MODE_SIZE (reg_mode);
17097 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17099 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17101 /* Move register range backwards, if we might have destructive
17104 for (i = nregs - 1; i >= 0; i--)
17105 emit_insn (gen_rtx_SET (VOIDmode,
17106 simplify_gen_subreg (reg_mode, dst, mode,
17107 i * reg_mode_size),
17108 simplify_gen_subreg (reg_mode, src, mode,
17109 i * reg_mode_size)));
17115 bool used_update = false;
17116 rtx restore_basereg = NULL_RTX;
17118 if (MEM_P (src) && INT_REGNO_P (reg))
17122 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17123 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17126 breg = XEXP (XEXP (src, 0), 0);
17127 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17128 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17129 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17130 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17131 src = replace_equiv_address (src, breg);
17133 else if (! rs6000_offsettable_memref_p (src))
17135 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17137 rtx basereg = XEXP (XEXP (src, 0), 0);
17140 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17141 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17142 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17143 used_update = true;
17146 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17147 XEXP (XEXP (src, 0), 1)));
17148 src = replace_equiv_address (src, basereg);
17152 rtx basereg = gen_rtx_REG (Pmode, reg);
17153 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17154 src = replace_equiv_address (src, basereg);
17158 breg = XEXP (src, 0);
17159 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17160 breg = XEXP (breg, 0);
17162 /* If the base register we are using to address memory is
17163 also a destination reg, then change that register last. */
17165 && REGNO (breg) >= REGNO (dst)
17166 && REGNO (breg) < REGNO (dst) + nregs)
17167 j = REGNO (breg) - REGNO (dst);
17169 else if (MEM_P (dst) && INT_REGNO_P (reg))
17173 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17174 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17177 breg = XEXP (XEXP (dst, 0), 0);
17178 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17179 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17180 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17182 /* We have to update the breg before doing the store.
17183 Use store with update, if available. */
17187 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17188 emit_insn (TARGET_32BIT
17189 ? (TARGET_POWERPC64
17190 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17191 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17192 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17193 used_update = true;
17196 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17197 dst = replace_equiv_address (dst, breg);
17199 else if (!rs6000_offsettable_memref_p (dst)
17200 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17202 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17204 rtx basereg = XEXP (XEXP (dst, 0), 0);
17207 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17208 emit_insn (gen_rtx_SET (VOIDmode,
17209 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17210 used_update = true;
17213 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17214 XEXP (XEXP (dst, 0), 1)));
17215 dst = replace_equiv_address (dst, basereg);
17219 rtx basereg = XEXP (XEXP (dst, 0), 0);
17220 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17221 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17223 && REG_P (offsetreg)
17224 && REGNO (basereg) != REGNO (offsetreg));
17225 if (REGNO (basereg) == 0)
17227 rtx tmp = offsetreg;
17228 offsetreg = basereg;
17231 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17232 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17233 dst = replace_equiv_address (dst, basereg);
17236 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17237 gcc_assert (rs6000_offsettable_memref_p (dst));
17240 for (i = 0; i < nregs; i++)
17242 /* Calculate index to next subword. */
17247 /* If compiler already emitted move of first word by
17248 store with update, no need to do anything. */
17249 if (j == 0 && used_update)
17252 emit_insn (gen_rtx_SET (VOIDmode,
17253 simplify_gen_subreg (reg_mode, dst, mode,
17254 j * reg_mode_size),
17255 simplify_gen_subreg (reg_mode, src, mode,
17256 j * reg_mode_size)));
17258 if (restore_basereg != NULL_RTX)
17259 emit_insn (restore_basereg);
17264 /* This page contains routines that are used to determine what the
17265 function prologue and epilogue code will do and write them out. */
17267 /* Return the first fixed-point register that is required to be
17268 saved. 32 if none. */
17271 first_reg_to_save (void)
17275 /* Find lowest numbered live register. */
17276 for (first_reg = 13; first_reg <= 31; first_reg++)
17277 if (df_regs_ever_live_p (first_reg)
17278 && (! call_used_regs[first_reg]
17279 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17280 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17281 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17282 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17287 && crtl->uses_pic_offset_table
17288 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17289 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17295 /* Similar, for FP regs. */
17298 first_fp_reg_to_save (void)
17302 /* Find lowest numbered live register. */
17303 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17304 if (df_regs_ever_live_p (first_reg))
17310 /* Similar, for AltiVec regs. */
17313 first_altivec_reg_to_save (void)
17317 /* Stack frame remains as is unless we are in AltiVec ABI. */
17318 if (! TARGET_ALTIVEC_ABI)
17319 return LAST_ALTIVEC_REGNO + 1;
17321 /* On Darwin, the unwind routines are compiled without
17322 TARGET_ALTIVEC, and use save_world to save/restore the
17323 altivec registers when necessary. */
17324 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17325 && ! TARGET_ALTIVEC)
17326 return FIRST_ALTIVEC_REGNO + 20;
17328 /* Find lowest numbered live register. */
17329 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17330 if (df_regs_ever_live_p (i))
17336 /* Return a 32-bit mask of the AltiVec registers we need to set in
17337 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17338 the 32-bit word is 0. */
17340 static unsigned int
17341 compute_vrsave_mask (void)
17343 unsigned int i, mask = 0;
17345 /* On Darwin, the unwind routines are compiled without
17346 TARGET_ALTIVEC, and use save_world to save/restore the
17347 call-saved altivec registers when necessary. */
17348 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17349 && ! TARGET_ALTIVEC)
17352 /* First, find out if we use _any_ altivec registers. */
17353 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17354 if (df_regs_ever_live_p (i))
17355 mask |= ALTIVEC_REG_BIT (i);
17360 /* Next, remove the argument registers from the set. These must
17361 be in the VRSAVE mask set by the caller, so we don't need to add
17362 them in again. More importantly, the mask we compute here is
17363 used to generate CLOBBERs in the set_vrsave insn, and we do not
17364 wish the argument registers to die. */
17365 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17366 mask &= ~ALTIVEC_REG_BIT (i);
17368 /* Similarly, remove the return value from the set. */
17371 diddle_return_value (is_altivec_return_reg, &yes);
17373 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17379 /* For a very restricted set of circumstances, we can cut down the
17380 size of prologues/epilogues by calling our own save/restore-the-world
17384 compute_save_world_info (rs6000_stack_t *info_ptr)
17386 info_ptr->world_save_p = 1;
17387 info_ptr->world_save_p
17388 = (WORLD_SAVE_P (info_ptr)
17389 && DEFAULT_ABI == ABI_DARWIN
17390 && ! (cfun->calls_setjmp && flag_exceptions)
17391 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17392 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17393 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17394 && info_ptr->cr_save_p);
17396 /* This will not work in conjunction with sibcalls. Make sure there
17397 are none. (This check is expensive, but seldom executed.) */
17398 if (WORLD_SAVE_P (info_ptr))
17401 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17402 if ( GET_CODE (insn) == CALL_INSN
17403 && SIBLING_CALL_P (insn))
17405 info_ptr->world_save_p = 0;
17410 if (WORLD_SAVE_P (info_ptr))
17412 /* Even if we're not touching VRsave, make sure there's room on the
17413 stack for it, if it looks like we're calling SAVE_WORLD, which
17414 will attempt to save it. */
17415 info_ptr->vrsave_size = 4;
17417 /* If we are going to save the world, we need to save the link register too. */
17418 info_ptr->lr_save_p = 1;
17420 /* "Save" the VRsave register too if we're saving the world. */
17421 if (info_ptr->vrsave_mask == 0)
17422 info_ptr->vrsave_mask = compute_vrsave_mask ();
17424 /* Because the Darwin register save/restore routines only handle
17425 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17427 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17428 && (info_ptr->first_altivec_reg_save
17429 >= FIRST_SAVED_ALTIVEC_REGNO));
17436 is_altivec_return_reg (rtx reg, void *xyes)
17438 bool *yes = (bool *) xyes;
17439 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17444 /* Calculate the stack information for the current function. This is
17445 complicated by having two separate calling sequences, the AIX calling
17446 sequence and the V.4 calling sequence.
17448 AIX (and Darwin/Mac OS X) stack frames look like:
17450 SP----> +---------------------------------------+
17451 | back chain to caller | 0 0
17452 +---------------------------------------+
17453 | saved CR | 4 8 (8-11)
17454 +---------------------------------------+
17456 +---------------------------------------+
17457 | reserved for compilers | 12 24
17458 +---------------------------------------+
17459 | reserved for binders | 16 32
17460 +---------------------------------------+
17461 | saved TOC pointer | 20 40
17462 +---------------------------------------+
17463 | Parameter save area (P) | 24 48
17464 +---------------------------------------+
17465 | Alloca space (A) | 24+P etc.
17466 +---------------------------------------+
17467 | Local variable space (L) | 24+P+A
17468 +---------------------------------------+
17469 | Float/int conversion temporary (X) | 24+P+A+L
17470 +---------------------------------------+
17471 | Save area for AltiVec registers (W) | 24+P+A+L+X
17472 +---------------------------------------+
17473 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
17474 +---------------------------------------+
17475 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
17476 +---------------------------------------+
17477 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
17478 +---------------------------------------+
17479 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
17480 +---------------------------------------+
17481 old SP->| back chain to caller's caller |
17482 +---------------------------------------+
17484 The required alignment for AIX configurations is two words (i.e., 8
17488 V.4 stack frames look like:
17490 SP----> +---------------------------------------+
17491 | back chain to caller | 0
17492 +---------------------------------------+
17493 | caller's saved LR | 4
17494 +---------------------------------------+
17495 | Parameter save area (P) | 8
17496 +---------------------------------------+
17497 | Alloca space (A) | 8+P
17498 +---------------------------------------+
17499 | Varargs save area (V) | 8+P+A
17500 +---------------------------------------+
17501 | Local variable space (L) | 8+P+A+V
17502 +---------------------------------------+
17503 | Float/int conversion temporary (X) | 8+P+A+V+L
17504 +---------------------------------------+
17505 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
17506 +---------------------------------------+
17507 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
17508 +---------------------------------------+
17509 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
17510 +---------------------------------------+
17511 | SPE: area for 64-bit GP registers |
17512 +---------------------------------------+
17513 | SPE alignment padding |
17514 +---------------------------------------+
17515 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
17516 +---------------------------------------+
17517 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
17518 +---------------------------------------+
17519 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
17520 +---------------------------------------+
17521 old SP->| back chain to caller's caller |
17522 +---------------------------------------+
17524 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
17525 given. (But note below and in sysv4.h that we require only 8 and
17526 may round up the size of our stack frame anyways. The historical
17527 reason is early versions of powerpc-linux which didn't properly
17528 align the stack at program startup. A happy side-effect is that
17529 -mno-eabi libraries can be used with -meabi programs.)
17531 The EABI configuration defaults to the V.4 layout. However,
17532 the stack alignment requirements may differ. If -mno-eabi is not
17533 given, the required stack alignment is 8 bytes; if -mno-eabi is
17534 given, the required alignment is 16 bytes. (But see V.4 comment
17537 #ifndef ABI_STACK_BOUNDARY
17538 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
17541 static rs6000_stack_t *
17542 rs6000_stack_info (void)
17544 static rs6000_stack_t info;
17545 rs6000_stack_t *info_ptr = &info;
17546 int reg_size = TARGET_32BIT ? 4 : 8;
17550 HOST_WIDE_INT non_fixed_size;
17552 memset (&info, 0, sizeof (info));
17556 /* Cache value so we don't rescan instruction chain over and over. */
17557 if (cfun->machine->insn_chain_scanned_p == 0)
17558 cfun->machine->insn_chain_scanned_p
17559 = spe_func_has_64bit_regs_p () + 1;
17560 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
17563 /* Select which calling sequence. */
17564 info_ptr->abi = DEFAULT_ABI;
17566 /* Calculate which registers need to be saved & save area size. */
17567 info_ptr->first_gp_reg_save = first_reg_to_save ();
17568 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
17569 even if it currently looks like we won't. Reload may need it to
17570 get at a constant; if so, it will have already created a constant
17571 pool entry for it. */
17572 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
17573 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
17574 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
17575 && crtl->uses_const_pool
17576 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
17577 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
17579 first_gp = info_ptr->first_gp_reg_save;
17581 info_ptr->gp_size = reg_size * (32 - first_gp);
17583 /* For the SPE, we have an additional upper 32-bits on each GPR.
17584 Ideally we should save the entire 64-bits only when the upper
17585 half is used in SIMD instructions. Since we only record
17586 registers live (not the size they are used in), this proves
17587 difficult because we'd have to traverse the instruction chain at
17588 the right time, taking reload into account. This is a real pain,
17589 so we opt to save the GPRs in 64-bits always if but one register
17590 gets used in 64-bits. Otherwise, all the registers in the frame
17591 get saved in 32-bits.
17593 So... since when we save all GPRs (except the SP) in 64-bits, the
17594 traditional GP save area will be empty. */
17595 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17596 info_ptr->gp_size = 0;
17598 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
17599 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
17601 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
17602 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
17603 - info_ptr->first_altivec_reg_save);
17605 /* Does this function call anything? */
17606 info_ptr->calls_p = (! current_function_is_leaf
17607 || cfun->machine->ra_needs_full_frame);
17609 /* Determine if we need to save the link register. */
17610 if ((DEFAULT_ABI == ABI_AIX
17612 && !TARGET_PROFILE_KERNEL)
17613 #ifdef TARGET_RELOCATABLE
17614 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
17616 || (info_ptr->first_fp_reg_save != 64
17617 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
17618 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
17619 || info_ptr->calls_p
17620 || rs6000_ra_ever_killed ())
17622 info_ptr->lr_save_p = 1;
17623 df_set_regs_ever_live (LR_REGNO, true);
17626 /* Determine if we need to save the condition code registers. */
17627 if (df_regs_ever_live_p (CR2_REGNO)
17628 || df_regs_ever_live_p (CR3_REGNO)
17629 || df_regs_ever_live_p (CR4_REGNO))
17631 info_ptr->cr_save_p = 1;
17632 if (DEFAULT_ABI == ABI_V4)
17633 info_ptr->cr_size = reg_size;
17636 /* If the current function calls __builtin_eh_return, then we need
17637 to allocate stack space for registers that will hold data for
17638 the exception handler. */
17639 if (crtl->calls_eh_return)
17642 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
17645 /* SPE saves EH registers in 64-bits. */
17646 ehrd_size = i * (TARGET_SPE_ABI
17647 && info_ptr->spe_64bit_regs_used != 0
17648 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
17653 /* Determine various sizes. */
17654 info_ptr->reg_size = reg_size;
17655 info_ptr->fixed_size = RS6000_SAVE_AREA;
17656 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
17657 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
17658 TARGET_ALTIVEC ? 16 : 8);
17659 if (FRAME_GROWS_DOWNWARD)
17660 info_ptr->vars_size
17661 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
17662 + info_ptr->parm_size,
17663 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
17664 - (info_ptr->fixed_size + info_ptr->vars_size
17665 + info_ptr->parm_size);
17667 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17668 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17670 info_ptr->spe_gp_size = 0;
17672 if (TARGET_ALTIVEC_ABI)
17673 info_ptr->vrsave_mask = compute_vrsave_mask ();
17675 info_ptr->vrsave_mask = 0;
17677 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17678 info_ptr->vrsave_size = 4;
17680 info_ptr->vrsave_size = 0;
17682 compute_save_world_info (info_ptr);
17684 /* Calculate the offsets. */
17685 switch (DEFAULT_ABI)
17689 gcc_unreachable ();
17693 info_ptr->fp_save_offset = - info_ptr->fp_size;
17694 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17696 if (TARGET_ALTIVEC_ABI)
17698 info_ptr->vrsave_save_offset
17699 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17701 /* Align stack so vector save area is on a quadword boundary.
17702 The padding goes above the vectors. */
17703 if (info_ptr->altivec_size != 0)
17704 info_ptr->altivec_padding_size
17705 = info_ptr->vrsave_save_offset & 0xF;
17707 info_ptr->altivec_padding_size = 0;
17709 info_ptr->altivec_save_offset
17710 = info_ptr->vrsave_save_offset
17711 - info_ptr->altivec_padding_size
17712 - info_ptr->altivec_size;
17713 gcc_assert (info_ptr->altivec_size == 0
17714 || info_ptr->altivec_save_offset % 16 == 0);
17716 /* Adjust for AltiVec case. */
17717 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17720 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17721 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17722 info_ptr->lr_save_offset = 2*reg_size;
17726 info_ptr->fp_save_offset = - info_ptr->fp_size;
17727 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17728 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17730 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17732 /* Align stack so SPE GPR save area is aligned on a
17733 double-word boundary. */
17734 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17735 info_ptr->spe_padding_size
17736 = 8 - (-info_ptr->cr_save_offset % 8);
17738 info_ptr->spe_padding_size = 0;
17740 info_ptr->spe_gp_save_offset
17741 = info_ptr->cr_save_offset
17742 - info_ptr->spe_padding_size
17743 - info_ptr->spe_gp_size;
17745 /* Adjust for SPE case. */
17746 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17748 else if (TARGET_ALTIVEC_ABI)
17750 info_ptr->vrsave_save_offset
17751 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17753 /* Align stack so vector save area is on a quadword boundary. */
17754 if (info_ptr->altivec_size != 0)
17755 info_ptr->altivec_padding_size
17756 = 16 - (-info_ptr->vrsave_save_offset % 16);
17758 info_ptr->altivec_padding_size = 0;
17760 info_ptr->altivec_save_offset
17761 = info_ptr->vrsave_save_offset
17762 - info_ptr->altivec_padding_size
17763 - info_ptr->altivec_size;
17765 /* Adjust for AltiVec case. */
17766 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17769 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17770 info_ptr->ehrd_offset -= ehrd_size;
17771 info_ptr->lr_save_offset = reg_size;
17775 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17776 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17777 + info_ptr->gp_size
17778 + info_ptr->altivec_size
17779 + info_ptr->altivec_padding_size
17780 + info_ptr->spe_gp_size
17781 + info_ptr->spe_padding_size
17783 + info_ptr->cr_size
17784 + info_ptr->vrsave_size,
17787 non_fixed_size = (info_ptr->vars_size
17788 + info_ptr->parm_size
17789 + info_ptr->save_size);
17791 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17792 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17794 /* Determine if we need to allocate any stack frame:
17796 For AIX we need to push the stack if a frame pointer is needed
17797 (because the stack might be dynamically adjusted), if we are
17798 debugging, if we make calls, or if the sum of fp_save, gp_save,
17799 and local variables are more than the space needed to save all
17800 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17801 + 18*8 = 288 (GPR13 reserved).
17803 For V.4 we don't have the stack cushion that AIX uses, but assume
17804 that the debugger can handle stackless frames. */
17806 if (info_ptr->calls_p)
17807 info_ptr->push_p = 1;
17809 else if (DEFAULT_ABI == ABI_V4)
17810 info_ptr->push_p = non_fixed_size != 0;
17812 else if (frame_pointer_needed)
17813 info_ptr->push_p = 1;
17815 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17816 info_ptr->push_p = 1;
17819 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17821 /* Zero offsets if we're not saving those registers. */
17822 if (info_ptr->fp_size == 0)
17823 info_ptr->fp_save_offset = 0;
17825 if (info_ptr->gp_size == 0)
17826 info_ptr->gp_save_offset = 0;
17828 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17829 info_ptr->altivec_save_offset = 0;
17831 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17832 info_ptr->vrsave_save_offset = 0;
17834 if (! TARGET_SPE_ABI
17835 || info_ptr->spe_64bit_regs_used == 0
17836 || info_ptr->spe_gp_size == 0)
17837 info_ptr->spe_gp_save_offset = 0;
17839 if (! info_ptr->lr_save_p)
17840 info_ptr->lr_save_offset = 0;
17842 if (! info_ptr->cr_save_p)
17843 info_ptr->cr_save_offset = 0;
17848 /* Return true if the current function uses any GPRs in 64-bit SIMD
17852 spe_func_has_64bit_regs_p (void)
17856 /* Functions that save and restore all the call-saved registers will
17857 need to save/restore the registers in 64-bits. */
17858 if (crtl->calls_eh_return
17859 || cfun->calls_setjmp
17860 || crtl->has_nonlocal_goto)
17863 insns = get_insns ();
17865 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17871 /* FIXME: This should be implemented with attributes...
17873 (set_attr "spe64" "true")....then,
17874 if (get_spe64(insn)) return true;
17876 It's the only reliable way to do the stuff below. */
17878 i = PATTERN (insn);
17879 if (GET_CODE (i) == SET)
17881 enum machine_mode mode = GET_MODE (SET_SRC (i));
17883 if (SPE_VECTOR_MODE (mode))
17885 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17895 debug_stack_info (rs6000_stack_t *info)
17897 const char *abi_string;
17900 info = rs6000_stack_info ();
17902 fprintf (stderr, "\nStack information for function %s:\n",
17903 ((current_function_decl && DECL_NAME (current_function_decl))
17904 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17909 default: abi_string = "Unknown"; break;
17910 case ABI_NONE: abi_string = "NONE"; break;
17911 case ABI_AIX: abi_string = "AIX"; break;
17912 case ABI_DARWIN: abi_string = "Darwin"; break;
17913 case ABI_V4: abi_string = "V.4"; break;
17916 fprintf (stderr, "\tABI = %5s\n", abi_string);
17918 if (TARGET_ALTIVEC_ABI)
17919 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17921 if (TARGET_SPE_ABI)
17922 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17924 if (info->first_gp_reg_save != 32)
17925 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17927 if (info->first_fp_reg_save != 64)
17928 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17930 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17931 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17932 info->first_altivec_reg_save);
17934 if (info->lr_save_p)
17935 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17937 if (info->cr_save_p)
17938 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17940 if (info->vrsave_mask)
17941 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17944 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17947 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17949 if (info->gp_save_offset)
17950 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17952 if (info->fp_save_offset)
17953 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17955 if (info->altivec_save_offset)
17956 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17957 info->altivec_save_offset);
17959 if (info->spe_gp_save_offset)
17960 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17961 info->spe_gp_save_offset);
17963 if (info->vrsave_save_offset)
17964 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17965 info->vrsave_save_offset);
17967 if (info->lr_save_offset)
17968 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
17970 if (info->cr_save_offset)
17971 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
17973 if (info->varargs_save_offset)
17974 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
17976 if (info->total_size)
17977 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17980 if (info->vars_size)
17981 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17984 if (info->parm_size)
17985 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
17987 if (info->fixed_size)
17988 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
17991 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
17993 if (info->spe_gp_size)
17994 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
17997 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
17999 if (info->altivec_size)
18000 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18002 if (info->vrsave_size)
18003 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18005 if (info->altivec_padding_size)
18006 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18007 info->altivec_padding_size);
18009 if (info->spe_padding_size)
18010 fprintf (stderr, "\tspe_padding_size = %5d\n",
18011 info->spe_padding_size);
18014 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18016 if (info->save_size)
18017 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18019 if (info->reg_size != 4)
18020 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18022 fprintf (stderr, "\n");
18026 rs6000_return_addr (int count, rtx frame)
18028 /* Currently we don't optimize very well between prolog and body
18029 code and for PIC code the code can be actually quite bad, so
18030 don't try to be too clever here. */
18031 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18033 cfun->machine->ra_needs_full_frame = 1;
18040 plus_constant (copy_to_reg
18041 (gen_rtx_MEM (Pmode,
18042 memory_address (Pmode, frame))),
18043 RETURN_ADDRESS_OFFSET)));
18046 cfun->machine->ra_need_lr = 1;
18047 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18050 /* Say whether a function is a candidate for sibcall handling or not.
18051 We do not allow indirect calls to be optimized into sibling calls.
18052 Also, we can't do it if there are any vector parameters; there's
18053 nowhere to put the VRsave code so it works; note that functions with
18054 vector parameters are required to have a prototype, so the argument
18055 type info must be available here. (The tail recursion case can work
18056 with vector parameters, but there's no way to distinguish here.) */
18058 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
18063 if (TARGET_ALTIVEC_VRSAVE)
18065 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
18066 type; type = TREE_CHAIN (type))
18068 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
18072 if (DEFAULT_ABI == ABI_DARWIN
18073 || ((*targetm.binds_local_p) (decl)
18074 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
18076 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
18078 if (!lookup_attribute ("longcall", attr_list)
18079 || lookup_attribute ("shortcall", attr_list))
18086 /* NULL if INSN insn is valid within a low-overhead loop.
18087 Otherwise return why doloop cannot be applied.
18088 PowerPC uses the COUNT register for branch on table instructions. */
18090 static const char *
18091 rs6000_invalid_within_doloop (const_rtx insn)
18094 return "Function call in the loop.";
18097 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18098 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18099 return "Computed branch in the loop.";
18105 rs6000_ra_ever_killed (void)
18111 if (cfun->is_thunk)
18114 if (cfun->machine->lr_save_state)
18115 return cfun->machine->lr_save_state - 1;
18117 /* regs_ever_live has LR marked as used if any sibcalls are present,
18118 but this should not force saving and restoring in the
18119 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18120 clobbers LR, so that is inappropriate. */
18122 /* Also, the prologue can generate a store into LR that
18123 doesn't really count, like this:
18126 bcl to set PIC register
18130 When we're called from the epilogue, we need to avoid counting
18131 this as a store. */
18133 push_topmost_sequence ();
18134 top = get_insns ();
18135 pop_topmost_sequence ();
18136 reg = gen_rtx_REG (Pmode, LR_REGNO);
18138 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18144 if (!SIBLING_CALL_P (insn))
18147 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18149 else if (set_of (reg, insn) != NULL_RTX
18150 && !prologue_epilogue_contains (insn))
18157 /* Emit instructions needed to load the TOC register.
18158 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18159 a constant pool; or for SVR4 -fpic. */
18162 rs6000_emit_load_toc_table (int fromprolog)
18165 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18167 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18170 rtx lab, tmp1, tmp2, got;
18172 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18173 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18175 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18177 got = rs6000_got_sym ();
18178 tmp1 = tmp2 = dest;
18181 tmp1 = gen_reg_rtx (Pmode);
18182 tmp2 = gen_reg_rtx (Pmode);
18184 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18185 emit_move_insn (tmp1,
18186 gen_rtx_REG (Pmode, LR_REGNO));
18187 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18188 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18190 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18192 emit_insn (gen_load_toc_v4_pic_si ());
18193 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18195 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18198 rtx temp0 = (fromprolog
18199 ? gen_rtx_REG (Pmode, 0)
18200 : gen_reg_rtx (Pmode));
18206 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18207 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18209 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18210 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18212 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18213 emit_move_insn (dest,
18214 gen_rtx_REG (Pmode, LR_REGNO));
18215 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18221 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18222 lab = gen_label_rtx ();
18223 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18224 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18225 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18227 emit_insn (gen_addsi3 (dest, temp0, dest));
18229 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18231 /* This is for AIX code running in non-PIC ELF32. */
18234 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18235 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18237 emit_insn (gen_elf_high (dest, realsym));
18238 emit_insn (gen_elf_low (dest, dest, realsym));
18242 gcc_assert (DEFAULT_ABI == ABI_AIX);
18245 emit_insn (gen_load_toc_aix_si (dest));
18247 emit_insn (gen_load_toc_aix_di (dest));
18251 /* Emit instructions to restore the link register after determining where
18252 its value has been stored. */
18255 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18257 rs6000_stack_t *info = rs6000_stack_info ();
18260 operands[0] = source;
18261 operands[1] = scratch;
18263 if (info->lr_save_p)
18265 rtx frame_rtx = stack_pointer_rtx;
18266 HOST_WIDE_INT sp_offset = 0;
18269 if (frame_pointer_needed
18270 || cfun->calls_alloca
18271 || info->total_size > 32767)
18273 tmp = gen_frame_mem (Pmode, frame_rtx);
18274 emit_move_insn (operands[1], tmp);
18275 frame_rtx = operands[1];
18277 else if (info->push_p)
18278 sp_offset = info->total_size;
18280 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18281 tmp = gen_frame_mem (Pmode, tmp);
18282 emit_move_insn (tmp, operands[0]);
18285 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
18287 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18288 state of lr_save_p so any change from here on would be a bug. In
18289 particular, stop rs6000_ra_ever_killed from considering the SET
18290 of lr we may have added just above. */
18291 cfun->machine->lr_save_state = info->lr_save_p + 1;
18294 static GTY(()) alias_set_type set = -1;
18297 get_TOC_alias_set (void)
18300 set = new_alias_set ();
18304 /* This returns nonzero if the current function uses the TOC. This is
18305 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
18306 is generated by the ABI_V4 load_toc_* patterns. */
18313 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
18316 rtx pat = PATTERN (insn);
18319 if (GET_CODE (pat) == PARALLEL)
18320 for (i = 0; i < XVECLEN (pat, 0); i++)
18322 rtx sub = XVECEXP (pat, 0, i);
18323 if (GET_CODE (sub) == USE)
18325 sub = XEXP (sub, 0);
18326 if (GET_CODE (sub) == UNSPEC
18327 && XINT (sub, 1) == UNSPEC_TOC)
18337 create_TOC_reference (rtx symbol, rtx largetoc_reg)
18339 rtx tocrel, tocreg;
18341 if (TARGET_DEBUG_ADDR)
18343 if (GET_CODE (symbol) == SYMBOL_REF)
18344 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
18348 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
18349 GET_RTX_NAME (GET_CODE (symbol)));
18350 debug_rtx (symbol);
18354 if (!can_create_pseudo_p ())
18355 df_set_regs_ever_live (TOC_REGISTER, true);
18357 tocrel = gen_rtx_CONST (Pmode,
18358 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
18360 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
18361 if (TARGET_CMODEL != CMODEL_SMALL)
18363 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
18364 if (largetoc_reg != NULL)
18366 emit_move_insn (largetoc_reg, hi);
18369 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
18372 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
18375 /* Issue assembly directives that create a reference to the given DWARF
18376 FRAME_TABLE_LABEL from the current function section. */
18378 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
18380 fprintf (asm_out_file, "\t.ref %s\n",
18381 TARGET_STRIP_NAME_ENCODING (frame_table_label));
18384 /* If _Unwind_* has been called from within the same module,
18385 toc register is not guaranteed to be saved to 40(1) on function
18386 entry. Save it there in that case. */
18389 rs6000_aix_emit_builtin_unwind_init (void)
18392 rtx stack_top = gen_reg_rtx (Pmode);
18393 rtx opcode_addr = gen_reg_rtx (Pmode);
18394 rtx opcode = gen_reg_rtx (SImode);
18395 rtx tocompare = gen_reg_rtx (SImode);
18396 rtx no_toc_save_needed = gen_label_rtx ();
18398 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
18399 emit_move_insn (stack_top, mem);
18401 mem = gen_frame_mem (Pmode,
18402 gen_rtx_PLUS (Pmode, stack_top,
18403 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
18404 emit_move_insn (opcode_addr, mem);
18405 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
18406 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
18407 : 0xE8410028, SImode));
18409 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
18410 SImode, NULL_RTX, NULL_RTX,
18411 no_toc_save_needed, -1);
18413 mem = gen_frame_mem (Pmode,
18414 gen_rtx_PLUS (Pmode, stack_top,
18415 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
18416 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
18417 emit_label (no_toc_save_needed);
18420 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18421 and the change to the stack pointer. */
18424 rs6000_emit_stack_tie (void)
18426 rtx mem = gen_frame_mem (BLKmode,
18427 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
18429 emit_insn (gen_stack_tie (mem));
18432 /* Emit the correct code for allocating stack space, as insns.
18433 If COPY_REG, make sure a copy of the old frame is left there.
18434 The generated code may use hard register 0 as a temporary. */
18437 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
18440 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18441 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
18442 rtx todec = gen_int_mode (-size, Pmode);
18445 if (INTVAL (todec) != -size)
18447 warning (0, "stack frame too large");
18448 emit_insn (gen_trap ());
18452 if (crtl->limit_stack)
18454 if (REG_P (stack_limit_rtx)
18455 && REGNO (stack_limit_rtx) > 1
18456 && REGNO (stack_limit_rtx) <= 31)
18458 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
18459 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18462 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
18464 && DEFAULT_ABI == ABI_V4)
18466 rtx toload = gen_rtx_CONST (VOIDmode,
18467 gen_rtx_PLUS (Pmode,
18471 emit_insn (gen_elf_high (tmp_reg, toload));
18472 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
18473 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18477 warning (0, "stack limit expression is not supported");
18481 emit_move_insn (copy_reg, stack_reg);
18485 /* Need a note here so that try_split doesn't get confused. */
18486 if (get_last_insn () == NULL_RTX)
18487 emit_note (NOTE_INSN_DELETED);
18488 insn = emit_move_insn (tmp_reg, todec);
18489 try_split (PATTERN (insn), insn, 0);
18493 insn = emit_insn (TARGET_32BIT
18494 ? gen_movsi_update_stack (stack_reg, stack_reg,
18496 : gen_movdi_di_update_stack (stack_reg, stack_reg,
18497 todec, stack_reg));
18498 /* Since we didn't use gen_frame_mem to generate the MEM, grab
18499 it now and set the alias set/attributes. The above gen_*_update
18500 calls will generate a PARALLEL with the MEM set being the first
18502 par = PATTERN (insn);
18503 gcc_assert (GET_CODE (par) == PARALLEL);
18504 set = XVECEXP (par, 0, 0);
18505 gcc_assert (GET_CODE (set) == SET);
18506 mem = SET_DEST (set);
18507 gcc_assert (MEM_P (mem));
18508 MEM_NOTRAP_P (mem) = 1;
18509 set_mem_alias_set (mem, get_frame_alias_set ());
18511 RTX_FRAME_RELATED_P (insn) = 1;
18512 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
18513 gen_rtx_SET (VOIDmode, stack_reg,
18514 gen_rtx_PLUS (Pmode, stack_reg,
18515 GEN_INT (-size))));
18518 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
18519 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
18520 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
18521 deduce these equivalences by itself so it wasn't necessary to hold
18522 its hand so much. */
18525 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
18526 rtx reg2, rtx rreg)
18530 /* copy_rtx will not make unique copies of registers, so we need to
18531 ensure we don't have unwanted sharing here. */
18533 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18536 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18538 real = copy_rtx (PATTERN (insn));
18540 if (reg2 != NULL_RTX)
18541 real = replace_rtx (real, reg2, rreg);
18543 real = replace_rtx (real, reg,
18544 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
18545 STACK_POINTER_REGNUM),
18548 /* We expect that 'real' is either a SET or a PARALLEL containing
18549 SETs (and possibly other stuff). In a PARALLEL, all the SETs
18550 are important so they all have to be marked RTX_FRAME_RELATED_P. */
18552 if (GET_CODE (real) == SET)
18556 temp = simplify_rtx (SET_SRC (set));
18558 SET_SRC (set) = temp;
18559 temp = simplify_rtx (SET_DEST (set));
18561 SET_DEST (set) = temp;
18562 if (GET_CODE (SET_DEST (set)) == MEM)
18564 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18566 XEXP (SET_DEST (set), 0) = temp;
18573 gcc_assert (GET_CODE (real) == PARALLEL);
18574 for (i = 0; i < XVECLEN (real, 0); i++)
18575 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
18577 rtx set = XVECEXP (real, 0, i);
18579 temp = simplify_rtx (SET_SRC (set));
18581 SET_SRC (set) = temp;
18582 temp = simplify_rtx (SET_DEST (set));
18584 SET_DEST (set) = temp;
18585 if (GET_CODE (SET_DEST (set)) == MEM)
18587 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18589 XEXP (SET_DEST (set), 0) = temp;
18591 RTX_FRAME_RELATED_P (set) = 1;
18595 RTX_FRAME_RELATED_P (insn) = 1;
18596 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
18599 /* Returns an insn that has a vrsave set operation with the
18600 appropriate CLOBBERs. */
18603 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
18606 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
18607 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18610 = gen_rtx_SET (VOIDmode,
18612 gen_rtx_UNSPEC_VOLATILE (SImode,
18613 gen_rtvec (2, reg, vrsave),
18614 UNSPECV_SET_VRSAVE));
18618 /* We need to clobber the registers in the mask so the scheduler
18619 does not move sets to VRSAVE before sets of AltiVec registers.
18621 However, if the function receives nonlocal gotos, reload will set
18622 all call saved registers live. We will end up with:
18624 (set (reg 999) (mem))
18625 (parallel [ (set (reg vrsave) (unspec blah))
18626 (clobber (reg 999))])
18628 The clobber will cause the store into reg 999 to be dead, and
18629 flow will attempt to delete an epilogue insn. In this case, we
18630 need an unspec use/set of the register. */
18632 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18633 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18635 if (!epiloguep || call_used_regs [i])
18636 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
18637 gen_rtx_REG (V4SImode, i));
18640 rtx reg = gen_rtx_REG (V4SImode, i);
18643 = gen_rtx_SET (VOIDmode,
18645 gen_rtx_UNSPEC (V4SImode,
18646 gen_rtvec (1, reg), 27));
18650 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
18652 for (i = 0; i < nclobs; ++i)
18653 XVECEXP (insn, 0, i) = clobs[i];
18658 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
18659 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
18662 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
18663 unsigned int regno, int offset, HOST_WIDE_INT total_size)
18665 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
18666 rtx replacea, replaceb;
18668 int_rtx = GEN_INT (offset);
18670 /* Some cases that need register indexed addressing. */
18671 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
18672 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
18673 || (TARGET_E500_DOUBLE && mode == DFmode)
18675 && SPE_VECTOR_MODE (mode)
18676 && !SPE_CONST_OFFSET_OK (offset)))
18678 /* Whomever calls us must make sure r11 is available in the
18679 flow path of instructions in the prologue. */
18680 offset_rtx = gen_rtx_REG (Pmode, 11);
18681 emit_move_insn (offset_rtx, int_rtx);
18683 replacea = offset_rtx;
18684 replaceb = int_rtx;
18688 offset_rtx = int_rtx;
18689 replacea = NULL_RTX;
18690 replaceb = NULL_RTX;
18693 reg = gen_rtx_REG (mode, regno);
18694 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18695 mem = gen_frame_mem (mode, addr);
18697 insn = emit_move_insn (mem, reg);
18699 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18702 /* Emit an offset memory reference suitable for a frame store, while
18703 converting to a valid addressing mode. */
18706 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18708 rtx int_rtx, offset_rtx;
18710 int_rtx = GEN_INT (offset);
18712 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18713 || (TARGET_E500_DOUBLE && mode == DFmode))
18715 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18716 emit_move_insn (offset_rtx, int_rtx);
18719 offset_rtx = int_rtx;
18721 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18724 /* Look for user-defined global regs. We should not save and restore these,
18725 and cannot use stmw/lmw if there are any in its range. */
18728 no_global_regs_above (int first, bool gpr)
18731 int last = gpr ? 32 : 64;
18732 for (i = first; i < last; i++)
18733 if (global_regs[i])
18738 #ifndef TARGET_FIX_AND_CONTINUE
18739 #define TARGET_FIX_AND_CONTINUE 0
18742 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18743 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18744 #define LAST_SAVRES_REGISTER 31
18745 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18747 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18749 /* Temporary holding space for an out-of-line register save/restore
18751 static char savres_routine_name[30];
18753 /* Return the name for an out-of-line register save/restore routine.
18754 We are saving/restoring GPRs if GPR is true. */
18757 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18758 bool savep, bool gpr, bool lr)
18760 const char *prefix = "";
18761 const char *suffix = "";
18763 /* Different targets are supposed to define
18764 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18765 routine name could be defined with:
18767 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18769 This is a nice idea in practice, but in reality, things are
18770 complicated in several ways:
18772 - ELF targets have save/restore routines for GPRs.
18774 - SPE targets use different prefixes for 32/64-bit registers, and
18775 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18777 - PPC64 ELF targets have routines for save/restore of GPRs that
18778 differ in what they do with the link register, so having a set
18779 prefix doesn't work. (We only use one of the save routines at
18780 the moment, though.)
18782 - PPC32 elf targets have "exit" versions of the restore routines
18783 that restore the link register and can save some extra space.
18784 These require an extra suffix. (There are also "tail" versions
18785 of the restore routines and "GOT" versions of the save routines,
18786 but we don't generate those at present. Same problems apply,
18789 We deal with all this by synthesizing our own prefix/suffix and
18790 using that for the simple sprintf call shown above. */
18793 /* No floating point saves on the SPE. */
18797 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
18799 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
18804 else if (DEFAULT_ABI == ABI_V4)
18810 prefix = savep ? "_savegpr_" : "_restgpr_";
18812 prefix = savep ? "_savefpr_" : "_restfpr_";
18817 else if (DEFAULT_ABI == ABI_AIX)
18819 #ifndef POWERPC_LINUX
18820 /* No out-of-line save/restore routines for GPRs on AIX. */
18821 gcc_assert (!TARGET_AIX || !gpr);
18827 ? (lr ? "_savegpr0_" : "_savegpr1_")
18828 : (lr ? "_restgpr0_" : "_restgpr1_"));
18829 #ifdef POWERPC_LINUX
18831 prefix = (savep ? "_savefpr_" : "_restfpr_");
18835 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
18836 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
18839 else if (DEFAULT_ABI == ABI_DARWIN)
18840 sorry ("Out-of-line save/restore routines not supported on Darwin");
18842 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
18844 return savres_routine_name;
18847 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18848 We are saving/restoring GPRs if GPR is true. */
18851 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
18854 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18856 int select = ((savep ? 1 : 0) << 2
18858 /* On the SPE, we never have any FPRs, but we do have
18859 32/64-bit versions of the routines. */
18860 ? (info->spe_64bit_regs_used ? 1 : 0)
18861 : (gpr ? 1 : 0)) << 1)
18864 /* Don't generate bogus routine names. */
18865 gcc_assert (FIRST_SAVRES_REGISTER <= regno
18866 && regno <= LAST_SAVRES_REGISTER);
18868 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18874 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
18876 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18877 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18878 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
18884 /* Emit a sequence of insns, including a stack tie if needed, for
18885 resetting the stack pointer. If SAVRES is true, then don't reset the
18886 stack pointer, but move the base of the frame into r11 for use by
18887 out-of-line register restore routines. */
18890 rs6000_emit_stack_reset (rs6000_stack_t *info,
18891 rtx sp_reg_rtx, rtx frame_reg_rtx,
18892 int sp_offset, bool savres)
18894 /* This blockage is needed so that sched doesn't decide to move
18895 the sp change before the register restores. */
18896 if (frame_reg_rtx != sp_reg_rtx
18898 && info->spe_64bit_regs_used != 0
18899 && info->first_gp_reg_save != 32))
18900 rs6000_emit_stack_tie ();
18902 if (frame_reg_rtx != sp_reg_rtx)
18904 if (sp_offset != 0)
18906 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
18907 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
18908 GEN_INT (sp_offset)));
18911 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18913 else if (sp_offset != 0)
18915 /* If we are restoring registers out-of-line, we will be using the
18916 "exit" variants of the restore routines, which will reset the
18917 stack for us. But we do need to point r11 into the right place
18918 for those routines. */
18919 rtx dest_reg = (savres
18920 ? gen_rtx_REG (Pmode, 11)
18923 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18924 GEN_INT (sp_offset)));
18931 /* Construct a parallel rtx describing the effect of a call to an
18932 out-of-line register save/restore routine. */
18935 rs6000_make_savres_rtx (rs6000_stack_t *info,
18936 rtx frame_reg_rtx, int save_area_offset,
18937 enum machine_mode reg_mode,
18938 bool savep, bool gpr, bool lr)
18941 int offset, start_reg, end_reg, n_regs;
18942 int reg_size = GET_MODE_SIZE (reg_mode);
18948 ? info->first_gp_reg_save
18949 : info->first_fp_reg_save);
18950 end_reg = gpr ? 32 : 64;
18951 n_regs = end_reg - start_reg;
18952 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
18955 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18957 RTVEC_ELT (p, offset++)
18958 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18960 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
18961 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18962 RTVEC_ELT (p, offset++)
18963 = gen_rtx_USE (VOIDmode,
18964 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
18968 for (i = 0; i < end_reg - start_reg; i++)
18970 rtx addr, reg, mem;
18971 reg = gen_rtx_REG (reg_mode, start_reg + i);
18972 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18973 GEN_INT (save_area_offset + reg_size*i));
18974 mem = gen_frame_mem (reg_mode, addr);
18976 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
18978 savep ? reg : mem);
18983 rtx addr, reg, mem;
18984 reg = gen_rtx_REG (Pmode, 0);
18985 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18986 GEN_INT (info->lr_save_offset));
18987 mem = gen_frame_mem (Pmode, addr);
18988 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
18991 return gen_rtx_PARALLEL (VOIDmode, p);
18994 /* Determine whether the gp REG is really used. */
18997 rs6000_reg_live_or_pic_offset_p (int reg)
18999 return ((df_regs_ever_live_p (reg)
19000 && (!call_used_regs[reg]
19001 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19002 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19003 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19004 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19005 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19009 SAVRES_MULTIPLE = 0x1,
19010 SAVRES_INLINE_FPRS = 0x2,
19011 SAVRES_INLINE_GPRS = 0x4,
19012 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
19013 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
19014 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
19017 /* Determine the strategy for savings/restoring registers. */
19020 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
19021 int using_static_chain_p, int sibcall)
19023 bool using_multiple_p;
19025 bool savres_fprs_inline;
19026 bool savres_gprs_inline;
19027 bool noclobber_global_gprs
19028 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
19031 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
19032 && (!TARGET_SPE_ABI
19033 || info->spe_64bit_regs_used == 0)
19034 && info->first_gp_reg_save < 31
19035 && noclobber_global_gprs);
19036 /* Don't bother to try to save things out-of-line if r11 is occupied
19037 by the static chain. It would require too much fiddling and the
19038 static chain is rarely used anyway. */
19039 common = (using_static_chain_p
19041 || crtl->calls_eh_return
19042 || !info->lr_save_p
19043 || cfun->machine->ra_need_lr
19044 || info->total_size > 32767);
19045 savres_fprs_inline = (common
19046 || info->first_fp_reg_save == 64
19047 || !no_global_regs_above (info->first_fp_reg_save,
19049 /* The out-of-line FP routines use
19050 double-precision stores; we can't use those
19051 routines if we don't have such stores. */
19052 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
19053 || FP_SAVE_INLINE (info->first_fp_reg_save));
19054 savres_gprs_inline = (common
19055 /* Saving CR interferes with the exit routines
19056 used on the SPE, so just punt here. */
19059 && info->spe_64bit_regs_used != 0
19060 && info->cr_save_p != 0)
19061 || info->first_gp_reg_save == 32
19062 || !noclobber_global_gprs
19063 || GP_SAVE_INLINE (info->first_gp_reg_save));
19066 /* If we are going to use store multiple, then don't even bother
19067 with the out-of-line routines, since the store-multiple instruction
19068 will always be smaller. */
19069 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19072 /* The situation is more complicated with load multiple. We'd
19073 prefer to use the out-of-line routines for restores, since the
19074 "exit" out-of-line routines can handle the restore of LR and
19075 the frame teardown. But we can only use the out-of-line
19076 routines if we know that we've used store multiple or
19077 out-of-line routines in the prologue, i.e. if we've saved all
19078 the registers from first_gp_reg_save. Otherwise, we risk
19079 loading garbage from the stack. Furthermore, we can only use
19080 the "exit" out-of-line gpr restore if we haven't saved any
19082 bool saved_all = !savres_gprs_inline || using_multiple_p;
19084 if (saved_all && info->first_fp_reg_save != 64)
19085 /* We can't use the exit routine; use load multiple if it's
19087 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19090 strategy = (using_multiple_p
19091 | (savres_fprs_inline << 1)
19092 | (savres_gprs_inline << 2));
19093 #ifdef POWERPC_LINUX
19096 if (!savres_fprs_inline)
19097 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
19098 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
19099 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
19102 if (TARGET_AIX && !savres_fprs_inline)
19103 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
19108 /* Emit function prologue as insns. */
19111 rs6000_emit_prologue (void)
19113 rs6000_stack_t *info = rs6000_stack_info ();
19114 enum machine_mode reg_mode = Pmode;
19115 int reg_size = TARGET_32BIT ? 4 : 8;
19116 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19117 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19118 rtx frame_reg_rtx = sp_reg_rtx;
19119 rtx cr_save_rtx = NULL_RTX;
19122 int saving_FPRs_inline;
19123 int saving_GPRs_inline;
19124 int using_store_multiple;
19125 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19126 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19127 && call_used_regs[STATIC_CHAIN_REGNUM]);
19128 HOST_WIDE_INT sp_offset = 0;
19130 if (TARGET_FIX_AND_CONTINUE)
19132 /* gdb on darwin arranges to forward a function from the old
19133 address by modifying the first 5 instructions of the function
19134 to branch to the overriding function. This is necessary to
19135 permit function pointers that point to the old function to
19136 actually forward to the new function. */
19137 emit_insn (gen_nop ());
19138 emit_insn (gen_nop ());
19139 emit_insn (gen_nop ());
19140 emit_insn (gen_nop ());
19141 emit_insn (gen_nop ());
19144 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19146 reg_mode = V2SImode;
19150 strategy = rs6000_savres_strategy (info, /*savep=*/true,
19151 /*static_chain_p=*/using_static_chain_p,
19153 using_store_multiple = strategy & SAVRES_MULTIPLE;
19154 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19155 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19157 /* For V.4, update stack before we do any saving and set back pointer. */
19158 if (! WORLD_SAVE_P (info)
19160 && (DEFAULT_ABI == ABI_V4
19161 || crtl->calls_eh_return))
19163 bool need_r11 = (TARGET_SPE
19164 ? (!saving_GPRs_inline
19165 && info->spe_64bit_regs_used == 0)
19166 : (!saving_FPRs_inline || !saving_GPRs_inline));
19167 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19169 if (info->total_size < 32767)
19170 sp_offset = info->total_size;
19172 frame_reg_rtx = copy_reg;
19173 else if (info->cr_save_p
19175 || info->first_fp_reg_save < 64
19176 || info->first_gp_reg_save < 32
19177 || info->altivec_size != 0
19178 || info->vrsave_mask != 0
19179 || crtl->calls_eh_return)
19181 copy_reg = frame_ptr_rtx;
19182 frame_reg_rtx = copy_reg;
19186 /* The prologue won't be saving any regs so there is no need
19187 to set up a frame register to access any frame save area.
19188 We also won't be using sp_offset anywhere below, but set
19189 the correct value anyway to protect against future
19190 changes to this function. */
19191 sp_offset = info->total_size;
19193 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19194 if (frame_reg_rtx != sp_reg_rtx)
19195 rs6000_emit_stack_tie ();
19198 /* Handle world saves specially here. */
19199 if (WORLD_SAVE_P (info))
19206 /* save_world expects lr in r0. */
19207 reg0 = gen_rtx_REG (Pmode, 0);
19208 if (info->lr_save_p)
19210 insn = emit_move_insn (reg0,
19211 gen_rtx_REG (Pmode, LR_REGNO));
19212 RTX_FRAME_RELATED_P (insn) = 1;
19215 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19216 assumptions about the offsets of various bits of the stack
19218 gcc_assert (info->gp_save_offset == -220
19219 && info->fp_save_offset == -144
19220 && info->lr_save_offset == 8
19221 && info->cr_save_offset == 4
19224 && (!crtl->calls_eh_return
19225 || info->ehrd_offset == -432)
19226 && info->vrsave_save_offset == -224
19227 && info->altivec_save_offset == -416);
19229 treg = gen_rtx_REG (SImode, 11);
19230 emit_move_insn (treg, GEN_INT (-info->total_size));
19232 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19233 in R11. It also clobbers R12, so beware! */
19235 /* Preserve CR2 for save_world prologues */
19237 sz += 32 - info->first_gp_reg_save;
19238 sz += 64 - info->first_fp_reg_save;
19239 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19240 p = rtvec_alloc (sz);
19242 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19243 gen_rtx_REG (SImode,
19245 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19246 gen_rtx_SYMBOL_REF (Pmode,
19248 /* We do floats first so that the instruction pattern matches
19250 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19252 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19253 ? DFmode : SFmode),
19254 info->first_fp_reg_save + i);
19255 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19256 GEN_INT (info->fp_save_offset
19257 + sp_offset + 8 * i));
19258 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19259 ? DFmode : SFmode), addr);
19261 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19263 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19265 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19266 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19267 GEN_INT (info->altivec_save_offset
19268 + sp_offset + 16 * i));
19269 rtx mem = gen_frame_mem (V4SImode, addr);
19271 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19273 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19275 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19276 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19277 GEN_INT (info->gp_save_offset
19278 + sp_offset + reg_size * i));
19279 rtx mem = gen_frame_mem (reg_mode, addr);
19281 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19285 /* CR register traditionally saved as CR2. */
19286 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19287 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19288 GEN_INT (info->cr_save_offset
19290 rtx mem = gen_frame_mem (reg_mode, addr);
19292 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19294 /* Explain about use of R0. */
19295 if (info->lr_save_p)
19297 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19298 GEN_INT (info->lr_save_offset
19300 rtx mem = gen_frame_mem (reg_mode, addr);
19302 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
19304 /* Explain what happens to the stack pointer. */
19306 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
19307 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
19310 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19311 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19312 treg, GEN_INT (-info->total_size));
19313 sp_offset = info->total_size;
19316 /* If we use the link register, get it into r0. */
19317 if (!WORLD_SAVE_P (info) && info->lr_save_p)
19319 rtx addr, reg, mem;
19321 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
19322 gen_rtx_REG (Pmode, LR_REGNO));
19323 RTX_FRAME_RELATED_P (insn) = 1;
19325 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
19326 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
19328 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19329 GEN_INT (info->lr_save_offset + sp_offset));
19330 reg = gen_rtx_REG (Pmode, 0);
19331 mem = gen_rtx_MEM (Pmode, addr);
19332 /* This should not be of rs6000_sr_alias_set, because of
19333 __builtin_return_address. */
19335 insn = emit_move_insn (mem, reg);
19336 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19337 NULL_RTX, NULL_RTX);
19341 /* If we need to save CR, put it into r12 or r11. */
19342 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
19347 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
19349 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19350 RTX_FRAME_RELATED_P (insn) = 1;
19351 /* Now, there's no way that dwarf2out_frame_debug_expr is going
19352 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
19353 But that's OK. All we have to do is specify that _one_ condition
19354 code register is saved in this stack slot. The thrower's epilogue
19355 will then restore all the call-saved registers.
19356 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
19357 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
19358 gen_rtx_REG (SImode, CR2_REGNO));
19359 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19362 /* Do any required saving of fpr's. If only one or two to save, do
19363 it ourselves. Otherwise, call function. */
19364 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
19367 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19368 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
19369 && ! call_used_regs[info->first_fp_reg_save+i]))
19370 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
19371 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19373 info->first_fp_reg_save + i,
19374 info->fp_save_offset + sp_offset + 8 * i,
19377 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
19381 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19382 info->fp_save_offset + sp_offset,
19384 /*savep=*/true, /*gpr=*/false,
19386 & SAVRES_NOINLINE_FPRS_SAVES_LR)
19388 insn = emit_insn (par);
19389 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19390 NULL_RTX, NULL_RTX);
19393 /* Save GPRs. This is done as a PARALLEL if we are using
19394 the store-multiple instructions. */
19395 if (!WORLD_SAVE_P (info)
19397 && info->spe_64bit_regs_used != 0
19398 && info->first_gp_reg_save != 32)
19401 rtx spe_save_area_ptr;
19403 /* Determine whether we can address all of the registers that need
19404 to be saved with an offset from the stack pointer that fits in
19405 the small const field for SPE memory instructions. */
19406 int spe_regs_addressable_via_sp
19407 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19408 + (32 - info->first_gp_reg_save - 1) * reg_size)
19409 && saving_GPRs_inline);
19412 if (spe_regs_addressable_via_sp)
19414 spe_save_area_ptr = frame_reg_rtx;
19415 spe_offset = info->spe_gp_save_offset + sp_offset;
19419 /* Make r11 point to the start of the SPE save area. We need
19420 to be careful here if r11 is holding the static chain. If
19421 it is, then temporarily save it in r0. We would use r0 as
19422 our base register here, but using r0 as a base register in
19423 loads and stores means something different from what we
19425 int ool_adjust = (saving_GPRs_inline
19427 : (info->first_gp_reg_save
19428 - (FIRST_SAVRES_REGISTER+1))*8);
19429 HOST_WIDE_INT offset = (info->spe_gp_save_offset
19430 + sp_offset - ool_adjust);
19432 if (using_static_chain_p)
19434 rtx r0 = gen_rtx_REG (Pmode, 0);
19435 gcc_assert (info->first_gp_reg_save > 11);
19437 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
19440 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
19441 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
19443 GEN_INT (offset)));
19444 /* We need to make sure the move to r11 gets noted for
19445 properly outputting unwind information. */
19446 if (!saving_GPRs_inline)
19447 rs6000_frame_related (insn, frame_reg_rtx, offset,
19448 NULL_RTX, NULL_RTX);
19452 if (saving_GPRs_inline)
19454 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19455 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19457 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19458 rtx offset, addr, mem;
19460 /* We're doing all this to ensure that the offset fits into
19461 the immediate offset of 'evstdd'. */
19462 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
19464 offset = GEN_INT (reg_size * i + spe_offset);
19465 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
19466 mem = gen_rtx_MEM (V2SImode, addr);
19468 insn = emit_move_insn (mem, reg);
19470 rs6000_frame_related (insn, spe_save_area_ptr,
19471 info->spe_gp_save_offset
19472 + sp_offset + reg_size * i,
19473 offset, const0_rtx);
19480 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19482 /*savep=*/true, /*gpr=*/true,
19484 insn = emit_insn (par);
19485 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19486 NULL_RTX, NULL_RTX);
19490 /* Move the static chain pointer back. */
19491 if (using_static_chain_p && !spe_regs_addressable_via_sp)
19492 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
19494 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
19498 /* Need to adjust r11 (r12) if we saved any FPRs. */
19499 if (info->first_fp_reg_save != 64)
19501 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
19503 rtx offset = GEN_INT (sp_offset
19504 + (-8 * (64-info->first_fp_reg_save)));
19505 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
19508 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19509 info->gp_save_offset + sp_offset,
19511 /*savep=*/true, /*gpr=*/true,
19513 & SAVRES_NOINLINE_GPRS_SAVES_LR)
19515 insn = emit_insn (par);
19516 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19517 NULL_RTX, NULL_RTX);
19519 else if (!WORLD_SAVE_P (info) && using_store_multiple)
19523 p = rtvec_alloc (32 - info->first_gp_reg_save);
19524 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19526 rtx addr, reg, mem;
19527 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19528 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19529 GEN_INT (info->gp_save_offset
19532 mem = gen_frame_mem (reg_mode, addr);
19534 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
19536 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19537 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19538 NULL_RTX, NULL_RTX);
19540 else if (!WORLD_SAVE_P (info))
19543 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19544 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19546 rtx addr, reg, mem;
19547 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19549 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19550 GEN_INT (info->gp_save_offset
19553 mem = gen_frame_mem (reg_mode, addr);
19555 insn = emit_move_insn (mem, reg);
19556 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19557 NULL_RTX, NULL_RTX);
19561 /* ??? There's no need to emit actual instructions here, but it's the
19562 easiest way to get the frame unwind information emitted. */
19563 if (crtl->calls_eh_return)
19565 unsigned int i, regno;
19567 /* In AIX ABI we need to pretend we save r2 here. */
19570 rtx addr, reg, mem;
19572 reg = gen_rtx_REG (reg_mode, 2);
19573 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19574 GEN_INT (sp_offset + 5 * reg_size));
19575 mem = gen_frame_mem (reg_mode, addr);
19577 insn = emit_move_insn (mem, reg);
19578 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19579 NULL_RTX, NULL_RTX);
19580 PATTERN (insn) = gen_blockage ();
19585 regno = EH_RETURN_DATA_REGNO (i);
19586 if (regno == INVALID_REGNUM)
19589 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
19590 info->ehrd_offset + sp_offset
19591 + reg_size * (int) i,
19596 /* Save CR if we use any that must be preserved. */
19597 if (!WORLD_SAVE_P (info) && info->cr_save_p)
19599 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19600 GEN_INT (info->cr_save_offset + sp_offset));
19601 rtx mem = gen_frame_mem (SImode, addr);
19602 /* See the large comment above about why CR2_REGNO is used. */
19603 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
19605 /* If r12 was used to hold the original sp, copy cr into r0 now
19607 if (REGNO (frame_reg_rtx) == 12)
19611 cr_save_rtx = gen_rtx_REG (SImode, 0);
19612 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19613 RTX_FRAME_RELATED_P (insn) = 1;
19614 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
19615 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19617 insn = emit_move_insn (mem, cr_save_rtx);
19619 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19620 NULL_RTX, NULL_RTX);
19623 /* Update stack and set back pointer unless this is V.4,
19624 for which it was done previously. */
19625 if (!WORLD_SAVE_P (info) && info->push_p
19626 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
19628 rtx copy_reg = NULL;
19630 if (info->total_size < 32767)
19631 sp_offset = info->total_size;
19632 else if (info->altivec_size != 0
19633 || info->vrsave_mask != 0)
19635 copy_reg = frame_ptr_rtx;
19636 frame_reg_rtx = copy_reg;
19639 sp_offset = info->total_size;
19640 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19641 if (frame_reg_rtx != sp_reg_rtx)
19642 rs6000_emit_stack_tie ();
19645 /* Set frame pointer, if needed. */
19646 if (frame_pointer_needed)
19648 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
19650 RTX_FRAME_RELATED_P (insn) = 1;
19653 /* Save AltiVec registers if needed. Save here because the red zone does
19654 not include AltiVec registers. */
19655 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
19659 /* There should be a non inline version of this, for when we
19660 are saving lots of vector registers. */
19661 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19662 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19664 rtx areg, savereg, mem;
19667 offset = info->altivec_save_offset + sp_offset
19668 + 16 * (i - info->first_altivec_reg_save);
19670 savereg = gen_rtx_REG (V4SImode, i);
19672 areg = gen_rtx_REG (Pmode, 0);
19673 emit_move_insn (areg, GEN_INT (offset));
19675 /* AltiVec addressing mode is [reg+reg]. */
19676 mem = gen_frame_mem (V4SImode,
19677 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
19679 insn = emit_move_insn (mem, savereg);
19681 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19682 areg, GEN_INT (offset));
19686 /* VRSAVE is a bit vector representing which AltiVec registers
19687 are used. The OS uses this to determine which vector
19688 registers to save on a context switch. We need to save
19689 VRSAVE on the stack frame, add whatever AltiVec registers we
19690 used in this function, and do the corresponding magic in the
19693 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
19694 && info->vrsave_mask != 0)
19696 rtx reg, mem, vrsave;
19699 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
19700 as frame_reg_rtx and r11 as the static chain pointer for
19701 nested functions. */
19702 reg = gen_rtx_REG (SImode, 0);
19703 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19705 emit_insn (gen_get_vrsave_internal (reg));
19707 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19709 if (!WORLD_SAVE_P (info))
19712 offset = info->vrsave_save_offset + sp_offset;
19713 mem = gen_frame_mem (SImode,
19714 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19715 GEN_INT (offset)));
19716 insn = emit_move_insn (mem, reg);
19719 /* Include the registers in the mask. */
19720 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19722 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19725 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19726 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19727 || (DEFAULT_ABI == ABI_V4
19728 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19729 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19731 /* If emit_load_toc_table will use the link register, we need to save
19732 it. We use R12 for this purpose because emit_load_toc_table
19733 can use register 0. This allows us to use a plain 'blr' to return
19734 from the procedure more often. */
19735 int save_LR_around_toc_setup = (TARGET_ELF
19736 && DEFAULT_ABI != ABI_AIX
19738 && ! info->lr_save_p
19739 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19740 if (save_LR_around_toc_setup)
19742 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19744 insn = emit_move_insn (frame_ptr_rtx, lr);
19745 RTX_FRAME_RELATED_P (insn) = 1;
19747 rs6000_emit_load_toc_table (TRUE);
19749 insn = emit_move_insn (lr, frame_ptr_rtx);
19750 RTX_FRAME_RELATED_P (insn) = 1;
19753 rs6000_emit_load_toc_table (TRUE);
19757 if (DEFAULT_ABI == ABI_DARWIN
19758 && flag_pic && crtl->uses_pic_offset_table)
19760 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19761 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19763 /* Save and restore LR locally around this call (in R0). */
19764 if (!info->lr_save_p)
19765 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19767 emit_insn (gen_load_macho_picbase (src));
19769 emit_move_insn (gen_rtx_REG (Pmode,
19770 RS6000_PIC_OFFSET_TABLE_REGNUM),
19773 if (!info->lr_save_p)
19774 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19779 /* Write function prologue. */
19782 rs6000_output_function_prologue (FILE *file,
19783 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19785 rs6000_stack_t *info = rs6000_stack_info ();
19787 if (TARGET_DEBUG_STACK)
19788 debug_stack_info (info);
19790 /* Write .extern for any function we will call to save and restore
19792 if (info->first_fp_reg_save < 64
19793 && !FP_SAVE_INLINE (info->first_fp_reg_save))
19796 int regno = info->first_fp_reg_save - 32;
19798 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
19799 /*gpr=*/false, /*lr=*/false);
19800 fprintf (file, "\t.extern %s\n", name);
19802 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
19803 /*gpr=*/false, /*lr=*/true);
19804 fprintf (file, "\t.extern %s\n", name);
19807 /* Write .extern for AIX common mode routines, if needed. */
19808 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
19810 fputs ("\t.extern __mulh\n", file);
19811 fputs ("\t.extern __mull\n", file);
19812 fputs ("\t.extern __divss\n", file);
19813 fputs ("\t.extern __divus\n", file);
19814 fputs ("\t.extern __quoss\n", file);
19815 fputs ("\t.extern __quous\n", file);
19816 common_mode_defined = 1;
19819 if (! HAVE_prologue)
19825 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19826 the "toplevel" insn chain. */
19827 emit_note (NOTE_INSN_DELETED);
19828 rs6000_emit_prologue ();
19829 emit_note (NOTE_INSN_DELETED);
19831 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19835 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19837 INSN_ADDRESSES_NEW (insn, addr);
19842 prologue = get_insns ();
19845 if (TARGET_DEBUG_STACK)
19846 debug_rtx_list (prologue, 100);
19848 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
19852 rs6000_pic_labelno++;
19855 /* Non-zero if vmx regs are restored before the frame pop, zero if
19856 we restore after the pop when possible. */
19857 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19859 /* Reload CR from REG. */
19862 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
19867 if (using_mfcr_multiple)
19869 for (i = 0; i < 8; i++)
19870 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19872 gcc_assert (count);
19875 if (using_mfcr_multiple && count > 1)
19880 p = rtvec_alloc (count);
19883 for (i = 0; i < 8; i++)
19884 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19886 rtvec r = rtvec_alloc (2);
19887 RTVEC_ELT (r, 0) = reg;
19888 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19889 RTVEC_ELT (p, ndx) =
19890 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19891 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19894 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19895 gcc_assert (ndx == count);
19898 for (i = 0; i < 8; i++)
19899 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19901 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19907 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19908 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19909 below stack pointer not cloberred by signals. */
19912 offset_below_red_zone_p (HOST_WIDE_INT offset)
19914 return offset < (DEFAULT_ABI == ABI_V4
19916 : TARGET_32BIT ? -220 : -288);
19919 /* Emit function epilogue as insns. */
19922 rs6000_emit_epilogue (int sibcall)
19924 rs6000_stack_t *info;
19925 int restoring_GPRs_inline;
19926 int restoring_FPRs_inline;
19927 int using_load_multiple;
19928 int using_mtcr_multiple;
19929 int use_backchain_to_restore_sp;
19933 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19934 rtx frame_reg_rtx = sp_reg_rtx;
19935 rtx cfa_restores = NULL_RTX;
19937 rtx cr_save_reg = NULL_RTX;
19938 enum machine_mode reg_mode = Pmode;
19939 int reg_size = TARGET_32BIT ? 4 : 8;
19942 info = rs6000_stack_info ();
19944 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19946 reg_mode = V2SImode;
19950 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19951 /*static_chain_p=*/0, sibcall);
19952 using_load_multiple = strategy & SAVRES_MULTIPLE;
19953 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19954 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19955 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19956 || rs6000_cpu == PROCESSOR_PPC603
19957 || rs6000_cpu == PROCESSOR_PPC750
19959 /* Restore via the backchain when we have a large frame, since this
19960 is more efficient than an addis, addi pair. The second condition
19961 here will not trigger at the moment; We don't actually need a
19962 frame pointer for alloca, but the generic parts of the compiler
19963 give us one anyway. */
19964 use_backchain_to_restore_sp = (info->total_size > 32767
19965 || info->total_size
19966 + (info->lr_save_p ? info->lr_save_offset : 0)
19968 || (cfun->calls_alloca
19969 && !frame_pointer_needed));
19970 restore_lr = (info->lr_save_p
19971 && (restoring_FPRs_inline
19972 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
19973 && (restoring_GPRs_inline
19974 || info->first_fp_reg_save < 64));
19976 if (WORLD_SAVE_P (info))
19980 const char *alloc_rname;
19983 /* eh_rest_world_r10 will return to the location saved in the LR
19984 stack slot (which is not likely to be our caller.)
19985 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19986 rest_world is similar, except any R10 parameter is ignored.
19987 The exception-handling stuff that was here in 2.95 is no
19988 longer necessary. */
19992 + 32 - info->first_gp_reg_save
19993 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
19994 + 63 + 1 - info->first_fp_reg_save);
19996 strcpy (rname, ((crtl->calls_eh_return) ?
19997 "*eh_rest_world_r10" : "*rest_world"));
19998 alloc_rname = ggc_strdup (rname);
20001 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
20002 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20003 gen_rtx_REG (Pmode,
20006 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20007 /* The instruction pattern requires a clobber here;
20008 it is shared with the restVEC helper. */
20010 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20013 /* CR register traditionally saved as CR2. */
20014 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20015 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20016 GEN_INT (info->cr_save_offset));
20017 rtx mem = gen_frame_mem (reg_mode, addr);
20019 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20022 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20024 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20025 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20026 GEN_INT (info->gp_save_offset
20028 rtx mem = gen_frame_mem (reg_mode, addr);
20030 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20032 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20034 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20035 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20036 GEN_INT (info->altivec_save_offset
20038 rtx mem = gen_frame_mem (V4SImode, addr);
20040 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20042 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20044 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20045 ? DFmode : SFmode),
20046 info->first_fp_reg_save + i);
20047 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20048 GEN_INT (info->fp_save_offset
20050 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20051 ? DFmode : SFmode), addr);
20053 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20056 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20058 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20060 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20062 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20064 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20065 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20070 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20072 sp_offset = info->total_size;
20074 /* Restore AltiVec registers if we must do so before adjusting the
20076 if (TARGET_ALTIVEC_ABI
20077 && info->altivec_size != 0
20078 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20079 || (DEFAULT_ABI != ABI_V4
20080 && offset_below_red_zone_p (info->altivec_save_offset))))
20084 if (use_backchain_to_restore_sp)
20086 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20087 emit_move_insn (frame_reg_rtx,
20088 gen_rtx_MEM (Pmode, sp_reg_rtx));
20091 else if (frame_pointer_needed)
20092 frame_reg_rtx = hard_frame_pointer_rtx;
20094 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20095 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20097 rtx addr, areg, mem, reg;
20099 areg = gen_rtx_REG (Pmode, 0);
20101 (areg, GEN_INT (info->altivec_save_offset
20103 + 16 * (i - info->first_altivec_reg_save)));
20105 /* AltiVec addressing mode is [reg+reg]. */
20106 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20107 mem = gen_frame_mem (V4SImode, addr);
20109 reg = gen_rtx_REG (V4SImode, i);
20110 emit_move_insn (reg, mem);
20111 if (offset_below_red_zone_p (info->altivec_save_offset
20112 + (i - info->first_altivec_reg_save)
20114 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20119 /* Restore VRSAVE if we must do so before adjusting the stack. */
20121 && TARGET_ALTIVEC_VRSAVE
20122 && info->vrsave_mask != 0
20123 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20124 || (DEFAULT_ABI != ABI_V4
20125 && offset_below_red_zone_p (info->vrsave_save_offset))))
20127 rtx addr, mem, reg;
20129 if (frame_reg_rtx == sp_reg_rtx)
20131 if (use_backchain_to_restore_sp)
20133 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20134 emit_move_insn (frame_reg_rtx,
20135 gen_rtx_MEM (Pmode, sp_reg_rtx));
20138 else if (frame_pointer_needed)
20139 frame_reg_rtx = hard_frame_pointer_rtx;
20142 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20143 GEN_INT (info->vrsave_save_offset + sp_offset));
20144 mem = gen_frame_mem (SImode, addr);
20145 reg = gen_rtx_REG (SImode, 12);
20146 emit_move_insn (reg, mem);
20148 emit_insn (generate_set_vrsave (reg, info, 1));
20152 /* If we have a large stack frame, restore the old stack pointer
20153 using the backchain. */
20154 if (use_backchain_to_restore_sp)
20156 if (frame_reg_rtx == sp_reg_rtx)
20158 /* Under V.4, don't reset the stack pointer until after we're done
20159 loading the saved registers. */
20160 if (DEFAULT_ABI == ABI_V4)
20161 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20163 insn = emit_move_insn (frame_reg_rtx,
20164 gen_rtx_MEM (Pmode, sp_reg_rtx));
20167 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20168 && DEFAULT_ABI == ABI_V4)
20169 /* frame_reg_rtx has been set up by the altivec restore. */
20173 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20174 frame_reg_rtx = sp_reg_rtx;
20177 /* If we have a frame pointer, we can restore the old stack pointer
20179 else if (frame_pointer_needed)
20181 frame_reg_rtx = sp_reg_rtx;
20182 if (DEFAULT_ABI == ABI_V4)
20183 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20184 /* Prevent reordering memory accesses against stack pointer restore. */
20185 else if (cfun->calls_alloca
20186 || offset_below_red_zone_p (-info->total_size))
20188 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20189 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20190 MEM_NOTRAP_P (mem1) = 1;
20191 MEM_NOTRAP_P (mem2) = 1;
20192 emit_insn (gen_frame_tie (mem1, mem2));
20195 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20196 GEN_INT (info->total_size)));
20199 else if (info->push_p
20200 && DEFAULT_ABI != ABI_V4
20201 && !crtl->calls_eh_return)
20203 /* Prevent reordering memory accesses against stack pointer restore. */
20204 if (cfun->calls_alloca
20205 || offset_below_red_zone_p (-info->total_size))
20207 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20208 MEM_NOTRAP_P (mem) = 1;
20209 emit_insn (gen_stack_tie (mem));
20211 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20212 GEN_INT (info->total_size)));
20215 if (insn && frame_reg_rtx == sp_reg_rtx)
20219 REG_NOTES (insn) = cfa_restores;
20220 cfa_restores = NULL_RTX;
20222 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20223 RTX_FRAME_RELATED_P (insn) = 1;
20226 /* Restore AltiVec registers if we have not done so already. */
20227 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20228 && TARGET_ALTIVEC_ABI
20229 && info->altivec_size != 0
20230 && (DEFAULT_ABI == ABI_V4
20231 || !offset_below_red_zone_p (info->altivec_save_offset)))
20235 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20236 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20238 rtx addr, areg, mem, reg;
20240 areg = gen_rtx_REG (Pmode, 0);
20242 (areg, GEN_INT (info->altivec_save_offset
20244 + 16 * (i - info->first_altivec_reg_save)));
20246 /* AltiVec addressing mode is [reg+reg]. */
20247 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20248 mem = gen_frame_mem (V4SImode, addr);
20250 reg = gen_rtx_REG (V4SImode, i);
20251 emit_move_insn (reg, mem);
20252 if (DEFAULT_ABI == ABI_V4)
20253 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20258 /* Restore VRSAVE if we have not done so already. */
20259 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20261 && TARGET_ALTIVEC_VRSAVE
20262 && info->vrsave_mask != 0
20263 && (DEFAULT_ABI == ABI_V4
20264 || !offset_below_red_zone_p (info->vrsave_save_offset)))
20266 rtx addr, mem, reg;
20268 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20269 GEN_INT (info->vrsave_save_offset + sp_offset));
20270 mem = gen_frame_mem (SImode, addr);
20271 reg = gen_rtx_REG (SImode, 12);
20272 emit_move_insn (reg, mem);
20274 emit_insn (generate_set_vrsave (reg, info, 1));
20277 /* Get the old lr if we saved it. If we are restoring registers
20278 out-of-line, then the out-of-line routines can do this for us. */
20279 if (restore_lr && restoring_GPRs_inline)
20281 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20282 info->lr_save_offset + sp_offset);
20284 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20287 /* Get the old cr if we saved it. */
20288 if (info->cr_save_p)
20290 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20291 GEN_INT (info->cr_save_offset + sp_offset));
20292 rtx mem = gen_frame_mem (SImode, addr);
20294 cr_save_reg = gen_rtx_REG (SImode,
20295 DEFAULT_ABI == ABI_AIX
20296 && !restoring_GPRs_inline
20297 && info->first_fp_reg_save < 64
20299 emit_move_insn (cr_save_reg, mem);
20302 /* Set LR here to try to overlap restores below. LR is always saved
20303 above incoming stack, so it never needs REG_CFA_RESTORE. */
20304 if (restore_lr && restoring_GPRs_inline)
20305 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20306 gen_rtx_REG (Pmode, 0));
20308 /* Load exception handler data registers, if needed. */
20309 if (crtl->calls_eh_return)
20311 unsigned int i, regno;
20315 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20316 GEN_INT (sp_offset + 5 * reg_size));
20317 rtx mem = gen_frame_mem (reg_mode, addr);
20319 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
20326 regno = EH_RETURN_DATA_REGNO (i);
20327 if (regno == INVALID_REGNUM)
20330 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
20331 info->ehrd_offset + sp_offset
20332 + reg_size * (int) i);
20334 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
20338 /* Restore GPRs. This is done as a PARALLEL if we are using
20339 the load-multiple instructions. */
20341 && info->spe_64bit_regs_used != 0
20342 && info->first_gp_reg_save != 32)
20344 /* Determine whether we can address all of the registers that need
20345 to be saved with an offset from the stack pointer that fits in
20346 the small const field for SPE memory instructions. */
20347 int spe_regs_addressable_via_sp
20348 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20349 + (32 - info->first_gp_reg_save - 1) * reg_size)
20350 && restoring_GPRs_inline);
20353 if (spe_regs_addressable_via_sp)
20354 spe_offset = info->spe_gp_save_offset + sp_offset;
20357 rtx old_frame_reg_rtx = frame_reg_rtx;
20358 /* Make r11 point to the start of the SPE save area. We worried about
20359 not clobbering it when we were saving registers in the prologue.
20360 There's no need to worry here because the static chain is passed
20361 anew to every function. */
20362 int ool_adjust = (restoring_GPRs_inline
20364 : (info->first_gp_reg_save
20365 - (FIRST_SAVRES_REGISTER+1))*8);
20367 if (frame_reg_rtx == sp_reg_rtx)
20368 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20369 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
20370 GEN_INT (info->spe_gp_save_offset
20373 /* Keep the invariant that frame_reg_rtx + sp_offset points
20374 at the top of the stack frame. */
20375 sp_offset = -info->spe_gp_save_offset;
20380 if (restoring_GPRs_inline)
20382 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20383 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20385 rtx offset, addr, mem, reg;
20387 /* We're doing all this to ensure that the immediate offset
20388 fits into the immediate field of 'evldd'. */
20389 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
20391 offset = GEN_INT (spe_offset + reg_size * i);
20392 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
20393 mem = gen_rtx_MEM (V2SImode, addr);
20394 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20396 insn = emit_move_insn (reg, mem);
20397 if (DEFAULT_ABI == ABI_V4)
20399 if (frame_pointer_needed
20400 && info->first_gp_reg_save + i
20401 == HARD_FRAME_POINTER_REGNUM)
20403 add_reg_note (insn, REG_CFA_DEF_CFA,
20404 plus_constant (frame_reg_rtx,
20406 RTX_FRAME_RELATED_P (insn) = 1;
20409 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20418 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20420 /*savep=*/false, /*gpr=*/true,
20422 emit_jump_insn (par);
20423 /* We don't want anybody else emitting things after we jumped
20428 else if (!restoring_GPRs_inline)
20430 /* We are jumping to an out-of-line function. */
20431 bool can_use_exit = info->first_fp_reg_save == 64;
20434 /* Emit stack reset code if we need it. */
20436 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20437 sp_offset, can_use_exit);
20440 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
20443 GEN_INT (sp_offset - info->fp_size)));
20444 if (REGNO (frame_reg_rtx) == 11)
20445 sp_offset += info->fp_size;
20448 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20449 info->gp_save_offset, reg_mode,
20450 /*savep=*/false, /*gpr=*/true,
20451 /*lr=*/can_use_exit);
20455 if (info->cr_save_p)
20457 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20458 if (DEFAULT_ABI == ABI_V4)
20460 = alloc_reg_note (REG_CFA_RESTORE,
20461 gen_rtx_REG (SImode, CR2_REGNO),
20465 emit_jump_insn (par);
20467 /* We don't want anybody else emitting things after we jumped
20472 insn = emit_insn (par);
20473 if (DEFAULT_ABI == ABI_V4)
20475 if (frame_pointer_needed)
20477 add_reg_note (insn, REG_CFA_DEF_CFA,
20478 plus_constant (frame_reg_rtx, sp_offset));
20479 RTX_FRAME_RELATED_P (insn) = 1;
20482 for (i = info->first_gp_reg_save; i < 32; i++)
20484 = alloc_reg_note (REG_CFA_RESTORE,
20485 gen_rtx_REG (reg_mode, i), cfa_restores);
20488 else if (using_load_multiple)
20491 p = rtvec_alloc (32 - info->first_gp_reg_save);
20492 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20494 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20495 GEN_INT (info->gp_save_offset
20498 rtx mem = gen_frame_mem (reg_mode, addr);
20499 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20501 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
20502 if (DEFAULT_ABI == ABI_V4)
20503 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20506 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20507 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
20509 add_reg_note (insn, REG_CFA_DEF_CFA,
20510 plus_constant (frame_reg_rtx, sp_offset));
20511 RTX_FRAME_RELATED_P (insn) = 1;
20516 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20517 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20519 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20520 GEN_INT (info->gp_save_offset
20523 rtx mem = gen_frame_mem (reg_mode, addr);
20524 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20526 insn = emit_move_insn (reg, mem);
20527 if (DEFAULT_ABI == ABI_V4)
20529 if (frame_pointer_needed
20530 && info->first_gp_reg_save + i
20531 == HARD_FRAME_POINTER_REGNUM)
20533 add_reg_note (insn, REG_CFA_DEF_CFA,
20534 plus_constant (frame_reg_rtx, sp_offset));
20535 RTX_FRAME_RELATED_P (insn) = 1;
20538 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20544 if (restore_lr && !restoring_GPRs_inline)
20546 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20547 info->lr_save_offset + sp_offset);
20549 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20550 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20551 gen_rtx_REG (Pmode, 0));
20554 /* Restore fpr's if we need to do it without calling a function. */
20555 if (restoring_FPRs_inline)
20556 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20557 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20558 && ! call_used_regs[info->first_fp_reg_save+i]))
20560 rtx addr, mem, reg;
20561 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20562 GEN_INT (info->fp_save_offset
20565 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20566 ? DFmode : SFmode), addr);
20567 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20568 ? DFmode : SFmode),
20569 info->first_fp_reg_save + i);
20571 emit_move_insn (reg, mem);
20572 if (DEFAULT_ABI == ABI_V4)
20573 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20577 /* If we saved cr, restore it here. Just those that were used. */
20578 if (info->cr_save_p)
20580 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20581 if (DEFAULT_ABI == ABI_V4)
20583 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
20587 /* If this is V.4, unwind the stack pointer after all of the loads
20589 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20590 sp_offset, !restoring_FPRs_inline);
20595 REG_NOTES (insn) = cfa_restores;
20596 cfa_restores = NULL_RTX;
20598 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20599 RTX_FRAME_RELATED_P (insn) = 1;
20602 if (crtl->calls_eh_return)
20604 rtx sa = EH_RETURN_STACKADJ_RTX;
20605 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
20611 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
20612 if (! restoring_FPRs_inline)
20613 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
20615 p = rtvec_alloc (2);
20617 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
20618 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
20619 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
20620 : gen_rtx_CLOBBER (VOIDmode,
20621 gen_rtx_REG (Pmode, 65)));
20623 /* If we have to restore more than two FP registers, branch to the
20624 restore function. It will return to our caller. */
20625 if (! restoring_FPRs_inline)
20630 sym = rs6000_savres_routine_sym (info,
20634 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
20635 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
20636 gen_rtx_REG (Pmode,
20637 DEFAULT_ABI == ABI_AIX
20639 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20642 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
20643 GEN_INT (info->fp_save_offset + 8*i));
20644 mem = gen_frame_mem (DFmode, addr);
20646 RTVEC_ELT (p, i+4) =
20647 gen_rtx_SET (VOIDmode,
20648 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
20653 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20657 /* Write function epilogue. */
20660 rs6000_output_function_epilogue (FILE *file,
20661 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20663 if (! HAVE_epilogue)
20665 rtx insn = get_last_insn ();
20666 /* If the last insn was a BARRIER, we don't have to write anything except
20667 the trace table. */
20668 if (GET_CODE (insn) == NOTE)
20669 insn = prev_nonnote_insn (insn);
20670 if (insn == 0 || GET_CODE (insn) != BARRIER)
20672 /* This is slightly ugly, but at least we don't have two
20673 copies of the epilogue-emitting code. */
20676 /* A NOTE_INSN_DELETED is supposed to be at the start
20677 and end of the "toplevel" insn chain. */
20678 emit_note (NOTE_INSN_DELETED);
20679 rs6000_emit_epilogue (FALSE);
20680 emit_note (NOTE_INSN_DELETED);
20682 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20686 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20688 INSN_ADDRESSES_NEW (insn, addr);
20693 if (TARGET_DEBUG_STACK)
20694 debug_rtx_list (get_insns (), 100);
20695 final (get_insns (), file, FALSE);
20701 macho_branch_islands ();
20702 /* Mach-O doesn't support labels at the end of objects, so if
20703 it looks like we might want one, insert a NOP. */
20705 rtx insn = get_last_insn ();
20708 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
20709 insn = PREV_INSN (insn);
20713 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
20714 fputs ("\tnop\n", file);
20718 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20721 We don't output a traceback table if -finhibit-size-directive was
20722 used. The documentation for -finhibit-size-directive reads
20723 ``don't output a @code{.size} assembler directive, or anything
20724 else that would cause trouble if the function is split in the
20725 middle, and the two halves are placed at locations far apart in
20726 memory.'' The traceback table has this property, since it
20727 includes the offset from the start of the function to the
20728 traceback table itself.
20730 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20731 different traceback table. */
20732 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20733 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20735 const char *fname = NULL;
20736 const char *language_string = lang_hooks.name;
20737 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20739 int optional_tbtab;
20740 rs6000_stack_t *info = rs6000_stack_info ();
20742 if (rs6000_traceback == traceback_full)
20743 optional_tbtab = 1;
20744 else if (rs6000_traceback == traceback_part)
20745 optional_tbtab = 0;
20747 optional_tbtab = !optimize_size && !TARGET_ELF;
20749 if (optional_tbtab)
20751 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20752 while (*fname == '.') /* V.4 encodes . in the name */
20755 /* Need label immediately before tbtab, so we can compute
20756 its offset from the function start. */
20757 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20758 ASM_OUTPUT_LABEL (file, fname);
20761 /* The .tbtab pseudo-op can only be used for the first eight
20762 expressions, since it can't handle the possibly variable
20763 length fields that follow. However, if you omit the optional
20764 fields, the assembler outputs zeros for all optional fields
20765 anyways, giving each variable length field is minimum length
20766 (as defined in sys/debug.h). Thus we can not use the .tbtab
20767 pseudo-op at all. */
20769 /* An all-zero word flags the start of the tbtab, for debuggers
20770 that have to find it by searching forward from the entry
20771 point or from the current pc. */
20772 fputs ("\t.long 0\n", file);
20774 /* Tbtab format type. Use format type 0. */
20775 fputs ("\t.byte 0,", file);
20777 /* Language type. Unfortunately, there does not seem to be any
20778 official way to discover the language being compiled, so we
20779 use language_string.
20780 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20781 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20782 a number, so for now use 9. LTO isn't assigned a number either,
20783 so for now use 0. */
20784 if (! strcmp (language_string, "GNU C")
20785 || ! strcmp (language_string, "GNU GIMPLE"))
20787 else if (! strcmp (language_string, "GNU F77")
20788 || ! strcmp (language_string, "GNU Fortran"))
20790 else if (! strcmp (language_string, "GNU Pascal"))
20792 else if (! strcmp (language_string, "GNU Ada"))
20794 else if (! strcmp (language_string, "GNU C++")
20795 || ! strcmp (language_string, "GNU Objective-C++"))
20797 else if (! strcmp (language_string, "GNU Java"))
20799 else if (! strcmp (language_string, "GNU Objective-C"))
20802 gcc_unreachable ();
20803 fprintf (file, "%d,", i);
20805 /* 8 single bit fields: global linkage (not set for C extern linkage,
20806 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20807 from start of procedure stored in tbtab, internal function, function
20808 has controlled storage, function has no toc, function uses fp,
20809 function logs/aborts fp operations. */
20810 /* Assume that fp operations are used if any fp reg must be saved. */
20811 fprintf (file, "%d,",
20812 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
20814 /* 6 bitfields: function is interrupt handler, name present in
20815 proc table, function calls alloca, on condition directives
20816 (controls stack walks, 3 bits), saves condition reg, saves
20818 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20819 set up as a frame pointer, even when there is no alloca call. */
20820 fprintf (file, "%d,",
20821 ((optional_tbtab << 6)
20822 | ((optional_tbtab & frame_pointer_needed) << 5)
20823 | (info->cr_save_p << 1)
20824 | (info->lr_save_p)));
20826 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20828 fprintf (file, "%d,",
20829 (info->push_p << 7) | (64 - info->first_fp_reg_save));
20831 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20832 fprintf (file, "%d,", (32 - first_reg_to_save ()));
20834 if (optional_tbtab)
20836 /* Compute the parameter info from the function decl argument
20839 int next_parm_info_bit = 31;
20841 for (decl = DECL_ARGUMENTS (current_function_decl);
20842 decl; decl = TREE_CHAIN (decl))
20844 rtx parameter = DECL_INCOMING_RTL (decl);
20845 enum machine_mode mode = GET_MODE (parameter);
20847 if (GET_CODE (parameter) == REG)
20849 if (SCALAR_FLOAT_MODE_P (mode))
20870 gcc_unreachable ();
20873 /* If only one bit will fit, don't or in this entry. */
20874 if (next_parm_info_bit > 0)
20875 parm_info |= (bits << (next_parm_info_bit - 1));
20876 next_parm_info_bit -= 2;
20880 fixed_parms += ((GET_MODE_SIZE (mode)
20881 + (UNITS_PER_WORD - 1))
20883 next_parm_info_bit -= 1;
20889 /* Number of fixed point parameters. */
20890 /* This is actually the number of words of fixed point parameters; thus
20891 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20892 fprintf (file, "%d,", fixed_parms);
20894 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20896 /* This is actually the number of fp registers that hold parameters;
20897 and thus the maximum value is 13. */
20898 /* Set parameters on stack bit if parameters are not in their original
20899 registers, regardless of whether they are on the stack? Xlc
20900 seems to set the bit when not optimizing. */
20901 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
20903 if (! optional_tbtab)
20906 /* Optional fields follow. Some are variable length. */
20908 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20909 11 double float. */
20910 /* There is an entry for each parameter in a register, in the order that
20911 they occur in the parameter list. Any intervening arguments on the
20912 stack are ignored. If the list overflows a long (max possible length
20913 34 bits) then completely leave off all elements that don't fit. */
20914 /* Only emit this long if there was at least one parameter. */
20915 if (fixed_parms || float_parms)
20916 fprintf (file, "\t.long %d\n", parm_info);
20918 /* Offset from start of code to tb table. */
20919 fputs ("\t.long ", file);
20920 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20921 RS6000_OUTPUT_BASENAME (file, fname);
20923 rs6000_output_function_entry (file, fname);
20926 /* Interrupt handler mask. */
20927 /* Omit this long, since we never set the interrupt handler bit
20930 /* Number of CTL (controlled storage) anchors. */
20931 /* Omit this long, since the has_ctl bit is never set above. */
20933 /* Displacement into stack of each CTL anchor. */
20934 /* Omit this list of longs, because there are no CTL anchors. */
20936 /* Length of function name. */
20939 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20941 /* Function name. */
20942 assemble_string (fname, strlen (fname));
20944 /* Register for alloca automatic storage; this is always reg 31.
20945 Only emit this if the alloca bit was set above. */
20946 if (frame_pointer_needed)
20947 fputs ("\t.byte 31\n", file);
20949 fputs ("\t.align 2\n", file);
20953 /* A C compound statement that outputs the assembler code for a thunk
20954 function, used to implement C++ virtual function calls with
20955 multiple inheritance. The thunk acts as a wrapper around a virtual
20956 function, adjusting the implicit object parameter before handing
20957 control off to the real function.
20959 First, emit code to add the integer DELTA to the location that
20960 contains the incoming first argument. Assume that this argument
20961 contains a pointer, and is the one used to pass the `this' pointer
20962 in C++. This is the incoming argument *before* the function
20963 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20964 values of all other incoming arguments.
20966 After the addition, emit code to jump to FUNCTION, which is a
20967 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20968 not touch the return address. Hence returning from FUNCTION will
20969 return to whoever called the current `thunk'.
20971 The effect must be as if FUNCTION had been called directly with the
20972 adjusted first argument. This macro is responsible for emitting
20973 all of the code for a thunk function; output_function_prologue()
20974 and output_function_epilogue() are not invoked.
20976 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20977 been extracted from it.) It might possibly be useful on some
20978 targets, but probably not.
20980 If you do not define this macro, the target-independent code in the
20981 C++ frontend will generate a less efficient heavyweight thunk that
20982 calls FUNCTION instead of jumping to it. The generic approach does
20983 not support varargs. */
20986 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
20987 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
20990 rtx this_rtx, insn, funexp;
20992 reload_completed = 1;
20993 epilogue_completed = 1;
20995 /* Mark the end of the (empty) prologue. */
20996 emit_note (NOTE_INSN_PROLOGUE_END);
20998 /* Find the "this" pointer. If the function returns a structure,
20999 the structure return pointer is in r3. */
21000 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21001 this_rtx = gen_rtx_REG (Pmode, 4);
21003 this_rtx = gen_rtx_REG (Pmode, 3);
21005 /* Apply the constant offset, if required. */
21007 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21009 /* Apply the offset from the vtable, if required. */
21012 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21013 rtx tmp = gen_rtx_REG (Pmode, 12);
21015 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21016 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21018 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21019 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21023 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21025 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21027 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21030 /* Generate a tail call to the target function. */
21031 if (!TREE_USED (function))
21033 assemble_external (function);
21034 TREE_USED (function) = 1;
21036 funexp = XEXP (DECL_RTL (function), 0);
21037 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21040 if (MACHOPIC_INDIRECT)
21041 funexp = machopic_indirect_call_target (funexp);
21044 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21045 generate sibcall RTL explicitly. */
21046 insn = emit_call_insn (
21047 gen_rtx_PARALLEL (VOIDmode,
21049 gen_rtx_CALL (VOIDmode,
21050 funexp, const0_rtx),
21051 gen_rtx_USE (VOIDmode, const0_rtx),
21052 gen_rtx_USE (VOIDmode,
21053 gen_rtx_REG (SImode,
21055 gen_rtx_RETURN (VOIDmode))));
21056 SIBLING_CALL_P (insn) = 1;
21059 /* Run just enough of rest_of_compilation to get the insns emitted.
21060 There's not really enough bulk here to make other passes such as
21061 instruction scheduling worth while. Note that use_thunk calls
21062 assemble_start_function and assemble_end_function. */
21063 insn = get_insns ();
21064 insn_locators_alloc ();
21065 shorten_branches (insn);
21066 final_start_function (insn, file, 1);
21067 final (insn, file, 1);
21068 final_end_function ();
21070 reload_completed = 0;
21071 epilogue_completed = 0;
21074 /* A quick summary of the various types of 'constant-pool tables'
21077 Target Flags Name One table per
21078 AIX (none) AIX TOC object file
21079 AIX -mfull-toc AIX TOC object file
21080 AIX -mminimal-toc AIX minimal TOC translation unit
21081 SVR4/EABI (none) SVR4 SDATA object file
21082 SVR4/EABI -fpic SVR4 pic object file
21083 SVR4/EABI -fPIC SVR4 PIC translation unit
21084 SVR4/EABI -mrelocatable EABI TOC function
21085 SVR4/EABI -maix AIX TOC object file
21086 SVR4/EABI -maix -mminimal-toc
21087 AIX minimal TOC translation unit
21089 Name Reg. Set by entries contains:
21090 made by addrs? fp? sum?
21092 AIX TOC 2 crt0 as Y option option
21093 AIX minimal TOC 30 prolog gcc Y Y option
21094 SVR4 SDATA 13 crt0 gcc N Y N
21095 SVR4 pic 30 prolog ld Y not yet N
21096 SVR4 PIC 30 prolog gcc Y option option
21097 EABI TOC 30 prolog gcc Y option option
21101 /* Hash functions for the hash table. */
21104 rs6000_hash_constant (rtx k)
21106 enum rtx_code code = GET_CODE (k);
21107 enum machine_mode mode = GET_MODE (k);
21108 unsigned result = (code << 3) ^ mode;
21109 const char *format;
21112 format = GET_RTX_FORMAT (code);
21113 flen = strlen (format);
21119 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21122 if (mode != VOIDmode)
21123 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21135 for (; fidx < flen; fidx++)
21136 switch (format[fidx])
21141 const char *str = XSTR (k, fidx);
21142 len = strlen (str);
21143 result = result * 613 + len;
21144 for (i = 0; i < len; i++)
21145 result = result * 613 + (unsigned) str[i];
21150 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21154 result = result * 613 + (unsigned) XINT (k, fidx);
21157 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21158 result = result * 613 + (unsigned) XWINT (k, fidx);
21162 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21163 result = result * 613 + (unsigned) (XWINT (k, fidx)
21170 gcc_unreachable ();
21177 toc_hash_function (const void *hash_entry)
21179 const struct toc_hash_struct *thc =
21180 (const struct toc_hash_struct *) hash_entry;
21181 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21184 /* Compare H1 and H2 for equivalence. */
21187 toc_hash_eq (const void *h1, const void *h2)
21189 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21190 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21192 if (((const struct toc_hash_struct *) h1)->key_mode
21193 != ((const struct toc_hash_struct *) h2)->key_mode)
21196 return rtx_equal_p (r1, r2);
21199 /* These are the names given by the C++ front-end to vtables, and
21200 vtable-like objects. Ideally, this logic should not be here;
21201 instead, there should be some programmatic way of inquiring as
21202 to whether or not an object is a vtable. */
21204 #define VTABLE_NAME_P(NAME) \
21205 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21206 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21207 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21208 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21209 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21211 #ifdef NO_DOLLAR_IN_LABEL
21212 /* Return a GGC-allocated character string translating dollar signs in
21213 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21216 rs6000_xcoff_strip_dollar (const char *name)
21221 p = strchr (name, '$');
21223 if (p == 0 || p == name)
21226 len = strlen (name);
21227 strip = (char *) alloca (len + 1);
21228 strcpy (strip, name);
21229 p = strchr (strip, '$');
21233 p = strchr (p + 1, '$');
21236 return ggc_alloc_string (strip, len);
21241 rs6000_output_symbol_ref (FILE *file, rtx x)
21243 /* Currently C++ toc references to vtables can be emitted before it
21244 is decided whether the vtable is public or private. If this is
21245 the case, then the linker will eventually complain that there is
21246 a reference to an unknown section. Thus, for vtables only,
21247 we emit the TOC reference to reference the symbol and not the
21249 const char *name = XSTR (x, 0);
21251 if (VTABLE_NAME_P (name))
21253 RS6000_OUTPUT_BASENAME (file, name);
21256 assemble_name (file, name);
21259 /* Output a TOC entry. We derive the entry name from what is being
21263 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
21266 const char *name = buf;
21268 HOST_WIDE_INT offset = 0;
21270 gcc_assert (!TARGET_NO_TOC);
21272 /* When the linker won't eliminate them, don't output duplicate
21273 TOC entries (this happens on AIX if there is any kind of TOC,
21274 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
21276 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
21278 struct toc_hash_struct *h;
21281 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
21282 time because GGC is not initialized at that point. */
21283 if (toc_hash_table == NULL)
21284 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
21285 toc_hash_eq, NULL);
21287 h = ggc_alloc_toc_hash_struct ();
21289 h->key_mode = mode;
21290 h->labelno = labelno;
21292 found = htab_find_slot (toc_hash_table, h, INSERT);
21293 if (*found == NULL)
21295 else /* This is indeed a duplicate.
21296 Set this label equal to that label. */
21298 fputs ("\t.set ", file);
21299 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21300 fprintf (file, "%d,", labelno);
21301 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21302 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
21308 /* If we're going to put a double constant in the TOC, make sure it's
21309 aligned properly when strict alignment is on. */
21310 if (GET_CODE (x) == CONST_DOUBLE
21311 && STRICT_ALIGNMENT
21312 && GET_MODE_BITSIZE (mode) >= 64
21313 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
21314 ASM_OUTPUT_ALIGN (file, 3);
21317 (*targetm.asm_out.internal_label) (file, "LC", labelno);
21319 /* Handle FP constants specially. Note that if we have a minimal
21320 TOC, things we put here aren't actually in the TOC, so we can allow
21322 if (GET_CODE (x) == CONST_DOUBLE &&
21323 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
21325 REAL_VALUE_TYPE rv;
21328 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21329 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21330 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
21332 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
21336 if (TARGET_MINIMAL_TOC)
21337 fputs (DOUBLE_INT_ASM_OP, file);
21339 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
21340 k[0] & 0xffffffff, k[1] & 0xffffffff,
21341 k[2] & 0xffffffff, k[3] & 0xffffffff);
21342 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
21343 k[0] & 0xffffffff, k[1] & 0xffffffff,
21344 k[2] & 0xffffffff, k[3] & 0xffffffff);
21349 if (TARGET_MINIMAL_TOC)
21350 fputs ("\t.long ", file);
21352 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
21353 k[0] & 0xffffffff, k[1] & 0xffffffff,
21354 k[2] & 0xffffffff, k[3] & 0xffffffff);
21355 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
21356 k[0] & 0xffffffff, k[1] & 0xffffffff,
21357 k[2] & 0xffffffff, k[3] & 0xffffffff);
21361 else if (GET_CODE (x) == CONST_DOUBLE &&
21362 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
21364 REAL_VALUE_TYPE rv;
21367 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21369 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21370 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
21372 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
21376 if (TARGET_MINIMAL_TOC)
21377 fputs (DOUBLE_INT_ASM_OP, file);
21379 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
21380 k[0] & 0xffffffff, k[1] & 0xffffffff);
21381 fprintf (file, "0x%lx%08lx\n",
21382 k[0] & 0xffffffff, k[1] & 0xffffffff);
21387 if (TARGET_MINIMAL_TOC)
21388 fputs ("\t.long ", file);
21390 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
21391 k[0] & 0xffffffff, k[1] & 0xffffffff);
21392 fprintf (file, "0x%lx,0x%lx\n",
21393 k[0] & 0xffffffff, k[1] & 0xffffffff);
21397 else if (GET_CODE (x) == CONST_DOUBLE &&
21398 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
21400 REAL_VALUE_TYPE rv;
21403 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21404 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21405 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
21407 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
21411 if (TARGET_MINIMAL_TOC)
21412 fputs (DOUBLE_INT_ASM_OP, file);
21414 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
21415 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
21420 if (TARGET_MINIMAL_TOC)
21421 fputs ("\t.long ", file);
21423 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
21424 fprintf (file, "0x%lx\n", l & 0xffffffff);
21428 else if (GET_MODE (x) == VOIDmode
21429 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
21431 unsigned HOST_WIDE_INT low;
21432 HOST_WIDE_INT high;
21434 if (GET_CODE (x) == CONST_DOUBLE)
21436 low = CONST_DOUBLE_LOW (x);
21437 high = CONST_DOUBLE_HIGH (x);
21440 #if HOST_BITS_PER_WIDE_INT == 32
21443 high = (low & 0x80000000) ? ~0 : 0;
21447 low = INTVAL (x) & 0xffffffff;
21448 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
21452 /* TOC entries are always Pmode-sized, but since this
21453 is a bigendian machine then if we're putting smaller
21454 integer constants in the TOC we have to pad them.
21455 (This is still a win over putting the constants in
21456 a separate constant pool, because then we'd have
21457 to have both a TOC entry _and_ the actual constant.)
21459 For a 32-bit target, CONST_INT values are loaded and shifted
21460 entirely within `low' and can be stored in one TOC entry. */
21462 /* It would be easy to make this work, but it doesn't now. */
21463 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
21465 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
21467 #if HOST_BITS_PER_WIDE_INT == 32
21468 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
21469 POINTER_SIZE, &low, &high, 0);
21472 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
21473 high = (HOST_WIDE_INT) low >> 32;
21480 if (TARGET_MINIMAL_TOC)
21481 fputs (DOUBLE_INT_ASM_OP, file);
21483 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21484 (long) high & 0xffffffff, (long) low & 0xffffffff);
21485 fprintf (file, "0x%lx%08lx\n",
21486 (long) high & 0xffffffff, (long) low & 0xffffffff);
21491 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
21493 if (TARGET_MINIMAL_TOC)
21494 fputs ("\t.long ", file);
21496 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21497 (long) high & 0xffffffff, (long) low & 0xffffffff);
21498 fprintf (file, "0x%lx,0x%lx\n",
21499 (long) high & 0xffffffff, (long) low & 0xffffffff);
21503 if (TARGET_MINIMAL_TOC)
21504 fputs ("\t.long ", file);
21506 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
21507 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
21513 if (GET_CODE (x) == CONST)
21515 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
21516 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
21518 base = XEXP (XEXP (x, 0), 0);
21519 offset = INTVAL (XEXP (XEXP (x, 0), 1));
21522 switch (GET_CODE (base))
21525 name = XSTR (base, 0);
21529 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
21530 CODE_LABEL_NUMBER (XEXP (base, 0)));
21534 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
21538 gcc_unreachable ();
21541 if (TARGET_MINIMAL_TOC)
21542 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
21545 fputs ("\t.tc ", file);
21546 RS6000_OUTPUT_BASENAME (file, name);
21549 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
21551 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
21553 fputs ("[TC],", file);
21556 /* Currently C++ toc references to vtables can be emitted before it
21557 is decided whether the vtable is public or private. If this is
21558 the case, then the linker will eventually complain that there is
21559 a TOC reference to an unknown section. Thus, for vtables only,
21560 we emit the TOC reference to reference the symbol and not the
21562 if (VTABLE_NAME_P (name))
21564 RS6000_OUTPUT_BASENAME (file, name);
21566 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
21567 else if (offset > 0)
21568 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
21571 output_addr_const (file, x);
21575 /* Output an assembler pseudo-op to write an ASCII string of N characters
21576 starting at P to FILE.
21578 On the RS/6000, we have to do this using the .byte operation and
21579 write out special characters outside the quoted string.
21580 Also, the assembler is broken; very long strings are truncated,
21581 so we must artificially break them up early. */
21584 output_ascii (FILE *file, const char *p, int n)
21587 int i, count_string;
21588 const char *for_string = "\t.byte \"";
21589 const char *for_decimal = "\t.byte ";
21590 const char *to_close = NULL;
21593 for (i = 0; i < n; i++)
21596 if (c >= ' ' && c < 0177)
21599 fputs (for_string, file);
21602 /* Write two quotes to get one. */
21610 for_decimal = "\"\n\t.byte ";
21614 if (count_string >= 512)
21616 fputs (to_close, file);
21618 for_string = "\t.byte \"";
21619 for_decimal = "\t.byte ";
21627 fputs (for_decimal, file);
21628 fprintf (file, "%d", c);
21630 for_string = "\n\t.byte \"";
21631 for_decimal = ", ";
21637 /* Now close the string if we have written one. Then end the line. */
21639 fputs (to_close, file);
21642 /* Generate a unique section name for FILENAME for a section type
21643 represented by SECTION_DESC. Output goes into BUF.
21645 SECTION_DESC can be any string, as long as it is different for each
21646 possible section type.
21648 We name the section in the same manner as xlc. The name begins with an
21649 underscore followed by the filename (after stripping any leading directory
21650 names) with the last period replaced by the string SECTION_DESC. If
21651 FILENAME does not contain a period, SECTION_DESC is appended to the end of
21655 rs6000_gen_section_name (char **buf, const char *filename,
21656 const char *section_desc)
21658 const char *q, *after_last_slash, *last_period = 0;
21662 after_last_slash = filename;
21663 for (q = filename; *q; q++)
21666 after_last_slash = q + 1;
21667 else if (*q == '.')
21671 len = strlen (after_last_slash) + strlen (section_desc) + 2;
21672 *buf = (char *) xmalloc (len);
21677 for (q = after_last_slash; *q; q++)
21679 if (q == last_period)
21681 strcpy (p, section_desc);
21682 p += strlen (section_desc);
21686 else if (ISALNUM (*q))
21690 if (last_period == 0)
21691 strcpy (p, section_desc);
21696 /* Emit profile function. */
21699 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
21701 /* Non-standard profiling for kernels, which just saves LR then calls
21702 _mcount without worrying about arg saves. The idea is to change
21703 the function prologue as little as possible as it isn't easy to
21704 account for arg save/restore code added just for _mcount. */
21705 if (TARGET_PROFILE_KERNEL)
21708 if (DEFAULT_ABI == ABI_AIX)
21710 #ifndef NO_PROFILE_COUNTERS
21711 # define NO_PROFILE_COUNTERS 0
21713 if (NO_PROFILE_COUNTERS)
21714 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21715 LCT_NORMAL, VOIDmode, 0);
21719 const char *label_name;
21722 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21723 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21724 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21726 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21727 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21730 else if (DEFAULT_ABI == ABI_DARWIN)
21732 const char *mcount_name = RS6000_MCOUNT;
21733 int caller_addr_regno = LR_REGNO;
21735 /* Be conservative and always set this, at least for now. */
21736 crtl->uses_pic_offset_table = 1;
21739 /* For PIC code, set up a stub and collect the caller's address
21740 from r0, which is where the prologue puts it. */
21741 if (MACHOPIC_INDIRECT
21742 && crtl->uses_pic_offset_table)
21743 caller_addr_regno = 0;
21745 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21746 LCT_NORMAL, VOIDmode, 1,
21747 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21751 /* Write function profiler code. */
21754 output_function_profiler (FILE *file, int labelno)
21758 switch (DEFAULT_ABI)
21761 gcc_unreachable ();
21766 warning (0, "no profiling of 64-bit code for this ABI");
21769 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21770 fprintf (file, "\tmflr %s\n", reg_names[0]);
21771 if (NO_PROFILE_COUNTERS)
21773 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21774 reg_names[0], reg_names[1]);
21776 else if (TARGET_SECURE_PLT && flag_pic)
21778 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21779 reg_names[0], reg_names[1]);
21780 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21781 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21782 reg_names[12], reg_names[12]);
21783 assemble_name (file, buf);
21784 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21785 assemble_name (file, buf);
21786 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21788 else if (flag_pic == 1)
21790 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21791 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21792 reg_names[0], reg_names[1]);
21793 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21794 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
21795 assemble_name (file, buf);
21796 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
21798 else if (flag_pic > 1)
21800 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21801 reg_names[0], reg_names[1]);
21802 /* Now, we need to get the address of the label. */
21803 fputs ("\tbcl 20,31,1f\n\t.long ", file);
21804 assemble_name (file, buf);
21805 fputs ("-.\n1:", file);
21806 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
21807 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
21808 reg_names[0], reg_names[11]);
21809 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
21810 reg_names[0], reg_names[0], reg_names[11]);
21814 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
21815 assemble_name (file, buf);
21816 fputs ("@ha\n", file);
21817 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21818 reg_names[0], reg_names[1]);
21819 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
21820 assemble_name (file, buf);
21821 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
21824 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21825 fprintf (file, "\tbl %s%s\n",
21826 RS6000_MCOUNT, flag_pic ? "@plt" : "");
21831 if (!TARGET_PROFILE_KERNEL)
21833 /* Don't do anything, done in output_profile_hook (). */
21837 gcc_assert (!TARGET_32BIT);
21839 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
21840 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
21842 if (cfun->static_chain_decl != NULL)
21844 asm_fprintf (file, "\tstd %s,24(%s)\n",
21845 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21846 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21847 asm_fprintf (file, "\tld %s,24(%s)\n",
21848 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21851 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21859 /* The following variable value is the last issued insn. */
21861 static rtx last_scheduled_insn;
21863 /* The following variable helps to balance issuing of load and
21864 store instructions */
21866 static int load_store_pendulum;
21868 /* Power4 load update and store update instructions are cracked into a
21869 load or store and an integer insn which are executed in the same cycle.
21870 Branches have their own dispatch slot which does not count against the
21871 GCC issue rate, but it changes the program flow so there are no other
21872 instructions to issue in this cycle. */
21875 rs6000_variable_issue_1 (rtx insn, int more)
21877 last_scheduled_insn = insn;
21878 if (GET_CODE (PATTERN (insn)) == USE
21879 || GET_CODE (PATTERN (insn)) == CLOBBER)
21881 cached_can_issue_more = more;
21882 return cached_can_issue_more;
21885 if (insn_terminates_group_p (insn, current_group))
21887 cached_can_issue_more = 0;
21888 return cached_can_issue_more;
21891 /* If no reservation, but reach here */
21892 if (recog_memoized (insn) < 0)
21895 if (rs6000_sched_groups)
21897 if (is_microcoded_insn (insn))
21898 cached_can_issue_more = 0;
21899 else if (is_cracked_insn (insn))
21900 cached_can_issue_more = more > 2 ? more - 2 : 0;
21902 cached_can_issue_more = more - 1;
21904 return cached_can_issue_more;
21907 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21910 cached_can_issue_more = more - 1;
21911 return cached_can_issue_more;
21915 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
21917 int r = rs6000_variable_issue_1 (insn, more);
21919 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
21923 /* Adjust the cost of a scheduling dependency. Return the new cost of
21924 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21927 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21929 enum attr_type attr_type;
21931 if (! recog_memoized (insn))
21934 switch (REG_NOTE_KIND (link))
21938 /* Data dependency; DEP_INSN writes a register that INSN reads
21939 some cycles later. */
21941 /* Separate a load from a narrower, dependent store. */
21942 if (rs6000_sched_groups
21943 && GET_CODE (PATTERN (insn)) == SET
21944 && GET_CODE (PATTERN (dep_insn)) == SET
21945 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21946 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21947 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21948 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21951 attr_type = get_attr_type (insn);
21956 /* Tell the first scheduling pass about the latency between
21957 a mtctr and bctr (and mtlr and br/blr). The first
21958 scheduling pass will not know about this latency since
21959 the mtctr instruction, which has the latency associated
21960 to it, will be generated by reload. */
21961 return TARGET_POWER ? 5 : 4;
21963 /* Leave some extra cycles between a compare and its
21964 dependent branch, to inhibit expensive mispredicts. */
21965 if ((rs6000_cpu_attr == CPU_PPC603
21966 || rs6000_cpu_attr == CPU_PPC604
21967 || rs6000_cpu_attr == CPU_PPC604E
21968 || rs6000_cpu_attr == CPU_PPC620
21969 || rs6000_cpu_attr == CPU_PPC630
21970 || rs6000_cpu_attr == CPU_PPC750
21971 || rs6000_cpu_attr == CPU_PPC7400
21972 || rs6000_cpu_attr == CPU_PPC7450
21973 || rs6000_cpu_attr == CPU_POWER4
21974 || rs6000_cpu_attr == CPU_POWER5
21975 || rs6000_cpu_attr == CPU_POWER7
21976 || rs6000_cpu_attr == CPU_CELL)
21977 && recog_memoized (dep_insn)
21978 && (INSN_CODE (dep_insn) >= 0))
21980 switch (get_attr_type (dep_insn))
21984 case TYPE_DELAYED_COMPARE:
21985 case TYPE_IMUL_COMPARE:
21986 case TYPE_LMUL_COMPARE:
21987 case TYPE_FPCOMPARE:
21988 case TYPE_CR_LOGICAL:
21989 case TYPE_DELAYED_CR:
21998 case TYPE_STORE_UX:
22000 case TYPE_FPSTORE_U:
22001 case TYPE_FPSTORE_UX:
22002 if ((rs6000_cpu == PROCESSOR_POWER6)
22003 && recog_memoized (dep_insn)
22004 && (INSN_CODE (dep_insn) >= 0))
22007 if (GET_CODE (PATTERN (insn)) != SET)
22008 /* If this happens, we have to extend this to schedule
22009 optimally. Return default for now. */
22012 /* Adjust the cost for the case where the value written
22013 by a fixed point operation is used as the address
22014 gen value on a store. */
22015 switch (get_attr_type (dep_insn))
22022 if (! store_data_bypass_p (dep_insn, insn))
22026 case TYPE_LOAD_EXT:
22027 case TYPE_LOAD_EXT_U:
22028 case TYPE_LOAD_EXT_UX:
22029 case TYPE_VAR_SHIFT_ROTATE:
22030 case TYPE_VAR_DELAYED_COMPARE:
22032 if (! store_data_bypass_p (dep_insn, insn))
22038 case TYPE_FAST_COMPARE:
22041 case TYPE_INSERT_WORD:
22042 case TYPE_INSERT_DWORD:
22043 case TYPE_FPLOAD_U:
22044 case TYPE_FPLOAD_UX:
22046 case TYPE_STORE_UX:
22047 case TYPE_FPSTORE_U:
22048 case TYPE_FPSTORE_UX:
22050 if (! store_data_bypass_p (dep_insn, insn))
22058 case TYPE_IMUL_COMPARE:
22059 case TYPE_LMUL_COMPARE:
22061 if (! store_data_bypass_p (dep_insn, insn))
22067 if (! store_data_bypass_p (dep_insn, insn))
22073 if (! store_data_bypass_p (dep_insn, insn))
22086 case TYPE_LOAD_EXT:
22087 case TYPE_LOAD_EXT_U:
22088 case TYPE_LOAD_EXT_UX:
22089 if ((rs6000_cpu == PROCESSOR_POWER6)
22090 && recog_memoized (dep_insn)
22091 && (INSN_CODE (dep_insn) >= 0))
22094 /* Adjust the cost for the case where the value written
22095 by a fixed point instruction is used within the address
22096 gen portion of a subsequent load(u)(x) */
22097 switch (get_attr_type (dep_insn))
22104 if (set_to_load_agen (dep_insn, insn))
22108 case TYPE_LOAD_EXT:
22109 case TYPE_LOAD_EXT_U:
22110 case TYPE_LOAD_EXT_UX:
22111 case TYPE_VAR_SHIFT_ROTATE:
22112 case TYPE_VAR_DELAYED_COMPARE:
22114 if (set_to_load_agen (dep_insn, insn))
22120 case TYPE_FAST_COMPARE:
22123 case TYPE_INSERT_WORD:
22124 case TYPE_INSERT_DWORD:
22125 case TYPE_FPLOAD_U:
22126 case TYPE_FPLOAD_UX:
22128 case TYPE_STORE_UX:
22129 case TYPE_FPSTORE_U:
22130 case TYPE_FPSTORE_UX:
22132 if (set_to_load_agen (dep_insn, insn))
22140 case TYPE_IMUL_COMPARE:
22141 case TYPE_LMUL_COMPARE:
22143 if (set_to_load_agen (dep_insn, insn))
22149 if (set_to_load_agen (dep_insn, insn))
22155 if (set_to_load_agen (dep_insn, insn))
22166 if ((rs6000_cpu == PROCESSOR_POWER6)
22167 && recog_memoized (dep_insn)
22168 && (INSN_CODE (dep_insn) >= 0)
22169 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22176 /* Fall out to return default cost. */
22180 case REG_DEP_OUTPUT:
22181 /* Output dependency; DEP_INSN writes a register that INSN writes some
22183 if ((rs6000_cpu == PROCESSOR_POWER6)
22184 && recog_memoized (dep_insn)
22185 && (INSN_CODE (dep_insn) >= 0))
22187 attr_type = get_attr_type (insn);
22192 if (get_attr_type (dep_insn) == TYPE_FP)
22196 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22204 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22209 gcc_unreachable ();
22215 /* Debug version of rs6000_adjust_cost. */
22218 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22220 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
22226 switch (REG_NOTE_KIND (link))
22228 default: dep = "unknown depencency"; break;
22229 case REG_DEP_TRUE: dep = "data dependency"; break;
22230 case REG_DEP_OUTPUT: dep = "output dependency"; break;
22231 case REG_DEP_ANTI: dep = "anti depencency"; break;
22235 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22236 "%s, insn:\n", ret, cost, dep);
22244 /* The function returns a true if INSN is microcoded.
22245 Return false otherwise. */
22248 is_microcoded_insn (rtx insn)
22250 if (!insn || !NONDEBUG_INSN_P (insn)
22251 || GET_CODE (PATTERN (insn)) == USE
22252 || GET_CODE (PATTERN (insn)) == CLOBBER)
22255 if (rs6000_cpu_attr == CPU_CELL)
22256 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
22258 if (rs6000_sched_groups)
22260 enum attr_type type = get_attr_type (insn);
22261 if (type == TYPE_LOAD_EXT_U
22262 || type == TYPE_LOAD_EXT_UX
22263 || type == TYPE_LOAD_UX
22264 || type == TYPE_STORE_UX
22265 || type == TYPE_MFCR)
22272 /* The function returns true if INSN is cracked into 2 instructions
22273 by the processor (and therefore occupies 2 issue slots). */
22276 is_cracked_insn (rtx insn)
22278 if (!insn || !NONDEBUG_INSN_P (insn)
22279 || GET_CODE (PATTERN (insn)) == USE
22280 || GET_CODE (PATTERN (insn)) == CLOBBER)
22283 if (rs6000_sched_groups)
22285 enum attr_type type = get_attr_type (insn);
22286 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
22287 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
22288 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
22289 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
22290 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
22291 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
22292 || type == TYPE_IDIV || type == TYPE_LDIV
22293 || type == TYPE_INSERT_WORD)
22300 /* The function returns true if INSN can be issued only from
22301 the branch slot. */
22304 is_branch_slot_insn (rtx insn)
22306 if (!insn || !NONDEBUG_INSN_P (insn)
22307 || GET_CODE (PATTERN (insn)) == USE
22308 || GET_CODE (PATTERN (insn)) == CLOBBER)
22311 if (rs6000_sched_groups)
22313 enum attr_type type = get_attr_type (insn);
22314 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
22322 /* The function returns true if out_inst sets a value that is
22323 used in the address generation computation of in_insn */
22325 set_to_load_agen (rtx out_insn, rtx in_insn)
22327 rtx out_set, in_set;
22329 /* For performance reasons, only handle the simple case where
22330 both loads are a single_set. */
22331 out_set = single_set (out_insn);
22334 in_set = single_set (in_insn);
22336 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
22342 /* The function returns true if the target storage location of
22343 out_insn is adjacent to the target storage location of in_insn */
22344 /* Return 1 if memory locations are adjacent. */
22347 adjacent_mem_locations (rtx insn1, rtx insn2)
22350 rtx a = get_store_dest (PATTERN (insn1));
22351 rtx b = get_store_dest (PATTERN (insn2));
22353 if ((GET_CODE (XEXP (a, 0)) == REG
22354 || (GET_CODE (XEXP (a, 0)) == PLUS
22355 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
22356 && (GET_CODE (XEXP (b, 0)) == REG
22357 || (GET_CODE (XEXP (b, 0)) == PLUS
22358 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
22360 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
22363 if (GET_CODE (XEXP (a, 0)) == PLUS)
22365 reg0 = XEXP (XEXP (a, 0), 0);
22366 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
22369 reg0 = XEXP (a, 0);
22371 if (GET_CODE (XEXP (b, 0)) == PLUS)
22373 reg1 = XEXP (XEXP (b, 0), 0);
22374 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
22377 reg1 = XEXP (b, 0);
22379 val_diff = val1 - val0;
22381 return ((REGNO (reg0) == REGNO (reg1))
22382 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
22383 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
22389 /* A C statement (sans semicolon) to update the integer scheduling
22390 priority INSN_PRIORITY (INSN). Increase the priority to execute the
22391 INSN earlier, reduce the priority to execute INSN later. Do not
22392 define this macro if you do not need to adjust the scheduling
22393 priorities of insns. */
22396 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
22398 /* On machines (like the 750) which have asymmetric integer units,
22399 where one integer unit can do multiply and divides and the other
22400 can't, reduce the priority of multiply/divide so it is scheduled
22401 before other integer operations. */
22404 if (! INSN_P (insn))
22407 if (GET_CODE (PATTERN (insn)) == USE)
22410 switch (rs6000_cpu_attr) {
22412 switch (get_attr_type (insn))
22419 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
22420 priority, priority);
22421 if (priority >= 0 && priority < 0x01000000)
22428 if (insn_must_be_first_in_group (insn)
22429 && reload_completed
22430 && current_sched_info->sched_max_insns_priority
22431 && rs6000_sched_restricted_insns_priority)
22434 /* Prioritize insns that can be dispatched only in the first
22436 if (rs6000_sched_restricted_insns_priority == 1)
22437 /* Attach highest priority to insn. This means that in
22438 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
22439 precede 'priority' (critical path) considerations. */
22440 return current_sched_info->sched_max_insns_priority;
22441 else if (rs6000_sched_restricted_insns_priority == 2)
22442 /* Increase priority of insn by a minimal amount. This means that in
22443 haifa-sched.c:ready_sort(), only 'priority' (critical path)
22444 considerations precede dispatch-slot restriction considerations. */
22445 return (priority + 1);
22448 if (rs6000_cpu == PROCESSOR_POWER6
22449 && ((load_store_pendulum == -2 && is_load_insn (insn))
22450 || (load_store_pendulum == 2 && is_store_insn (insn))))
22451 /* Attach highest priority to insn if the scheduler has just issued two
22452 stores and this instruction is a load, or two loads and this instruction
22453 is a store. Power6 wants loads and stores scheduled alternately
22455 return current_sched_info->sched_max_insns_priority;
22460 /* Return true if the instruction is nonpipelined on the Cell. */
22462 is_nonpipeline_insn (rtx insn)
22464 enum attr_type type;
22465 if (!insn || !NONDEBUG_INSN_P (insn)
22466 || GET_CODE (PATTERN (insn)) == USE
22467 || GET_CODE (PATTERN (insn)) == CLOBBER)
22470 type = get_attr_type (insn);
22471 if (type == TYPE_IMUL
22472 || type == TYPE_IMUL2
22473 || type == TYPE_IMUL3
22474 || type == TYPE_LMUL
22475 || type == TYPE_IDIV
22476 || type == TYPE_LDIV
22477 || type == TYPE_SDIV
22478 || type == TYPE_DDIV
22479 || type == TYPE_SSQRT
22480 || type == TYPE_DSQRT
22481 || type == TYPE_MFCR
22482 || type == TYPE_MFCRF
22483 || type == TYPE_MFJMPR)
22491 /* Return how many instructions the machine can issue per cycle. */
22494 rs6000_issue_rate (void)
22496 /* Unless scheduling for register pressure, use issue rate of 1 for
22497 first scheduling pass to decrease degradation. */
22498 if (!reload_completed && !flag_sched_pressure)
22501 switch (rs6000_cpu_attr) {
22502 case CPU_RIOS1: /* ? */
22504 case CPU_PPC601: /* ? */
22513 case CPU_PPCE300C2:
22514 case CPU_PPCE300C3:
22515 case CPU_PPCE500MC:
22516 case CPU_PPCE500MC64:
22535 /* Return how many instructions to look ahead for better insn
22539 rs6000_use_sched_lookahead (void)
22541 if (rs6000_cpu_attr == CPU_PPC8540)
22543 if (rs6000_cpu_attr == CPU_CELL)
22544 return (reload_completed ? 8 : 0);
22548 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
22550 rs6000_use_sched_lookahead_guard (rtx insn)
22552 if (rs6000_cpu_attr != CPU_CELL)
22555 if (insn == NULL_RTX || !INSN_P (insn))
22558 if (!reload_completed
22559 || is_nonpipeline_insn (insn)
22560 || is_microcoded_insn (insn))
22566 /* Determine is PAT refers to memory. */
22569 is_mem_ref (rtx pat)
22575 /* stack_tie does not produce any real memory traffic. */
22576 if (GET_CODE (pat) == UNSPEC
22577 && XINT (pat, 1) == UNSPEC_TIE)
22580 if (GET_CODE (pat) == MEM)
22583 /* Recursively process the pattern. */
22584 fmt = GET_RTX_FORMAT (GET_CODE (pat));
22586 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
22589 ret |= is_mem_ref (XEXP (pat, i));
22590 else if (fmt[i] == 'E')
22591 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
22592 ret |= is_mem_ref (XVECEXP (pat, i, j));
22598 /* Determine if PAT is a PATTERN of a load insn. */
22601 is_load_insn1 (rtx pat)
22603 if (!pat || pat == NULL_RTX)
22606 if (GET_CODE (pat) == SET)
22607 return is_mem_ref (SET_SRC (pat));
22609 if (GET_CODE (pat) == PARALLEL)
22613 for (i = 0; i < XVECLEN (pat, 0); i++)
22614 if (is_load_insn1 (XVECEXP (pat, 0, i)))
22621 /* Determine if INSN loads from memory. */
22624 is_load_insn (rtx insn)
22626 if (!insn || !INSN_P (insn))
22629 if (GET_CODE (insn) == CALL_INSN)
22632 return is_load_insn1 (PATTERN (insn));
22635 /* Determine if PAT is a PATTERN of a store insn. */
22638 is_store_insn1 (rtx pat)
22640 if (!pat || pat == NULL_RTX)
22643 if (GET_CODE (pat) == SET)
22644 return is_mem_ref (SET_DEST (pat));
22646 if (GET_CODE (pat) == PARALLEL)
22650 for (i = 0; i < XVECLEN (pat, 0); i++)
22651 if (is_store_insn1 (XVECEXP (pat, 0, i)))
22658 /* Determine if INSN stores to memory. */
22661 is_store_insn (rtx insn)
22663 if (!insn || !INSN_P (insn))
22666 return is_store_insn1 (PATTERN (insn));
22669 /* Return the dest of a store insn. */
22672 get_store_dest (rtx pat)
22674 gcc_assert (is_store_insn1 (pat));
22676 if (GET_CODE (pat) == SET)
22677 return SET_DEST (pat);
22678 else if (GET_CODE (pat) == PARALLEL)
22682 for (i = 0; i < XVECLEN (pat, 0); i++)
22684 rtx inner_pat = XVECEXP (pat, 0, i);
22685 if (GET_CODE (inner_pat) == SET
22686 && is_mem_ref (SET_DEST (inner_pat)))
22690 /* We shouldn't get here, because we should have either a simple
22691 store insn or a store with update which are covered above. */
22695 /* Returns whether the dependence between INSN and NEXT is considered
22696 costly by the given target. */
22699 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
22704 /* If the flag is not enabled - no dependence is considered costly;
22705 allow all dependent insns in the same group.
22706 This is the most aggressive option. */
22707 if (rs6000_sched_costly_dep == no_dep_costly)
22710 /* If the flag is set to 1 - a dependence is always considered costly;
22711 do not allow dependent instructions in the same group.
22712 This is the most conservative option. */
22713 if (rs6000_sched_costly_dep == all_deps_costly)
22716 insn = DEP_PRO (dep);
22717 next = DEP_CON (dep);
22719 if (rs6000_sched_costly_dep == store_to_load_dep_costly
22720 && is_load_insn (next)
22721 && is_store_insn (insn))
22722 /* Prevent load after store in the same group. */
22725 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
22726 && is_load_insn (next)
22727 && is_store_insn (insn)
22728 && DEP_TYPE (dep) == REG_DEP_TRUE)
22729 /* Prevent load after store in the same group if it is a true
22733 /* The flag is set to X; dependences with latency >= X are considered costly,
22734 and will not be scheduled in the same group. */
22735 if (rs6000_sched_costly_dep <= max_dep_latency
22736 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22742 /* Return the next insn after INSN that is found before TAIL is reached,
22743 skipping any "non-active" insns - insns that will not actually occupy
22744 an issue slot. Return NULL_RTX if such an insn is not found. */
22747 get_next_active_insn (rtx insn, rtx tail)
22749 if (insn == NULL_RTX || insn == tail)
22754 insn = NEXT_INSN (insn);
22755 if (insn == NULL_RTX || insn == tail)
22760 || (NONJUMP_INSN_P (insn)
22761 && GET_CODE (PATTERN (insn)) != USE
22762 && GET_CODE (PATTERN (insn)) != CLOBBER
22763 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22769 /* We are about to begin issuing insns for this clock cycle. */
22772 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22773 rtx *ready ATTRIBUTE_UNUSED,
22774 int *pn_ready ATTRIBUTE_UNUSED,
22775 int clock_var ATTRIBUTE_UNUSED)
22777 int n_ready = *pn_ready;
22780 fprintf (dump, "// rs6000_sched_reorder :\n");
22782 /* Reorder the ready list, if the second to last ready insn
22783 is a nonepipeline insn. */
22784 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22786 if (is_nonpipeline_insn (ready[n_ready - 1])
22787 && (recog_memoized (ready[n_ready - 2]) > 0))
22788 /* Simply swap first two insns. */
22790 rtx tmp = ready[n_ready - 1];
22791 ready[n_ready - 1] = ready[n_ready - 2];
22792 ready[n_ready - 2] = tmp;
22796 if (rs6000_cpu == PROCESSOR_POWER6)
22797 load_store_pendulum = 0;
22799 return rs6000_issue_rate ();
22802 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22805 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
22806 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
22809 fprintf (dump, "// rs6000_sched_reorder2 :\n");
22811 /* For Power6, we need to handle some special cases to try and keep the
22812 store queue from overflowing and triggering expensive flushes.
22814 This code monitors how load and store instructions are being issued
22815 and skews the ready list one way or the other to increase the likelihood
22816 that a desired instruction is issued at the proper time.
22818 A couple of things are done. First, we maintain a "load_store_pendulum"
22819 to track the current state of load/store issue.
22821 - If the pendulum is at zero, then no loads or stores have been
22822 issued in the current cycle so we do nothing.
22824 - If the pendulum is 1, then a single load has been issued in this
22825 cycle and we attempt to locate another load in the ready list to
22828 - If the pendulum is -2, then two stores have already been
22829 issued in this cycle, so we increase the priority of the first load
22830 in the ready list to increase it's likelihood of being chosen first
22833 - If the pendulum is -1, then a single store has been issued in this
22834 cycle and we attempt to locate another store in the ready list to
22835 issue with it, preferring a store to an adjacent memory location to
22836 facilitate store pairing in the store queue.
22838 - If the pendulum is 2, then two loads have already been
22839 issued in this cycle, so we increase the priority of the first store
22840 in the ready list to increase it's likelihood of being chosen first
22843 - If the pendulum < -2 or > 2, then do nothing.
22845 Note: This code covers the most common scenarios. There exist non
22846 load/store instructions which make use of the LSU and which
22847 would need to be accounted for to strictly model the behavior
22848 of the machine. Those instructions are currently unaccounted
22849 for to help minimize compile time overhead of this code.
22851 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
22857 if (is_store_insn (last_scheduled_insn))
22858 /* Issuing a store, swing the load_store_pendulum to the left */
22859 load_store_pendulum--;
22860 else if (is_load_insn (last_scheduled_insn))
22861 /* Issuing a load, swing the load_store_pendulum to the right */
22862 load_store_pendulum++;
22864 return cached_can_issue_more;
22866 /* If the pendulum is balanced, or there is only one instruction on
22867 the ready list, then all is well, so return. */
22868 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
22869 return cached_can_issue_more;
22871 if (load_store_pendulum == 1)
22873 /* A load has been issued in this cycle. Scan the ready list
22874 for another load to issue with it */
22879 if (is_load_insn (ready[pos]))
22881 /* Found a load. Move it to the head of the ready list,
22882 and adjust it's priority so that it is more likely to
22885 for (i=pos; i<*pn_ready-1; i++)
22886 ready[i] = ready[i + 1];
22887 ready[*pn_ready-1] = tmp;
22889 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22890 INSN_PRIORITY (tmp)++;
22896 else if (load_store_pendulum == -2)
22898 /* Two stores have been issued in this cycle. Increase the
22899 priority of the first load in the ready list to favor it for
22900 issuing in the next cycle. */
22905 if (is_load_insn (ready[pos])
22907 && INSN_PRIORITY_KNOWN (ready[pos]))
22909 INSN_PRIORITY (ready[pos])++;
22911 /* Adjust the pendulum to account for the fact that a load
22912 was found and increased in priority. This is to prevent
22913 increasing the priority of multiple loads */
22914 load_store_pendulum--;
22921 else if (load_store_pendulum == -1)
22923 /* A store has been issued in this cycle. Scan the ready list for
22924 another store to issue with it, preferring a store to an adjacent
22926 int first_store_pos = -1;
22932 if (is_store_insn (ready[pos]))
22934 /* Maintain the index of the first store found on the
22936 if (first_store_pos == -1)
22937 first_store_pos = pos;
22939 if (is_store_insn (last_scheduled_insn)
22940 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22942 /* Found an adjacent store. Move it to the head of the
22943 ready list, and adjust it's priority so that it is
22944 more likely to stay there */
22946 for (i=pos; i<*pn_ready-1; i++)
22947 ready[i] = ready[i + 1];
22948 ready[*pn_ready-1] = tmp;
22950 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22951 INSN_PRIORITY (tmp)++;
22953 first_store_pos = -1;
22961 if (first_store_pos >= 0)
22963 /* An adjacent store wasn't found, but a non-adjacent store was,
22964 so move the non-adjacent store to the front of the ready
22965 list, and adjust its priority so that it is more likely to
22967 tmp = ready[first_store_pos];
22968 for (i=first_store_pos; i<*pn_ready-1; i++)
22969 ready[i] = ready[i + 1];
22970 ready[*pn_ready-1] = tmp;
22971 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22972 INSN_PRIORITY (tmp)++;
22975 else if (load_store_pendulum == 2)
22977 /* Two loads have been issued in this cycle. Increase the priority
22978 of the first store in the ready list to favor it for issuing in
22984 if (is_store_insn (ready[pos])
22986 && INSN_PRIORITY_KNOWN (ready[pos]))
22988 INSN_PRIORITY (ready[pos])++;
22990 /* Adjust the pendulum to account for the fact that a store
22991 was found and increased in priority. This is to prevent
22992 increasing the priority of multiple stores */
22993 load_store_pendulum++;
23002 return cached_can_issue_more;
23005 /* Return whether the presence of INSN causes a dispatch group termination
23006 of group WHICH_GROUP.
23008 If WHICH_GROUP == current_group, this function will return true if INSN
23009 causes the termination of the current group (i.e, the dispatch group to
23010 which INSN belongs). This means that INSN will be the last insn in the
23011 group it belongs to.
23013 If WHICH_GROUP == previous_group, this function will return true if INSN
23014 causes the termination of the previous group (i.e, the dispatch group that
23015 precedes the group to which INSN belongs). This means that INSN will be
23016 the first insn in the group it belongs to). */
23019 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23026 first = insn_must_be_first_in_group (insn);
23027 last = insn_must_be_last_in_group (insn);
23032 if (which_group == current_group)
23034 else if (which_group == previous_group)
23042 insn_must_be_first_in_group (rtx insn)
23044 enum attr_type type;
23047 || GET_CODE (insn) == NOTE
23048 || DEBUG_INSN_P (insn)
23049 || GET_CODE (PATTERN (insn)) == USE
23050 || GET_CODE (PATTERN (insn)) == CLOBBER)
23053 switch (rs6000_cpu)
23055 case PROCESSOR_POWER5:
23056 if (is_cracked_insn (insn))
23058 case PROCESSOR_POWER4:
23059 if (is_microcoded_insn (insn))
23062 if (!rs6000_sched_groups)
23065 type = get_attr_type (insn);
23072 case TYPE_DELAYED_CR:
23073 case TYPE_CR_LOGICAL:
23087 case PROCESSOR_POWER6:
23088 type = get_attr_type (insn);
23092 case TYPE_INSERT_DWORD:
23096 case TYPE_VAR_SHIFT_ROTATE:
23103 case TYPE_INSERT_WORD:
23104 case TYPE_DELAYED_COMPARE:
23105 case TYPE_IMUL_COMPARE:
23106 case TYPE_LMUL_COMPARE:
23107 case TYPE_FPCOMPARE:
23118 case TYPE_LOAD_EXT_UX:
23120 case TYPE_STORE_UX:
23121 case TYPE_FPLOAD_U:
23122 case TYPE_FPLOAD_UX:
23123 case TYPE_FPSTORE_U:
23124 case TYPE_FPSTORE_UX:
23130 case PROCESSOR_POWER7:
23131 type = get_attr_type (insn);
23135 case TYPE_CR_LOGICAL:
23142 case TYPE_DELAYED_COMPARE:
23143 case TYPE_VAR_DELAYED_COMPARE:
23149 case TYPE_LOAD_EXT:
23150 case TYPE_LOAD_EXT_U:
23151 case TYPE_LOAD_EXT_UX:
23153 case TYPE_STORE_UX:
23154 case TYPE_FPLOAD_U:
23155 case TYPE_FPLOAD_UX:
23156 case TYPE_FPSTORE_U:
23157 case TYPE_FPSTORE_UX:
23173 insn_must_be_last_in_group (rtx insn)
23175 enum attr_type type;
23178 || GET_CODE (insn) == NOTE
23179 || DEBUG_INSN_P (insn)
23180 || GET_CODE (PATTERN (insn)) == USE
23181 || GET_CODE (PATTERN (insn)) == CLOBBER)
23184 switch (rs6000_cpu) {
23185 case PROCESSOR_POWER4:
23186 case PROCESSOR_POWER5:
23187 if (is_microcoded_insn (insn))
23190 if (is_branch_slot_insn (insn))
23194 case PROCESSOR_POWER6:
23195 type = get_attr_type (insn);
23202 case TYPE_VAR_SHIFT_ROTATE:
23209 case TYPE_DELAYED_COMPARE:
23210 case TYPE_IMUL_COMPARE:
23211 case TYPE_LMUL_COMPARE:
23212 case TYPE_FPCOMPARE:
23226 case PROCESSOR_POWER7:
23227 type = get_attr_type (insn);
23235 case TYPE_LOAD_EXT_U:
23236 case TYPE_LOAD_EXT_UX:
23237 case TYPE_STORE_UX:
23250 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
23251 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
23254 is_costly_group (rtx *group_insns, rtx next_insn)
23257 int issue_rate = rs6000_issue_rate ();
23259 for (i = 0; i < issue_rate; i++)
23261 sd_iterator_def sd_it;
23263 rtx insn = group_insns[i];
23268 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
23270 rtx next = DEP_CON (dep);
23272 if (next == next_insn
23273 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
23281 /* Utility of the function redefine_groups.
23282 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
23283 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
23284 to keep it "far" (in a separate group) from GROUP_INSNS, following
23285 one of the following schemes, depending on the value of the flag
23286 -minsert_sched_nops = X:
23287 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
23288 in order to force NEXT_INSN into a separate group.
23289 (2) X < sched_finish_regroup_exact: insert exactly X nops.
23290 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
23291 insertion (has a group just ended, how many vacant issue slots remain in the
23292 last group, and how many dispatch groups were encountered so far). */
23295 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
23296 rtx next_insn, bool *group_end, int can_issue_more,
23301 int issue_rate = rs6000_issue_rate ();
23302 bool end = *group_end;
23305 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
23306 return can_issue_more;
23308 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
23309 return can_issue_more;
23311 force = is_costly_group (group_insns, next_insn);
23313 return can_issue_more;
23315 if (sched_verbose > 6)
23316 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
23317 *group_count ,can_issue_more);
23319 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
23322 can_issue_more = 0;
23324 /* Since only a branch can be issued in the last issue_slot, it is
23325 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
23326 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
23327 in this case the last nop will start a new group and the branch
23328 will be forced to the new group. */
23329 if (can_issue_more && !is_branch_slot_insn (next_insn))
23332 while (can_issue_more > 0)
23335 emit_insn_before (nop, next_insn);
23343 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
23345 int n_nops = rs6000_sched_insert_nops;
23347 /* Nops can't be issued from the branch slot, so the effective
23348 issue_rate for nops is 'issue_rate - 1'. */
23349 if (can_issue_more == 0)
23350 can_issue_more = issue_rate;
23352 if (can_issue_more == 0)
23354 can_issue_more = issue_rate - 1;
23357 for (i = 0; i < issue_rate; i++)
23359 group_insns[i] = 0;
23366 emit_insn_before (nop, next_insn);
23367 if (can_issue_more == issue_rate - 1) /* new group begins */
23370 if (can_issue_more == 0)
23372 can_issue_more = issue_rate - 1;
23375 for (i = 0; i < issue_rate; i++)
23377 group_insns[i] = 0;
23383 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
23386 /* Is next_insn going to start a new group? */
23389 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23390 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23391 || (can_issue_more < issue_rate &&
23392 insn_terminates_group_p (next_insn, previous_group)));
23393 if (*group_end && end)
23396 if (sched_verbose > 6)
23397 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
23398 *group_count, can_issue_more);
23399 return can_issue_more;
23402 return can_issue_more;
23405 /* This function tries to synch the dispatch groups that the compiler "sees"
23406 with the dispatch groups that the processor dispatcher is expected to
23407 form in practice. It tries to achieve this synchronization by forcing the
23408 estimated processor grouping on the compiler (as opposed to the function
23409 'pad_goups' which tries to force the scheduler's grouping on the processor).
23411 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
23412 examines the (estimated) dispatch groups that will be formed by the processor
23413 dispatcher. It marks these group boundaries to reflect the estimated
23414 processor grouping, overriding the grouping that the scheduler had marked.
23415 Depending on the value of the flag '-minsert-sched-nops' this function can
23416 force certain insns into separate groups or force a certain distance between
23417 them by inserting nops, for example, if there exists a "costly dependence"
23420 The function estimates the group boundaries that the processor will form as
23421 follows: It keeps track of how many vacant issue slots are available after
23422 each insn. A subsequent insn will start a new group if one of the following
23424 - no more vacant issue slots remain in the current dispatch group.
23425 - only the last issue slot, which is the branch slot, is vacant, but the next
23426 insn is not a branch.
23427 - only the last 2 or less issue slots, including the branch slot, are vacant,
23428 which means that a cracked insn (which occupies two issue slots) can't be
23429 issued in this group.
23430 - less than 'issue_rate' slots are vacant, and the next insn always needs to
23431 start a new group. */
23434 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23436 rtx insn, next_insn;
23438 int can_issue_more;
23441 int group_count = 0;
23445 issue_rate = rs6000_issue_rate ();
23446 group_insns = XALLOCAVEC (rtx, issue_rate);
23447 for (i = 0; i < issue_rate; i++)
23449 group_insns[i] = 0;
23451 can_issue_more = issue_rate;
23453 insn = get_next_active_insn (prev_head_insn, tail);
23456 while (insn != NULL_RTX)
23458 slot = (issue_rate - can_issue_more);
23459 group_insns[slot] = insn;
23461 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23462 if (insn_terminates_group_p (insn, current_group))
23463 can_issue_more = 0;
23465 next_insn = get_next_active_insn (insn, tail);
23466 if (next_insn == NULL_RTX)
23467 return group_count + 1;
23469 /* Is next_insn going to start a new group? */
23471 = (can_issue_more == 0
23472 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23473 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23474 || (can_issue_more < issue_rate &&
23475 insn_terminates_group_p (next_insn, previous_group)));
23477 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
23478 next_insn, &group_end, can_issue_more,
23484 can_issue_more = 0;
23485 for (i = 0; i < issue_rate; i++)
23487 group_insns[i] = 0;
23491 if (GET_MODE (next_insn) == TImode && can_issue_more)
23492 PUT_MODE (next_insn, VOIDmode);
23493 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
23494 PUT_MODE (next_insn, TImode);
23497 if (can_issue_more == 0)
23498 can_issue_more = issue_rate;
23501 return group_count;
23504 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
23505 dispatch group boundaries that the scheduler had marked. Pad with nops
23506 any dispatch groups which have vacant issue slots, in order to force the
23507 scheduler's grouping on the processor dispatcher. The function
23508 returns the number of dispatch groups found. */
23511 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23513 rtx insn, next_insn;
23516 int can_issue_more;
23518 int group_count = 0;
23520 /* Initialize issue_rate. */
23521 issue_rate = rs6000_issue_rate ();
23522 can_issue_more = issue_rate;
23524 insn = get_next_active_insn (prev_head_insn, tail);
23525 next_insn = get_next_active_insn (insn, tail);
23527 while (insn != NULL_RTX)
23530 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23532 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
23534 if (next_insn == NULL_RTX)
23539 /* If the scheduler had marked group termination at this location
23540 (between insn and next_insn), and neither insn nor next_insn will
23541 force group termination, pad the group with nops to force group
23544 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
23545 && !insn_terminates_group_p (insn, current_group)
23546 && !insn_terminates_group_p (next_insn, previous_group))
23548 if (!is_branch_slot_insn (next_insn))
23551 while (can_issue_more)
23554 emit_insn_before (nop, next_insn);
23559 can_issue_more = issue_rate;
23564 next_insn = get_next_active_insn (insn, tail);
23567 return group_count;
23570 /* We're beginning a new block. Initialize data structures as necessary. */
23573 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
23574 int sched_verbose ATTRIBUTE_UNUSED,
23575 int max_ready ATTRIBUTE_UNUSED)
23577 last_scheduled_insn = NULL_RTX;
23578 load_store_pendulum = 0;
23581 /* The following function is called at the end of scheduling BB.
23582 After reload, it inserts nops at insn group bundling. */
23585 rs6000_sched_finish (FILE *dump, int sched_verbose)
23590 fprintf (dump, "=== Finishing schedule.\n");
23592 if (reload_completed && rs6000_sched_groups)
23594 /* Do not run sched_finish hook when selective scheduling enabled. */
23595 if (sel_sched_p ())
23598 if (rs6000_sched_insert_nops == sched_finish_none)
23601 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
23602 n_groups = pad_groups (dump, sched_verbose,
23603 current_sched_info->prev_head,
23604 current_sched_info->next_tail);
23606 n_groups = redefine_groups (dump, sched_verbose,
23607 current_sched_info->prev_head,
23608 current_sched_info->next_tail);
23610 if (sched_verbose >= 6)
23612 fprintf (dump, "ngroups = %d\n", n_groups);
23613 print_rtl (dump, current_sched_info->prev_head);
23614 fprintf (dump, "Done finish_sched\n");
23619 struct _rs6000_sched_context
23621 short cached_can_issue_more;
23622 rtx last_scheduled_insn;
23623 int load_store_pendulum;
23626 typedef struct _rs6000_sched_context rs6000_sched_context_def;
23627 typedef rs6000_sched_context_def *rs6000_sched_context_t;
23629 /* Allocate store for new scheduling context. */
23631 rs6000_alloc_sched_context (void)
23633 return xmalloc (sizeof (rs6000_sched_context_def));
23636 /* If CLEAN_P is true then initializes _SC with clean data,
23637 and from the global context otherwise. */
23639 rs6000_init_sched_context (void *_sc, bool clean_p)
23641 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23645 sc->cached_can_issue_more = 0;
23646 sc->last_scheduled_insn = NULL_RTX;
23647 sc->load_store_pendulum = 0;
23651 sc->cached_can_issue_more = cached_can_issue_more;
23652 sc->last_scheduled_insn = last_scheduled_insn;
23653 sc->load_store_pendulum = load_store_pendulum;
23657 /* Sets the global scheduling context to the one pointed to by _SC. */
23659 rs6000_set_sched_context (void *_sc)
23661 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23663 gcc_assert (sc != NULL);
23665 cached_can_issue_more = sc->cached_can_issue_more;
23666 last_scheduled_insn = sc->last_scheduled_insn;
23667 load_store_pendulum = sc->load_store_pendulum;
23672 rs6000_free_sched_context (void *_sc)
23674 gcc_assert (_sc != NULL);
23680 /* Length in units of the trampoline for entering a nested function. */
23683 rs6000_trampoline_size (void)
23687 switch (DEFAULT_ABI)
23690 gcc_unreachable ();
23693 ret = (TARGET_32BIT) ? 12 : 24;
23698 ret = (TARGET_32BIT) ? 40 : 48;
23705 /* Emit RTL insns to initialize the variable parts of a trampoline.
23706 FNADDR is an RTX for the address of the function's pure code.
23707 CXT is an RTX for the static chain value for the function. */
23710 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
23712 int regsize = (TARGET_32BIT) ? 4 : 8;
23713 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
23714 rtx ctx_reg = force_reg (Pmode, cxt);
23715 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
23717 switch (DEFAULT_ABI)
23720 gcc_unreachable ();
23722 /* Under AIX, just build the 3 word function descriptor */
23725 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
23726 rtx fn_reg = gen_reg_rtx (Pmode);
23727 rtx toc_reg = gen_reg_rtx (Pmode);
23729 /* Macro to shorten the code expansions below. */
23730 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23732 m_tramp = replace_equiv_address (m_tramp, addr);
23734 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
23735 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23736 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23737 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23738 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23744 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23747 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23748 LCT_NORMAL, VOIDmode, 4,
23750 GEN_INT (rs6000_trampoline_size ()), SImode,
23758 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
23759 identifier as an argument, so the front end shouldn't look it up. */
23762 rs6000_attribute_takes_identifier_p (const_tree attr_id)
23764 return is_attribute_p ("altivec", attr_id);
23767 /* Handle the "altivec" attribute. The attribute may have
23768 arguments as follows:
23770 __attribute__((altivec(vector__)))
23771 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23772 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23774 and may appear more than once (e.g., 'vector bool char') in a
23775 given declaration. */
23778 rs6000_handle_altivec_attribute (tree *node,
23779 tree name ATTRIBUTE_UNUSED,
23781 int flags ATTRIBUTE_UNUSED,
23782 bool *no_add_attrs)
23784 tree type = *node, result = NULL_TREE;
23785 enum machine_mode mode;
23788 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23789 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23790 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23793 while (POINTER_TYPE_P (type)
23794 || TREE_CODE (type) == FUNCTION_TYPE
23795 || TREE_CODE (type) == METHOD_TYPE
23796 || TREE_CODE (type) == ARRAY_TYPE)
23797 type = TREE_TYPE (type);
23799 mode = TYPE_MODE (type);
23801 /* Check for invalid AltiVec type qualifiers. */
23802 if (type == long_double_type_node)
23803 error ("use of %<long double%> in AltiVec types is invalid");
23804 else if (type == boolean_type_node)
23805 error ("use of boolean types in AltiVec types is invalid");
23806 else if (TREE_CODE (type) == COMPLEX_TYPE)
23807 error ("use of %<complex%> in AltiVec types is invalid");
23808 else if (DECIMAL_FLOAT_MODE_P (mode))
23809 error ("use of decimal floating point types in AltiVec types is invalid");
23810 else if (!TARGET_VSX)
23812 if (type == long_unsigned_type_node || type == long_integer_type_node)
23815 error ("use of %<long%> in AltiVec types is invalid for "
23816 "64-bit code without -mvsx");
23817 else if (rs6000_warn_altivec_long)
23818 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23821 else if (type == long_long_unsigned_type_node
23822 || type == long_long_integer_type_node)
23823 error ("use of %<long long%> in AltiVec types is invalid without "
23825 else if (type == double_type_node)
23826 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23829 switch (altivec_type)
23832 unsigned_p = TYPE_UNSIGNED (type);
23836 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
23839 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
23842 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
23845 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
23847 case SFmode: result = V4SF_type_node; break;
23848 case DFmode: result = V2DF_type_node; break;
23849 /* If the user says 'vector int bool', we may be handed the 'bool'
23850 attribute _before_ the 'vector' attribute, and so select the
23851 proper type in the 'b' case below. */
23852 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
23853 case V2DImode: case V2DFmode:
23861 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
23862 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
23863 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
23864 case QImode: case V16QImode: result = bool_V16QI_type_node;
23871 case V8HImode: result = pixel_V8HI_type_node;
23877 /* Propagate qualifiers attached to the element type
23878 onto the vector type. */
23879 if (result && result != type && TYPE_QUALS (type))
23880 result = build_qualified_type (result, TYPE_QUALS (type));
23882 *no_add_attrs = true; /* No need to hang on to the attribute. */
23885 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
23890 /* AltiVec defines four built-in scalar types that serve as vector
23891 elements; we must teach the compiler how to mangle them. */
23893 static const char *
23894 rs6000_mangle_type (const_tree type)
23896 type = TYPE_MAIN_VARIANT (type);
23898 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
23899 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
23902 if (type == bool_char_type_node) return "U6__boolc";
23903 if (type == bool_short_type_node) return "U6__bools";
23904 if (type == pixel_type_node) return "u7__pixel";
23905 if (type == bool_int_type_node) return "U6__booli";
23906 if (type == bool_long_type_node) return "U6__booll";
23908 /* Mangle IBM extended float long double as `g' (__float128) on
23909 powerpc*-linux where long-double-64 previously was the default. */
23910 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
23912 && TARGET_LONG_DOUBLE_128
23913 && !TARGET_IEEEQUAD)
23916 /* For all other types, use normal C++ mangling. */
23920 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23921 struct attribute_spec.handler. */
23924 rs6000_handle_longcall_attribute (tree *node, tree name,
23925 tree args ATTRIBUTE_UNUSED,
23926 int flags ATTRIBUTE_UNUSED,
23927 bool *no_add_attrs)
23929 if (TREE_CODE (*node) != FUNCTION_TYPE
23930 && TREE_CODE (*node) != FIELD_DECL
23931 && TREE_CODE (*node) != TYPE_DECL)
23933 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23935 *no_add_attrs = true;
23941 /* Set longcall attributes on all functions declared when
23942 rs6000_default_long_calls is true. */
23944 rs6000_set_default_type_attributes (tree type)
23946 if (rs6000_default_long_calls
23947 && (TREE_CODE (type) == FUNCTION_TYPE
23948 || TREE_CODE (type) == METHOD_TYPE))
23949 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23951 TYPE_ATTRIBUTES (type));
23954 darwin_set_default_type_attributes (type);
23958 /* Return a reference suitable for calling a function with the
23959 longcall attribute. */
23962 rs6000_longcall_ref (rtx call_ref)
23964 const char *call_name;
23967 if (GET_CODE (call_ref) != SYMBOL_REF)
23970 /* System V adds '.' to the internal name, so skip them. */
23971 call_name = XSTR (call_ref, 0);
23972 if (*call_name == '.')
23974 while (*call_name == '.')
23977 node = get_identifier (call_name);
23978 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
23981 return force_reg (Pmode, call_ref);
23984 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23985 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23988 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23989 struct attribute_spec.handler. */
23991 rs6000_handle_struct_attribute (tree *node, tree name,
23992 tree args ATTRIBUTE_UNUSED,
23993 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
23996 if (DECL_P (*node))
23998 if (TREE_CODE (*node) == TYPE_DECL)
23999 type = &TREE_TYPE (*node);
24004 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24005 || TREE_CODE (*type) == UNION_TYPE)))
24007 warning (OPT_Wattributes, "%qE attribute ignored", name);
24008 *no_add_attrs = true;
24011 else if ((is_attribute_p ("ms_struct", name)
24012 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24013 || ((is_attribute_p ("gcc_struct", name)
24014 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24016 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24018 *no_add_attrs = true;
24025 rs6000_ms_bitfield_layout_p (const_tree record_type)
24027 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24028 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24029 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24032 #ifdef USING_ELFOS_H
24034 /* A get_unnamed_section callback, used for switching to toc_section. */
24037 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24039 if (DEFAULT_ABI == ABI_AIX
24040 && TARGET_MINIMAL_TOC
24041 && !TARGET_RELOCATABLE)
24043 if (!toc_initialized)
24045 toc_initialized = 1;
24046 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24047 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24048 fprintf (asm_out_file, "\t.tc ");
24049 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24050 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24051 fprintf (asm_out_file, "\n");
24053 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24054 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24055 fprintf (asm_out_file, " = .+32768\n");
24058 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24060 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24061 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24064 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24065 if (!toc_initialized)
24067 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24068 fprintf (asm_out_file, " = .+32768\n");
24069 toc_initialized = 1;
24074 /* Implement TARGET_ASM_INIT_SECTIONS. */
24077 rs6000_elf_asm_init_sections (void)
24080 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24083 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24084 SDATA2_SECTION_ASM_OP);
24087 /* Implement TARGET_SELECT_RTX_SECTION. */
24090 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24091 unsigned HOST_WIDE_INT align)
24093 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24094 return toc_section;
24096 return default_elf_select_rtx_section (mode, x, align);
24099 /* For a SYMBOL_REF, set generic flags and then perform some
24100 target-specific processing.
24102 When the AIX ABI is requested on a non-AIX system, replace the
24103 function name with the real name (with a leading .) rather than the
24104 function descriptor name. This saves a lot of overriding code to
24105 read the prefixes. */
24108 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24110 default_encode_section_info (decl, rtl, first);
24113 && TREE_CODE (decl) == FUNCTION_DECL
24115 && DEFAULT_ABI == ABI_AIX)
24117 rtx sym_ref = XEXP (rtl, 0);
24118 size_t len = strlen (XSTR (sym_ref, 0));
24119 char *str = XALLOCAVEC (char, len + 2);
24121 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24122 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24127 compare_section_name (const char *section, const char *templ)
24131 len = strlen (templ);
24132 return (strncmp (section, templ, len) == 0
24133 && (section[len] == 0 || section[len] == '.'));
24137 rs6000_elf_in_small_data_p (const_tree decl)
24139 if (rs6000_sdata == SDATA_NONE)
24142 /* We want to merge strings, so we never consider them small data. */
24143 if (TREE_CODE (decl) == STRING_CST)
24146 /* Functions are never in the small data area. */
24147 if (TREE_CODE (decl) == FUNCTION_DECL)
24150 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24152 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24153 if (compare_section_name (section, ".sdata")
24154 || compare_section_name (section, ".sdata2")
24155 || compare_section_name (section, ".gnu.linkonce.s")
24156 || compare_section_name (section, ".sbss")
24157 || compare_section_name (section, ".sbss2")
24158 || compare_section_name (section, ".gnu.linkonce.sb")
24159 || strcmp (section, ".PPC.EMB.sdata0") == 0
24160 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24165 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24168 && (unsigned HOST_WIDE_INT) size <= g_switch_value
24169 /* If it's not public, and we're not going to reference it there,
24170 there's no need to put it in the small data section. */
24171 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24178 #endif /* USING_ELFOS_H */
24180 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24183 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24185 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24188 /* Return a REG that occurs in ADDR with coefficient 1.
24189 ADDR can be effectively incremented by incrementing REG.
24191 r0 is special and we must not select it as an address
24192 register by this routine since our caller will try to
24193 increment the returned register via an "la" instruction. */
24196 find_addr_reg (rtx addr)
24198 while (GET_CODE (addr) == PLUS)
24200 if (GET_CODE (XEXP (addr, 0)) == REG
24201 && REGNO (XEXP (addr, 0)) != 0)
24202 addr = XEXP (addr, 0);
24203 else if (GET_CODE (XEXP (addr, 1)) == REG
24204 && REGNO (XEXP (addr, 1)) != 0)
24205 addr = XEXP (addr, 1);
24206 else if (CONSTANT_P (XEXP (addr, 0)))
24207 addr = XEXP (addr, 1);
24208 else if (CONSTANT_P (XEXP (addr, 1)))
24209 addr = XEXP (addr, 0);
24211 gcc_unreachable ();
24213 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
24218 rs6000_fatal_bad_address (rtx op)
24220 fatal_insn ("bad address", op);
24225 static tree branch_island_list = 0;
24227 /* Remember to generate a branch island for far calls to the given
24231 add_compiler_branch_island (tree label_name, tree function_name,
24234 tree branch_island = build_tree_list (function_name, label_name);
24235 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
24236 TREE_CHAIN (branch_island) = branch_island_list;
24237 branch_island_list = branch_island;
24240 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
24241 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
24242 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
24243 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
24245 /* Generate far-jump branch islands for everything on the
24246 branch_island_list. Invoked immediately after the last instruction
24247 of the epilogue has been emitted; the branch-islands must be
24248 appended to, and contiguous with, the function body. Mach-O stubs
24249 are generated in machopic_output_stub(). */
24252 macho_branch_islands (void)
24255 tree branch_island;
24257 for (branch_island = branch_island_list;
24259 branch_island = TREE_CHAIN (branch_island))
24261 const char *label =
24262 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
24264 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
24265 char name_buf[512];
24266 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
24267 if (name[0] == '*' || name[0] == '&')
24268 strcpy (name_buf, name+1);
24272 strcpy (name_buf+1, name);
24274 strcpy (tmp_buf, "\n");
24275 strcat (tmp_buf, label);
24276 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24277 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24278 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
24279 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24282 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
24283 strcat (tmp_buf, label);
24284 strcat (tmp_buf, "_pic\n");
24285 strcat (tmp_buf, label);
24286 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
24288 strcat (tmp_buf, "\taddis r11,r11,ha16(");
24289 strcat (tmp_buf, name_buf);
24290 strcat (tmp_buf, " - ");
24291 strcat (tmp_buf, label);
24292 strcat (tmp_buf, "_pic)\n");
24294 strcat (tmp_buf, "\tmtlr r0\n");
24296 strcat (tmp_buf, "\taddi r12,r11,lo16(");
24297 strcat (tmp_buf, name_buf);
24298 strcat (tmp_buf, " - ");
24299 strcat (tmp_buf, label);
24300 strcat (tmp_buf, "_pic)\n");
24302 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
24306 strcat (tmp_buf, ":\nlis r12,hi16(");
24307 strcat (tmp_buf, name_buf);
24308 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
24309 strcat (tmp_buf, name_buf);
24310 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
24312 output_asm_insn (tmp_buf, 0);
24313 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24314 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24315 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
24316 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24319 branch_island_list = 0;
24322 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
24323 already there or not. */
24326 no_previous_def (tree function_name)
24328 tree branch_island;
24329 for (branch_island = branch_island_list;
24331 branch_island = TREE_CHAIN (branch_island))
24332 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
24337 /* GET_PREV_LABEL gets the label name from the previous definition of
24341 get_prev_label (tree function_name)
24343 tree branch_island;
24344 for (branch_island = branch_island_list;
24346 branch_island = TREE_CHAIN (branch_island))
24347 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
24348 return BRANCH_ISLAND_LABEL_NAME (branch_island);
24352 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
24353 #define DARWIN_LINKER_GENERATES_ISLANDS 0
24356 /* KEXTs still need branch islands. */
24357 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
24358 || flag_mkernel || flag_apple_kext)
24360 /* INSN is either a function call or a millicode call. It may have an
24361 unconditional jump in its delay slot.
24363 CALL_DEST is the routine we are calling. */
24366 output_call (rtx insn, rtx *operands, int dest_operand_number,
24367 int cookie_operand_number)
24369 static char buf[256];
24370 if (DARWIN_GENERATE_ISLANDS
24371 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
24372 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
24375 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
24377 if (no_previous_def (funname))
24379 rtx label_rtx = gen_label_rtx ();
24380 char *label_buf, temp_buf[256];
24381 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
24382 CODE_LABEL_NUMBER (label_rtx));
24383 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
24384 labelname = get_identifier (label_buf);
24385 add_compiler_branch_island (labelname, funname, insn_line (insn));
24388 labelname = get_prev_label (funname);
24390 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
24391 instruction will reach 'foo', otherwise link as 'bl L42'".
24392 "L42" should be a 'branch island', that will do a far jump to
24393 'foo'. Branch islands are generated in
24394 macho_branch_islands(). */
24395 sprintf (buf, "jbsr %%z%d,%.246s",
24396 dest_operand_number, IDENTIFIER_POINTER (labelname));
24399 sprintf (buf, "bl %%z%d", dest_operand_number);
24403 /* Generate PIC and indirect symbol stubs. */
24406 machopic_output_stub (FILE *file, const char *symb, const char *stub)
24408 unsigned int length;
24409 char *symbol_name, *lazy_ptr_name;
24410 char *local_label_0;
24411 static int label = 0;
24413 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
24414 symb = (*targetm.strip_name_encoding) (symb);
24417 length = strlen (symb);
24418 symbol_name = XALLOCAVEC (char, length + 32);
24419 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
24421 lazy_ptr_name = XALLOCAVEC (char, length + 32);
24422 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
24425 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
24427 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
24431 fprintf (file, "\t.align 5\n");
24433 fprintf (file, "%s:\n", stub);
24434 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24437 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
24438 sprintf (local_label_0, "\"L%011d$spb\"", label);
24440 fprintf (file, "\tmflr r0\n");
24441 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
24442 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
24443 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
24444 lazy_ptr_name, local_label_0);
24445 fprintf (file, "\tmtlr r0\n");
24446 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
24447 (TARGET_64BIT ? "ldu" : "lwzu"),
24448 lazy_ptr_name, local_label_0);
24449 fprintf (file, "\tmtctr r12\n");
24450 fprintf (file, "\tbctr\n");
24454 fprintf (file, "\t.align 4\n");
24456 fprintf (file, "%s:\n", stub);
24457 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24459 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
24460 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
24461 (TARGET_64BIT ? "ldu" : "lwzu"),
24463 fprintf (file, "\tmtctr r12\n");
24464 fprintf (file, "\tbctr\n");
24467 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
24468 fprintf (file, "%s:\n", lazy_ptr_name);
24469 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24470 fprintf (file, "%sdyld_stub_binding_helper\n",
24471 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
24474 /* Legitimize PIC addresses. If the address is already
24475 position-independent, we return ORIG. Newly generated
24476 position-independent addresses go into a reg. This is REG if non
24477 zero, otherwise we allocate register(s) as necessary. */
24479 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
24482 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
24487 if (reg == NULL && ! reload_in_progress && ! reload_completed)
24488 reg = gen_reg_rtx (Pmode);
24490 if (GET_CODE (orig) == CONST)
24494 if (GET_CODE (XEXP (orig, 0)) == PLUS
24495 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
24498 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
24500 /* Use a different reg for the intermediate value, as
24501 it will be marked UNCHANGING. */
24502 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
24503 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
24506 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
24509 if (GET_CODE (offset) == CONST_INT)
24511 if (SMALL_INT (offset))
24512 return plus_constant (base, INTVAL (offset));
24513 else if (! reload_in_progress && ! reload_completed)
24514 offset = force_reg (Pmode, offset);
24517 rtx mem = force_const_mem (Pmode, orig);
24518 return machopic_legitimize_pic_address (mem, Pmode, reg);
24521 return gen_rtx_PLUS (Pmode, base, offset);
24524 /* Fall back on generic machopic code. */
24525 return machopic_legitimize_pic_address (orig, mode, reg);
24528 /* Output a .machine directive for the Darwin assembler, and call
24529 the generic start_file routine. */
24532 rs6000_darwin_file_start (void)
24534 static const struct
24540 { "ppc64", "ppc64", MASK_64BIT },
24541 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
24542 { "power4", "ppc970", 0 },
24543 { "G5", "ppc970", 0 },
24544 { "7450", "ppc7450", 0 },
24545 { "7400", "ppc7400", MASK_ALTIVEC },
24546 { "G4", "ppc7400", 0 },
24547 { "750", "ppc750", 0 },
24548 { "740", "ppc750", 0 },
24549 { "G3", "ppc750", 0 },
24550 { "604e", "ppc604e", 0 },
24551 { "604", "ppc604", 0 },
24552 { "603e", "ppc603", 0 },
24553 { "603", "ppc603", 0 },
24554 { "601", "ppc601", 0 },
24555 { NULL, "ppc", 0 } };
24556 const char *cpu_id = "";
24559 rs6000_file_start ();
24560 darwin_file_start ();
24562 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
24563 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
24564 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
24565 && rs6000_select[i].string[0] != '\0')
24566 cpu_id = rs6000_select[i].string;
24568 /* Look through the mapping array. Pick the first name that either
24569 matches the argument, has a bit set in IF_SET that is also set
24570 in the target flags, or has a NULL name. */
24573 while (mapping[i].arg != NULL
24574 && strcmp (mapping[i].arg, cpu_id) != 0
24575 && (mapping[i].if_set & target_flags) == 0)
24578 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
24581 #endif /* TARGET_MACHO */
24585 rs6000_elf_reloc_rw_mask (void)
24589 else if (DEFAULT_ABI == ABI_AIX)
24595 /* Record an element in the table of global constructors. SYMBOL is
24596 a SYMBOL_REF of the function to be called; PRIORITY is a number
24597 between 0 and MAX_INIT_PRIORITY.
24599 This differs from default_named_section_asm_out_constructor in
24600 that we have special handling for -mrelocatable. */
24603 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
24605 const char *section = ".ctors";
24608 if (priority != DEFAULT_INIT_PRIORITY)
24610 sprintf (buf, ".ctors.%.5u",
24611 /* Invert the numbering so the linker puts us in the proper
24612 order; constructors are run from right to left, and the
24613 linker sorts in increasing order. */
24614 MAX_INIT_PRIORITY - priority);
24618 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24619 assemble_align (POINTER_SIZE);
24621 if (TARGET_RELOCATABLE)
24623 fputs ("\t.long (", asm_out_file);
24624 output_addr_const (asm_out_file, symbol);
24625 fputs (")@fixup\n", asm_out_file);
24628 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24632 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
24634 const char *section = ".dtors";
24637 if (priority != DEFAULT_INIT_PRIORITY)
24639 sprintf (buf, ".dtors.%.5u",
24640 /* Invert the numbering so the linker puts us in the proper
24641 order; constructors are run from right to left, and the
24642 linker sorts in increasing order. */
24643 MAX_INIT_PRIORITY - priority);
24647 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24648 assemble_align (POINTER_SIZE);
24650 if (TARGET_RELOCATABLE)
24652 fputs ("\t.long (", asm_out_file);
24653 output_addr_const (asm_out_file, symbol);
24654 fputs (")@fixup\n", asm_out_file);
24657 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24661 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
24665 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
24666 ASM_OUTPUT_LABEL (file, name);
24667 fputs (DOUBLE_INT_ASM_OP, file);
24668 rs6000_output_function_entry (file, name);
24669 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
24672 fputs ("\t.size\t", file);
24673 assemble_name (file, name);
24674 fputs (",24\n\t.type\t.", file);
24675 assemble_name (file, name);
24676 fputs (",@function\n", file);
24677 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
24679 fputs ("\t.globl\t.", file);
24680 assemble_name (file, name);
24685 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24686 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24687 rs6000_output_function_entry (file, name);
24688 fputs (":\n", file);
24692 if (TARGET_RELOCATABLE
24693 && !TARGET_SECURE_PLT
24694 && (get_pool_size () != 0 || crtl->profile)
24699 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
24701 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
24702 fprintf (file, "\t.long ");
24703 assemble_name (file, buf);
24705 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
24706 assemble_name (file, buf);
24710 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24711 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24713 if (DEFAULT_ABI == ABI_AIX)
24715 const char *desc_name, *orig_name;
24717 orig_name = (*targetm.strip_name_encoding) (name);
24718 desc_name = orig_name;
24719 while (*desc_name == '.')
24722 if (TREE_PUBLIC (decl))
24723 fprintf (file, "\t.globl %s\n", desc_name);
24725 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24726 fprintf (file, "%s:\n", desc_name);
24727 fprintf (file, "\t.long %s\n", orig_name);
24728 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
24729 if (DEFAULT_ABI == ABI_AIX)
24730 fputs ("\t.long 0\n", file);
24731 fprintf (file, "\t.previous\n");
24733 ASM_OUTPUT_LABEL (file, name);
24737 rs6000_elf_end_indicate_exec_stack (void)
24740 file_end_indicate_exec_stack ();
24746 rs6000_xcoff_asm_output_anchor (rtx symbol)
24750 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24751 SYMBOL_REF_BLOCK_OFFSET (symbol));
24752 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24756 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24758 fputs (GLOBAL_ASM_OP, stream);
24759 RS6000_OUTPUT_BASENAME (stream, name);
24760 putc ('\n', stream);
24763 /* A get_unnamed_decl callback, used for read-only sections. PTR
24764 points to the section string variable. */
24767 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24769 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24770 *(const char *const *) directive,
24771 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24774 /* Likewise for read-write sections. */
24777 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24779 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24780 *(const char *const *) directive,
24781 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24784 /* A get_unnamed_section callback, used for switching to toc_section. */
24787 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24789 if (TARGET_MINIMAL_TOC)
24791 /* toc_section is always selected at least once from
24792 rs6000_xcoff_file_start, so this is guaranteed to
24793 always be defined once and only once in each file. */
24794 if (!toc_initialized)
24796 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24797 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24798 toc_initialized = 1;
24800 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
24801 (TARGET_32BIT ? "" : ",3"));
24804 fputs ("\t.toc\n", asm_out_file);
24807 /* Implement TARGET_ASM_INIT_SECTIONS. */
24810 rs6000_xcoff_asm_init_sections (void)
24812 read_only_data_section
24813 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24814 &xcoff_read_only_section_name);
24816 private_data_section
24817 = get_unnamed_section (SECTION_WRITE,
24818 rs6000_xcoff_output_readwrite_section_asm_op,
24819 &xcoff_private_data_section_name);
24821 read_only_private_data_section
24822 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24823 &xcoff_private_data_section_name);
24826 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
24828 readonly_data_section = read_only_data_section;
24829 exception_section = data_section;
24833 rs6000_xcoff_reloc_rw_mask (void)
24839 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
24840 tree decl ATTRIBUTE_UNUSED)
24843 static const char * const suffix[3] = { "PR", "RO", "RW" };
24845 if (flags & SECTION_CODE)
24847 else if (flags & SECTION_WRITE)
24852 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
24853 (flags & SECTION_CODE) ? "." : "",
24854 name, suffix[smclass], flags & SECTION_ENTSIZE);
24858 rs6000_xcoff_select_section (tree decl, int reloc,
24859 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24861 if (decl_readonly_section (decl, reloc))
24863 if (TREE_PUBLIC (decl))
24864 return read_only_data_section;
24866 return read_only_private_data_section;
24870 if (TREE_PUBLIC (decl))
24871 return data_section;
24873 return private_data_section;
24878 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
24882 /* Use select_section for private and uninitialized data. */
24883 if (!TREE_PUBLIC (decl)
24884 || DECL_COMMON (decl)
24885 || DECL_INITIAL (decl) == NULL_TREE
24886 || DECL_INITIAL (decl) == error_mark_node
24887 || (flag_zero_initialized_in_bss
24888 && initializer_zerop (DECL_INITIAL (decl))))
24891 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
24892 name = (*targetm.strip_name_encoding) (name);
24893 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
24896 /* Select section for constant in constant pool.
24898 On RS/6000, all constants are in the private read-only data area.
24899 However, if this is being placed in the TOC it must be output as a
24903 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
24904 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24906 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24907 return toc_section;
24909 return read_only_private_data_section;
24912 /* Remove any trailing [DS] or the like from the symbol name. */
24914 static const char *
24915 rs6000_xcoff_strip_name_encoding (const char *name)
24920 len = strlen (name);
24921 if (name[len - 1] == ']')
24922 return ggc_alloc_string (name, len - 4);
24927 /* Section attributes. AIX is always PIC. */
24929 static unsigned int
24930 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24932 unsigned int align;
24933 unsigned int flags = default_section_type_flags (decl, name, reloc);
24935 /* Align to at least UNIT size. */
24936 if (flags & SECTION_CODE)
24937 align = MIN_UNITS_PER_WORD;
24939 /* Increase alignment of large objects if not already stricter. */
24940 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24941 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24942 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24944 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24947 /* Output at beginning of assembler file.
24949 Initialize the section names for the RS/6000 at this point.
24951 Specify filename, including full path, to assembler.
24953 We want to go into the TOC section so at least one .toc will be emitted.
24954 Also, in order to output proper .bs/.es pairs, we need at least one static
24955 [RW] section emitted.
24957 Finally, declare mcount when profiling to make the assembler happy. */
24960 rs6000_xcoff_file_start (void)
24962 rs6000_gen_section_name (&xcoff_bss_section_name,
24963 main_input_filename, ".bss_");
24964 rs6000_gen_section_name (&xcoff_private_data_section_name,
24965 main_input_filename, ".rw_");
24966 rs6000_gen_section_name (&xcoff_read_only_section_name,
24967 main_input_filename, ".ro_");
24969 fputs ("\t.file\t", asm_out_file);
24970 output_quoted_string (asm_out_file, main_input_filename);
24971 fputc ('\n', asm_out_file);
24972 if (write_symbols != NO_DEBUG)
24973 switch_to_section (private_data_section);
24974 switch_to_section (text_section);
24976 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
24977 rs6000_file_start ();
24980 /* Output at end of assembler file.
24981 On the RS/6000, referencing data should automatically pull in text. */
24984 rs6000_xcoff_file_end (void)
24986 switch_to_section (text_section);
24987 fputs ("_section_.text:\n", asm_out_file);
24988 switch_to_section (data_section);
24989 fputs (TARGET_32BIT
24990 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24993 #endif /* TARGET_XCOFF */
24995 /* Compute a (partial) cost for rtx X. Return true if the complete
24996 cost has been computed, and false if subexpressions should be
24997 scanned. In either case, *TOTAL contains the cost result. */
25000 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25003 enum machine_mode mode = GET_MODE (x);
25007 /* On the RS/6000, if it is valid in the insn, it is free. */
25009 if (((outer_code == SET
25010 || outer_code == PLUS
25011 || outer_code == MINUS)
25012 && (satisfies_constraint_I (x)
25013 || satisfies_constraint_L (x)))
25014 || (outer_code == AND
25015 && (satisfies_constraint_K (x)
25017 ? satisfies_constraint_L (x)
25018 : satisfies_constraint_J (x))
25019 || mask_operand (x, mode)
25021 && mask64_operand (x, DImode))))
25022 || ((outer_code == IOR || outer_code == XOR)
25023 && (satisfies_constraint_K (x)
25025 ? satisfies_constraint_L (x)
25026 : satisfies_constraint_J (x))))
25027 || outer_code == ASHIFT
25028 || outer_code == ASHIFTRT
25029 || outer_code == LSHIFTRT
25030 || outer_code == ROTATE
25031 || outer_code == ROTATERT
25032 || outer_code == ZERO_EXTRACT
25033 || (outer_code == MULT
25034 && satisfies_constraint_I (x))
25035 || ((outer_code == DIV || outer_code == UDIV
25036 || outer_code == MOD || outer_code == UMOD)
25037 && exact_log2 (INTVAL (x)) >= 0)
25038 || (outer_code == COMPARE
25039 && (satisfies_constraint_I (x)
25040 || satisfies_constraint_K (x)))
25041 || (outer_code == EQ
25042 && (satisfies_constraint_I (x)
25043 || satisfies_constraint_K (x)
25045 ? satisfies_constraint_L (x)
25046 : satisfies_constraint_J (x))))
25047 || (outer_code == GTU
25048 && satisfies_constraint_I (x))
25049 || (outer_code == LTU
25050 && satisfies_constraint_P (x)))
25055 else if ((outer_code == PLUS
25056 && reg_or_add_cint_operand (x, VOIDmode))
25057 || (outer_code == MINUS
25058 && reg_or_sub_cint_operand (x, VOIDmode))
25059 || ((outer_code == SET
25060 || outer_code == IOR
25061 || outer_code == XOR)
25063 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25065 *total = COSTS_N_INSNS (1);
25071 if (mode == DImode && code == CONST_DOUBLE)
25073 if ((outer_code == IOR || outer_code == XOR)
25074 && CONST_DOUBLE_HIGH (x) == 0
25075 && (CONST_DOUBLE_LOW (x)
25076 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25081 else if ((outer_code == AND && and64_2_operand (x, DImode))
25082 || ((outer_code == SET
25083 || outer_code == IOR
25084 || outer_code == XOR)
25085 && CONST_DOUBLE_HIGH (x) == 0))
25087 *total = COSTS_N_INSNS (1);
25097 /* When optimizing for size, MEM should be slightly more expensive
25098 than generating address, e.g., (plus (reg) (const)).
25099 L1 cache latency is about two instructions. */
25100 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25108 if (mode == DFmode)
25110 if (GET_CODE (XEXP (x, 0)) == MULT)
25112 /* FNMA accounted in outer NEG. */
25113 if (outer_code == NEG)
25114 *total = rs6000_cost->dmul - rs6000_cost->fp;
25116 *total = rs6000_cost->dmul;
25119 *total = rs6000_cost->fp;
25121 else if (mode == SFmode)
25123 /* FNMA accounted in outer NEG. */
25124 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25127 *total = rs6000_cost->fp;
25130 *total = COSTS_N_INSNS (1);
25134 if (mode == DFmode)
25136 if (GET_CODE (XEXP (x, 0)) == MULT
25137 || GET_CODE (XEXP (x, 1)) == MULT)
25139 /* FNMA accounted in outer NEG. */
25140 if (outer_code == NEG)
25141 *total = rs6000_cost->dmul - rs6000_cost->fp;
25143 *total = rs6000_cost->dmul;
25146 *total = rs6000_cost->fp;
25148 else if (mode == SFmode)
25150 /* FNMA accounted in outer NEG. */
25151 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25154 *total = rs6000_cost->fp;
25157 *total = COSTS_N_INSNS (1);
25161 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25162 && satisfies_constraint_I (XEXP (x, 1)))
25164 if (INTVAL (XEXP (x, 1)) >= -256
25165 && INTVAL (XEXP (x, 1)) <= 255)
25166 *total = rs6000_cost->mulsi_const9;
25168 *total = rs6000_cost->mulsi_const;
25170 /* FMA accounted in outer PLUS/MINUS. */
25171 else if ((mode == DFmode || mode == SFmode)
25172 && (outer_code == PLUS || outer_code == MINUS))
25174 else if (mode == DFmode)
25175 *total = rs6000_cost->dmul;
25176 else if (mode == SFmode)
25177 *total = rs6000_cost->fp;
25178 else if (mode == DImode)
25179 *total = rs6000_cost->muldi;
25181 *total = rs6000_cost->mulsi;
25186 if (FLOAT_MODE_P (mode))
25188 *total = mode == DFmode ? rs6000_cost->ddiv
25189 : rs6000_cost->sdiv;
25196 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25197 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25199 if (code == DIV || code == MOD)
25201 *total = COSTS_N_INSNS (2);
25204 *total = COSTS_N_INSNS (1);
25208 if (GET_MODE (XEXP (x, 1)) == DImode)
25209 *total = rs6000_cost->divdi;
25211 *total = rs6000_cost->divsi;
25213 /* Add in shift and subtract for MOD. */
25214 if (code == MOD || code == UMOD)
25215 *total += COSTS_N_INSNS (2);
25220 *total = COSTS_N_INSNS (4);
25224 *total = COSTS_N_INSNS (6);
25228 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
25240 *total = COSTS_N_INSNS (1);
25248 /* Handle mul_highpart. */
25249 if (outer_code == TRUNCATE
25250 && GET_CODE (XEXP (x, 0)) == MULT)
25252 if (mode == DImode)
25253 *total = rs6000_cost->muldi;
25255 *total = rs6000_cost->mulsi;
25258 else if (outer_code == AND)
25261 *total = COSTS_N_INSNS (1);
25266 if (GET_CODE (XEXP (x, 0)) == MEM)
25269 *total = COSTS_N_INSNS (1);
25275 if (!FLOAT_MODE_P (mode))
25277 *total = COSTS_N_INSNS (1);
25283 case UNSIGNED_FLOAT:
25286 case FLOAT_TRUNCATE:
25287 *total = rs6000_cost->fp;
25291 if (mode == DFmode)
25294 *total = rs6000_cost->fp;
25298 switch (XINT (x, 1))
25301 *total = rs6000_cost->fp;
25313 *total = COSTS_N_INSNS (1);
25316 else if (FLOAT_MODE_P (mode)
25317 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
25319 *total = rs6000_cost->fp;
25327 /* Carry bit requires mode == Pmode.
25328 NEG or PLUS already counted so only add one. */
25330 && (outer_code == NEG || outer_code == PLUS))
25332 *total = COSTS_N_INSNS (1);
25335 if (outer_code == SET)
25337 if (XEXP (x, 1) == const0_rtx)
25339 if (TARGET_ISEL && !TARGET_MFCRF)
25340 *total = COSTS_N_INSNS (8);
25342 *total = COSTS_N_INSNS (2);
25345 else if (mode == Pmode)
25347 *total = COSTS_N_INSNS (3);
25356 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
25358 if (TARGET_ISEL && !TARGET_MFCRF)
25359 *total = COSTS_N_INSNS (8);
25361 *total = COSTS_N_INSNS (2);
25365 if (outer_code == COMPARE)
25379 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
25382 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
25385 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
25388 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
25389 "total = %d, speed = %s, x:\n",
25390 ret ? "complete" : "scan inner",
25391 GET_RTX_NAME (code),
25392 GET_RTX_NAME (outer_code),
25394 speed ? "true" : "false");
25401 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
25404 rs6000_debug_address_cost (rtx x, bool speed)
25406 int ret = TARGET_ADDRESS_COST (x, speed);
25408 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
25409 ret, speed ? "true" : "false");
25416 /* A C expression returning the cost of moving data from a register of class
25417 CLASS1 to one of CLASS2. */
25420 rs6000_register_move_cost (enum machine_mode mode,
25421 enum reg_class from, enum reg_class to)
25425 /* Moves from/to GENERAL_REGS. */
25426 if (reg_classes_intersect_p (to, GENERAL_REGS)
25427 || reg_classes_intersect_p (from, GENERAL_REGS))
25429 if (! reg_classes_intersect_p (to, GENERAL_REGS))
25432 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
25433 ret = (rs6000_memory_move_cost (mode, from, 0)
25434 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
25436 /* It's more expensive to move CR_REGS than CR0_REGS because of the
25438 else if (from == CR_REGS)
25441 /* Power6 has slower LR/CTR moves so make them more expensive than
25442 memory in order to bias spills to memory .*/
25443 else if (rs6000_cpu == PROCESSOR_POWER6
25444 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
25445 ret = 6 * hard_regno_nregs[0][mode];
25448 /* A move will cost one instruction per GPR moved. */
25449 ret = 2 * hard_regno_nregs[0][mode];
25452 /* If we have VSX, we can easily move between FPR or Altivec registers. */
25453 else if (VECTOR_UNIT_VSX_P (mode)
25454 && reg_classes_intersect_p (to, VSX_REGS)
25455 && reg_classes_intersect_p (from, VSX_REGS))
25456 ret = 2 * hard_regno_nregs[32][mode];
25458 /* Moving between two similar registers is just one instruction. */
25459 else if (reg_classes_intersect_p (to, from))
25460 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
25462 /* Everything else has to go through GENERAL_REGS. */
25464 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
25465 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
25467 if (TARGET_DEBUG_COST)
25469 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
25470 ret, GET_MODE_NAME (mode), reg_class_names[from],
25471 reg_class_names[to]);
25476 /* A C expressions returning the cost of moving data of MODE from a register to
25480 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
25481 int in ATTRIBUTE_UNUSED)
25485 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
25486 ret = 4 * hard_regno_nregs[0][mode];
25487 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
25488 ret = 4 * hard_regno_nregs[32][mode];
25489 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
25490 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
25492 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
25494 if (TARGET_DEBUG_COST)
25496 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
25497 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
25502 /* Returns a code for a target-specific builtin that implements
25503 reciprocal of the function, or NULL_TREE if not available. */
25506 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
25507 bool sqrt ATTRIBUTE_UNUSED)
25509 if (optimize_insn_for_size_p ())
25515 case VSX_BUILTIN_XVSQRTDP:
25516 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
25519 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
25521 case VSX_BUILTIN_XVSQRTSP:
25522 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
25525 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
25534 case BUILT_IN_SQRT:
25535 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
25538 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
25540 case BUILT_IN_SQRTF:
25541 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
25544 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
25551 /* Load up a constant. If the mode is a vector mode, splat the value across
25552 all of the vector elements. */
25555 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
25559 if (mode == SFmode || mode == DFmode)
25561 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
25562 reg = force_reg (mode, d);
25564 else if (mode == V4SFmode)
25566 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
25567 rtvec v = gen_rtvec (4, d, d, d, d);
25568 reg = gen_reg_rtx (mode);
25569 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
25571 else if (mode == V2DFmode)
25573 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
25574 rtvec v = gen_rtvec (2, d, d);
25575 reg = gen_reg_rtx (mode);
25576 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
25579 gcc_unreachable ();
25584 /* Generate a FMADD instruction:
25585 dst = (m1 * m2) + a
25587 generating different RTL based on the fused multiply/add switch. */
25590 rs6000_emit_madd (rtx dst, rtx m1, rtx m2, rtx a)
25592 enum machine_mode mode = GET_MODE (dst);
25594 if (!TARGET_FUSED_MADD)
25596 /* For the simple ops, use the generator function, rather than assuming
25597 that the RTL is standard. */
25598 enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code;
25599 enum insn_code acode = optab_handler (add_optab, mode)->insn_code;
25600 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25601 gen_2arg_fn_t gen_add = (gen_2arg_fn_t) GEN_FCN (acode);
25602 rtx mreg = gen_reg_rtx (mode);
25604 gcc_assert (mcode != CODE_FOR_nothing && acode != CODE_FOR_nothing);
25605 emit_insn (gen_mul (mreg, m1, m2));
25606 emit_insn (gen_add (dst, mreg, a));
25610 emit_insn (gen_rtx_SET (VOIDmode, dst,
25611 gen_rtx_PLUS (mode,
25612 gen_rtx_MULT (mode, m1, m2),
25616 /* Generate a FMSUB instruction:
25617 dst = (m1 * m2) - a
25619 generating different RTL based on the fused multiply/add switch. */
25622 rs6000_emit_msub (rtx dst, rtx m1, rtx m2, rtx a)
25624 enum machine_mode mode = GET_MODE (dst);
25626 if (!TARGET_FUSED_MADD
25627 || (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (V4SFmode)))
25629 /* For the simple ops, use the generator function, rather than assuming
25630 that the RTL is standard. */
25631 enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code;
25632 enum insn_code scode = optab_handler (add_optab, mode)->insn_code;
25633 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25634 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
25635 rtx mreg = gen_reg_rtx (mode);
25637 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
25638 emit_insn (gen_mul (mreg, m1, m2));
25639 emit_insn (gen_sub (dst, mreg, a));
25643 emit_insn (gen_rtx_SET (VOIDmode, dst,
25644 gen_rtx_MINUS (mode,
25645 gen_rtx_MULT (mode, m1, m2),
25649 /* Generate a FNMSUB instruction:
25650 dst = - ((m1 * m2) - a)
25652 Which is equivalent to (except in the prescence of -0.0):
25653 dst = a - (m1 * m2)
25655 generating different RTL based on the fast-math and fused multiply/add
25659 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
25661 enum machine_mode mode = GET_MODE (dst);
25663 if (!TARGET_FUSED_MADD)
25665 /* For the simple ops, use the generator function, rather than assuming
25666 that the RTL is standard. */
25667 enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code;
25668 enum insn_code scode = optab_handler (sub_optab, mode)->insn_code;
25669 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25670 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
25671 rtx mreg = gen_reg_rtx (mode);
25673 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
25674 emit_insn (gen_mul (mreg, m1, m2));
25675 emit_insn (gen_sub (dst, a, mreg));
25680 rtx m = gen_rtx_MULT (mode, m1, m2);
25682 if (!HONOR_SIGNED_ZEROS (mode))
25683 emit_insn (gen_rtx_SET (VOIDmode, dst, gen_rtx_MINUS (mode, a, m)));
25686 emit_insn (gen_rtx_SET (VOIDmode, dst,
25688 gen_rtx_MINUS (mode, m, a))));
25692 /* Newton-Raphson approximation of floating point divide with just 2 passes
25693 (either single precision floating point, or newer machines with higher
25694 accuracy estimates). Support both scalar and vector divide. Assumes no
25695 trapping math and finite arguments. */
25698 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
25700 enum machine_mode mode = GET_MODE (dst);
25701 rtx x0, e0, e1, y1, u0, v0;
25702 enum insn_code code = optab_handler (smul_optab, mode)->insn_code;
25703 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25704 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
25706 gcc_assert (code != CODE_FOR_nothing);
25708 /* x0 = 1./d estimate */
25709 x0 = gen_reg_rtx (mode);
25710 emit_insn (gen_rtx_SET (VOIDmode, x0,
25711 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
25714 e0 = gen_reg_rtx (mode);
25715 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
25717 e1 = gen_reg_rtx (mode);
25718 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
25720 y1 = gen_reg_rtx (mode);
25721 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
25723 u0 = gen_reg_rtx (mode);
25724 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
25726 v0 = gen_reg_rtx (mode);
25727 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
25729 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
25732 /* Newton-Raphson approximation of floating point divide that has a low
25733 precision estimate. Assumes no trapping math and finite arguments. */
25736 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
25738 enum machine_mode mode = GET_MODE (dst);
25739 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
25740 enum insn_code code = optab_handler (smul_optab, mode)->insn_code;
25741 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25743 gcc_assert (code != CODE_FOR_nothing);
25745 one = rs6000_load_constant_and_splat (mode, dconst1);
25747 /* x0 = 1./d estimate */
25748 x0 = gen_reg_rtx (mode);
25749 emit_insn (gen_rtx_SET (VOIDmode, x0,
25750 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
25753 e0 = gen_reg_rtx (mode);
25754 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
25756 y1 = gen_reg_rtx (mode);
25757 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
25759 e1 = gen_reg_rtx (mode);
25760 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
25762 y2 = gen_reg_rtx (mode);
25763 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
25765 e2 = gen_reg_rtx (mode);
25766 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
25768 y3 = gen_reg_rtx (mode);
25769 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
25771 u0 = gen_reg_rtx (mode);
25772 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
25774 v0 = gen_reg_rtx (mode);
25775 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
25777 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
25780 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
25781 add a reg_note saying that this was a division. Support both scalar and
25782 vector divide. Assumes no trapping math and finite arguments. */
25785 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
25787 enum machine_mode mode = GET_MODE (dst);
25789 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
25790 rs6000_emit_swdiv_high_precision (dst, n, d);
25792 rs6000_emit_swdiv_low_precision (dst, n, d);
25795 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
25798 /* Newton-Raphson approximation of single/double-precision floating point
25799 rsqrt. Assumes no trapping math and finite arguments. */
25802 rs6000_emit_swrsqrt (rtx dst, rtx src)
25804 enum machine_mode mode = GET_MODE (src);
25805 rtx x0 = gen_reg_rtx (mode);
25806 rtx y = gen_reg_rtx (mode);
25807 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
25808 REAL_VALUE_TYPE dconst3_2;
25811 enum insn_code code = optab_handler (smul_optab, mode)->insn_code;
25812 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25814 gcc_assert (code != CODE_FOR_nothing);
25816 /* Load up the constant 1.5 either as a scalar, or as a vector. */
25817 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
25818 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
25820 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
25822 /* x0 = rsqrt estimate */
25823 emit_insn (gen_rtx_SET (VOIDmode, x0,
25824 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
25827 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
25828 rs6000_emit_msub (y, src, halfthree, src);
25830 for (i = 0; i < passes; i++)
25832 rtx x1 = gen_reg_rtx (mode);
25833 rtx u = gen_reg_rtx (mode);
25834 rtx v = gen_reg_rtx (mode);
25836 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
25837 emit_insn (gen_mul (u, x0, x0));
25838 rs6000_emit_nmsub (v, y, u, halfthree);
25839 emit_insn (gen_mul (x1, x0, v));
25843 emit_move_insn (dst, x0);
25847 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
25848 (Power7) targets. DST is the target, and SRC is the argument operand. */
25851 rs6000_emit_popcount (rtx dst, rtx src)
25853 enum machine_mode mode = GET_MODE (dst);
25856 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
25857 if (TARGET_POPCNTD)
25859 if (mode == SImode)
25860 emit_insn (gen_popcntwsi2 (dst, src));
25862 emit_insn (gen_popcntddi2 (dst, src));
25866 tmp1 = gen_reg_rtx (mode);
25868 if (mode == SImode)
25870 emit_insn (gen_popcntbsi2 (tmp1, src));
25871 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
25873 tmp2 = force_reg (SImode, tmp2);
25874 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
25878 emit_insn (gen_popcntbdi2 (tmp1, src));
25879 tmp2 = expand_mult (DImode, tmp1,
25880 GEN_INT ((HOST_WIDE_INT)
25881 0x01010101 << 32 | 0x01010101),
25883 tmp2 = force_reg (DImode, tmp2);
25884 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
25889 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25890 target, and SRC is the argument operand. */
25893 rs6000_emit_parity (rtx dst, rtx src)
25895 enum machine_mode mode = GET_MODE (dst);
25898 tmp = gen_reg_rtx (mode);
25899 if (mode == SImode)
25901 /* Is mult+shift >= shift+xor+shift+xor? */
25902 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
25904 rtx tmp1, tmp2, tmp3, tmp4;
25906 tmp1 = gen_reg_rtx (SImode);
25907 emit_insn (gen_popcntbsi2 (tmp1, src));
25909 tmp2 = gen_reg_rtx (SImode);
25910 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
25911 tmp3 = gen_reg_rtx (SImode);
25912 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
25914 tmp4 = gen_reg_rtx (SImode);
25915 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
25916 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
25919 rs6000_emit_popcount (tmp, src);
25920 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
25924 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25925 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
25927 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
25929 tmp1 = gen_reg_rtx (DImode);
25930 emit_insn (gen_popcntbdi2 (tmp1, src));
25932 tmp2 = gen_reg_rtx (DImode);
25933 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
25934 tmp3 = gen_reg_rtx (DImode);
25935 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
25937 tmp4 = gen_reg_rtx (DImode);
25938 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
25939 tmp5 = gen_reg_rtx (DImode);
25940 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
25942 tmp6 = gen_reg_rtx (DImode);
25943 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
25944 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
25947 rs6000_emit_popcount (tmp, src);
25948 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
25952 /* Return an RTX representing where to find the function value of a
25953 function returning MODE. */
25955 rs6000_complex_function_value (enum machine_mode mode)
25957 unsigned int regno;
25959 enum machine_mode inner = GET_MODE_INNER (mode);
25960 unsigned int inner_bytes = GET_MODE_SIZE (inner);
25962 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25963 regno = FP_ARG_RETURN;
25966 regno = GP_ARG_RETURN;
25968 /* 32-bit is OK since it'll go in r3/r4. */
25969 if (TARGET_32BIT && inner_bytes >= 4)
25970 return gen_rtx_REG (mode, regno);
25973 if (inner_bytes >= 8)
25974 return gen_rtx_REG (mode, regno);
25976 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
25978 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
25979 GEN_INT (inner_bytes));
25980 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
25983 /* Target hook for TARGET_FUNCTION_VALUE.
25985 On the SPE, both FPs and vectors are returned in r3.
25987 On RS/6000 an integer value is in r3 and a floating-point value is in
25988 fp1, unless -msoft-float. */
25991 rs6000_function_value (const_tree valtype,
25992 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
25993 bool outgoing ATTRIBUTE_UNUSED)
25995 enum machine_mode mode;
25996 unsigned int regno;
25998 /* Special handling for structs in darwin64. */
25999 if (rs6000_darwin64_abi
26000 && TYPE_MODE (valtype) == BLKmode
26001 && TREE_CODE (valtype) == RECORD_TYPE
26002 && int_size_in_bytes (valtype) > 0)
26004 CUMULATIVE_ARGS valcum;
26008 valcum.fregno = FP_ARG_MIN_REG;
26009 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26010 /* Do a trial code generation as if this were going to be passed as
26011 an argument; if any part goes in memory, we return NULL. */
26012 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
26015 /* Otherwise fall through to standard ABI rules. */
26018 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26020 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26021 return gen_rtx_PARALLEL (DImode,
26023 gen_rtx_EXPR_LIST (VOIDmode,
26024 gen_rtx_REG (SImode, GP_ARG_RETURN),
26026 gen_rtx_EXPR_LIST (VOIDmode,
26027 gen_rtx_REG (SImode,
26028 GP_ARG_RETURN + 1),
26031 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26033 return gen_rtx_PARALLEL (DCmode,
26035 gen_rtx_EXPR_LIST (VOIDmode,
26036 gen_rtx_REG (SImode, GP_ARG_RETURN),
26038 gen_rtx_EXPR_LIST (VOIDmode,
26039 gen_rtx_REG (SImode,
26040 GP_ARG_RETURN + 1),
26042 gen_rtx_EXPR_LIST (VOIDmode,
26043 gen_rtx_REG (SImode,
26044 GP_ARG_RETURN + 2),
26046 gen_rtx_EXPR_LIST (VOIDmode,
26047 gen_rtx_REG (SImode,
26048 GP_ARG_RETURN + 3),
26052 mode = TYPE_MODE (valtype);
26053 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26054 || POINTER_TYPE_P (valtype))
26055 mode = TARGET_32BIT ? SImode : DImode;
26057 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26058 /* _Decimal128 must use an even/odd register pair. */
26059 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26060 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26061 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26062 regno = FP_ARG_RETURN;
26063 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26064 && targetm.calls.split_complex_arg)
26065 return rs6000_complex_function_value (mode);
26066 else if (TREE_CODE (valtype) == VECTOR_TYPE
26067 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26068 && ALTIVEC_VECTOR_MODE (mode))
26069 regno = ALTIVEC_ARG_RETURN;
26070 else if (TREE_CODE (valtype) == VECTOR_TYPE
26071 && TARGET_VSX && TARGET_ALTIVEC_ABI
26072 && VSX_VECTOR_MODE (mode))
26073 regno = ALTIVEC_ARG_RETURN;
26074 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26075 && (mode == DFmode || mode == DCmode
26076 || mode == TFmode || mode == TCmode))
26077 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26079 regno = GP_ARG_RETURN;
26081 return gen_rtx_REG (mode, regno);
26084 /* Define how to find the value returned by a library function
26085 assuming the value has mode MODE. */
26087 rs6000_libcall_value (enum machine_mode mode)
26089 unsigned int regno;
26091 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26093 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26094 return gen_rtx_PARALLEL (DImode,
26096 gen_rtx_EXPR_LIST (VOIDmode,
26097 gen_rtx_REG (SImode, GP_ARG_RETURN),
26099 gen_rtx_EXPR_LIST (VOIDmode,
26100 gen_rtx_REG (SImode,
26101 GP_ARG_RETURN + 1),
26105 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26106 /* _Decimal128 must use an even/odd register pair. */
26107 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26108 else if (SCALAR_FLOAT_MODE_P (mode)
26109 && TARGET_HARD_FLOAT && TARGET_FPRS
26110 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26111 regno = FP_ARG_RETURN;
26112 else if (ALTIVEC_VECTOR_MODE (mode)
26113 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26114 regno = ALTIVEC_ARG_RETURN;
26115 else if (VSX_VECTOR_MODE (mode)
26116 && TARGET_VSX && TARGET_ALTIVEC_ABI)
26117 regno = ALTIVEC_ARG_RETURN;
26118 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26119 return rs6000_complex_function_value (mode);
26120 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26121 && (mode == DFmode || mode == DCmode
26122 || mode == TFmode || mode == TCmode))
26123 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26125 regno = GP_ARG_RETURN;
26127 return gen_rtx_REG (mode, regno);
26131 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26132 Frame pointer elimination is automatically handled.
26134 For the RS/6000, if frame pointer elimination is being done, we would like
26135 to convert ap into fp, not sp.
26137 We need r30 if -mminimal-toc was specified, and there are constant pool
26141 rs6000_can_eliminate (const int from, const int to)
26143 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26144 ? ! frame_pointer_needed
26145 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26146 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26150 /* Define the offset between two registers, FROM to be eliminated and its
26151 replacement TO, at the start of a routine. */
26153 rs6000_initial_elimination_offset (int from, int to)
26155 rs6000_stack_t *info = rs6000_stack_info ();
26156 HOST_WIDE_INT offset;
26158 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26159 offset = info->push_p ? 0 : -info->total_size;
26160 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26162 offset = info->push_p ? 0 : -info->total_size;
26163 if (FRAME_GROWS_DOWNWARD)
26164 offset += info->fixed_size + info->vars_size + info->parm_size;
26166 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26167 offset = FRAME_GROWS_DOWNWARD
26168 ? info->fixed_size + info->vars_size + info->parm_size
26170 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26171 offset = info->total_size;
26172 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26173 offset = info->push_p ? info->total_size : 0;
26174 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26177 gcc_unreachable ();
26183 rs6000_dwarf_register_span (rtx reg)
26187 unsigned regno = REGNO (reg);
26188 enum machine_mode mode = GET_MODE (reg);
26192 && (SPE_VECTOR_MODE (GET_MODE (reg))
26193 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26194 && mode != SFmode && mode != SDmode && mode != SCmode)))
26199 regno = REGNO (reg);
26201 /* The duality of the SPE register size wreaks all kinds of havoc.
26202 This is a way of distinguishing r0 in 32-bits from r0 in
26204 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26205 gcc_assert (words <= 4);
26206 for (i = 0; i < words; i++, regno++)
26208 if (BYTES_BIG_ENDIAN)
26210 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26211 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
26215 parts[2 * i] = gen_rtx_REG (SImode, regno);
26216 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
26220 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
26223 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26226 rs6000_init_dwarf_reg_sizes_extra (tree address)
26231 enum machine_mode mode = TYPE_MODE (char_type_node);
26232 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
26233 rtx mem = gen_rtx_MEM (BLKmode, addr);
26234 rtx value = gen_int_mode (4, mode);
26236 for (i = 1201; i < 1232; i++)
26238 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
26239 HOST_WIDE_INT offset
26240 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
26242 emit_move_insn (adjust_address (mem, mode, offset), value);
26247 /* Map internal gcc register numbers to DWARF2 register numbers. */
26250 rs6000_dbx_register_number (unsigned int regno)
26252 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
26254 if (regno == MQ_REGNO)
26256 if (regno == LR_REGNO)
26258 if (regno == CTR_REGNO)
26260 if (CR_REGNO_P (regno))
26261 return regno - CR0_REGNO + 86;
26262 if (regno == CA_REGNO)
26263 return 101; /* XER */
26264 if (ALTIVEC_REGNO_P (regno))
26265 return regno - FIRST_ALTIVEC_REGNO + 1124;
26266 if (regno == VRSAVE_REGNO)
26268 if (regno == VSCR_REGNO)
26270 if (regno == SPE_ACC_REGNO)
26272 if (regno == SPEFSCR_REGNO)
26274 /* SPE high reg number. We get these values of regno from
26275 rs6000_dwarf_register_span. */
26276 gcc_assert (regno >= 1200 && regno < 1232);
26280 /* target hook eh_return_filter_mode */
26281 static enum machine_mode
26282 rs6000_eh_return_filter_mode (void)
26284 return TARGET_32BIT ? SImode : word_mode;
26287 /* Target hook for scalar_mode_supported_p. */
26289 rs6000_scalar_mode_supported_p (enum machine_mode mode)
26291 if (DECIMAL_FLOAT_MODE_P (mode))
26292 return default_decimal_float_supported_p ();
26294 return default_scalar_mode_supported_p (mode);
26297 /* Target hook for vector_mode_supported_p. */
26299 rs6000_vector_mode_supported_p (enum machine_mode mode)
26302 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
26305 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
26308 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
26315 /* Target hook for invalid_arg_for_unprototyped_fn. */
26316 static const char *
26317 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
26319 return (!rs6000_darwin64_abi
26321 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
26322 && (funcdecl == NULL_TREE
26323 || (TREE_CODE (funcdecl) == FUNCTION_DECL
26324 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
26325 ? N_("AltiVec argument passed to unprototyped function")
26329 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
26330 setup by using __stack_chk_fail_local hidden function instead of
26331 calling __stack_chk_fail directly. Otherwise it is better to call
26332 __stack_chk_fail directly. */
26335 rs6000_stack_protect_fail (void)
26337 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
26338 ? default_hidden_stack_protect_fail ()
26339 : default_external_stack_protect_fail ();
26343 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
26344 int num_operands ATTRIBUTE_UNUSED)
26346 if (rs6000_warn_cell_microcode)
26349 int insn_code_number = recog_memoized (insn);
26350 location_t location = locator_location (INSN_LOCATOR (insn));
26352 /* Punt on insns we cannot recognize. */
26353 if (insn_code_number < 0)
26356 temp = get_insn_template (insn_code_number, insn);
26358 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
26359 warning_at (location, OPT_mwarn_cell_microcode,
26360 "emitting microcode insn %s\t[%s] #%d",
26361 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
26362 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
26363 warning_at (location, OPT_mwarn_cell_microcode,
26364 "emitting conditional microcode insn %s\t[%s] #%d",
26365 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
26369 #include "gt-rs6000.h"