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, "medium") == 0)
3657 cmodel = CMODEL_MEDIUM;
3658 else if (strcmp (arg, "large") == 0)
3659 cmodel = CMODEL_LARGE;
3662 error ("invalid option for -mcmodel: '%s'", arg);
3665 rs6000_explicit_options.cmodel = true;
3668 #ifdef TARGET_USES_AIX64_OPT
3673 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3674 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3675 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3678 #ifdef TARGET_USES_AIX64_OPT
3683 target_flags &= ~MASK_POWERPC64;
3684 target_flags_explicit |= MASK_POWERPC64;
3687 case OPT_minsert_sched_nops_:
3688 rs6000_sched_insert_nops_str = arg;
3691 case OPT_mminimal_toc:
3694 TARGET_NO_FP_IN_TOC = 0;
3695 TARGET_NO_SUM_IN_TOC = 0;
3702 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3703 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3710 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3711 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3715 case OPT_mpowerpc_gpopt:
3716 case OPT_mpowerpc_gfxopt:
3719 target_flags |= MASK_POWERPC;
3720 target_flags_explicit |= MASK_POWERPC;
3724 case OPT_maix_struct_return:
3725 case OPT_msvr4_struct_return:
3726 rs6000_explicit_options.aix_struct_ret = true;
3730 rs6000_explicit_options.vrsave = true;
3731 TARGET_ALTIVEC_VRSAVE = value;
3735 rs6000_explicit_options.vrsave = true;
3736 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3740 target_flags_explicit |= MASK_ISEL;
3742 rs6000_parse_yes_no_option ("isel", arg, &isel);
3744 target_flags |= MASK_ISEL;
3746 target_flags &= ~MASK_ISEL;
3750 rs6000_explicit_options.spe = true;
3755 rs6000_explicit_options.spe = true;
3756 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3760 rs6000_debug_name = arg;
3763 #ifdef TARGET_USES_SYSV4_OPT
3765 rs6000_abi_name = arg;
3769 rs6000_sdata_name = arg;
3772 case OPT_mtls_size_:
3773 rs6000_tls_size_string = arg;
3776 case OPT_mrelocatable:
3779 target_flags |= MASK_MINIMAL_TOC;
3780 target_flags_explicit |= MASK_MINIMAL_TOC;
3781 TARGET_NO_FP_IN_TOC = 1;
3785 case OPT_mrelocatable_lib:
3788 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3789 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3790 TARGET_NO_FP_IN_TOC = 1;
3794 target_flags &= ~MASK_RELOCATABLE;
3795 target_flags_explicit |= MASK_RELOCATABLE;
3801 if (!strcmp (arg, "altivec"))
3803 rs6000_explicit_options.altivec_abi = true;
3804 rs6000_altivec_abi = 1;
3806 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3809 else if (! strcmp (arg, "no-altivec"))
3811 rs6000_explicit_options.altivec_abi = true;
3812 rs6000_altivec_abi = 0;
3814 else if (! strcmp (arg, "spe"))
3816 rs6000_explicit_options.spe_abi = true;
3818 rs6000_altivec_abi = 0;
3819 if (!TARGET_SPE_ABI)
3820 error ("not configured for ABI: '%s'", arg);
3822 else if (! strcmp (arg, "no-spe"))
3824 rs6000_explicit_options.spe_abi = true;
3828 /* These are here for testing during development only, do not
3829 document in the manual please. */
3830 else if (! strcmp (arg, "d64"))
3832 rs6000_darwin64_abi = 1;
3833 warning (0, "Using darwin64 ABI");
3835 else if (! strcmp (arg, "d32"))
3837 rs6000_darwin64_abi = 0;
3838 warning (0, "Using old darwin ABI");
3841 else if (! strcmp (arg, "ibmlongdouble"))
3843 rs6000_explicit_options.ieee = true;
3844 rs6000_ieeequad = 0;
3845 warning (0, "Using IBM extended precision long double");
3847 else if (! strcmp (arg, "ieeelongdouble"))
3849 rs6000_explicit_options.ieee = true;
3850 rs6000_ieeequad = 1;
3851 warning (0, "Using IEEE extended precision long double");
3856 error ("unknown ABI specified: '%s'", arg);
3862 rs6000_select[1].string = arg;
3866 rs6000_select[2].string = arg;
3869 case OPT_mtraceback_:
3870 rs6000_traceback_name = arg;
3873 case OPT_mfloat_gprs_:
3874 rs6000_explicit_options.float_gprs = true;
3875 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3876 rs6000_float_gprs = 1;
3877 else if (! strcmp (arg, "double"))
3878 rs6000_float_gprs = 2;
3879 else if (! strcmp (arg, "no"))
3880 rs6000_float_gprs = 0;
3883 error ("invalid option for -mfloat-gprs: '%s'", arg);
3888 case OPT_mlong_double_:
3889 rs6000_explicit_options.long_double = true;
3890 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3891 if (value != 64 && value != 128)
3893 error ("Unknown switch -mlong-double-%s", arg);
3894 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3898 rs6000_long_double_type_size = value;
3901 case OPT_msched_costly_dep_:
3902 rs6000_sched_costly_dep_str = arg;
3906 rs6000_explicit_options.alignment = true;
3907 if (! strcmp (arg, "power"))
3909 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3910 some C library functions, so warn about it. The flag may be
3911 useful for performance studies from time to time though, so
3912 don't disable it entirely. */
3913 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3914 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3915 " it is incompatible with the installed C and C++ libraries");
3916 rs6000_alignment_flags = MASK_ALIGN_POWER;
3918 else if (! strcmp (arg, "natural"))
3919 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3922 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3927 case OPT_msingle_float:
3928 if (!TARGET_SINGLE_FPU)
3929 warning (0, "-msingle-float option equivalent to -mhard-float");
3930 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3931 rs6000_double_float = 0;
3932 target_flags &= ~MASK_SOFT_FLOAT;
3933 target_flags_explicit |= MASK_SOFT_FLOAT;
3936 case OPT_mdouble_float:
3937 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3938 rs6000_single_float = 1;
3939 target_flags &= ~MASK_SOFT_FLOAT;
3940 target_flags_explicit |= MASK_SOFT_FLOAT;
3943 case OPT_msimple_fpu:
3944 if (!TARGET_SINGLE_FPU)
3945 warning (0, "-msimple-fpu option ignored");
3948 case OPT_mhard_float:
3949 /* -mhard_float implies -msingle-float and -mdouble-float. */
3950 rs6000_single_float = rs6000_double_float = 1;
3953 case OPT_msoft_float:
3954 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3955 rs6000_single_float = rs6000_double_float = 0;
3959 fpu_type = rs6000_parse_fpu_option(arg);
3960 if (fpu_type != FPU_NONE)
3961 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3963 target_flags &= ~MASK_SOFT_FLOAT;
3964 target_flags_explicit |= MASK_SOFT_FLOAT;
3965 rs6000_xilinx_fpu = 1;
3966 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3967 rs6000_single_float = 1;
3968 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3969 rs6000_single_float = rs6000_double_float = 1;
3970 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3971 rs6000_simple_fpu = 1;
3975 /* -mfpu=none is equivalent to -msoft-float */
3976 target_flags |= MASK_SOFT_FLOAT;
3977 target_flags_explicit |= MASK_SOFT_FLOAT;
3978 rs6000_single_float = rs6000_double_float = 0;
3982 rs6000_recip_name = (value) ? "default" : "none";
3986 rs6000_recip_name = arg;
3992 /* Do anything needed at the start of the asm file. */
3995 rs6000_file_start (void)
3999 const char *start = buffer;
4000 struct rs6000_cpu_select *ptr;
4001 const char *default_cpu = TARGET_CPU_DEFAULT;
4002 FILE *file = asm_out_file;
4004 default_file_start ();
4006 #ifdef TARGET_BI_ARCH
4007 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4011 if (flag_verbose_asm)
4013 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4014 rs6000_select[0].string = default_cpu;
4016 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4018 ptr = &rs6000_select[i];
4019 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4021 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4026 if (PPC405_ERRATUM77)
4028 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4032 #ifdef USING_ELFOS_H
4033 switch (rs6000_sdata)
4035 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4036 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4037 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4038 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4041 if (rs6000_sdata && g_switch_value)
4043 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
4053 #ifdef HAVE_AS_GNU_ATTRIBUTE
4054 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
4056 fprintf (file, "\t.gnu_attribute 4, %d\n",
4057 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
4058 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
4060 fprintf (file, "\t.gnu_attribute 8, %d\n",
4061 (TARGET_ALTIVEC_ABI ? 2
4062 : TARGET_SPE_ABI ? 3
4064 fprintf (file, "\t.gnu_attribute 12, %d\n",
4065 aix_struct_return ? 2 : 1);
4070 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4072 switch_to_section (toc_section);
4073 switch_to_section (text_section);
4078 /* Return nonzero if this function is known to have a null epilogue. */
4081 direct_return (void)
4083 if (reload_completed)
4085 rs6000_stack_t *info = rs6000_stack_info ();
4087 if (info->first_gp_reg_save == 32
4088 && info->first_fp_reg_save == 64
4089 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4090 && ! info->lr_save_p
4091 && ! info->cr_save_p
4092 && info->vrsave_mask == 0
4100 /* Return the number of instructions it takes to form a constant in an
4101 integer register. */
4104 num_insns_constant_wide (HOST_WIDE_INT value)
4106 /* signed constant loadable with {cal|addi} */
4107 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4110 /* constant loadable with {cau|addis} */
4111 else if ((value & 0xffff) == 0
4112 && (value >> 31 == -1 || value >> 31 == 0))
4115 #if HOST_BITS_PER_WIDE_INT == 64
4116 else if (TARGET_POWERPC64)
4118 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4119 HOST_WIDE_INT high = value >> 31;
4121 if (high == 0 || high == -1)
4127 return num_insns_constant_wide (high) + 1;
4129 return num_insns_constant_wide (low) + 1;
4131 return (num_insns_constant_wide (high)
4132 + num_insns_constant_wide (low) + 1);
4141 num_insns_constant (rtx op, enum machine_mode mode)
4143 HOST_WIDE_INT low, high;
4145 switch (GET_CODE (op))
4148 #if HOST_BITS_PER_WIDE_INT == 64
4149 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4150 && mask64_operand (op, mode))
4154 return num_insns_constant_wide (INTVAL (op));
4157 if (mode == SFmode || mode == SDmode)
4162 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4163 if (DECIMAL_FLOAT_MODE_P (mode))
4164 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4166 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4167 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4170 if (mode == VOIDmode || mode == DImode)
4172 high = CONST_DOUBLE_HIGH (op);
4173 low = CONST_DOUBLE_LOW (op);
4180 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4181 if (DECIMAL_FLOAT_MODE_P (mode))
4182 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4184 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4185 high = l[WORDS_BIG_ENDIAN == 0];
4186 low = l[WORDS_BIG_ENDIAN != 0];
4190 return (num_insns_constant_wide (low)
4191 + num_insns_constant_wide (high));
4194 if ((high == 0 && low >= 0)
4195 || (high == -1 && low < 0))
4196 return num_insns_constant_wide (low);
4198 else if (mask64_operand (op, mode))
4202 return num_insns_constant_wide (high) + 1;
4205 return (num_insns_constant_wide (high)
4206 + num_insns_constant_wide (low) + 1);
4214 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4215 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4216 corresponding element of the vector, but for V4SFmode and V2SFmode,
4217 the corresponding "float" is interpreted as an SImode integer. */
4220 const_vector_elt_as_int (rtx op, unsigned int elt)
4222 rtx tmp = CONST_VECTOR_ELT (op, elt);
4223 if (GET_MODE (op) == V4SFmode
4224 || GET_MODE (op) == V2SFmode)
4225 tmp = gen_lowpart (SImode, tmp);
4226 return INTVAL (tmp);
4229 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4230 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4231 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4232 all items are set to the same value and contain COPIES replicas of the
4233 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4234 operand and the others are set to the value of the operand's msb. */
4237 vspltis_constant (rtx op, unsigned step, unsigned copies)
4239 enum machine_mode mode = GET_MODE (op);
4240 enum machine_mode inner = GET_MODE_INNER (mode);
4243 unsigned nunits = GET_MODE_NUNITS (mode);
4244 unsigned bitsize = GET_MODE_BITSIZE (inner);
4245 unsigned mask = GET_MODE_MASK (inner);
4247 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
4248 HOST_WIDE_INT splat_val = val;
4249 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
4251 /* Construct the value to be splatted, if possible. If not, return 0. */
4252 for (i = 2; i <= copies; i *= 2)
4254 HOST_WIDE_INT small_val;
4256 small_val = splat_val >> bitsize;
4258 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4260 splat_val = small_val;
4263 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4264 if (EASY_VECTOR_15 (splat_val))
4267 /* Also check if we can splat, and then add the result to itself. Do so if
4268 the value is positive, of if the splat instruction is using OP's mode;
4269 for splat_val < 0, the splat and the add should use the same mode. */
4270 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4271 && (splat_val >= 0 || (step == 1 && copies == 1)))
4274 /* Also check if are loading up the most significant bit which can be done by
4275 loading up -1 and shifting the value left by -1. */
4276 else if (EASY_VECTOR_MSB (splat_val, inner))
4282 /* Check if VAL is present in every STEP-th element, and the
4283 other elements are filled with its most significant bit. */
4284 for (i = 0; i < nunits - 1; ++i)
4286 HOST_WIDE_INT desired_val;
4287 if (((i + 1) & (step - 1)) == 0)
4290 desired_val = msb_val;
4292 if (desired_val != const_vector_elt_as_int (op, i))
4300 /* Return true if OP is of the given MODE and can be synthesized
4301 with a vspltisb, vspltish or vspltisw. */
4304 easy_altivec_constant (rtx op, enum machine_mode mode)
4306 unsigned step, copies;
4308 if (mode == VOIDmode)
4309 mode = GET_MODE (op);
4310 else if (mode != GET_MODE (op))
4313 /* Start with a vspltisw. */
4314 step = GET_MODE_NUNITS (mode) / 4;
4317 if (vspltis_constant (op, step, copies))
4320 /* Then try with a vspltish. */
4326 if (vspltis_constant (op, step, copies))
4329 /* And finally a vspltisb. */
4335 if (vspltis_constant (op, step, copies))
4341 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4342 result is OP. Abort if it is not possible. */
4345 gen_easy_altivec_constant (rtx op)
4347 enum machine_mode mode = GET_MODE (op);
4348 int nunits = GET_MODE_NUNITS (mode);
4349 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4350 unsigned step = nunits / 4;
4351 unsigned copies = 1;
4353 /* Start with a vspltisw. */
4354 if (vspltis_constant (op, step, copies))
4355 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4357 /* Then try with a vspltish. */
4363 if (vspltis_constant (op, step, copies))
4364 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4366 /* And finally a vspltisb. */
4372 if (vspltis_constant (op, step, copies))
4373 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4379 output_vec_const_move (rtx *operands)
4382 enum machine_mode mode;
4387 mode = GET_MODE (dest);
4389 if (TARGET_VSX && zero_constant (vec, mode))
4390 return "xxlxor %x0,%x0,%x0";
4395 if (zero_constant (vec, mode))
4396 return "vxor %0,%0,%0";
4398 splat_vec = gen_easy_altivec_constant (vec);
4399 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4400 operands[1] = XEXP (splat_vec, 0);
4401 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4404 switch (GET_MODE (splat_vec))
4407 return "vspltisw %0,%1";
4410 return "vspltish %0,%1";
4413 return "vspltisb %0,%1";
4420 gcc_assert (TARGET_SPE);
4422 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4423 pattern of V1DI, V4HI, and V2SF.
4425 FIXME: We should probably return # and add post reload
4426 splitters for these, but this way is so easy ;-). */
4427 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4428 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4429 operands[1] = CONST_VECTOR_ELT (vec, 0);
4430 operands[2] = CONST_VECTOR_ELT (vec, 1);
4432 return "li %0,%1\n\tevmergelo %0,%0,%0";
4434 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4437 /* Initialize TARGET of vector PAIRED to VALS. */
4440 paired_expand_vector_init (rtx target, rtx vals)
4442 enum machine_mode mode = GET_MODE (target);
4443 int n_elts = GET_MODE_NUNITS (mode);
4445 rtx x, new_rtx, tmp, constant_op, op1, op2;
4448 for (i = 0; i < n_elts; ++i)
4450 x = XVECEXP (vals, 0, i);
4451 if (!CONSTANT_P (x))
4456 /* Load from constant pool. */
4457 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4463 /* The vector is initialized only with non-constants. */
4464 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4465 XVECEXP (vals, 0, 1));
4467 emit_move_insn (target, new_rtx);
4471 /* One field is non-constant and the other one is a constant. Load the
4472 constant from the constant pool and use ps_merge instruction to
4473 construct the whole vector. */
4474 op1 = XVECEXP (vals, 0, 0);
4475 op2 = XVECEXP (vals, 0, 1);
4477 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4479 tmp = gen_reg_rtx (GET_MODE (constant_op));
4480 emit_move_insn (tmp, constant_op);
4482 if (CONSTANT_P (op1))
4483 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4485 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4487 emit_move_insn (target, new_rtx);
4491 paired_expand_vector_move (rtx operands[])
4493 rtx op0 = operands[0], op1 = operands[1];
4495 emit_move_insn (op0, op1);
4498 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4499 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4500 operands for the relation operation COND. This is a recursive
4504 paired_emit_vector_compare (enum rtx_code rcode,
4505 rtx dest, rtx op0, rtx op1,
4506 rtx cc_op0, rtx cc_op1)
4508 rtx tmp = gen_reg_rtx (V2SFmode);
4511 gcc_assert (TARGET_PAIRED_FLOAT);
4512 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4518 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4522 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4523 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4527 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4530 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4533 tmp1 = gen_reg_rtx (V2SFmode);
4534 max = gen_reg_rtx (V2SFmode);
4535 min = gen_reg_rtx (V2SFmode);
4536 gen_reg_rtx (V2SFmode);
4538 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4539 emit_insn (gen_selv2sf4
4540 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4541 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4542 emit_insn (gen_selv2sf4
4543 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4544 emit_insn (gen_subv2sf3 (tmp1, min, max));
4545 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4548 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4551 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4554 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4557 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4560 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4569 /* Emit vector conditional expression.
4570 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4571 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4574 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4575 rtx cond, rtx cc_op0, rtx cc_op1)
4577 enum rtx_code rcode = GET_CODE (cond);
4579 if (!TARGET_PAIRED_FLOAT)
4582 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4587 /* Initialize vector TARGET to VALS. */
4590 rs6000_expand_vector_init (rtx target, rtx vals)
4592 enum machine_mode mode = GET_MODE (target);
4593 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4594 int n_elts = GET_MODE_NUNITS (mode);
4595 int n_var = 0, one_var = -1;
4596 bool all_same = true, all_const_zero = true;
4600 for (i = 0; i < n_elts; ++i)
4602 x = XVECEXP (vals, 0, i);
4603 if (!CONSTANT_P (x))
4604 ++n_var, one_var = i;
4605 else if (x != CONST0_RTX (inner_mode))
4606 all_const_zero = false;
4608 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4614 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4615 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4616 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4618 /* Zero register. */
4619 emit_insn (gen_rtx_SET (VOIDmode, target,
4620 gen_rtx_XOR (mode, target, target)));
4623 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4625 /* Splat immediate. */
4626 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4631 /* Load from constant pool. */
4632 emit_move_insn (target, const_vec);
4637 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4638 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4642 rtx element = XVECEXP (vals, 0, 0);
4643 if (mode == V2DFmode)
4644 emit_insn (gen_vsx_splat_v2df (target, element));
4646 emit_insn (gen_vsx_splat_v2di (target, element));
4650 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4651 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4652 if (mode == V2DFmode)
4653 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4655 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4660 /* With single precision floating point on VSX, know that internally single
4661 precision is actually represented as a double, and either make 2 V2DF
4662 vectors, and convert these vectors to single precision, or do one
4663 conversion, and splat the result to the other elements. */
4664 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4668 rtx freg = gen_reg_rtx (V4SFmode);
4669 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4671 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4672 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4676 rtx dbl_even = gen_reg_rtx (V2DFmode);
4677 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4678 rtx flt_even = gen_reg_rtx (V4SFmode);
4679 rtx flt_odd = gen_reg_rtx (V4SFmode);
4681 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4682 copy_to_reg (XVECEXP (vals, 0, 0)),
4683 copy_to_reg (XVECEXP (vals, 0, 1))));
4684 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4685 copy_to_reg (XVECEXP (vals, 0, 2)),
4686 copy_to_reg (XVECEXP (vals, 0, 3))));
4687 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4688 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4689 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4694 /* Store value to stack temp. Load vector element. Splat. However, splat
4695 of 64-bit items is not supported on Altivec. */
4696 if (all_same && GET_MODE_SIZE (mode) <= 4)
4698 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4699 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4700 XVECEXP (vals, 0, 0));
4701 x = gen_rtx_UNSPEC (VOIDmode,
4702 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4703 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4705 gen_rtx_SET (VOIDmode,
4708 x = gen_rtx_VEC_SELECT (inner_mode, target,
4709 gen_rtx_PARALLEL (VOIDmode,
4710 gen_rtvec (1, const0_rtx)));
4711 emit_insn (gen_rtx_SET (VOIDmode, target,
4712 gen_rtx_VEC_DUPLICATE (mode, x)));
4716 /* One field is non-constant. Load constant then overwrite
4720 rtx copy = copy_rtx (vals);
4722 /* Load constant part of vector, substitute neighboring value for
4724 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4725 rs6000_expand_vector_init (target, copy);
4727 /* Insert variable. */
4728 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4732 /* Construct the vector in memory one field at a time
4733 and load the whole vector. */
4734 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4735 for (i = 0; i < n_elts; i++)
4736 emit_move_insn (adjust_address_nv (mem, inner_mode,
4737 i * GET_MODE_SIZE (inner_mode)),
4738 XVECEXP (vals, 0, i));
4739 emit_move_insn (target, mem);
4742 /* Set field ELT of TARGET to VAL. */
4745 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4747 enum machine_mode mode = GET_MODE (target);
4748 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4749 rtx reg = gen_reg_rtx (mode);
4751 int width = GET_MODE_SIZE (inner_mode);
4754 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4756 rtx (*set_func) (rtx, rtx, rtx, rtx)
4757 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4758 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4762 /* Load single variable value. */
4763 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4764 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4765 x = gen_rtx_UNSPEC (VOIDmode,
4766 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4767 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4769 gen_rtx_SET (VOIDmode,
4773 /* Linear sequence. */
4774 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4775 for (i = 0; i < 16; ++i)
4776 XVECEXP (mask, 0, i) = GEN_INT (i);
4778 /* Set permute mask to insert element into target. */
4779 for (i = 0; i < width; ++i)
4780 XVECEXP (mask, 0, elt*width + i)
4781 = GEN_INT (i + 0x10);
4782 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4783 x = gen_rtx_UNSPEC (mode,
4784 gen_rtvec (3, target, reg,
4785 force_reg (V16QImode, x)),
4787 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4790 /* Extract field ELT from VEC into TARGET. */
4793 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4795 enum machine_mode mode = GET_MODE (vec);
4796 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4799 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4801 rtx (*extract_func) (rtx, rtx, rtx)
4802 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4803 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4807 /* Allocate mode-sized buffer. */
4808 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4810 /* Add offset to field within buffer matching vector element. */
4811 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4813 /* Store single field into mode-sized buffer. */
4814 x = gen_rtx_UNSPEC (VOIDmode,
4815 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4816 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4818 gen_rtx_SET (VOIDmode,
4821 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4824 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4825 implement ANDing by the mask IN. */
4827 build_mask64_2_operands (rtx in, rtx *out)
4829 #if HOST_BITS_PER_WIDE_INT >= 64
4830 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4833 gcc_assert (GET_CODE (in) == CONST_INT);
4838 /* Assume c initially something like 0x00fff000000fffff. The idea
4839 is to rotate the word so that the middle ^^^^^^ group of zeros
4840 is at the MS end and can be cleared with an rldicl mask. We then
4841 rotate back and clear off the MS ^^ group of zeros with a
4843 c = ~c; /* c == 0xff000ffffff00000 */
4844 lsb = c & -c; /* lsb == 0x0000000000100000 */
4845 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4846 c = ~c; /* c == 0x00fff000000fffff */
4847 c &= -lsb; /* c == 0x00fff00000000000 */
4848 lsb = c & -c; /* lsb == 0x0000100000000000 */
4849 c = ~c; /* c == 0xff000fffffffffff */
4850 c &= -lsb; /* c == 0xff00000000000000 */
4852 while ((lsb >>= 1) != 0)
4853 shift++; /* shift == 44 on exit from loop */
4854 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4855 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4856 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4860 /* Assume c initially something like 0xff000f0000000000. The idea
4861 is to rotate the word so that the ^^^ middle group of zeros
4862 is at the LS end and can be cleared with an rldicr mask. We then
4863 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4865 lsb = c & -c; /* lsb == 0x0000010000000000 */
4866 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4867 c = ~c; /* c == 0x00fff0ffffffffff */
4868 c &= -lsb; /* c == 0x00fff00000000000 */
4869 lsb = c & -c; /* lsb == 0x0000100000000000 */
4870 c = ~c; /* c == 0xff000fffffffffff */
4871 c &= -lsb; /* c == 0xff00000000000000 */
4873 while ((lsb >>= 1) != 0)
4874 shift++; /* shift == 44 on exit from loop */
4875 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4876 m1 >>= shift; /* m1 == 0x0000000000000fff */
4877 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4880 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4881 masks will be all 1's. We are guaranteed more than one transition. */
4882 out[0] = GEN_INT (64 - shift);
4883 out[1] = GEN_INT (m1);
4884 out[2] = GEN_INT (shift);
4885 out[3] = GEN_INT (m2);
4893 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4896 invalid_e500_subreg (rtx op, enum machine_mode mode)
4898 if (TARGET_E500_DOUBLE)
4900 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4901 subreg:TI and reg:TF. Decimal float modes are like integer
4902 modes (only low part of each register used) for this
4904 if (GET_CODE (op) == SUBREG
4905 && (mode == SImode || mode == DImode || mode == TImode
4906 || mode == DDmode || mode == TDmode)
4907 && REG_P (SUBREG_REG (op))
4908 && (GET_MODE (SUBREG_REG (op)) == DFmode
4909 || GET_MODE (SUBREG_REG (op)) == TFmode))
4912 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4914 if (GET_CODE (op) == SUBREG
4915 && (mode == DFmode || mode == TFmode)
4916 && REG_P (SUBREG_REG (op))
4917 && (GET_MODE (SUBREG_REG (op)) == DImode
4918 || GET_MODE (SUBREG_REG (op)) == TImode
4919 || GET_MODE (SUBREG_REG (op)) == DDmode
4920 || GET_MODE (SUBREG_REG (op)) == TDmode))
4925 && GET_CODE (op) == SUBREG
4927 && REG_P (SUBREG_REG (op))
4928 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4934 /* AIX increases natural record alignment to doubleword if the first
4935 field is an FP double while the FP fields remain word aligned. */
4938 rs6000_special_round_type_align (tree type, unsigned int computed,
4939 unsigned int specified)
4941 unsigned int align = MAX (computed, specified);
4942 tree field = TYPE_FIELDS (type);
4944 /* Skip all non field decls */
4945 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4946 field = TREE_CHAIN (field);
4948 if (field != NULL && field != type)
4950 type = TREE_TYPE (field);
4951 while (TREE_CODE (type) == ARRAY_TYPE)
4952 type = TREE_TYPE (type);
4954 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4955 align = MAX (align, 64);
4961 /* Darwin increases record alignment to the natural alignment of
4965 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4966 unsigned int specified)
4968 unsigned int align = MAX (computed, specified);
4970 if (TYPE_PACKED (type))
4973 /* Find the first field, looking down into aggregates. */
4975 tree field = TYPE_FIELDS (type);
4976 /* Skip all non field decls */
4977 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4978 field = TREE_CHAIN (field);
4981 /* A packed field does not contribute any extra alignment. */
4982 if (DECL_PACKED (field))
4984 type = TREE_TYPE (field);
4985 while (TREE_CODE (type) == ARRAY_TYPE)
4986 type = TREE_TYPE (type);
4987 } while (AGGREGATE_TYPE_P (type));
4989 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
4990 align = MAX (align, TYPE_ALIGN (type));
4995 /* Return 1 for an operand in small memory on V.4/eabi. */
4998 small_data_operand (rtx op ATTRIBUTE_UNUSED,
4999 enum machine_mode mode ATTRIBUTE_UNUSED)
5004 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5007 if (DEFAULT_ABI != ABI_V4)
5010 /* Vector and float memory instructions have a limited offset on the
5011 SPE, so using a vector or float variable directly as an operand is
5014 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5017 if (GET_CODE (op) == SYMBOL_REF)
5020 else if (GET_CODE (op) != CONST
5021 || GET_CODE (XEXP (op, 0)) != PLUS
5022 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5023 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5028 rtx sum = XEXP (op, 0);
5029 HOST_WIDE_INT summand;
5031 /* We have to be careful here, because it is the referenced address
5032 that must be 32k from _SDA_BASE_, not just the symbol. */
5033 summand = INTVAL (XEXP (sum, 1));
5034 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
5037 sym_ref = XEXP (sum, 0);
5040 return SYMBOL_REF_SMALL_P (sym_ref);
5046 /* Return true if either operand is a general purpose register. */
5049 gpr_or_gpr_p (rtx op0, rtx op1)
5051 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5052 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5056 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5059 reg_offset_addressing_ok_p (enum machine_mode mode)
5069 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5070 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5078 /* Paired vector modes. Only reg+reg addressing is valid. */
5079 if (TARGET_PAIRED_FLOAT)
5091 virtual_stack_registers_memory_p (rtx op)
5095 if (GET_CODE (op) == REG)
5096 regnum = REGNO (op);
5098 else if (GET_CODE (op) == PLUS
5099 && GET_CODE (XEXP (op, 0)) == REG
5100 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5101 regnum = REGNO (XEXP (op, 0));
5106 return (regnum >= FIRST_VIRTUAL_REGISTER
5107 && regnum <= LAST_VIRTUAL_REGISTER);
5111 constant_pool_expr_p (rtx op)
5115 split_const (op, &base, &offset);
5116 return (GET_CODE (base) == SYMBOL_REF
5117 && CONSTANT_POOL_ADDRESS_P (base)
5118 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5121 static rtx tocrel_base, tocrel_offset;
5124 toc_relative_expr_p (rtx op)
5126 if (GET_CODE (op) != CONST)
5129 split_const (op, &tocrel_base, &tocrel_offset);
5130 return (GET_CODE (tocrel_base) == UNSPEC
5131 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5135 legitimate_constant_pool_address_p (const_rtx x, bool strict)
5138 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5139 && GET_CODE (XEXP (x, 0)) == REG
5140 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5141 || ((TARGET_MINIMAL_TOC
5142 || TARGET_CMODEL != CMODEL_SMALL)
5143 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5144 && toc_relative_expr_p (XEXP (x, 1)));
5148 legitimate_small_data_p (enum machine_mode mode, rtx x)
5150 return (DEFAULT_ABI == ABI_V4
5151 && !flag_pic && !TARGET_TOC
5152 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5153 && small_data_operand (x, mode));
5156 /* SPE offset addressing is limited to 5-bits worth of double words. */
5157 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5160 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5162 unsigned HOST_WIDE_INT offset, extra;
5164 if (GET_CODE (x) != PLUS)
5166 if (GET_CODE (XEXP (x, 0)) != REG)
5168 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5170 if (!reg_offset_addressing_ok_p (mode))
5171 return virtual_stack_registers_memory_p (x);
5172 if (legitimate_constant_pool_address_p (x, strict))
5174 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5177 offset = INTVAL (XEXP (x, 1));
5185 /* SPE vector modes. */
5186 return SPE_CONST_OFFSET_OK (offset);
5189 if (TARGET_E500_DOUBLE)
5190 return SPE_CONST_OFFSET_OK (offset);
5192 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5194 if (VECTOR_MEM_VSX_P (DFmode))
5199 /* On e500v2, we may have:
5201 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5203 Which gets addressed with evldd instructions. */
5204 if (TARGET_E500_DOUBLE)
5205 return SPE_CONST_OFFSET_OK (offset);
5207 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5209 else if (offset & 3)
5214 if (TARGET_E500_DOUBLE)
5215 return (SPE_CONST_OFFSET_OK (offset)
5216 && SPE_CONST_OFFSET_OK (offset + 8));
5220 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5222 else if (offset & 3)
5233 return (offset < 0x10000) && (offset + extra < 0x10000);
5237 legitimate_indexed_address_p (rtx x, int strict)
5241 if (GET_CODE (x) != PLUS)
5247 /* Recognize the rtl generated by reload which we know will later be
5248 replaced with proper base and index regs. */
5250 && reload_in_progress
5251 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5255 return (REG_P (op0) && REG_P (op1)
5256 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5257 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5258 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5259 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5263 avoiding_indexed_address_p (enum machine_mode mode)
5265 /* Avoid indexed addressing for modes that have non-indexed
5266 load/store instruction forms. */
5267 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5271 legitimate_indirect_address_p (rtx x, int strict)
5273 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5277 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5279 if (!TARGET_MACHO || !flag_pic
5280 || mode != SImode || GET_CODE (x) != MEM)
5284 if (GET_CODE (x) != LO_SUM)
5286 if (GET_CODE (XEXP (x, 0)) != REG)
5288 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5292 return CONSTANT_P (x);
5296 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5298 if (GET_CODE (x) != LO_SUM)
5300 if (GET_CODE (XEXP (x, 0)) != REG)
5302 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5304 /* Restrict addressing for DI because of our SUBREG hackery. */
5305 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5306 || mode == DDmode || mode == TDmode
5311 if (TARGET_ELF || TARGET_MACHO)
5313 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5317 if (GET_MODE_NUNITS (mode) != 1)
5319 if (GET_MODE_BITSIZE (mode) > 64
5320 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5321 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5322 && (mode == DFmode || mode == DDmode))))
5325 return CONSTANT_P (x);
5332 /* Try machine-dependent ways of modifying an illegitimate address
5333 to be legitimate. If we find one, return the new, valid address.
5334 This is used from only one place: `memory_address' in explow.c.
5336 OLDX is the address as it was before break_out_memory_refs was
5337 called. In some cases it is useful to look at this to decide what
5340 It is always safe for this function to do nothing. It exists to
5341 recognize opportunities to optimize the output.
5343 On RS/6000, first check for the sum of a register with a constant
5344 integer that is out of range. If so, generate code to add the
5345 constant with the low-order 16 bits masked to the register and force
5346 this result into another register (this can be done with `cau').
5347 Then generate an address of REG+(CONST&0xffff), allowing for the
5348 possibility of bit 16 being a one.
5350 Then check for the sum of a register and something not constant, try to
5351 load the other things into a register and return the sum. */
5354 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5355 enum machine_mode mode)
5357 unsigned int extra = 0;
5359 if (!reg_offset_addressing_ok_p (mode))
5361 if (virtual_stack_registers_memory_p (x))
5364 /* In theory we should not be seeing addresses of the form reg+0,
5365 but just in case it is generated, optimize it away. */
5366 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5367 return force_reg (Pmode, XEXP (x, 0));
5369 /* Make sure both operands are registers. */
5370 else if (GET_CODE (x) == PLUS)
5371 return gen_rtx_PLUS (Pmode,
5372 force_reg (Pmode, XEXP (x, 0)),
5373 force_reg (Pmode, XEXP (x, 1)));
5375 return force_reg (Pmode, x);
5377 if (GET_CODE (x) == SYMBOL_REF)
5379 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5381 return rs6000_legitimize_tls_address (x, model);
5391 if (!TARGET_POWERPC64)
5399 extra = TARGET_POWERPC64 ? 8 : 12;
5405 if (GET_CODE (x) == PLUS
5406 && GET_CODE (XEXP (x, 0)) == REG
5407 && GET_CODE (XEXP (x, 1)) == CONST_INT
5408 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5410 && !((TARGET_POWERPC64
5411 && (mode == DImode || mode == TImode)
5412 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5413 || SPE_VECTOR_MODE (mode)
5414 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5415 || mode == DImode || mode == DDmode
5416 || mode == TDmode))))
5418 HOST_WIDE_INT high_int, low_int;
5420 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5421 if (low_int >= 0x8000 - extra)
5423 high_int = INTVAL (XEXP (x, 1)) - low_int;
5424 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5425 GEN_INT (high_int)), 0);
5426 return plus_constant (sum, low_int);
5428 else if (GET_CODE (x) == PLUS
5429 && GET_CODE (XEXP (x, 0)) == REG
5430 && GET_CODE (XEXP (x, 1)) != CONST_INT
5431 && GET_MODE_NUNITS (mode) == 1
5432 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5434 || ((mode != DImode && mode != DFmode && mode != DDmode)
5435 || (TARGET_E500_DOUBLE && mode != DDmode)))
5436 && (TARGET_POWERPC64 || mode != DImode)
5437 && !avoiding_indexed_address_p (mode)
5442 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5443 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5445 else if (SPE_VECTOR_MODE (mode)
5446 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5447 || mode == DDmode || mode == TDmode
5448 || mode == DImode)))
5452 /* We accept [reg + reg] and [reg + OFFSET]. */
5454 if (GET_CODE (x) == PLUS)
5456 rtx op1 = XEXP (x, 0);
5457 rtx op2 = XEXP (x, 1);
5460 op1 = force_reg (Pmode, op1);
5462 if (GET_CODE (op2) != REG
5463 && (GET_CODE (op2) != CONST_INT
5464 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5465 || (GET_MODE_SIZE (mode) > 8
5466 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5467 op2 = force_reg (Pmode, op2);
5469 /* We can't always do [reg + reg] for these, because [reg +
5470 reg + offset] is not a legitimate addressing mode. */
5471 y = gen_rtx_PLUS (Pmode, op1, op2);
5473 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5474 return force_reg (Pmode, y);
5479 return force_reg (Pmode, x);
5485 && GET_CODE (x) != CONST_INT
5486 && GET_CODE (x) != CONST_DOUBLE
5488 && GET_MODE_NUNITS (mode) == 1
5489 && (GET_MODE_BITSIZE (mode) <= 32
5490 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5491 && (mode == DFmode || mode == DDmode))))
5493 rtx reg = gen_reg_rtx (Pmode);
5494 emit_insn (gen_elf_high (reg, x));
5495 return gen_rtx_LO_SUM (Pmode, reg, x);
5497 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5500 && ! MACHO_DYNAMIC_NO_PIC_P
5502 && GET_CODE (x) != CONST_INT
5503 && GET_CODE (x) != CONST_DOUBLE
5505 && GET_MODE_NUNITS (mode) == 1
5506 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5507 || (mode != DFmode && mode != DDmode))
5511 rtx reg = gen_reg_rtx (Pmode);
5512 emit_insn (gen_macho_high (reg, x));
5513 return gen_rtx_LO_SUM (Pmode, reg, x);
5516 && GET_CODE (x) == SYMBOL_REF
5517 && constant_pool_expr_p (x)
5518 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5520 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5521 return create_TOC_reference (x, reg);
5527 /* Debug version of rs6000_legitimize_address. */
5529 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5535 ret = rs6000_legitimize_address (x, oldx, mode);
5536 insns = get_insns ();
5542 "\nrs6000_legitimize_address: mode %s, old code %s, "
5543 "new code %s, modified\n",
5544 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5545 GET_RTX_NAME (GET_CODE (ret)));
5547 fprintf (stderr, "Original address:\n");
5550 fprintf (stderr, "oldx:\n");
5553 fprintf (stderr, "New address:\n");
5558 fprintf (stderr, "Insns added:\n");
5559 debug_rtx_list (insns, 20);
5565 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5566 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5577 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5578 We need to emit DTP-relative relocations. */
5581 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5586 fputs ("\t.long\t", file);
5589 fputs (DOUBLE_INT_ASM_OP, file);
5594 output_addr_const (file, x);
5595 fputs ("@dtprel+0x8000", file);
5598 /* In the name of slightly smaller debug output, and to cater to
5599 general assembler lossage, recognize various UNSPEC sequences
5600 and turn them back into a direct symbol reference. */
5603 rs6000_delegitimize_address (rtx orig_x)
5607 orig_x = delegitimize_mem_from_attrs (orig_x);
5612 if ((GET_CODE (x) == PLUS
5613 || GET_CODE (x) == LO_SUM)
5614 && GET_CODE (XEXP (x, 0)) == REG
5615 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5616 || TARGET_MINIMAL_TOC
5617 || TARGET_CMODEL != CMODEL_SMALL)
5618 && GET_CODE (XEXP (x, 1)) == CONST)
5620 y = XEXP (XEXP (x, 1), 0);
5621 if (GET_CODE (y) == UNSPEC
5622 && XINT (y, 1) == UNSPEC_TOCREL)
5624 y = XVECEXP (y, 0, 0);
5625 if (!MEM_P (orig_x))
5628 return replace_equiv_address_nv (orig_x, y);
5633 && GET_CODE (orig_x) == LO_SUM
5634 && GET_CODE (XEXP (x, 1)) == CONST)
5636 y = XEXP (XEXP (x, 1), 0);
5637 if (GET_CODE (y) == UNSPEC
5638 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5639 return XVECEXP (y, 0, 0);
5645 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5647 static GTY(()) rtx rs6000_tls_symbol;
5649 rs6000_tls_get_addr (void)
5651 if (!rs6000_tls_symbol)
5652 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5654 return rs6000_tls_symbol;
5657 /* Construct the SYMBOL_REF for TLS GOT references. */
5659 static GTY(()) rtx rs6000_got_symbol;
5661 rs6000_got_sym (void)
5663 if (!rs6000_got_symbol)
5665 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5666 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5667 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5670 return rs6000_got_symbol;
5673 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5674 this (thread-local) address. */
5677 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5681 dest = gen_reg_rtx (Pmode);
5682 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5688 tlsreg = gen_rtx_REG (Pmode, 13);
5689 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5693 tlsreg = gen_rtx_REG (Pmode, 2);
5694 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5698 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5702 tmp = gen_reg_rtx (Pmode);
5705 tlsreg = gen_rtx_REG (Pmode, 13);
5706 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5710 tlsreg = gen_rtx_REG (Pmode, 2);
5711 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5715 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5717 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5722 rtx r3, got, tga, tmp1, tmp2, call_insn;
5724 /* We currently use relocations like @got@tlsgd for tls, which
5725 means the linker will handle allocation of tls entries, placing
5726 them in the .got section. So use a pointer to the .got section,
5727 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5728 or to secondary GOT sections used by 32-bit -fPIC. */
5730 got = gen_rtx_REG (Pmode, 2);
5734 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5737 rtx gsym = rs6000_got_sym ();
5738 got = gen_reg_rtx (Pmode);
5740 rs6000_emit_move (got, gsym, Pmode);
5745 tmp1 = gen_reg_rtx (Pmode);
5746 tmp2 = gen_reg_rtx (Pmode);
5747 mem = gen_const_mem (Pmode, tmp1);
5748 lab = gen_label_rtx ();
5749 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
5750 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
5751 emit_move_insn (tmp2, mem);
5752 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
5753 set_unique_reg_note (last, REG_EQUAL, gsym);
5758 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5760 r3 = gen_rtx_REG (Pmode, 3);
5761 tga = rs6000_tls_get_addr ();
5762 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
5764 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5765 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5766 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5767 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5768 else if (DEFAULT_ABI == ABI_V4)
5769 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5772 call_insn = last_call_insn ();
5773 PATTERN (call_insn) = insn;
5774 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5775 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5776 pic_offset_table_rtx);
5778 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5780 r3 = gen_rtx_REG (Pmode, 3);
5781 tga = rs6000_tls_get_addr ();
5782 tmp1 = gen_reg_rtx (Pmode);
5783 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
5785 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5786 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5787 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5788 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5789 else if (DEFAULT_ABI == ABI_V4)
5790 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5793 call_insn = last_call_insn ();
5794 PATTERN (call_insn) = insn;
5795 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5796 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5797 pic_offset_table_rtx);
5799 if (rs6000_tls_size == 16)
5802 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5804 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5806 else if (rs6000_tls_size == 32)
5808 tmp2 = gen_reg_rtx (Pmode);
5810 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5812 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5815 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5817 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5821 tmp2 = gen_reg_rtx (Pmode);
5823 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5825 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5827 insn = gen_rtx_SET (Pmode, dest,
5828 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5834 /* IE, or 64-bit offset LE. */
5835 tmp2 = gen_reg_rtx (Pmode);
5837 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5839 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5842 insn = gen_tls_tls_64 (dest, tmp2, addr);
5844 insn = gen_tls_tls_32 (dest, tmp2, addr);
5852 /* Return 1 if X contains a thread-local symbol. */
5855 rs6000_tls_referenced_p (rtx x)
5857 if (! TARGET_HAVE_TLS)
5860 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5863 /* Return 1 if *X is a thread-local symbol. This is the same as
5864 rs6000_tls_symbol_ref except for the type of the unused argument. */
5867 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5869 return RS6000_SYMBOL_REF_TLS_P (*x);
5872 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5873 replace the input X, or the original X if no replacement is called for.
5874 The output parameter *WIN is 1 if the calling macro should goto WIN,
5877 For RS/6000, we wish to handle large displacements off a base
5878 register by splitting the addend across an addiu/addis and the mem insn.
5879 This cuts number of extra insns needed from 3 to 1.
5881 On Darwin, we use this to generate code for floating point constants.
5882 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5883 The Darwin code is inside #if TARGET_MACHO because only then are the
5884 machopic_* functions defined. */
5886 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5887 int opnum, int type,
5888 int ind_levels ATTRIBUTE_UNUSED, int *win)
5890 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5892 /* We must recognize output that we have already generated ourselves. */
5893 if (GET_CODE (x) == PLUS
5894 && GET_CODE (XEXP (x, 0)) == PLUS
5895 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5896 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5897 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5899 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5900 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5901 opnum, (enum reload_type)type);
5907 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5908 && GET_CODE (x) == LO_SUM
5909 && GET_CODE (XEXP (x, 0)) == PLUS
5910 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5911 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5912 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5913 && machopic_operand_p (XEXP (x, 1)))
5915 /* Result of previous invocation of this function on Darwin
5916 floating point constant. */
5917 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5918 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5919 opnum, (enum reload_type)type);
5925 if (TARGET_CMODEL != CMODEL_SMALL
5926 && GET_CODE (x) == LO_SUM
5927 && GET_CODE (XEXP (x, 0)) == PLUS
5928 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5929 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
5930 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5931 && GET_CODE (XEXP (x, 1)) == CONST
5932 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
5933 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
5934 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
5936 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5937 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5938 opnum, (enum reload_type) type);
5943 /* Force ld/std non-word aligned offset into base register by wrapping
5945 if (GET_CODE (x) == PLUS
5946 && GET_CODE (XEXP (x, 0)) == REG
5947 && REGNO (XEXP (x, 0)) < 32
5948 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5949 && GET_CODE (XEXP (x, 1)) == CONST_INT
5951 && (INTVAL (XEXP (x, 1)) & 3) != 0
5952 && VECTOR_MEM_NONE_P (mode)
5953 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5954 && TARGET_POWERPC64)
5956 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5957 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5958 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5959 opnum, (enum reload_type) type);
5964 if (GET_CODE (x) == PLUS
5965 && GET_CODE (XEXP (x, 0)) == REG
5966 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5967 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5968 && GET_CODE (XEXP (x, 1)) == CONST_INT
5970 && !SPE_VECTOR_MODE (mode)
5971 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5972 || mode == DDmode || mode == TDmode
5974 && VECTOR_MEM_NONE_P (mode))
5976 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5977 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5979 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5981 /* Check for 32-bit overflow. */
5982 if (high + low != val)
5988 /* Reload the high part into a base reg; leave the low part
5989 in the mem directly. */
5991 x = gen_rtx_PLUS (GET_MODE (x),
5992 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5996 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5997 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5998 opnum, (enum reload_type)type);
6003 if (GET_CODE (x) == SYMBOL_REF
6005 && VECTOR_MEM_NONE_P (mode)
6006 && !SPE_VECTOR_MODE (mode)
6008 && DEFAULT_ABI == ABI_DARWIN
6009 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6011 && DEFAULT_ABI == ABI_V4
6014 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6015 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6019 && (mode != DImode || TARGET_POWERPC64)
6020 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6021 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6026 rtx offset = machopic_gen_offset (x);
6027 x = gen_rtx_LO_SUM (GET_MODE (x),
6028 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6029 gen_rtx_HIGH (Pmode, offset)), offset);
6033 x = gen_rtx_LO_SUM (GET_MODE (x),
6034 gen_rtx_HIGH (Pmode, x), x);
6036 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6037 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6038 opnum, (enum reload_type)type);
6043 /* Reload an offset address wrapped by an AND that represents the
6044 masking of the lower bits. Strip the outer AND and let reload
6045 convert the offset address into an indirect address. For VSX,
6046 force reload to create the address with an AND in a separate
6047 register, because we can't guarantee an altivec register will
6049 if (VECTOR_MEM_ALTIVEC_P (mode)
6050 && GET_CODE (x) == AND
6051 && GET_CODE (XEXP (x, 0)) == PLUS
6052 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6053 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6054 && GET_CODE (XEXP (x, 1)) == CONST_INT
6055 && INTVAL (XEXP (x, 1)) == -16)
6064 && GET_CODE (x) == SYMBOL_REF
6065 && constant_pool_expr_p (x)
6066 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6068 x = create_TOC_reference (x, NULL_RTX);
6069 if (TARGET_CMODEL != CMODEL_SMALL)
6070 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6071 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6072 opnum, (enum reload_type) type);
6080 /* Debug version of rs6000_legitimize_reload_address. */
6082 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6083 int opnum, int type,
6084 int ind_levels, int *win)
6086 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6089 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6090 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6091 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6095 fprintf (stderr, "Same address returned\n");
6097 fprintf (stderr, "NULL returned\n");
6100 fprintf (stderr, "New address:\n");
6107 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6108 that is a valid memory address for an instruction.
6109 The MODE argument is the machine mode for the MEM expression
6110 that wants to use this address.
6112 On the RS/6000, there are four valid address: a SYMBOL_REF that
6113 refers to a constant pool entry of an address (or the sum of it
6114 plus a constant), a short (16-bit signed) constant plus a register,
6115 the sum of two registers, or a register indirect, possibly with an
6116 auto-increment. For DFmode, DDmode and DImode with a constant plus
6117 register, we must ensure that both words are addressable or PowerPC64
6118 with offset word aligned.
6120 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6121 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6122 because adjacent memory cells are accessed by adding word-sized offsets
6123 during assembly output. */
6125 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6127 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6129 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6130 if (VECTOR_MEM_ALTIVEC_P (mode)
6131 && GET_CODE (x) == AND
6132 && GET_CODE (XEXP (x, 1)) == CONST_INT
6133 && INTVAL (XEXP (x, 1)) == -16)
6136 if (RS6000_SYMBOL_REF_TLS_P (x))
6138 if (legitimate_indirect_address_p (x, reg_ok_strict))
6140 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6141 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6142 && !SPE_VECTOR_MODE (mode)
6145 /* Restrict addressing for DI because of our SUBREG hackery. */
6146 && !(TARGET_E500_DOUBLE
6147 && (mode == DFmode || mode == DDmode || mode == DImode))
6149 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6151 if (virtual_stack_registers_memory_p (x))
6153 if (reg_offset_p && legitimate_small_data_p (mode, x))
6155 if (reg_offset_p && legitimate_constant_pool_address_p (x, reg_ok_strict))
6157 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6160 && GET_CODE (x) == PLUS
6161 && GET_CODE (XEXP (x, 0)) == REG
6162 && (XEXP (x, 0) == virtual_stack_vars_rtx
6163 || XEXP (x, 0) == arg_pointer_rtx)
6164 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6166 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6171 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6173 || (mode != DFmode && mode != DDmode)
6174 || (TARGET_E500_DOUBLE && mode != DDmode))
6175 && (TARGET_POWERPC64 || mode != DImode)
6176 && !avoiding_indexed_address_p (mode)
6177 && legitimate_indexed_address_p (x, reg_ok_strict))
6179 if (GET_CODE (x) == PRE_MODIFY
6183 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6185 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6186 && (TARGET_POWERPC64 || mode != DImode)
6187 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6188 && !SPE_VECTOR_MODE (mode)
6189 /* Restrict addressing for DI because of our SUBREG hackery. */
6190 && !(TARGET_E500_DOUBLE
6191 && (mode == DFmode || mode == DDmode || mode == DImode))
6193 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6194 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6195 || (!avoiding_indexed_address_p (mode)
6196 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6197 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6199 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6204 /* Debug version of rs6000_legitimate_address_p. */
6206 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6209 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6211 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6212 "strict = %d, code = %s\n",
6213 ret ? "true" : "false",
6214 GET_MODE_NAME (mode),
6216 GET_RTX_NAME (GET_CODE (x)));
6222 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6225 rs6000_mode_dependent_address_p (const_rtx addr)
6227 return rs6000_mode_dependent_address_ptr (addr);
6230 /* Go to LABEL if ADDR (a legitimate address expression)
6231 has an effect that depends on the machine mode it is used for.
6233 On the RS/6000 this is true of all integral offsets (since AltiVec
6234 and VSX modes don't allow them) or is a pre-increment or decrement.
6236 ??? Except that due to conceptual problems in offsettable_address_p
6237 we can't really report the problems of integral offsets. So leave
6238 this assuming that the adjustable offset must be valid for the
6239 sub-words of a TFmode operand, which is what we had before. */
6242 rs6000_mode_dependent_address (const_rtx addr)
6244 switch (GET_CODE (addr))
6247 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6248 is considered a legitimate address before reload, so there
6249 are no offset restrictions in that case. Note that this
6250 condition is safe in strict mode because any address involving
6251 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6252 been rejected as illegitimate. */
6253 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6254 && XEXP (addr, 0) != arg_pointer_rtx
6255 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6257 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6258 return val + 12 + 0x8000 >= 0x10000;
6263 /* Anything in the constant pool is sufficiently aligned that
6264 all bytes have the same high part address. */
6265 return !legitimate_constant_pool_address_p (addr, false);
6267 /* Auto-increment cases are now treated generically in recog.c. */
6269 return TARGET_UPDATE;
6271 /* AND is only allowed in Altivec loads. */
6282 /* Debug version of rs6000_mode_dependent_address. */
6284 rs6000_debug_mode_dependent_address (const_rtx addr)
6286 bool ret = rs6000_mode_dependent_address (addr);
6288 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6289 ret ? "true" : "false");
6295 /* Implement FIND_BASE_TERM. */
6298 rs6000_find_base_term (rtx op)
6302 split_const (op, &base, &offset);
6303 if (GET_CODE (base) == UNSPEC)
6304 switch (XINT (base, 1))
6307 case UNSPEC_MACHOPIC_OFFSET:
6308 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6309 for aliasing purposes. */
6310 return XVECEXP (base, 0, 0);
6316 /* More elaborate version of recog's offsettable_memref_p predicate
6317 that works around the ??? note of rs6000_mode_dependent_address.
6318 In particular it accepts
6320 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6322 in 32-bit mode, that the recog predicate rejects. */
6325 rs6000_offsettable_memref_p (rtx op)
6330 /* First mimic offsettable_memref_p. */
6331 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6334 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6335 the latter predicate knows nothing about the mode of the memory
6336 reference and, therefore, assumes that it is the largest supported
6337 mode (TFmode). As a consequence, legitimate offsettable memory
6338 references are rejected. rs6000_legitimate_offset_address_p contains
6339 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6340 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6343 /* Change register usage conditional on target flags. */
6345 rs6000_conditional_register_usage (void)
6349 /* Set MQ register fixed (already call_used) if not POWER
6350 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6355 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6357 fixed_regs[13] = call_used_regs[13]
6358 = call_really_used_regs[13] = 1;
6360 /* Conditionally disable FPRs. */
6361 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6362 for (i = 32; i < 64; i++)
6363 fixed_regs[i] = call_used_regs[i]
6364 = call_really_used_regs[i] = 1;
6366 /* The TOC register is not killed across calls in a way that is
6367 visible to the compiler. */
6368 if (DEFAULT_ABI == ABI_AIX)
6369 call_really_used_regs[2] = 0;
6371 if (DEFAULT_ABI == ABI_V4
6372 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6374 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6376 if (DEFAULT_ABI == ABI_V4
6377 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6379 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6380 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6381 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6383 if (DEFAULT_ABI == ABI_DARWIN
6384 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6385 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6386 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6387 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6389 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6390 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6391 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6395 global_regs[SPEFSCR_REGNO] = 1;
6396 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6397 registers in prologues and epilogues. We no longer use r14
6398 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6399 pool for link-compatibility with older versions of GCC. Once
6400 "old" code has died out, we can return r14 to the allocation
6403 = call_used_regs[14]
6404 = call_really_used_regs[14] = 1;
6407 if (!TARGET_ALTIVEC && !TARGET_VSX)
6409 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6410 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6411 call_really_used_regs[VRSAVE_REGNO] = 1;
6414 if (TARGET_ALTIVEC || TARGET_VSX)
6415 global_regs[VSCR_REGNO] = 1;
6417 if (TARGET_ALTIVEC_ABI)
6419 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6420 call_used_regs[i] = call_really_used_regs[i] = 1;
6422 /* AIX reserves VR20:31 in non-extended ABI mode. */
6424 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6425 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6429 /* Try to output insns to set TARGET equal to the constant C if it can
6430 be done in less than N insns. Do all computations in MODE.
6431 Returns the place where the output has been placed if it can be
6432 done and the insns have been emitted. If it would take more than N
6433 insns, zero is returned and no insns and emitted. */
6436 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6437 rtx source, int n ATTRIBUTE_UNUSED)
6439 rtx result, insn, set;
6440 HOST_WIDE_INT c0, c1;
6447 dest = gen_reg_rtx (mode);
6448 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6452 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6454 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6455 GEN_INT (INTVAL (source)
6456 & (~ (HOST_WIDE_INT) 0xffff))));
6457 emit_insn (gen_rtx_SET (VOIDmode, dest,
6458 gen_rtx_IOR (SImode, copy_rtx (result),
6459 GEN_INT (INTVAL (source) & 0xffff))));
6464 switch (GET_CODE (source))
6467 c0 = INTVAL (source);
6472 #if HOST_BITS_PER_WIDE_INT >= 64
6473 c0 = CONST_DOUBLE_LOW (source);
6476 c0 = CONST_DOUBLE_LOW (source);
6477 c1 = CONST_DOUBLE_HIGH (source);
6485 result = rs6000_emit_set_long_const (dest, c0, c1);
6492 insn = get_last_insn ();
6493 set = single_set (insn);
6494 if (! CONSTANT_P (SET_SRC (set)))
6495 set_unique_reg_note (insn, REG_EQUAL, source);
6500 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6501 fall back to a straight forward decomposition. We do this to avoid
6502 exponential run times encountered when looking for longer sequences
6503 with rs6000_emit_set_const. */
6505 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6507 if (!TARGET_POWERPC64)
6509 rtx operand1, operand2;
6511 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6513 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6515 emit_move_insn (operand1, GEN_INT (c1));
6516 emit_move_insn (operand2, GEN_INT (c2));
6520 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6523 ud2 = (c1 & 0xffff0000) >> 16;
6524 #if HOST_BITS_PER_WIDE_INT >= 64
6528 ud4 = (c2 & 0xffff0000) >> 16;
6530 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6531 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6534 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6536 emit_move_insn (dest, GEN_INT (ud1));
6539 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6540 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6543 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6546 emit_move_insn (dest, GEN_INT (ud2 << 16));
6548 emit_move_insn (copy_rtx (dest),
6549 gen_rtx_IOR (DImode, copy_rtx (dest),
6552 else if (ud3 == 0 && ud4 == 0)
6554 gcc_assert (ud2 & 0x8000);
6555 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6558 emit_move_insn (copy_rtx (dest),
6559 gen_rtx_IOR (DImode, copy_rtx (dest),
6561 emit_move_insn (copy_rtx (dest),
6562 gen_rtx_ZERO_EXTEND (DImode,
6563 gen_lowpart (SImode,
6566 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6567 || (ud4 == 0 && ! (ud3 & 0x8000)))
6570 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6573 emit_move_insn (dest, GEN_INT (ud3 << 16));
6576 emit_move_insn (copy_rtx (dest),
6577 gen_rtx_IOR (DImode, copy_rtx (dest),
6579 emit_move_insn (copy_rtx (dest),
6580 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6583 emit_move_insn (copy_rtx (dest),
6584 gen_rtx_IOR (DImode, copy_rtx (dest),
6590 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6593 emit_move_insn (dest, GEN_INT (ud4 << 16));
6596 emit_move_insn (copy_rtx (dest),
6597 gen_rtx_IOR (DImode, copy_rtx (dest),
6600 emit_move_insn (copy_rtx (dest),
6601 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6604 emit_move_insn (copy_rtx (dest),
6605 gen_rtx_IOR (DImode, copy_rtx (dest),
6606 GEN_INT (ud2 << 16)));
6608 emit_move_insn (copy_rtx (dest),
6609 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6615 /* Helper for the following. Get rid of [r+r] memory refs
6616 in cases where it won't work (TImode, TFmode, TDmode). */
6619 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6621 if (reload_in_progress)
6624 if (GET_CODE (operands[0]) == MEM
6625 && GET_CODE (XEXP (operands[0], 0)) != REG
6626 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), false))
6628 = replace_equiv_address (operands[0],
6629 copy_addr_to_reg (XEXP (operands[0], 0)));
6631 if (GET_CODE (operands[1]) == MEM
6632 && GET_CODE (XEXP (operands[1], 0)) != REG
6633 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), false))
6635 = replace_equiv_address (operands[1],
6636 copy_addr_to_reg (XEXP (operands[1], 0)));
6639 /* Return true if memory accesses to DECL are known to never straddle
6643 offsettable_ok_by_alignment (tree decl)
6645 unsigned HOST_WIDE_INT dsize;
6647 /* Presume any compiler generated symbol_ref is suitably aligned. */
6651 if (TREE_CODE (decl) != VAR_DECL
6652 && TREE_CODE (decl) != PARM_DECL
6653 && TREE_CODE (decl) != RESULT_DECL
6654 && TREE_CODE (decl) != FIELD_DECL)
6657 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
6660 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
6666 return DECL_ALIGN_UNIT (decl) >= dsize;
6669 /* Emit a move from SOURCE to DEST in mode MODE. */
6671 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6675 operands[1] = source;
6677 if (TARGET_DEBUG_ADDR)
6680 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6681 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6682 GET_MODE_NAME (mode),
6685 can_create_pseudo_p ());
6687 fprintf (stderr, "source:\n");
6691 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6692 if (GET_CODE (operands[1]) == CONST_DOUBLE
6693 && ! FLOAT_MODE_P (mode)
6694 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6696 /* FIXME. This should never happen. */
6697 /* Since it seems that it does, do the safe thing and convert
6699 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6701 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6702 || FLOAT_MODE_P (mode)
6703 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6704 || CONST_DOUBLE_LOW (operands[1]) < 0)
6705 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6706 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6708 /* Check if GCC is setting up a block move that will end up using FP
6709 registers as temporaries. We must make sure this is acceptable. */
6710 if (GET_CODE (operands[0]) == MEM
6711 && GET_CODE (operands[1]) == MEM
6713 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6714 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6715 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6716 ? 32 : MEM_ALIGN (operands[0])))
6717 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6719 : MEM_ALIGN (operands[1]))))
6720 && ! MEM_VOLATILE_P (operands [0])
6721 && ! MEM_VOLATILE_P (operands [1]))
6723 emit_move_insn (adjust_address (operands[0], SImode, 0),
6724 adjust_address (operands[1], SImode, 0));
6725 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6726 adjust_address (copy_rtx (operands[1]), SImode, 4));
6730 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6731 && !gpc_reg_operand (operands[1], mode))
6732 operands[1] = force_reg (mode, operands[1]);
6734 if (mode == SFmode && ! TARGET_POWERPC
6735 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6736 && GET_CODE (operands[0]) == MEM)
6740 if (reload_in_progress || reload_completed)
6741 regnum = true_regnum (operands[1]);
6742 else if (GET_CODE (operands[1]) == REG)
6743 regnum = REGNO (operands[1]);
6747 /* If operands[1] is a register, on POWER it may have
6748 double-precision data in it, so truncate it to single
6750 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6753 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6754 : gen_reg_rtx (mode));
6755 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6756 operands[1] = newreg;
6760 /* Recognize the case where operand[1] is a reference to thread-local
6761 data and load its address to a register. */
6762 if (rs6000_tls_referenced_p (operands[1]))
6764 enum tls_model model;
6765 rtx tmp = operands[1];
6768 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6770 addend = XEXP (XEXP (tmp, 0), 1);
6771 tmp = XEXP (XEXP (tmp, 0), 0);
6774 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6775 model = SYMBOL_REF_TLS_MODEL (tmp);
6776 gcc_assert (model != 0);
6778 tmp = rs6000_legitimize_tls_address (tmp, model);
6781 tmp = gen_rtx_PLUS (mode, tmp, addend);
6782 tmp = force_operand (tmp, operands[0]);
6787 /* Handle the case where reload calls us with an invalid address. */
6788 if (reload_in_progress && mode == Pmode
6789 && (! general_operand (operands[1], mode)
6790 || ! nonimmediate_operand (operands[0], mode)))
6793 /* 128-bit constant floating-point values on Darwin should really be
6794 loaded as two parts. */
6795 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6796 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6798 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6799 know how to get a DFmode SUBREG of a TFmode. */
6800 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6801 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6802 simplify_gen_subreg (imode, operands[1], mode, 0),
6804 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6805 GET_MODE_SIZE (imode)),
6806 simplify_gen_subreg (imode, operands[1], mode,
6807 GET_MODE_SIZE (imode)),
6812 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6813 cfun->machine->sdmode_stack_slot =
6814 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6816 if (reload_in_progress
6818 && MEM_P (operands[0])
6819 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6820 && REG_P (operands[1]))
6822 if (FP_REGNO_P (REGNO (operands[1])))
6824 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6825 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6826 emit_insn (gen_movsd_store (mem, operands[1]));
6828 else if (INT_REGNO_P (REGNO (operands[1])))
6830 rtx mem = adjust_address_nv (operands[0], mode, 4);
6831 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6832 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6838 if (reload_in_progress
6840 && REG_P (operands[0])
6841 && MEM_P (operands[1])
6842 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6844 if (FP_REGNO_P (REGNO (operands[0])))
6846 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6847 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6848 emit_insn (gen_movsd_load (operands[0], mem));
6850 else if (INT_REGNO_P (REGNO (operands[0])))
6852 rtx mem = adjust_address_nv (operands[1], mode, 4);
6853 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6854 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6861 /* FIXME: In the long term, this switch statement should go away
6862 and be replaced by a sequence of tests based on things like
6868 if (CONSTANT_P (operands[1])
6869 && GET_CODE (operands[1]) != CONST_INT)
6870 operands[1] = force_const_mem (mode, operands[1]);
6875 rs6000_eliminate_indexed_memrefs (operands);
6882 if (CONSTANT_P (operands[1])
6883 && ! easy_fp_constant (operands[1], mode))
6884 operands[1] = force_const_mem (mode, operands[1]);
6897 if (CONSTANT_P (operands[1])
6898 && !easy_vector_constant (operands[1], mode))
6899 operands[1] = force_const_mem (mode, operands[1]);
6904 /* Use default pattern for address of ELF small data */
6907 && DEFAULT_ABI == ABI_V4
6908 && (GET_CODE (operands[1]) == SYMBOL_REF
6909 || GET_CODE (operands[1]) == CONST)
6910 && small_data_operand (operands[1], mode))
6912 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6916 if (DEFAULT_ABI == ABI_V4
6917 && mode == Pmode && mode == SImode
6918 && flag_pic == 1 && got_operand (operands[1], mode))
6920 emit_insn (gen_movsi_got (operands[0], operands[1]));
6924 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6928 && CONSTANT_P (operands[1])
6929 && GET_CODE (operands[1]) != HIGH
6930 && GET_CODE (operands[1]) != CONST_INT)
6932 rtx target = (!can_create_pseudo_p ()
6934 : gen_reg_rtx (mode));
6936 /* If this is a function address on -mcall-aixdesc,
6937 convert it to the address of the descriptor. */
6938 if (DEFAULT_ABI == ABI_AIX
6939 && GET_CODE (operands[1]) == SYMBOL_REF
6940 && XSTR (operands[1], 0)[0] == '.')
6942 const char *name = XSTR (operands[1], 0);
6944 while (*name == '.')
6946 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6947 CONSTANT_POOL_ADDRESS_P (new_ref)
6948 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6949 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6950 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6951 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6952 operands[1] = new_ref;
6955 if (DEFAULT_ABI == ABI_DARWIN)
6958 if (MACHO_DYNAMIC_NO_PIC_P)
6960 /* Take care of any required data indirection. */
6961 operands[1] = rs6000_machopic_legitimize_pic_address (
6962 operands[1], mode, operands[0]);
6963 if (operands[0] != operands[1])
6964 emit_insn (gen_rtx_SET (VOIDmode,
6965 operands[0], operands[1]));
6969 emit_insn (gen_macho_high (target, operands[1]));
6970 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6974 emit_insn (gen_elf_high (target, operands[1]));
6975 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6979 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6980 and we have put it in the TOC, we just need to make a TOC-relative
6983 && GET_CODE (operands[1]) == SYMBOL_REF
6984 && constant_pool_expr_p (operands[1])
6985 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6986 get_pool_mode (operands[1])))
6987 || (TARGET_CMODEL == CMODEL_MEDIUM
6988 && GET_CODE (operands[1]) == SYMBOL_REF
6989 && !CONSTANT_POOL_ADDRESS_P (operands[1])
6990 && SYMBOL_REF_LOCAL_P (operands[1])
6991 && offsettable_ok_by_alignment (SYMBOL_REF_DECL (operands[1]))))
6994 if (TARGET_CMODEL != CMODEL_SMALL)
6996 if (can_create_pseudo_p ())
6997 reg = gen_reg_rtx (Pmode);
7001 operands[1] = create_TOC_reference (operands[1], reg);
7003 else if (mode == Pmode
7004 && CONSTANT_P (operands[1])
7005 && ((GET_CODE (operands[1]) != CONST_INT
7006 && ! easy_fp_constant (operands[1], mode))
7007 || (GET_CODE (operands[1]) == CONST_INT
7008 && (num_insns_constant (operands[1], mode)
7009 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7010 || (GET_CODE (operands[0]) == REG
7011 && FP_REGNO_P (REGNO (operands[0]))))
7012 && GET_CODE (operands[1]) != HIGH
7013 && ! legitimate_constant_pool_address_p (operands[1], false)
7014 && ! toc_relative_expr_p (operands[1])
7015 && (TARGET_CMODEL == CMODEL_SMALL
7016 || can_create_pseudo_p ()
7017 || (REG_P (operands[0])
7018 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7022 /* Darwin uses a special PIC legitimizer. */
7023 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7026 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7028 if (operands[0] != operands[1])
7029 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7034 /* If we are to limit the number of things we put in the TOC and
7035 this is a symbol plus a constant we can add in one insn,
7036 just put the symbol in the TOC and add the constant. Don't do
7037 this if reload is in progress. */
7038 if (GET_CODE (operands[1]) == CONST
7039 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7040 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7041 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7042 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7043 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7044 && ! side_effects_p (operands[0]))
7047 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7048 rtx other = XEXP (XEXP (operands[1], 0), 1);
7050 sym = force_reg (mode, sym);
7051 emit_insn (gen_add3_insn (operands[0], sym, other));
7055 operands[1] = force_const_mem (mode, operands[1]);
7058 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7059 && constant_pool_expr_p (XEXP (operands[1], 0))
7060 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7061 get_pool_constant (XEXP (operands[1], 0)),
7062 get_pool_mode (XEXP (operands[1], 0))))
7066 if (TARGET_CMODEL != CMODEL_SMALL)
7068 if (can_create_pseudo_p ())
7069 reg = gen_reg_rtx (Pmode);
7073 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7074 operands[1] = gen_const_mem (mode, tocref);
7075 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7081 rs6000_eliminate_indexed_memrefs (operands);
7085 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7087 gen_rtx_SET (VOIDmode,
7088 operands[0], operands[1]),
7089 gen_rtx_CLOBBER (VOIDmode,
7090 gen_rtx_SCRATCH (SImode)))));
7096 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7099 /* Above, we may have called force_const_mem which may have returned
7100 an invalid address. If we can, fix this up; otherwise, reload will
7101 have to deal with it. */
7102 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7103 operands[1] = validize_mem (operands[1]);
7106 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7109 /* Nonzero if we can use a floating-point register to pass this arg. */
7110 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7111 (SCALAR_FLOAT_MODE_P (MODE) \
7112 && (CUM)->fregno <= FP_ARG_MAX_REG \
7113 && TARGET_HARD_FLOAT && TARGET_FPRS)
7115 /* Nonzero if we can use an AltiVec register to pass this arg. */
7116 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7117 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7118 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7119 && TARGET_ALTIVEC_ABI \
7122 /* Return a nonzero value to say to return the function value in
7123 memory, just as large structures are always returned. TYPE will be
7124 the data type of the value, and FNTYPE will be the type of the
7125 function doing the returning, or @code{NULL} for libcalls.
7127 The AIX ABI for the RS/6000 specifies that all structures are
7128 returned in memory. The Darwin ABI does the same. The SVR4 ABI
7129 specifies that structures <= 8 bytes are returned in r3/r4, but a
7130 draft put them in memory, and GCC used to implement the draft
7131 instead of the final standard. Therefore, aix_struct_return
7132 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7133 compatibility can change DRAFT_V4_STRUCT_RET to override the
7134 default, and -m switches get the final word. See
7135 rs6000_override_options for more details.
7137 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7138 long double support is enabled. These values are returned in memory.
7140 int_size_in_bytes returns -1 for variable size objects, which go in
7141 memory always. The cast to unsigned makes -1 > 8. */
7144 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7146 /* In the darwin64 abi, try to use registers for larger structs
7148 if (rs6000_darwin64_abi
7149 && TREE_CODE (type) == RECORD_TYPE
7150 && int_size_in_bytes (type) > 0)
7152 CUMULATIVE_ARGS valcum;
7156 valcum.fregno = FP_ARG_MIN_REG;
7157 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7158 /* Do a trial code generation as if this were going to be passed
7159 as an argument; if any part goes in memory, we return NULL. */
7160 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
7163 /* Otherwise fall through to more conventional ABI rules. */
7166 if (AGGREGATE_TYPE_P (type)
7167 && (aix_struct_return
7168 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7171 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7172 modes only exist for GCC vector types if -maltivec. */
7173 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7174 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7177 /* Return synthetic vectors in memory. */
7178 if (TREE_CODE (type) == VECTOR_TYPE
7179 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7181 static bool warned_for_return_big_vectors = false;
7182 if (!warned_for_return_big_vectors)
7184 warning (0, "GCC vector returned by reference: "
7185 "non-standard ABI extension with no compatibility guarantee");
7186 warned_for_return_big_vectors = true;
7191 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7197 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7198 for a call to a function whose data type is FNTYPE.
7199 For a library call, FNTYPE is 0.
7201 For incoming args we set the number of arguments in the prototype large
7202 so we never return a PARALLEL. */
7205 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7206 rtx libname ATTRIBUTE_UNUSED, int incoming,
7207 int libcall, int n_named_args)
7209 static CUMULATIVE_ARGS zero_cumulative;
7211 *cum = zero_cumulative;
7213 cum->fregno = FP_ARG_MIN_REG;
7214 cum->vregno = ALTIVEC_ARG_MIN_REG;
7215 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7216 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7217 ? CALL_LIBCALL : CALL_NORMAL);
7218 cum->sysv_gregno = GP_ARG_MIN_REG;
7219 cum->stdarg = fntype
7220 && (TYPE_ARG_TYPES (fntype) != 0
7221 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
7222 != void_type_node));
7224 cum->nargs_prototype = 0;
7225 if (incoming || cum->prototype)
7226 cum->nargs_prototype = n_named_args;
7228 /* Check for a longcall attribute. */
7229 if ((!fntype && rs6000_default_long_calls)
7231 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7232 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7233 cum->call_cookie |= CALL_LONG;
7235 if (TARGET_DEBUG_ARG)
7237 fprintf (stderr, "\ninit_cumulative_args:");
7240 tree ret_type = TREE_TYPE (fntype);
7241 fprintf (stderr, " ret code = %s,",
7242 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7245 if (cum->call_cookie & CALL_LONG)
7246 fprintf (stderr, " longcall,");
7248 fprintf (stderr, " proto = %d, nargs = %d\n",
7249 cum->prototype, cum->nargs_prototype);
7254 && TARGET_ALTIVEC_ABI
7255 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7257 error ("cannot return value in vector register because"
7258 " altivec instructions are disabled, use -maltivec"
7263 /* Return true if TYPE must be passed on the stack and not in registers. */
7266 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7268 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7269 return must_pass_in_stack_var_size (mode, type);
7271 return must_pass_in_stack_var_size_or_pad (mode, type);
7274 /* If defined, a C expression which determines whether, and in which
7275 direction, to pad out an argument with extra space. The value
7276 should be of type `enum direction': either `upward' to pad above
7277 the argument, `downward' to pad below, or `none' to inhibit
7280 For the AIX ABI structs are always stored left shifted in their
7284 function_arg_padding (enum machine_mode mode, const_tree type)
7286 #ifndef AGGREGATE_PADDING_FIXED
7287 #define AGGREGATE_PADDING_FIXED 0
7289 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7290 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7293 if (!AGGREGATE_PADDING_FIXED)
7295 /* GCC used to pass structures of the same size as integer types as
7296 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7297 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7298 passed padded downward, except that -mstrict-align further
7299 muddied the water in that multi-component structures of 2 and 4
7300 bytes in size were passed padded upward.
7302 The following arranges for best compatibility with previous
7303 versions of gcc, but removes the -mstrict-align dependency. */
7304 if (BYTES_BIG_ENDIAN)
7306 HOST_WIDE_INT size = 0;
7308 if (mode == BLKmode)
7310 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7311 size = int_size_in_bytes (type);
7314 size = GET_MODE_SIZE (mode);
7316 if (size == 1 || size == 2 || size == 4)
7322 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7324 if (type != 0 && AGGREGATE_TYPE_P (type))
7328 /* Fall back to the default. */
7329 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7332 /* If defined, a C expression that gives the alignment boundary, in bits,
7333 of an argument with the specified mode and type. If it is not defined,
7334 PARM_BOUNDARY is used for all arguments.
7336 V.4 wants long longs and doubles to be double word aligned. Just
7337 testing the mode size is a boneheaded way to do this as it means
7338 that other types such as complex int are also double word aligned.
7339 However, we're stuck with this because changing the ABI might break
7340 existing library interfaces.
7342 Doubleword align SPE vectors.
7343 Quadword align Altivec vectors.
7344 Quadword align large synthetic vector types. */
7347 function_arg_boundary (enum machine_mode mode, tree type)
7349 if (DEFAULT_ABI == ABI_V4
7350 && (GET_MODE_SIZE (mode) == 8
7351 || (TARGET_HARD_FLOAT
7353 && (mode == TFmode || mode == TDmode))))
7355 else if (SPE_VECTOR_MODE (mode)
7356 || (type && TREE_CODE (type) == VECTOR_TYPE
7357 && int_size_in_bytes (type) >= 8
7358 && int_size_in_bytes (type) < 16))
7360 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
7361 || (type && TREE_CODE (type) == VECTOR_TYPE
7362 && int_size_in_bytes (type) >= 16))
7364 else if (rs6000_darwin64_abi && mode == BLKmode
7365 && type && TYPE_ALIGN (type) > 64)
7368 return PARM_BOUNDARY;
7371 /* For a function parm of MODE and TYPE, return the starting word in
7372 the parameter area. NWORDS of the parameter area are already used. */
7375 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
7378 unsigned int parm_offset;
7380 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7381 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7382 return nwords + (-(parm_offset + nwords) & align);
7385 /* Compute the size (in words) of a function argument. */
7387 static unsigned long
7388 rs6000_arg_size (enum machine_mode mode, tree type)
7392 if (mode != BLKmode)
7393 size = GET_MODE_SIZE (mode);
7395 size = int_size_in_bytes (type);
7398 return (size + 3) >> 2;
7400 return (size + 7) >> 3;
7403 /* Use this to flush pending int fields. */
7406 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7407 HOST_WIDE_INT bitpos)
7409 unsigned int startbit, endbit;
7410 int intregs, intoffset;
7411 enum machine_mode mode;
7413 if (cum->intoffset == -1)
7416 intoffset = cum->intoffset;
7417 cum->intoffset = -1;
7419 if (intoffset % BITS_PER_WORD != 0)
7421 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7423 if (mode == BLKmode)
7425 /* We couldn't find an appropriate mode, which happens,
7426 e.g., in packed structs when there are 3 bytes to load.
7427 Back intoffset back to the beginning of the word in this
7429 intoffset = intoffset & -BITS_PER_WORD;
7433 startbit = intoffset & -BITS_PER_WORD;
7434 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7435 intregs = (endbit - startbit) / BITS_PER_WORD;
7436 cum->words += intregs;
7439 /* The darwin64 ABI calls for us to recurse down through structs,
7440 looking for elements passed in registers. Unfortunately, we have
7441 to track int register count here also because of misalignments
7442 in powerpc alignment mode. */
7445 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7447 HOST_WIDE_INT startbitpos)
7451 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7452 if (TREE_CODE (f) == FIELD_DECL)
7454 HOST_WIDE_INT bitpos = startbitpos;
7455 tree ftype = TREE_TYPE (f);
7456 enum machine_mode mode;
7457 if (ftype == error_mark_node)
7459 mode = TYPE_MODE (ftype);
7461 if (DECL_SIZE (f) != 0
7462 && host_integerp (bit_position (f), 1))
7463 bitpos += int_bit_position (f);
7465 /* ??? FIXME: else assume zero offset. */
7467 if (TREE_CODE (ftype) == RECORD_TYPE)
7468 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7469 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7471 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7472 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7473 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7475 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7477 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7481 else if (cum->intoffset == -1)
7482 cum->intoffset = bitpos;
7486 /* Update the data in CUM to advance over an argument
7487 of mode MODE and data type TYPE.
7488 (TYPE is null for libcalls where that information may not be available.)
7490 Note that for args passed by reference, function_arg will be called
7491 with MODE and TYPE set to that of the pointer to the arg, not the arg
7495 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7496 tree type, int named, int depth)
7500 /* Only tick off an argument if we're not recursing. */
7502 cum->nargs_prototype--;
7504 if (TARGET_ALTIVEC_ABI
7505 && (ALTIVEC_VECTOR_MODE (mode)
7506 || VSX_VECTOR_MODE (mode)
7507 || (type && TREE_CODE (type) == VECTOR_TYPE
7508 && int_size_in_bytes (type) == 16)))
7512 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7515 if (!TARGET_ALTIVEC)
7516 error ("cannot pass argument in vector register because"
7517 " altivec instructions are disabled, use -maltivec"
7520 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7521 even if it is going to be passed in a vector register.
7522 Darwin does the same for variable-argument functions. */
7523 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7524 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7534 /* Vector parameters must be 16-byte aligned. This places
7535 them at 2 mod 4 in terms of words in 32-bit mode, since
7536 the parameter save area starts at offset 24 from the
7537 stack. In 64-bit mode, they just have to start on an
7538 even word, since the parameter save area is 16-byte
7539 aligned. Space for GPRs is reserved even if the argument
7540 will be passed in memory. */
7542 align = (2 - cum->words) & 3;
7544 align = cum->words & 1;
7545 cum->words += align + rs6000_arg_size (mode, type);
7547 if (TARGET_DEBUG_ARG)
7549 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7551 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7552 cum->nargs_prototype, cum->prototype,
7553 GET_MODE_NAME (mode));
7557 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7559 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7562 else if (rs6000_darwin64_abi
7564 && TREE_CODE (type) == RECORD_TYPE
7565 && (size = int_size_in_bytes (type)) > 0)
7567 /* Variable sized types have size == -1 and are
7568 treated as if consisting entirely of ints.
7569 Pad to 16 byte boundary if needed. */
7570 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7571 && (cum->words % 2) != 0)
7573 /* For varargs, we can just go up by the size of the struct. */
7575 cum->words += (size + 7) / 8;
7578 /* It is tempting to say int register count just goes up by
7579 sizeof(type)/8, but this is wrong in a case such as
7580 { int; double; int; } [powerpc alignment]. We have to
7581 grovel through the fields for these too. */
7583 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7584 rs6000_darwin64_record_arg_advance_flush (cum,
7585 size * BITS_PER_UNIT);
7588 else if (DEFAULT_ABI == ABI_V4)
7590 if (TARGET_HARD_FLOAT && TARGET_FPRS
7591 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7592 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7593 || (mode == TFmode && !TARGET_IEEEQUAD)
7594 || mode == SDmode || mode == DDmode || mode == TDmode))
7596 /* _Decimal128 must use an even/odd register pair. This assumes
7597 that the register number is odd when fregno is odd. */
7598 if (mode == TDmode && (cum->fregno % 2) == 1)
7601 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7602 <= FP_ARG_V4_MAX_REG)
7603 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7606 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7607 if (mode == DFmode || mode == TFmode
7608 || mode == DDmode || mode == TDmode)
7609 cum->words += cum->words & 1;
7610 cum->words += rs6000_arg_size (mode, type);
7615 int n_words = rs6000_arg_size (mode, type);
7616 int gregno = cum->sysv_gregno;
7618 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7619 (r7,r8) or (r9,r10). As does any other 2 word item such
7620 as complex int due to a historical mistake. */
7622 gregno += (1 - gregno) & 1;
7624 /* Multi-reg args are not split between registers and stack. */
7625 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7627 /* Long long and SPE vectors are aligned on the stack.
7628 So are other 2 word items such as complex int due to
7629 a historical mistake. */
7631 cum->words += cum->words & 1;
7632 cum->words += n_words;
7635 /* Note: continuing to accumulate gregno past when we've started
7636 spilling to the stack indicates the fact that we've started
7637 spilling to the stack to expand_builtin_saveregs. */
7638 cum->sysv_gregno = gregno + n_words;
7641 if (TARGET_DEBUG_ARG)
7643 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7644 cum->words, cum->fregno);
7645 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7646 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7647 fprintf (stderr, "mode = %4s, named = %d\n",
7648 GET_MODE_NAME (mode), named);
7653 int n_words = rs6000_arg_size (mode, type);
7654 int start_words = cum->words;
7655 int align_words = rs6000_parm_start (mode, type, start_words);
7657 cum->words = align_words + n_words;
7659 if (SCALAR_FLOAT_MODE_P (mode)
7660 && TARGET_HARD_FLOAT && TARGET_FPRS)
7662 /* _Decimal128 must be passed in an even/odd float register pair.
7663 This assumes that the register number is odd when fregno is
7665 if (mode == TDmode && (cum->fregno % 2) == 1)
7667 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7670 if (TARGET_DEBUG_ARG)
7672 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7673 cum->words, cum->fregno);
7674 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7675 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7676 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7677 named, align_words - start_words, depth);
7683 spe_build_register_parallel (enum machine_mode mode, int gregno)
7690 r1 = gen_rtx_REG (DImode, gregno);
7691 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7692 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7696 r1 = gen_rtx_REG (DImode, gregno);
7697 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7698 r3 = gen_rtx_REG (DImode, gregno + 2);
7699 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7700 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7703 r1 = gen_rtx_REG (DImode, gregno);
7704 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7705 r3 = gen_rtx_REG (DImode, gregno + 2);
7706 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7707 r5 = gen_rtx_REG (DImode, gregno + 4);
7708 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7709 r7 = gen_rtx_REG (DImode, gregno + 6);
7710 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7711 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7718 /* Determine where to put a SIMD argument on the SPE. */
7720 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7723 int gregno = cum->sysv_gregno;
7725 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7726 are passed and returned in a pair of GPRs for ABI compatibility. */
7727 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7728 || mode == DCmode || mode == TCmode))
7730 int n_words = rs6000_arg_size (mode, type);
7732 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7734 gregno += (1 - gregno) & 1;
7736 /* Multi-reg args are not split between registers and stack. */
7737 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7740 return spe_build_register_parallel (mode, gregno);
7744 int n_words = rs6000_arg_size (mode, type);
7746 /* SPE vectors are put in odd registers. */
7747 if (n_words == 2 && (gregno & 1) == 0)
7750 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7753 enum machine_mode m = SImode;
7755 r1 = gen_rtx_REG (m, gregno);
7756 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7757 r2 = gen_rtx_REG (m, gregno + 1);
7758 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7759 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7766 if (gregno <= GP_ARG_MAX_REG)
7767 return gen_rtx_REG (mode, gregno);
7773 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7774 structure between cum->intoffset and bitpos to integer registers. */
7777 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7778 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7780 enum machine_mode mode;
7782 unsigned int startbit, endbit;
7783 int this_regno, intregs, intoffset;
7786 if (cum->intoffset == -1)
7789 intoffset = cum->intoffset;
7790 cum->intoffset = -1;
7792 /* If this is the trailing part of a word, try to only load that
7793 much into the register. Otherwise load the whole register. Note
7794 that in the latter case we may pick up unwanted bits. It's not a
7795 problem at the moment but may wish to revisit. */
7797 if (intoffset % BITS_PER_WORD != 0)
7799 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7801 if (mode == BLKmode)
7803 /* We couldn't find an appropriate mode, which happens,
7804 e.g., in packed structs when there are 3 bytes to load.
7805 Back intoffset back to the beginning of the word in this
7807 intoffset = intoffset & -BITS_PER_WORD;
7814 startbit = intoffset & -BITS_PER_WORD;
7815 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7816 intregs = (endbit - startbit) / BITS_PER_WORD;
7817 this_regno = cum->words + intoffset / BITS_PER_WORD;
7819 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7822 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7826 intoffset /= BITS_PER_UNIT;
7829 regno = GP_ARG_MIN_REG + this_regno;
7830 reg = gen_rtx_REG (mode, regno);
7832 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7835 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7839 while (intregs > 0);
7842 /* Recursive workhorse for the following. */
7845 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7846 HOST_WIDE_INT startbitpos, rtx rvec[],
7851 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7852 if (TREE_CODE (f) == FIELD_DECL)
7854 HOST_WIDE_INT bitpos = startbitpos;
7855 tree ftype = TREE_TYPE (f);
7856 enum machine_mode mode;
7857 if (ftype == error_mark_node)
7859 mode = TYPE_MODE (ftype);
7861 if (DECL_SIZE (f) != 0
7862 && host_integerp (bit_position (f), 1))
7863 bitpos += int_bit_position (f);
7865 /* ??? FIXME: else assume zero offset. */
7867 if (TREE_CODE (ftype) == RECORD_TYPE)
7868 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7869 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7874 case SCmode: mode = SFmode; break;
7875 case DCmode: mode = DFmode; break;
7876 case TCmode: mode = TFmode; break;
7880 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7882 = gen_rtx_EXPR_LIST (VOIDmode,
7883 gen_rtx_REG (mode, cum->fregno++),
7884 GEN_INT (bitpos / BITS_PER_UNIT));
7885 if (mode == TFmode || mode == TDmode)
7888 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7890 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7892 = gen_rtx_EXPR_LIST (VOIDmode,
7893 gen_rtx_REG (mode, cum->vregno++),
7894 GEN_INT (bitpos / BITS_PER_UNIT));
7896 else if (cum->intoffset == -1)
7897 cum->intoffset = bitpos;
7901 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7902 the register(s) to be used for each field and subfield of a struct
7903 being passed by value, along with the offset of where the
7904 register's value may be found in the block. FP fields go in FP
7905 register, vector fields go in vector registers, and everything
7906 else goes in int registers, packed as in memory.
7908 This code is also used for function return values. RETVAL indicates
7909 whether this is the case.
7911 Much of this is taken from the SPARC V9 port, which has a similar
7912 calling convention. */
7915 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7916 int named, bool retval)
7918 rtx rvec[FIRST_PSEUDO_REGISTER];
7919 int k = 1, kbase = 1;
7920 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7921 /* This is a copy; modifications are not visible to our caller. */
7922 CUMULATIVE_ARGS copy_cum = *orig_cum;
7923 CUMULATIVE_ARGS *cum = ©_cum;
7925 /* Pad to 16 byte boundary if needed. */
7926 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7927 && (cum->words % 2) != 0)
7934 /* Put entries into rvec[] for individual FP and vector fields, and
7935 for the chunks of memory that go in int regs. Note we start at
7936 element 1; 0 is reserved for an indication of using memory, and
7937 may or may not be filled in below. */
7938 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7939 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7941 /* If any part of the struct went on the stack put all of it there.
7942 This hack is because the generic code for
7943 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7944 parts of the struct are not at the beginning. */
7948 return NULL_RTX; /* doesn't go in registers at all */
7950 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7952 if (k > 1 || cum->use_stack)
7953 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7958 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7961 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7965 rtx rvec[GP_ARG_NUM_REG + 1];
7967 if (align_words >= GP_ARG_NUM_REG)
7970 n_units = rs6000_arg_size (mode, type);
7972 /* Optimize the simple case where the arg fits in one gpr, except in
7973 the case of BLKmode due to assign_parms assuming that registers are
7974 BITS_PER_WORD wide. */
7976 || (n_units == 1 && mode != BLKmode))
7977 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7980 if (align_words + n_units > GP_ARG_NUM_REG)
7981 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7982 using a magic NULL_RTX component.
7983 This is not strictly correct. Only some of the arg belongs in
7984 memory, not all of it. However, the normal scheme using
7985 function_arg_partial_nregs can result in unusual subregs, eg.
7986 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7987 store the whole arg to memory is often more efficient than code
7988 to store pieces, and we know that space is available in the right
7989 place for the whole arg. */
7990 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7995 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7996 rtx off = GEN_INT (i++ * 4);
7997 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7999 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8001 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8004 /* Determine where to put an argument to a function.
8005 Value is zero to push the argument on the stack,
8006 or a hard register in which to store the argument.
8008 MODE is the argument's machine mode.
8009 TYPE is the data type of the argument (as a tree).
8010 This is null for libcalls where that information may
8012 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8013 the preceding args and about the function being called. It is
8014 not modified in this routine.
8015 NAMED is nonzero if this argument is a named parameter
8016 (otherwise it is an extra parameter matching an ellipsis).
8018 On RS/6000 the first eight words of non-FP are normally in registers
8019 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8020 Under V.4, the first 8 FP args are in registers.
8022 If this is floating-point and no prototype is specified, we use
8023 both an FP and integer register (or possibly FP reg and stack). Library
8024 functions (when CALL_LIBCALL is set) always have the proper types for args,
8025 so we can pass the FP value just in one register. emit_library_function
8026 doesn't support PARALLEL anyway.
8028 Note that for args passed by reference, function_arg will be called
8029 with MODE and TYPE set to that of the pointer to the arg, not the arg
8033 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8034 tree type, int named)
8036 enum rs6000_abi abi = DEFAULT_ABI;
8038 /* Return a marker to indicate whether CR1 needs to set or clear the
8039 bit that V.4 uses to say fp args were passed in registers.
8040 Assume that we don't need the marker for software floating point,
8041 or compiler generated library calls. */
8042 if (mode == VOIDmode)
8045 && (cum->call_cookie & CALL_LIBCALL) == 0
8047 || (cum->nargs_prototype < 0
8048 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8050 /* For the SPE, we need to crxor CR6 always. */
8052 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8053 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8054 return GEN_INT (cum->call_cookie
8055 | ((cum->fregno == FP_ARG_MIN_REG)
8056 ? CALL_V4_SET_FP_ARGS
8057 : CALL_V4_CLEAR_FP_ARGS));
8060 return GEN_INT (cum->call_cookie);
8063 if (rs6000_darwin64_abi && mode == BLKmode
8064 && TREE_CODE (type) == RECORD_TYPE)
8066 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
8067 if (rslt != NULL_RTX)
8069 /* Else fall through to usual handling. */
8072 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8073 if (TARGET_64BIT && ! cum->prototype)
8075 /* Vector parameters get passed in vector register
8076 and also in GPRs or memory, in absence of prototype. */
8079 align_words = (cum->words + 1) & ~1;
8081 if (align_words >= GP_ARG_NUM_REG)
8087 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8089 return gen_rtx_PARALLEL (mode,
8091 gen_rtx_EXPR_LIST (VOIDmode,
8093 gen_rtx_EXPR_LIST (VOIDmode,
8094 gen_rtx_REG (mode, cum->vregno),
8098 return gen_rtx_REG (mode, cum->vregno);
8099 else if (TARGET_ALTIVEC_ABI
8100 && (ALTIVEC_VECTOR_MODE (mode)
8101 || VSX_VECTOR_MODE (mode)
8102 || (type && TREE_CODE (type) == VECTOR_TYPE
8103 && int_size_in_bytes (type) == 16)))
8105 if (named || abi == ABI_V4)
8109 /* Vector parameters to varargs functions under AIX or Darwin
8110 get passed in memory and possibly also in GPRs. */
8111 int align, align_words, n_words;
8112 enum machine_mode part_mode;
8114 /* Vector parameters must be 16-byte aligned. This places them at
8115 2 mod 4 in terms of words in 32-bit mode, since the parameter
8116 save area starts at offset 24 from the stack. In 64-bit mode,
8117 they just have to start on an even word, since the parameter
8118 save area is 16-byte aligned. */
8120 align = (2 - cum->words) & 3;
8122 align = cum->words & 1;
8123 align_words = cum->words + align;
8125 /* Out of registers? Memory, then. */
8126 if (align_words >= GP_ARG_NUM_REG)
8129 if (TARGET_32BIT && TARGET_POWERPC64)
8130 return rs6000_mixed_function_arg (mode, type, align_words);
8132 /* The vector value goes in GPRs. Only the part of the
8133 value in GPRs is reported here. */
8135 n_words = rs6000_arg_size (mode, type);
8136 if (align_words + n_words > GP_ARG_NUM_REG)
8137 /* Fortunately, there are only two possibilities, the value
8138 is either wholly in GPRs or half in GPRs and half not. */
8141 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8144 else if (TARGET_SPE_ABI && TARGET_SPE
8145 && (SPE_VECTOR_MODE (mode)
8146 || (TARGET_E500_DOUBLE && (mode == DFmode
8149 || mode == TCmode))))
8150 return rs6000_spe_function_arg (cum, mode, type);
8152 else if (abi == ABI_V4)
8154 if (TARGET_HARD_FLOAT && TARGET_FPRS
8155 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8156 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8157 || (mode == TFmode && !TARGET_IEEEQUAD)
8158 || mode == SDmode || mode == DDmode || mode == TDmode))
8160 /* _Decimal128 must use an even/odd register pair. This assumes
8161 that the register number is odd when fregno is odd. */
8162 if (mode == TDmode && (cum->fregno % 2) == 1)
8165 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8166 <= FP_ARG_V4_MAX_REG)
8167 return gen_rtx_REG (mode, cum->fregno);
8173 int n_words = rs6000_arg_size (mode, type);
8174 int gregno = cum->sysv_gregno;
8176 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8177 (r7,r8) or (r9,r10). As does any other 2 word item such
8178 as complex int due to a historical mistake. */
8180 gregno += (1 - gregno) & 1;
8182 /* Multi-reg args are not split between registers and stack. */
8183 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8186 if (TARGET_32BIT && TARGET_POWERPC64)
8187 return rs6000_mixed_function_arg (mode, type,
8188 gregno - GP_ARG_MIN_REG);
8189 return gen_rtx_REG (mode, gregno);
8194 int align_words = rs6000_parm_start (mode, type, cum->words);
8196 /* _Decimal128 must be passed in an even/odd float register pair.
8197 This assumes that the register number is odd when fregno is odd. */
8198 if (mode == TDmode && (cum->fregno % 2) == 1)
8201 if (USE_FP_FOR_ARG_P (cum, mode, type))
8203 rtx rvec[GP_ARG_NUM_REG + 1];
8207 enum machine_mode fmode = mode;
8208 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8210 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8212 /* Currently, we only ever need one reg here because complex
8213 doubles are split. */
8214 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8215 && (fmode == TFmode || fmode == TDmode));
8217 /* Long double or _Decimal128 split over regs and memory. */
8218 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8221 /* Do we also need to pass this arg in the parameter save
8224 && (cum->nargs_prototype <= 0
8225 || (DEFAULT_ABI == ABI_AIX
8227 && align_words >= GP_ARG_NUM_REG)));
8229 if (!needs_psave && mode == fmode)
8230 return gen_rtx_REG (fmode, cum->fregno);
8235 /* Describe the part that goes in gprs or the stack.
8236 This piece must come first, before the fprs. */
8237 if (align_words < GP_ARG_NUM_REG)
8239 unsigned long n_words = rs6000_arg_size (mode, type);
8241 if (align_words + n_words > GP_ARG_NUM_REG
8242 || (TARGET_32BIT && TARGET_POWERPC64))
8244 /* If this is partially on the stack, then we only
8245 include the portion actually in registers here. */
8246 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8249 if (align_words + n_words > GP_ARG_NUM_REG)
8250 /* Not all of the arg fits in gprs. Say that it
8251 goes in memory too, using a magic NULL_RTX
8252 component. Also see comment in
8253 rs6000_mixed_function_arg for why the normal
8254 function_arg_partial_nregs scheme doesn't work
8256 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8260 r = gen_rtx_REG (rmode,
8261 GP_ARG_MIN_REG + align_words);
8262 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8263 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8265 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8269 /* The whole arg fits in gprs. */
8270 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8271 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8275 /* It's entirely in memory. */
8276 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8279 /* Describe where this piece goes in the fprs. */
8280 r = gen_rtx_REG (fmode, cum->fregno);
8281 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8283 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8285 else if (align_words < GP_ARG_NUM_REG)
8287 if (TARGET_32BIT && TARGET_POWERPC64)
8288 return rs6000_mixed_function_arg (mode, type, align_words);
8290 if (mode == BLKmode)
8293 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8300 /* For an arg passed partly in registers and partly in memory, this is
8301 the number of bytes passed in registers. For args passed entirely in
8302 registers or entirely in memory, zero. When an arg is described by a
8303 PARALLEL, perhaps using more than one register type, this function
8304 returns the number of bytes used by the first element of the PARALLEL. */
8307 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8308 tree type, bool named)
8313 if (DEFAULT_ABI == ABI_V4)
8316 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8317 && cum->nargs_prototype >= 0)
8320 /* In this complicated case we just disable the partial_nregs code. */
8321 if (rs6000_darwin64_abi && mode == BLKmode
8322 && TREE_CODE (type) == RECORD_TYPE
8323 && int_size_in_bytes (type) > 0)
8326 align_words = rs6000_parm_start (mode, type, cum->words);
8328 if (USE_FP_FOR_ARG_P (cum, mode, type))
8330 /* If we are passing this arg in the fixed parameter save area
8331 (gprs or memory) as well as fprs, then this function should
8332 return the number of partial bytes passed in the parameter
8333 save area rather than partial bytes passed in fprs. */
8335 && (cum->nargs_prototype <= 0
8336 || (DEFAULT_ABI == ABI_AIX
8338 && align_words >= GP_ARG_NUM_REG)))
8340 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8341 > FP_ARG_MAX_REG + 1)
8342 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8343 else if (cum->nargs_prototype >= 0)
8347 if (align_words < GP_ARG_NUM_REG
8348 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8349 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8351 if (ret != 0 && TARGET_DEBUG_ARG)
8352 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8357 /* A C expression that indicates when an argument must be passed by
8358 reference. If nonzero for an argument, a copy of that argument is
8359 made in memory and a pointer to the argument is passed instead of
8360 the argument itself. The pointer is passed in whatever way is
8361 appropriate for passing a pointer to that type.
8363 Under V.4, aggregates and long double are passed by reference.
8365 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8366 reference unless the AltiVec vector extension ABI is in force.
8368 As an extension to all ABIs, variable sized types are passed by
8372 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
8373 enum machine_mode mode, const_tree type,
8374 bool named ATTRIBUTE_UNUSED)
8376 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8378 if (TARGET_DEBUG_ARG)
8379 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8386 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8388 if (TARGET_DEBUG_ARG)
8389 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8393 if (int_size_in_bytes (type) < 0)
8395 if (TARGET_DEBUG_ARG)
8396 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8400 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8401 modes only exist for GCC vector types if -maltivec. */
8402 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8404 if (TARGET_DEBUG_ARG)
8405 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8409 /* Pass synthetic vectors in memory. */
8410 if (TREE_CODE (type) == VECTOR_TYPE
8411 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8413 static bool warned_for_pass_big_vectors = false;
8414 if (TARGET_DEBUG_ARG)
8415 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8416 if (!warned_for_pass_big_vectors)
8418 warning (0, "GCC vector passed by reference: "
8419 "non-standard ABI extension with no compatibility guarantee");
8420 warned_for_pass_big_vectors = true;
8429 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8432 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8437 for (i = 0; i < nregs; i++)
8439 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8440 if (reload_completed)
8442 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8445 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8446 i * GET_MODE_SIZE (reg_mode));
8449 tem = replace_equiv_address (tem, XEXP (tem, 0));
8453 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8457 /* Perform any needed actions needed for a function that is receiving a
8458 variable number of arguments.
8462 MODE and TYPE are the mode and type of the current parameter.
8464 PRETEND_SIZE is a variable that should be set to the amount of stack
8465 that must be pushed by the prolog to pretend that our caller pushed
8468 Normally, this macro will push all remaining incoming registers on the
8469 stack and set PRETEND_SIZE to the length of the registers pushed. */
8472 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8473 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8476 CUMULATIVE_ARGS next_cum;
8477 int reg_size = TARGET_32BIT ? 4 : 8;
8478 rtx save_area = NULL_RTX, mem;
8479 int first_reg_offset;
8482 /* Skip the last named argument. */
8484 function_arg_advance (&next_cum, mode, type, 1, 0);
8486 if (DEFAULT_ABI == ABI_V4)
8488 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8492 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8493 HOST_WIDE_INT offset = 0;
8495 /* Try to optimize the size of the varargs save area.
8496 The ABI requires that ap.reg_save_area is doubleword
8497 aligned, but we don't need to allocate space for all
8498 the bytes, only those to which we actually will save
8500 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8501 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8502 if (TARGET_HARD_FLOAT && TARGET_FPRS
8503 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8504 && cfun->va_list_fpr_size)
8507 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8508 * UNITS_PER_FP_WORD;
8509 if (cfun->va_list_fpr_size
8510 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8511 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8513 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8514 * UNITS_PER_FP_WORD;
8518 offset = -((first_reg_offset * reg_size) & ~7);
8519 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8521 gpr_reg_num = cfun->va_list_gpr_size;
8522 if (reg_size == 4 && (first_reg_offset & 1))
8525 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8528 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8530 - (int) (GP_ARG_NUM_REG * reg_size);
8532 if (gpr_size + fpr_size)
8535 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8536 gcc_assert (GET_CODE (reg_save_area) == MEM);
8537 reg_save_area = XEXP (reg_save_area, 0);
8538 if (GET_CODE (reg_save_area) == PLUS)
8540 gcc_assert (XEXP (reg_save_area, 0)
8541 == virtual_stack_vars_rtx);
8542 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8543 offset += INTVAL (XEXP (reg_save_area, 1));
8546 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8549 cfun->machine->varargs_save_offset = offset;
8550 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8555 first_reg_offset = next_cum.words;
8556 save_area = virtual_incoming_args_rtx;
8558 if (targetm.calls.must_pass_in_stack (mode, type))
8559 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8562 set = get_varargs_alias_set ();
8563 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8564 && cfun->va_list_gpr_size)
8566 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8568 if (va_list_gpr_counter_field)
8570 /* V4 va_list_gpr_size counts number of registers needed. */
8571 if (nregs > cfun->va_list_gpr_size)
8572 nregs = cfun->va_list_gpr_size;
8576 /* char * va_list instead counts number of bytes needed. */
8577 if (nregs > cfun->va_list_gpr_size / reg_size)
8578 nregs = cfun->va_list_gpr_size / reg_size;
8581 mem = gen_rtx_MEM (BLKmode,
8582 plus_constant (save_area,
8583 first_reg_offset * reg_size));
8584 MEM_NOTRAP_P (mem) = 1;
8585 set_mem_alias_set (mem, set);
8586 set_mem_align (mem, BITS_PER_WORD);
8588 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8592 /* Save FP registers if needed. */
8593 if (DEFAULT_ABI == ABI_V4
8594 && TARGET_HARD_FLOAT && TARGET_FPRS
8596 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8597 && cfun->va_list_fpr_size)
8599 int fregno = next_cum.fregno, nregs;
8600 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8601 rtx lab = gen_label_rtx ();
8602 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8603 * UNITS_PER_FP_WORD);
8606 (gen_rtx_SET (VOIDmode,
8608 gen_rtx_IF_THEN_ELSE (VOIDmode,
8609 gen_rtx_NE (VOIDmode, cr1,
8611 gen_rtx_LABEL_REF (VOIDmode, lab),
8615 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8616 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8618 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8620 plus_constant (save_area, off));
8621 MEM_NOTRAP_P (mem) = 1;
8622 set_mem_alias_set (mem, set);
8623 set_mem_align (mem, GET_MODE_ALIGNMENT (
8624 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8625 ? DFmode : SFmode));
8626 emit_move_insn (mem, gen_rtx_REG (
8627 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8628 ? DFmode : SFmode, fregno));
8635 /* Create the va_list data type. */
8638 rs6000_build_builtin_va_list (void)
8640 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8642 /* For AIX, prefer 'char *' because that's what the system
8643 header files like. */
8644 if (DEFAULT_ABI != ABI_V4)
8645 return build_pointer_type (char_type_node);
8647 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8648 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8649 get_identifier ("__va_list_tag"), record);
8651 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8652 unsigned_char_type_node);
8653 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8654 unsigned_char_type_node);
8655 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8657 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8658 get_identifier ("reserved"), short_unsigned_type_node);
8659 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8660 get_identifier ("overflow_arg_area"),
8662 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8663 get_identifier ("reg_save_area"),
8666 va_list_gpr_counter_field = f_gpr;
8667 va_list_fpr_counter_field = f_fpr;
8669 DECL_FIELD_CONTEXT (f_gpr) = record;
8670 DECL_FIELD_CONTEXT (f_fpr) = record;
8671 DECL_FIELD_CONTEXT (f_res) = record;
8672 DECL_FIELD_CONTEXT (f_ovf) = record;
8673 DECL_FIELD_CONTEXT (f_sav) = record;
8675 TREE_CHAIN (record) = type_decl;
8676 TYPE_NAME (record) = type_decl;
8677 TYPE_FIELDS (record) = f_gpr;
8678 TREE_CHAIN (f_gpr) = f_fpr;
8679 TREE_CHAIN (f_fpr) = f_res;
8680 TREE_CHAIN (f_res) = f_ovf;
8681 TREE_CHAIN (f_ovf) = f_sav;
8683 layout_type (record);
8685 /* The correct type is an array type of one element. */
8686 return build_array_type (record, build_index_type (size_zero_node));
8689 /* Implement va_start. */
8692 rs6000_va_start (tree valist, rtx nextarg)
8694 HOST_WIDE_INT words, n_gpr, n_fpr;
8695 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8696 tree gpr, fpr, ovf, sav, t;
8698 /* Only SVR4 needs something special. */
8699 if (DEFAULT_ABI != ABI_V4)
8701 std_expand_builtin_va_start (valist, nextarg);
8705 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8706 f_fpr = TREE_CHAIN (f_gpr);
8707 f_res = TREE_CHAIN (f_fpr);
8708 f_ovf = TREE_CHAIN (f_res);
8709 f_sav = TREE_CHAIN (f_ovf);
8711 valist = build_va_arg_indirect_ref (valist);
8712 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8713 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8715 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8717 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8720 /* Count number of gp and fp argument registers used. */
8721 words = crtl->args.info.words;
8722 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8724 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8727 if (TARGET_DEBUG_ARG)
8728 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8729 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8730 words, n_gpr, n_fpr);
8732 if (cfun->va_list_gpr_size)
8734 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8735 build_int_cst (NULL_TREE, n_gpr));
8736 TREE_SIDE_EFFECTS (t) = 1;
8737 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8740 if (cfun->va_list_fpr_size)
8742 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8743 build_int_cst (NULL_TREE, n_fpr));
8744 TREE_SIDE_EFFECTS (t) = 1;
8745 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8748 /* Find the overflow area. */
8749 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8751 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8752 size_int (words * UNITS_PER_WORD));
8753 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8754 TREE_SIDE_EFFECTS (t) = 1;
8755 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8757 /* If there were no va_arg invocations, don't set up the register
8759 if (!cfun->va_list_gpr_size
8760 && !cfun->va_list_fpr_size
8761 && n_gpr < GP_ARG_NUM_REG
8762 && n_fpr < FP_ARG_V4_MAX_REG)
8765 /* Find the register save area. */
8766 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8767 if (cfun->machine->varargs_save_offset)
8768 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8769 size_int (cfun->machine->varargs_save_offset));
8770 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8771 TREE_SIDE_EFFECTS (t) = 1;
8772 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8775 /* Implement va_arg. */
8778 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8781 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8782 tree gpr, fpr, ovf, sav, reg, t, u;
8783 int size, rsize, n_reg, sav_ofs, sav_scale;
8784 tree lab_false, lab_over, addr;
8786 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8790 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8792 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8793 return build_va_arg_indirect_ref (t);
8796 if (DEFAULT_ABI != ABI_V4)
8798 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8800 tree elem_type = TREE_TYPE (type);
8801 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8802 int elem_size = GET_MODE_SIZE (elem_mode);
8804 if (elem_size < UNITS_PER_WORD)
8806 tree real_part, imag_part;
8807 gimple_seq post = NULL;
8809 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8811 /* Copy the value into a temporary, lest the formal temporary
8812 be reused out from under us. */
8813 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8814 gimple_seq_add_seq (pre_p, post);
8816 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8819 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8823 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8826 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8827 f_fpr = TREE_CHAIN (f_gpr);
8828 f_res = TREE_CHAIN (f_fpr);
8829 f_ovf = TREE_CHAIN (f_res);
8830 f_sav = TREE_CHAIN (f_ovf);
8832 valist = build_va_arg_indirect_ref (valist);
8833 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8834 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8836 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8838 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8841 size = int_size_in_bytes (type);
8842 rsize = (size + 3) / 4;
8845 if (TARGET_HARD_FLOAT && TARGET_FPRS
8846 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8847 || (TARGET_DOUBLE_FLOAT
8848 && (TYPE_MODE (type) == DFmode
8849 || TYPE_MODE (type) == TFmode
8850 || TYPE_MODE (type) == SDmode
8851 || TYPE_MODE (type) == DDmode
8852 || TYPE_MODE (type) == TDmode))))
8854 /* FP args go in FP registers, if present. */
8856 n_reg = (size + 7) / 8;
8857 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8858 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8859 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8864 /* Otherwise into GP registers. */
8873 /* Pull the value out of the saved registers.... */
8876 addr = create_tmp_var (ptr_type_node, "addr");
8878 /* AltiVec vectors never go in registers when -mabi=altivec. */
8879 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8883 lab_false = create_artificial_label (input_location);
8884 lab_over = create_artificial_label (input_location);
8886 /* Long long and SPE vectors are aligned in the registers.
8887 As are any other 2 gpr item such as complex int due to a
8888 historical mistake. */
8890 if (n_reg == 2 && reg == gpr)
8893 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8894 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8895 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8896 unshare_expr (reg), u);
8898 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8899 reg number is 0 for f1, so we want to make it odd. */
8900 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8902 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8903 build_int_cst (TREE_TYPE (reg), 1));
8904 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8907 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8908 t = build2 (GE_EXPR, boolean_type_node, u, t);
8909 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8910 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8911 gimplify_and_add (t, pre_p);
8915 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8917 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8918 build_int_cst (TREE_TYPE (reg), n_reg));
8919 u = fold_convert (sizetype, u);
8920 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8921 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8923 /* _Decimal32 varargs are located in the second word of the 64-bit
8924 FP register for 32-bit binaries. */
8925 if (!TARGET_POWERPC64
8926 && TARGET_HARD_FLOAT && TARGET_FPRS
8927 && TYPE_MODE (type) == SDmode)
8928 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8930 gimplify_assign (addr, t, pre_p);
8932 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8934 stmt = gimple_build_label (lab_false);
8935 gimple_seq_add_stmt (pre_p, stmt);
8937 if ((n_reg == 2 && !regalign) || n_reg > 2)
8939 /* Ensure that we don't find any more args in regs.
8940 Alignment has taken care of for special cases. */
8941 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8945 /* ... otherwise out of the overflow area. */
8947 /* Care for on-stack alignment if needed. */
8951 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8952 t = fold_convert (sizetype, t);
8953 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8955 t = fold_convert (TREE_TYPE (ovf), t);
8957 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8959 gimplify_assign (unshare_expr (addr), t, pre_p);
8961 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8962 gimplify_assign (unshare_expr (ovf), t, pre_p);
8966 stmt = gimple_build_label (lab_over);
8967 gimple_seq_add_stmt (pre_p, stmt);
8970 if (STRICT_ALIGNMENT
8971 && (TYPE_ALIGN (type)
8972 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8974 /* The value (of type complex double, for example) may not be
8975 aligned in memory in the saved registers, so copy via a
8976 temporary. (This is the same code as used for SPARC.) */
8977 tree tmp = create_tmp_var (type, "va_arg_tmp");
8978 tree dest_addr = build_fold_addr_expr (tmp);
8980 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8981 3, dest_addr, addr, size_int (rsize * 4));
8983 gimplify_and_add (copy, pre_p);
8987 addr = fold_convert (ptrtype, addr);
8988 return build_va_arg_indirect_ref (addr);
8994 def_builtin (int mask, const char *name, tree type, int code)
8996 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8999 if (rs6000_builtin_decls[code])
9000 fatal_error ("internal error: builtin function to %s already processed.",
9003 rs6000_builtin_decls[code] = t =
9004 add_builtin_function (name, type, code, BUILT_IN_MD,
9007 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9008 switch (builtin_classify[code])
9013 /* assume builtin can do anything. */
9014 case RS6000_BTC_MISC:
9017 /* const function, function only depends on the inputs. */
9018 case RS6000_BTC_CONST:
9019 TREE_READONLY (t) = 1;
9020 TREE_NOTHROW (t) = 1;
9023 /* pure function, function can read global memory. */
9024 case RS6000_BTC_PURE:
9025 DECL_PURE_P (t) = 1;
9026 TREE_NOTHROW (t) = 1;
9029 /* Function is a math function. If rounding mode is on, then treat
9030 the function as not reading global memory, but it can have
9031 arbitrary side effects. If it is off, then assume the function is
9032 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9033 attribute in builtin-attribute.def that is used for the math
9035 case RS6000_BTC_FP_PURE:
9036 TREE_NOTHROW (t) = 1;
9037 if (flag_rounding_math)
9039 DECL_PURE_P (t) = 1;
9040 DECL_IS_NOVOPS (t) = 1;
9043 TREE_READONLY (t) = 1;
9049 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9051 static const struct builtin_description bdesc_3arg[] =
9053 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9054 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9055 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9056 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9057 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9058 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9059 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9060 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9061 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9062 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9063 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9064 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9065 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9066 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9067 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9068 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9069 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9070 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9071 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9072 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9073 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9074 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9075 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9076 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9077 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9078 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9079 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9080 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9081 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9082 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9083 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9084 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9085 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9086 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9087 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9089 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9090 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9091 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9092 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9093 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9094 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9095 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9096 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9097 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9098 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9099 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9100 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9101 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9102 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9103 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9105 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9106 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9107 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9108 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9110 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9111 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9112 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9113 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9115 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9116 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9118 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9119 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9120 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9121 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9122 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9123 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9124 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9125 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9126 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9127 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9129 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9130 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9131 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9132 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9133 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9134 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9135 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9136 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9137 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9138 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9140 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9141 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9142 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9143 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9144 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9145 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9146 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9147 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9148 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9150 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9151 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9152 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9153 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9154 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9155 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9156 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9158 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9159 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9160 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9161 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9162 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9163 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9164 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9165 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9166 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9169 /* DST operations: void foo (void *, const int, const char). */
9171 static const struct builtin_description bdesc_dst[] =
9173 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9174 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9175 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9176 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9178 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9179 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9180 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9181 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9184 /* Simple binary operations: VECc = foo (VECa, VECb). */
9186 static struct builtin_description bdesc_2arg[] =
9188 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9189 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9190 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9191 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9192 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9193 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9194 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9195 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9196 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9197 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9198 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9199 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9200 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9201 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9202 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9203 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9204 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9205 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9206 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9207 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9208 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9209 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9210 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9211 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9212 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9213 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9214 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9215 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9216 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9217 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9218 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9219 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9220 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9221 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9222 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9223 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9224 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9225 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9226 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9227 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9228 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9229 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9230 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9231 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9232 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9233 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9234 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9235 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9236 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9237 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9238 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9239 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9240 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9241 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9242 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9243 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9244 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9245 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9246 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9247 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9248 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9249 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9250 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9251 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9252 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9253 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9254 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9255 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9256 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9257 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9258 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9259 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9260 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9261 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9262 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9263 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9264 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9265 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9266 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9267 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9268 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9269 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9270 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9271 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9272 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9273 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9274 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9275 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9276 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9277 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9278 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9279 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9280 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9281 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9282 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9283 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9284 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9285 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9286 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9287 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9288 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9289 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9290 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9291 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9292 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9293 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9294 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9295 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9296 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9297 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9298 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9299 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9300 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9301 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9302 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9303 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9304 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9306 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9307 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9308 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9309 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9310 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9311 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9312 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9313 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9314 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9315 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9316 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9317 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9319 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9320 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9321 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9322 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9323 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9324 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9325 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9326 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9327 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9328 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9329 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9330 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9332 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9333 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9334 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9335 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9336 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9337 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9339 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9340 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9341 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9342 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9343 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9344 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9345 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9346 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9347 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9348 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9349 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9350 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9352 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9353 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9354 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9355 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9356 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9357 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9358 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9359 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9360 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9361 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9362 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9363 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9364 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9365 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9366 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9367 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9368 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9369 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9370 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9371 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9372 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9373 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9374 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9375 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9376 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9377 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9378 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9379 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9380 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9381 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9382 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9383 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9384 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9385 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9386 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9387 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9388 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9389 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9390 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9391 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9392 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9393 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9394 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9395 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9396 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9397 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9398 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9399 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9400 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9401 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9402 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9403 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9404 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9405 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9406 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9407 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9408 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9409 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9410 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9411 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9412 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9413 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9414 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9415 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9416 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9417 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9418 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9419 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9420 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9421 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9422 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9423 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9424 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9425 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9426 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9427 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9428 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9429 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9430 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9431 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9432 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9433 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9434 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9435 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9436 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9437 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9438 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9439 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9440 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
9441 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9442 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9443 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9444 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9445 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9446 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9447 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9448 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9449 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9450 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9453 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9454 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9455 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9456 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9457 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9458 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9459 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9460 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9461 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9462 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9463 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9464 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9465 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9466 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9467 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9468 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9469 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9470 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9471 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9472 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9473 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9474 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9475 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9476 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9477 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9478 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9479 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9480 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9482 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9483 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9485 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9486 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9487 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9488 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9489 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9490 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9491 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9492 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9493 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9494 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9496 /* Place holder, leave as first spe builtin. */
9497 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9498 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9499 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9500 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9501 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9502 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9503 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9504 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9505 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9506 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9507 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9508 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9509 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9510 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9511 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9512 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9513 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9514 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9515 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9516 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9517 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9518 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9519 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9520 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9521 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9522 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9523 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9524 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9525 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9526 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9527 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9528 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9529 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9530 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9531 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9532 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9533 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9534 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9535 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9536 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9537 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9538 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9539 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9540 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9541 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9542 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9543 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9544 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9545 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9546 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9547 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9548 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9549 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9550 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9551 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9552 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9553 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9554 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9555 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9556 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9557 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9558 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9559 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9560 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9561 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9562 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9563 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9564 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9565 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9566 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9567 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9568 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9569 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9570 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9571 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9572 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9573 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9574 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9575 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9576 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9577 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9578 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9579 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9580 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9581 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9582 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9583 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9584 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9585 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9586 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9587 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9588 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9589 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9590 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9591 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9592 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9593 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9594 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9595 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9596 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9597 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9598 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9599 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9600 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9601 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9602 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9603 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9604 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9605 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9607 /* SPE binary operations expecting a 5-bit unsigned literal. */
9608 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9610 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9611 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9612 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9613 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9614 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9615 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9616 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9617 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9618 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9619 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9620 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9621 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9622 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9623 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9624 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9625 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9626 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9627 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9628 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9629 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9630 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9631 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9632 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9633 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9634 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9635 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9637 /* Place-holder. Leave as last binary SPE builtin. */
9638 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9641 /* AltiVec predicates. */
9643 struct builtin_description_predicates
9645 const unsigned int mask;
9646 const enum insn_code icode;
9647 const char *const name;
9648 const enum rs6000_builtins code;
9651 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9653 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9654 ALTIVEC_BUILTIN_VCMPBFP_P },
9655 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9656 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9657 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9658 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9659 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9660 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9661 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9662 ALTIVEC_BUILTIN_VCMPEQUW_P },
9663 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9664 ALTIVEC_BUILTIN_VCMPGTSW_P },
9665 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9666 ALTIVEC_BUILTIN_VCMPGTUW_P },
9667 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9668 ALTIVEC_BUILTIN_VCMPEQUH_P },
9669 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9670 ALTIVEC_BUILTIN_VCMPGTSH_P },
9671 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9672 ALTIVEC_BUILTIN_VCMPGTUH_P },
9673 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9674 ALTIVEC_BUILTIN_VCMPEQUB_P },
9675 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9676 ALTIVEC_BUILTIN_VCMPGTSB_P },
9677 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9678 ALTIVEC_BUILTIN_VCMPGTUB_P },
9680 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9681 VSX_BUILTIN_XVCMPEQSP_P },
9682 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9683 VSX_BUILTIN_XVCMPGESP_P },
9684 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9685 VSX_BUILTIN_XVCMPGTSP_P },
9686 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9687 VSX_BUILTIN_XVCMPEQDP_P },
9688 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9689 VSX_BUILTIN_XVCMPGEDP_P },
9690 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9691 VSX_BUILTIN_XVCMPGTDP_P },
9693 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9694 ALTIVEC_BUILTIN_VCMPEQ_P },
9695 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9696 ALTIVEC_BUILTIN_VCMPGT_P },
9697 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9698 ALTIVEC_BUILTIN_VCMPGE_P }
9701 /* SPE predicates. */
9702 static struct builtin_description bdesc_spe_predicates[] =
9704 /* Place-holder. Leave as first. */
9705 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9706 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9707 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9708 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9709 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9710 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9711 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9712 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9713 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9714 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9715 /* Place-holder. Leave as last. */
9716 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9719 /* SPE evsel predicates. */
9720 static struct builtin_description bdesc_spe_evsel[] =
9722 /* Place-holder. Leave as first. */
9723 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9724 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9725 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9726 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9727 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9728 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9729 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9730 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9731 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9732 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9733 /* Place-holder. Leave as last. */
9734 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9737 /* PAIRED predicates. */
9738 static const struct builtin_description bdesc_paired_preds[] =
9740 /* Place-holder. Leave as first. */
9741 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9742 /* Place-holder. Leave as last. */
9743 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9746 /* ABS* operations. */
9748 static const struct builtin_description bdesc_abs[] =
9750 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9751 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9752 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9753 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9754 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9755 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9756 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9757 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9758 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9759 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9760 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9763 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9766 static struct builtin_description bdesc_1arg[] =
9768 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9769 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9770 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9771 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9772 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9773 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9774 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9775 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
9776 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9777 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9778 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9779 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9780 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9781 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9782 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9783 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9784 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9785 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9787 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9788 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9789 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
9790 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9791 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9792 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9793 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9795 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9796 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9797 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
9798 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9799 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9800 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9801 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9803 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9804 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9805 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9806 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9807 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9808 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9810 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9811 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9812 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9813 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9814 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9815 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9817 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9818 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9819 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9820 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9822 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9823 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9824 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9825 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9826 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9827 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9828 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9829 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9830 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9832 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9833 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9834 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9835 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9836 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9837 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9838 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9839 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9840 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9842 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9843 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9844 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9845 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9846 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9848 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9849 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9850 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9851 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9852 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9853 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9854 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9855 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9856 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9857 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
9858 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9859 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9860 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9861 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9862 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9863 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9864 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9865 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9866 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9867 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9869 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9870 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9871 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9873 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9874 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9875 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9876 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9878 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9879 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9880 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9881 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9882 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9883 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9884 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9885 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9886 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9887 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9888 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9889 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9890 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9891 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9892 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9893 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9894 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9895 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9896 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9897 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9898 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9899 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9900 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9901 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9902 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9903 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9904 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9905 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9906 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9907 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9909 /* Place-holder. Leave as last unary SPE builtin. */
9910 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9912 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9913 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9914 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9915 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9916 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9920 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9923 tree arg0 = CALL_EXPR_ARG (exp, 0);
9924 rtx op0 = expand_normal (arg0);
9925 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9926 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9928 if (icode == CODE_FOR_nothing)
9929 /* Builtin not supported on this processor. */
9932 /* If we got invalid arguments bail out before generating bad rtl. */
9933 if (arg0 == error_mark_node)
9936 if (icode == CODE_FOR_altivec_vspltisb
9937 || icode == CODE_FOR_altivec_vspltish
9938 || icode == CODE_FOR_altivec_vspltisw
9939 || icode == CODE_FOR_spe_evsplatfi
9940 || icode == CODE_FOR_spe_evsplati)
9942 /* Only allow 5-bit *signed* literals. */
9943 if (GET_CODE (op0) != CONST_INT
9944 || INTVAL (op0) > 15
9945 || INTVAL (op0) < -16)
9947 error ("argument 1 must be a 5-bit signed literal");
9953 || GET_MODE (target) != tmode
9954 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9955 target = gen_reg_rtx (tmode);
9957 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9958 op0 = copy_to_mode_reg (mode0, op0);
9960 pat = GEN_FCN (icode) (target, op0);
9969 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9971 rtx pat, scratch1, scratch2;
9972 tree arg0 = CALL_EXPR_ARG (exp, 0);
9973 rtx op0 = expand_normal (arg0);
9974 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9975 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9977 /* If we have invalid arguments, bail out before generating bad rtl. */
9978 if (arg0 == error_mark_node)
9982 || GET_MODE (target) != tmode
9983 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9984 target = gen_reg_rtx (tmode);
9986 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9987 op0 = copy_to_mode_reg (mode0, op0);
9989 scratch1 = gen_reg_rtx (mode0);
9990 scratch2 = gen_reg_rtx (mode0);
9992 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10001 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10004 tree arg0 = CALL_EXPR_ARG (exp, 0);
10005 tree arg1 = CALL_EXPR_ARG (exp, 1);
10006 rtx op0 = expand_normal (arg0);
10007 rtx op1 = expand_normal (arg1);
10008 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10009 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10010 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10012 if (icode == CODE_FOR_nothing)
10013 /* Builtin not supported on this processor. */
10016 /* If we got invalid arguments bail out before generating bad rtl. */
10017 if (arg0 == error_mark_node || arg1 == error_mark_node)
10020 if (icode == CODE_FOR_altivec_vcfux
10021 || icode == CODE_FOR_altivec_vcfsx
10022 || icode == CODE_FOR_altivec_vctsxs
10023 || icode == CODE_FOR_altivec_vctuxs
10024 || icode == CODE_FOR_altivec_vspltb
10025 || icode == CODE_FOR_altivec_vsplth
10026 || icode == CODE_FOR_altivec_vspltw
10027 || icode == CODE_FOR_spe_evaddiw
10028 || icode == CODE_FOR_spe_evldd
10029 || icode == CODE_FOR_spe_evldh
10030 || icode == CODE_FOR_spe_evldw
10031 || icode == CODE_FOR_spe_evlhhesplat
10032 || icode == CODE_FOR_spe_evlhhossplat
10033 || icode == CODE_FOR_spe_evlhhousplat
10034 || icode == CODE_FOR_spe_evlwhe
10035 || icode == CODE_FOR_spe_evlwhos
10036 || icode == CODE_FOR_spe_evlwhou
10037 || icode == CODE_FOR_spe_evlwhsplat
10038 || icode == CODE_FOR_spe_evlwwsplat
10039 || icode == CODE_FOR_spe_evrlwi
10040 || icode == CODE_FOR_spe_evslwi
10041 || icode == CODE_FOR_spe_evsrwis
10042 || icode == CODE_FOR_spe_evsubifw
10043 || icode == CODE_FOR_spe_evsrwiu)
10045 /* Only allow 5-bit unsigned literals. */
10047 if (TREE_CODE (arg1) != INTEGER_CST
10048 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10050 error ("argument 2 must be a 5-bit unsigned literal");
10056 || GET_MODE (target) != tmode
10057 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10058 target = gen_reg_rtx (tmode);
10060 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10061 op0 = copy_to_mode_reg (mode0, op0);
10062 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10063 op1 = copy_to_mode_reg (mode1, op1);
10065 pat = GEN_FCN (icode) (target, op0, op1);
10074 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10077 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10078 tree arg0 = CALL_EXPR_ARG (exp, 1);
10079 tree arg1 = CALL_EXPR_ARG (exp, 2);
10080 rtx op0 = expand_normal (arg0);
10081 rtx op1 = expand_normal (arg1);
10082 enum machine_mode tmode = SImode;
10083 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10084 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10087 if (TREE_CODE (cr6_form) != INTEGER_CST)
10089 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10093 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10095 gcc_assert (mode0 == mode1);
10097 /* If we have invalid arguments, bail out before generating bad rtl. */
10098 if (arg0 == error_mark_node || arg1 == error_mark_node)
10102 || GET_MODE (target) != tmode
10103 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10104 target = gen_reg_rtx (tmode);
10106 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10107 op0 = copy_to_mode_reg (mode0, op0);
10108 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10109 op1 = copy_to_mode_reg (mode1, op1);
10111 scratch = gen_reg_rtx (mode0);
10113 pat = GEN_FCN (icode) (scratch, op0, op1);
10118 /* The vec_any* and vec_all* predicates use the same opcodes for two
10119 different operations, but the bits in CR6 will be different
10120 depending on what information we want. So we have to play tricks
10121 with CR6 to get the right bits out.
10123 If you think this is disgusting, look at the specs for the
10124 AltiVec predicates. */
10126 switch (cr6_form_int)
10129 emit_insn (gen_cr6_test_for_zero (target));
10132 emit_insn (gen_cr6_test_for_zero_reverse (target));
10135 emit_insn (gen_cr6_test_for_lt (target));
10138 emit_insn (gen_cr6_test_for_lt_reverse (target));
10141 error ("argument 1 of __builtin_altivec_predicate is out of range");
10149 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10152 tree arg0 = CALL_EXPR_ARG (exp, 0);
10153 tree arg1 = CALL_EXPR_ARG (exp, 1);
10154 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10155 enum machine_mode mode0 = Pmode;
10156 enum machine_mode mode1 = Pmode;
10157 rtx op0 = expand_normal (arg0);
10158 rtx op1 = expand_normal (arg1);
10160 if (icode == CODE_FOR_nothing)
10161 /* Builtin not supported on this processor. */
10164 /* If we got invalid arguments bail out before generating bad rtl. */
10165 if (arg0 == error_mark_node || arg1 == error_mark_node)
10169 || GET_MODE (target) != tmode
10170 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10171 target = gen_reg_rtx (tmode);
10173 op1 = copy_to_mode_reg (mode1, op1);
10175 if (op0 == const0_rtx)
10177 addr = gen_rtx_MEM (tmode, op1);
10181 op0 = copy_to_mode_reg (mode0, op0);
10182 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10185 pat = GEN_FCN (icode) (target, addr);
10195 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10198 tree arg0 = CALL_EXPR_ARG (exp, 0);
10199 tree arg1 = CALL_EXPR_ARG (exp, 1);
10200 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10201 enum machine_mode mode0 = Pmode;
10202 enum machine_mode mode1 = Pmode;
10203 rtx op0 = expand_normal (arg0);
10204 rtx op1 = expand_normal (arg1);
10206 if (icode == CODE_FOR_nothing)
10207 /* Builtin not supported on this processor. */
10210 /* If we got invalid arguments bail out before generating bad rtl. */
10211 if (arg0 == error_mark_node || arg1 == error_mark_node)
10215 || GET_MODE (target) != tmode
10216 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10217 target = gen_reg_rtx (tmode);
10219 op1 = copy_to_mode_reg (mode1, op1);
10221 if (op0 == const0_rtx)
10223 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10227 op0 = copy_to_mode_reg (mode0, op0);
10228 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10231 pat = GEN_FCN (icode) (target, addr);
10241 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10243 tree arg0 = CALL_EXPR_ARG (exp, 0);
10244 tree arg1 = CALL_EXPR_ARG (exp, 1);
10245 tree arg2 = CALL_EXPR_ARG (exp, 2);
10246 rtx op0 = expand_normal (arg0);
10247 rtx op1 = expand_normal (arg1);
10248 rtx op2 = expand_normal (arg2);
10250 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10251 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10252 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10254 /* Invalid arguments. Bail before doing anything stoopid! */
10255 if (arg0 == error_mark_node
10256 || arg1 == error_mark_node
10257 || arg2 == error_mark_node)
10260 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10261 op0 = copy_to_mode_reg (mode2, op0);
10262 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10263 op1 = copy_to_mode_reg (mode0, op1);
10264 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10265 op2 = copy_to_mode_reg (mode1, op2);
10267 pat = GEN_FCN (icode) (op1, op2, op0);
10274 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10276 tree arg0 = CALL_EXPR_ARG (exp, 0);
10277 tree arg1 = CALL_EXPR_ARG (exp, 1);
10278 tree arg2 = CALL_EXPR_ARG (exp, 2);
10279 rtx op0 = expand_normal (arg0);
10280 rtx op1 = expand_normal (arg1);
10281 rtx op2 = expand_normal (arg2);
10283 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10284 enum machine_mode mode1 = Pmode;
10285 enum machine_mode mode2 = Pmode;
10287 /* Invalid arguments. Bail before doing anything stoopid! */
10288 if (arg0 == error_mark_node
10289 || arg1 == error_mark_node
10290 || arg2 == error_mark_node)
10293 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10294 op0 = copy_to_mode_reg (tmode, op0);
10296 op2 = copy_to_mode_reg (mode2, op2);
10298 if (op1 == const0_rtx)
10300 addr = gen_rtx_MEM (tmode, op2);
10304 op1 = copy_to_mode_reg (mode1, op1);
10305 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10308 pat = GEN_FCN (icode) (addr, op0);
10315 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10317 tree arg0 = CALL_EXPR_ARG (exp, 0);
10318 tree arg1 = CALL_EXPR_ARG (exp, 1);
10319 tree arg2 = CALL_EXPR_ARG (exp, 2);
10320 rtx op0 = expand_normal (arg0);
10321 rtx op1 = expand_normal (arg1);
10322 rtx op2 = expand_normal (arg2);
10324 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10325 enum machine_mode mode1 = Pmode;
10326 enum machine_mode mode2 = Pmode;
10328 /* Invalid arguments. Bail before doing anything stoopid! */
10329 if (arg0 == error_mark_node
10330 || arg1 == error_mark_node
10331 || arg2 == error_mark_node)
10334 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10335 op0 = copy_to_mode_reg (tmode, op0);
10337 op2 = copy_to_mode_reg (mode2, op2);
10339 if (op1 == const0_rtx)
10341 addr = gen_rtx_MEM (tmode, op2);
10345 op1 = copy_to_mode_reg (mode1, op1);
10346 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10349 pat = GEN_FCN (icode) (addr, op0);
10356 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10359 tree arg0 = CALL_EXPR_ARG (exp, 0);
10360 tree arg1 = CALL_EXPR_ARG (exp, 1);
10361 tree arg2 = CALL_EXPR_ARG (exp, 2);
10362 rtx op0 = expand_normal (arg0);
10363 rtx op1 = expand_normal (arg1);
10364 rtx op2 = expand_normal (arg2);
10365 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10366 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10367 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10368 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10370 if (icode == CODE_FOR_nothing)
10371 /* Builtin not supported on this processor. */
10374 /* If we got invalid arguments bail out before generating bad rtl. */
10375 if (arg0 == error_mark_node
10376 || arg1 == error_mark_node
10377 || arg2 == error_mark_node)
10382 case CODE_FOR_altivec_vsldoi_v4sf:
10383 case CODE_FOR_altivec_vsldoi_v4si:
10384 case CODE_FOR_altivec_vsldoi_v8hi:
10385 case CODE_FOR_altivec_vsldoi_v16qi:
10386 /* Only allow 4-bit unsigned literals. */
10388 if (TREE_CODE (arg2) != INTEGER_CST
10389 || TREE_INT_CST_LOW (arg2) & ~0xf)
10391 error ("argument 3 must be a 4-bit unsigned literal");
10396 case CODE_FOR_vsx_xxpermdi_v2df:
10397 case CODE_FOR_vsx_xxpermdi_v2di:
10398 case CODE_FOR_vsx_xxsldwi_v16qi:
10399 case CODE_FOR_vsx_xxsldwi_v8hi:
10400 case CODE_FOR_vsx_xxsldwi_v4si:
10401 case CODE_FOR_vsx_xxsldwi_v4sf:
10402 case CODE_FOR_vsx_xxsldwi_v2di:
10403 case CODE_FOR_vsx_xxsldwi_v2df:
10404 /* Only allow 2-bit unsigned literals. */
10406 if (TREE_CODE (arg2) != INTEGER_CST
10407 || TREE_INT_CST_LOW (arg2) & ~0x3)
10409 error ("argument 3 must be a 2-bit unsigned literal");
10414 case CODE_FOR_vsx_set_v2df:
10415 case CODE_FOR_vsx_set_v2di:
10416 /* Only allow 1-bit unsigned literals. */
10418 if (TREE_CODE (arg2) != INTEGER_CST
10419 || TREE_INT_CST_LOW (arg2) & ~0x1)
10421 error ("argument 3 must be a 1-bit unsigned literal");
10431 || GET_MODE (target) != tmode
10432 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10433 target = gen_reg_rtx (tmode);
10435 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10436 op0 = copy_to_mode_reg (mode0, op0);
10437 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10438 op1 = copy_to_mode_reg (mode1, op1);
10439 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10440 op2 = copy_to_mode_reg (mode2, op2);
10442 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10443 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10445 pat = GEN_FCN (icode) (target, op0, op1, op2);
10453 /* Expand the lvx builtins. */
10455 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10457 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10458 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10460 enum machine_mode tmode, mode0;
10462 enum insn_code icode;
10466 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10467 icode = CODE_FOR_vector_load_v16qi;
10469 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10470 icode = CODE_FOR_vector_load_v8hi;
10472 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10473 icode = CODE_FOR_vector_load_v4si;
10475 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10476 icode = CODE_FOR_vector_load_v4sf;
10479 *expandedp = false;
10485 arg0 = CALL_EXPR_ARG (exp, 0);
10486 op0 = expand_normal (arg0);
10487 tmode = insn_data[icode].operand[0].mode;
10488 mode0 = insn_data[icode].operand[1].mode;
10491 || GET_MODE (target) != tmode
10492 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10493 target = gen_reg_rtx (tmode);
10495 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10496 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10498 pat = GEN_FCN (icode) (target, op0);
10505 /* Expand the stvx builtins. */
10507 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10510 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10511 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10513 enum machine_mode mode0, mode1;
10515 enum insn_code icode;
10519 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10520 icode = CODE_FOR_vector_store_v16qi;
10522 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10523 icode = CODE_FOR_vector_store_v8hi;
10525 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10526 icode = CODE_FOR_vector_store_v4si;
10528 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10529 icode = CODE_FOR_vector_store_v4sf;
10532 *expandedp = false;
10536 arg0 = CALL_EXPR_ARG (exp, 0);
10537 arg1 = CALL_EXPR_ARG (exp, 1);
10538 op0 = expand_normal (arg0);
10539 op1 = expand_normal (arg1);
10540 mode0 = insn_data[icode].operand[0].mode;
10541 mode1 = insn_data[icode].operand[1].mode;
10543 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10544 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10545 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10546 op1 = copy_to_mode_reg (mode1, op1);
10548 pat = GEN_FCN (icode) (op0, op1);
10556 /* Expand the dst builtins. */
10558 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10561 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10562 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10563 tree arg0, arg1, arg2;
10564 enum machine_mode mode0, mode1;
10565 rtx pat, op0, op1, op2;
10566 const struct builtin_description *d;
10569 *expandedp = false;
10571 /* Handle DST variants. */
10573 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10574 if (d->code == fcode)
10576 arg0 = CALL_EXPR_ARG (exp, 0);
10577 arg1 = CALL_EXPR_ARG (exp, 1);
10578 arg2 = CALL_EXPR_ARG (exp, 2);
10579 op0 = expand_normal (arg0);
10580 op1 = expand_normal (arg1);
10581 op2 = expand_normal (arg2);
10582 mode0 = insn_data[d->icode].operand[0].mode;
10583 mode1 = insn_data[d->icode].operand[1].mode;
10585 /* Invalid arguments, bail out before generating bad rtl. */
10586 if (arg0 == error_mark_node
10587 || arg1 == error_mark_node
10588 || arg2 == error_mark_node)
10593 if (TREE_CODE (arg2) != INTEGER_CST
10594 || TREE_INT_CST_LOW (arg2) & ~0x3)
10596 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10600 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10601 op0 = copy_to_mode_reg (Pmode, op0);
10602 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10603 op1 = copy_to_mode_reg (mode1, op1);
10605 pat = GEN_FCN (d->icode) (op0, op1, op2);
10615 /* Expand vec_init builtin. */
10617 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10619 enum machine_mode tmode = TYPE_MODE (type);
10620 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10621 int i, n_elt = GET_MODE_NUNITS (tmode);
10622 rtvec v = rtvec_alloc (n_elt);
10624 gcc_assert (VECTOR_MODE_P (tmode));
10625 gcc_assert (n_elt == call_expr_nargs (exp));
10627 for (i = 0; i < n_elt; ++i)
10629 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10630 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10633 if (!target || !register_operand (target, tmode))
10634 target = gen_reg_rtx (tmode);
10636 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10640 /* Return the integer constant in ARG. Constrain it to be in the range
10641 of the subparts of VEC_TYPE; issue an error if not. */
10644 get_element_number (tree vec_type, tree arg)
10646 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10648 if (!host_integerp (arg, 1)
10649 || (elt = tree_low_cst (arg, 1), elt > max))
10651 error ("selector must be an integer constant in the range 0..%wi", max);
10658 /* Expand vec_set builtin. */
10660 altivec_expand_vec_set_builtin (tree exp)
10662 enum machine_mode tmode, mode1;
10663 tree arg0, arg1, arg2;
10667 arg0 = CALL_EXPR_ARG (exp, 0);
10668 arg1 = CALL_EXPR_ARG (exp, 1);
10669 arg2 = CALL_EXPR_ARG (exp, 2);
10671 tmode = TYPE_MODE (TREE_TYPE (arg0));
10672 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10673 gcc_assert (VECTOR_MODE_P (tmode));
10675 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10676 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10677 elt = get_element_number (TREE_TYPE (arg0), arg2);
10679 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10680 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10682 op0 = force_reg (tmode, op0);
10683 op1 = force_reg (mode1, op1);
10685 rs6000_expand_vector_set (op0, op1, elt);
10690 /* Expand vec_ext builtin. */
10692 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10694 enum machine_mode tmode, mode0;
10699 arg0 = CALL_EXPR_ARG (exp, 0);
10700 arg1 = CALL_EXPR_ARG (exp, 1);
10702 op0 = expand_normal (arg0);
10703 elt = get_element_number (TREE_TYPE (arg0), arg1);
10705 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10706 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10707 gcc_assert (VECTOR_MODE_P (mode0));
10709 op0 = force_reg (mode0, op0);
10711 if (optimize || !target || !register_operand (target, tmode))
10712 target = gen_reg_rtx (tmode);
10714 rs6000_expand_vector_extract (target, op0, elt);
10719 /* Expand the builtin in EXP and store the result in TARGET. Store
10720 true in *EXPANDEDP if we found a builtin to expand. */
10722 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10724 const struct builtin_description *d;
10725 const struct builtin_description_predicates *dp;
10727 enum insn_code icode;
10728 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10731 enum machine_mode tmode, mode0;
10732 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10734 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10735 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10736 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10737 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10740 error ("unresolved overload for Altivec builtin %qF", fndecl);
10744 target = altivec_expand_ld_builtin (exp, target, expandedp);
10748 target = altivec_expand_st_builtin (exp, target, expandedp);
10752 target = altivec_expand_dst_builtin (exp, target, expandedp);
10760 case ALTIVEC_BUILTIN_STVX:
10761 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10762 case ALTIVEC_BUILTIN_STVEBX:
10763 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10764 case ALTIVEC_BUILTIN_STVEHX:
10765 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10766 case ALTIVEC_BUILTIN_STVEWX:
10767 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10768 case ALTIVEC_BUILTIN_STVXL:
10769 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10771 case ALTIVEC_BUILTIN_STVLX:
10772 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10773 case ALTIVEC_BUILTIN_STVLXL:
10774 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10775 case ALTIVEC_BUILTIN_STVRX:
10776 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10777 case ALTIVEC_BUILTIN_STVRXL:
10778 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10780 case ALTIVEC_BUILTIN_MFVSCR:
10781 icode = CODE_FOR_altivec_mfvscr;
10782 tmode = insn_data[icode].operand[0].mode;
10785 || GET_MODE (target) != tmode
10786 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10787 target = gen_reg_rtx (tmode);
10789 pat = GEN_FCN (icode) (target);
10795 case ALTIVEC_BUILTIN_MTVSCR:
10796 icode = CODE_FOR_altivec_mtvscr;
10797 arg0 = CALL_EXPR_ARG (exp, 0);
10798 op0 = expand_normal (arg0);
10799 mode0 = insn_data[icode].operand[0].mode;
10801 /* If we got invalid arguments bail out before generating bad rtl. */
10802 if (arg0 == error_mark_node)
10805 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10806 op0 = copy_to_mode_reg (mode0, op0);
10808 pat = GEN_FCN (icode) (op0);
10813 case ALTIVEC_BUILTIN_DSSALL:
10814 emit_insn (gen_altivec_dssall ());
10817 case ALTIVEC_BUILTIN_DSS:
10818 icode = CODE_FOR_altivec_dss;
10819 arg0 = CALL_EXPR_ARG (exp, 0);
10821 op0 = expand_normal (arg0);
10822 mode0 = insn_data[icode].operand[0].mode;
10824 /* If we got invalid arguments bail out before generating bad rtl. */
10825 if (arg0 == error_mark_node)
10828 if (TREE_CODE (arg0) != INTEGER_CST
10829 || TREE_INT_CST_LOW (arg0) & ~0x3)
10831 error ("argument to dss must be a 2-bit unsigned literal");
10835 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10836 op0 = copy_to_mode_reg (mode0, op0);
10838 emit_insn (gen_altivec_dss (op0));
10841 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10842 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10843 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10844 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10845 case VSX_BUILTIN_VEC_INIT_V2DF:
10846 case VSX_BUILTIN_VEC_INIT_V2DI:
10847 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10849 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10850 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10851 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10852 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10853 case VSX_BUILTIN_VEC_SET_V2DF:
10854 case VSX_BUILTIN_VEC_SET_V2DI:
10855 return altivec_expand_vec_set_builtin (exp);
10857 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10858 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10859 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10860 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10861 case VSX_BUILTIN_VEC_EXT_V2DF:
10862 case VSX_BUILTIN_VEC_EXT_V2DI:
10863 return altivec_expand_vec_ext_builtin (exp, target);
10867 /* Fall through. */
10870 /* Expand abs* operations. */
10872 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10873 if (d->code == fcode)
10874 return altivec_expand_abs_builtin (d->icode, exp, target);
10876 /* Expand the AltiVec predicates. */
10877 dp = bdesc_altivec_preds;
10878 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10879 if (dp->code == fcode)
10880 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10882 /* LV* are funky. We initialized them differently. */
10885 case ALTIVEC_BUILTIN_LVSL:
10886 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10887 exp, target, false);
10888 case ALTIVEC_BUILTIN_LVSR:
10889 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10890 exp, target, false);
10891 case ALTIVEC_BUILTIN_LVEBX:
10892 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10893 exp, target, false);
10894 case ALTIVEC_BUILTIN_LVEHX:
10895 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10896 exp, target, false);
10897 case ALTIVEC_BUILTIN_LVEWX:
10898 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10899 exp, target, false);
10900 case ALTIVEC_BUILTIN_LVXL:
10901 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10902 exp, target, false);
10903 case ALTIVEC_BUILTIN_LVX:
10904 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10905 exp, target, false);
10906 case ALTIVEC_BUILTIN_LVLX:
10907 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10908 exp, target, true);
10909 case ALTIVEC_BUILTIN_LVLXL:
10910 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10911 exp, target, true);
10912 case ALTIVEC_BUILTIN_LVRX:
10913 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10914 exp, target, true);
10915 case ALTIVEC_BUILTIN_LVRXL:
10916 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10917 exp, target, true);
10920 /* Fall through. */
10923 *expandedp = false;
10927 /* Expand the builtin in EXP and store the result in TARGET. Store
10928 true in *EXPANDEDP if we found a builtin to expand. */
10930 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10932 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10933 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10934 const struct builtin_description *d;
10941 case PAIRED_BUILTIN_STX:
10942 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10943 case PAIRED_BUILTIN_LX:
10944 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10947 /* Fall through. */
10950 /* Expand the paired predicates. */
10951 d = bdesc_paired_preds;
10952 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10953 if (d->code == fcode)
10954 return paired_expand_predicate_builtin (d->icode, exp, target);
10956 *expandedp = false;
10960 /* Binops that need to be initialized manually, but can be expanded
10961 automagically by rs6000_expand_binop_builtin. */
10962 static struct builtin_description bdesc_2arg_spe[] =
10964 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10965 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10966 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10967 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10968 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10969 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10970 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10971 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10972 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10973 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10974 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10975 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10976 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10977 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10978 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10979 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10980 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10981 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10982 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10983 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10984 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10985 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10988 /* Expand the builtin in EXP and store the result in TARGET. Store
10989 true in *EXPANDEDP if we found a builtin to expand.
10991 This expands the SPE builtins that are not simple unary and binary
10994 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10996 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10998 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10999 enum insn_code icode;
11000 enum machine_mode tmode, mode0;
11002 struct builtin_description *d;
11007 /* Syntax check for a 5-bit unsigned immediate. */
11010 case SPE_BUILTIN_EVSTDD:
11011 case SPE_BUILTIN_EVSTDH:
11012 case SPE_BUILTIN_EVSTDW:
11013 case SPE_BUILTIN_EVSTWHE:
11014 case SPE_BUILTIN_EVSTWHO:
11015 case SPE_BUILTIN_EVSTWWE:
11016 case SPE_BUILTIN_EVSTWWO:
11017 arg1 = CALL_EXPR_ARG (exp, 2);
11018 if (TREE_CODE (arg1) != INTEGER_CST
11019 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11021 error ("argument 2 must be a 5-bit unsigned literal");
11029 /* The evsplat*i instructions are not quite generic. */
11032 case SPE_BUILTIN_EVSPLATFI:
11033 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11035 case SPE_BUILTIN_EVSPLATI:
11036 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11042 d = (struct builtin_description *) bdesc_2arg_spe;
11043 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11044 if (d->code == fcode)
11045 return rs6000_expand_binop_builtin (d->icode, exp, target);
11047 d = (struct builtin_description *) bdesc_spe_predicates;
11048 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11049 if (d->code == fcode)
11050 return spe_expand_predicate_builtin (d->icode, exp, target);
11052 d = (struct builtin_description *) bdesc_spe_evsel;
11053 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11054 if (d->code == fcode)
11055 return spe_expand_evsel_builtin (d->icode, exp, target);
11059 case SPE_BUILTIN_EVSTDDX:
11060 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11061 case SPE_BUILTIN_EVSTDHX:
11062 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11063 case SPE_BUILTIN_EVSTDWX:
11064 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11065 case SPE_BUILTIN_EVSTWHEX:
11066 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11067 case SPE_BUILTIN_EVSTWHOX:
11068 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11069 case SPE_BUILTIN_EVSTWWEX:
11070 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11071 case SPE_BUILTIN_EVSTWWOX:
11072 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11073 case SPE_BUILTIN_EVSTDD:
11074 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11075 case SPE_BUILTIN_EVSTDH:
11076 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11077 case SPE_BUILTIN_EVSTDW:
11078 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11079 case SPE_BUILTIN_EVSTWHE:
11080 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11081 case SPE_BUILTIN_EVSTWHO:
11082 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11083 case SPE_BUILTIN_EVSTWWE:
11084 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11085 case SPE_BUILTIN_EVSTWWO:
11086 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11087 case SPE_BUILTIN_MFSPEFSCR:
11088 icode = CODE_FOR_spe_mfspefscr;
11089 tmode = insn_data[icode].operand[0].mode;
11092 || GET_MODE (target) != tmode
11093 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11094 target = gen_reg_rtx (tmode);
11096 pat = GEN_FCN (icode) (target);
11101 case SPE_BUILTIN_MTSPEFSCR:
11102 icode = CODE_FOR_spe_mtspefscr;
11103 arg0 = CALL_EXPR_ARG (exp, 0);
11104 op0 = expand_normal (arg0);
11105 mode0 = insn_data[icode].operand[0].mode;
11107 if (arg0 == error_mark_node)
11110 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11111 op0 = copy_to_mode_reg (mode0, op0);
11113 pat = GEN_FCN (icode) (op0);
11121 *expandedp = false;
11126 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11128 rtx pat, scratch, tmp;
11129 tree form = CALL_EXPR_ARG (exp, 0);
11130 tree arg0 = CALL_EXPR_ARG (exp, 1);
11131 tree arg1 = CALL_EXPR_ARG (exp, 2);
11132 rtx op0 = expand_normal (arg0);
11133 rtx op1 = expand_normal (arg1);
11134 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11135 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11137 enum rtx_code code;
11139 if (TREE_CODE (form) != INTEGER_CST)
11141 error ("argument 1 of __builtin_paired_predicate must be a constant");
11145 form_int = TREE_INT_CST_LOW (form);
11147 gcc_assert (mode0 == mode1);
11149 if (arg0 == error_mark_node || arg1 == error_mark_node)
11153 || GET_MODE (target) != SImode
11154 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11155 target = gen_reg_rtx (SImode);
11156 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11157 op0 = copy_to_mode_reg (mode0, op0);
11158 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11159 op1 = copy_to_mode_reg (mode1, op1);
11161 scratch = gen_reg_rtx (CCFPmode);
11163 pat = GEN_FCN (icode) (scratch, op0, op1);
11185 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11188 error ("argument 1 of __builtin_paired_predicate is out of range");
11192 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11193 emit_move_insn (target, tmp);
11198 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11200 rtx pat, scratch, tmp;
11201 tree form = CALL_EXPR_ARG (exp, 0);
11202 tree arg0 = CALL_EXPR_ARG (exp, 1);
11203 tree arg1 = CALL_EXPR_ARG (exp, 2);
11204 rtx op0 = expand_normal (arg0);
11205 rtx op1 = expand_normal (arg1);
11206 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11207 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11209 enum rtx_code code;
11211 if (TREE_CODE (form) != INTEGER_CST)
11213 error ("argument 1 of __builtin_spe_predicate must be a constant");
11217 form_int = TREE_INT_CST_LOW (form);
11219 gcc_assert (mode0 == mode1);
11221 if (arg0 == error_mark_node || arg1 == error_mark_node)
11225 || GET_MODE (target) != SImode
11226 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11227 target = gen_reg_rtx (SImode);
11229 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11230 op0 = copy_to_mode_reg (mode0, op0);
11231 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11232 op1 = copy_to_mode_reg (mode1, op1);
11234 scratch = gen_reg_rtx (CCmode);
11236 pat = GEN_FCN (icode) (scratch, op0, op1);
11241 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11242 _lower_. We use one compare, but look in different bits of the
11243 CR for each variant.
11245 There are 2 elements in each SPE simd type (upper/lower). The CR
11246 bits are set as follows:
11248 BIT0 | BIT 1 | BIT 2 | BIT 3
11249 U | L | (U | L) | (U & L)
11251 So, for an "all" relationship, BIT 3 would be set.
11252 For an "any" relationship, BIT 2 would be set. Etc.
11254 Following traditional nomenclature, these bits map to:
11256 BIT0 | BIT 1 | BIT 2 | BIT 3
11259 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11264 /* All variant. OV bit. */
11266 /* We need to get to the OV bit, which is the ORDERED bit. We
11267 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11268 that's ugly and will make validate_condition_mode die.
11269 So let's just use another pattern. */
11270 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11272 /* Any variant. EQ bit. */
11276 /* Upper variant. LT bit. */
11280 /* Lower variant. GT bit. */
11285 error ("argument 1 of __builtin_spe_predicate is out of range");
11289 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11290 emit_move_insn (target, tmp);
11295 /* The evsel builtins look like this:
11297 e = __builtin_spe_evsel_OP (a, b, c, d);
11299 and work like this:
11301 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11302 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11306 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11309 tree arg0 = CALL_EXPR_ARG (exp, 0);
11310 tree arg1 = CALL_EXPR_ARG (exp, 1);
11311 tree arg2 = CALL_EXPR_ARG (exp, 2);
11312 tree arg3 = CALL_EXPR_ARG (exp, 3);
11313 rtx op0 = expand_normal (arg0);
11314 rtx op1 = expand_normal (arg1);
11315 rtx op2 = expand_normal (arg2);
11316 rtx op3 = expand_normal (arg3);
11317 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11318 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11320 gcc_assert (mode0 == mode1);
11322 if (arg0 == error_mark_node || arg1 == error_mark_node
11323 || arg2 == error_mark_node || arg3 == error_mark_node)
11327 || GET_MODE (target) != mode0
11328 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11329 target = gen_reg_rtx (mode0);
11331 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11332 op0 = copy_to_mode_reg (mode0, op0);
11333 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11334 op1 = copy_to_mode_reg (mode0, op1);
11335 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11336 op2 = copy_to_mode_reg (mode0, op2);
11337 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11338 op3 = copy_to_mode_reg (mode0, op3);
11340 /* Generate the compare. */
11341 scratch = gen_reg_rtx (CCmode);
11342 pat = GEN_FCN (icode) (scratch, op0, op1);
11347 if (mode0 == V2SImode)
11348 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11350 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11355 /* Expand an expression EXP that calls a built-in function,
11356 with result going to TARGET if that's convenient
11357 (and in mode MODE if that's convenient).
11358 SUBTARGET may be used as the target for computing one of EXP's operands.
11359 IGNORE is nonzero if the value is to be ignored. */
11362 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11363 enum machine_mode mode ATTRIBUTE_UNUSED,
11364 int ignore ATTRIBUTE_UNUSED)
11366 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11367 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11368 const struct builtin_description *d;
11375 case RS6000_BUILTIN_RECIP:
11376 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11378 case RS6000_BUILTIN_RECIPF:
11379 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11381 case RS6000_BUILTIN_RSQRTF:
11382 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11384 case RS6000_BUILTIN_RSQRT:
11385 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11387 case RS6000_BUILTIN_BSWAP_HI:
11388 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11390 case POWER7_BUILTIN_BPERMD:
11391 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11392 ? CODE_FOR_bpermd_di
11393 : CODE_FOR_bpermd_si), exp, target);
11395 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11396 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11398 int icode = (int) CODE_FOR_altivec_lvsr;
11399 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11400 enum machine_mode mode = insn_data[icode].operand[1].mode;
11404 gcc_assert (TARGET_ALTIVEC);
11406 arg = CALL_EXPR_ARG (exp, 0);
11407 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
11408 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11409 addr = memory_address (mode, op);
11410 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11414 /* For the load case need to negate the address. */
11415 op = gen_reg_rtx (GET_MODE (addr));
11416 emit_insn (gen_rtx_SET (VOIDmode, op,
11417 gen_rtx_NEG (GET_MODE (addr), addr)));
11419 op = gen_rtx_MEM (mode, op);
11422 || GET_MODE (target) != tmode
11423 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11424 target = gen_reg_rtx (tmode);
11426 /*pat = gen_altivec_lvsr (target, op);*/
11427 pat = GEN_FCN (icode) (target, op);
11435 case ALTIVEC_BUILTIN_VCFUX:
11436 case ALTIVEC_BUILTIN_VCFSX:
11437 case ALTIVEC_BUILTIN_VCTUXS:
11438 case ALTIVEC_BUILTIN_VCTSXS:
11439 /* FIXME: There's got to be a nicer way to handle this case than
11440 constructing a new CALL_EXPR. */
11441 if (call_expr_nargs (exp) == 1)
11443 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11444 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11452 if (TARGET_ALTIVEC)
11454 ret = altivec_expand_builtin (exp, target, &success);
11461 ret = spe_expand_builtin (exp, target, &success);
11466 if (TARGET_PAIRED_FLOAT)
11468 ret = paired_expand_builtin (exp, target, &success);
11474 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11476 /* Handle simple unary operations. */
11477 d = (struct builtin_description *) bdesc_1arg;
11478 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11479 if (d->code == fcode)
11480 return rs6000_expand_unop_builtin (d->icode, exp, target);
11482 /* Handle simple binary operations. */
11483 d = (struct builtin_description *) bdesc_2arg;
11484 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11485 if (d->code == fcode)
11486 return rs6000_expand_binop_builtin (d->icode, exp, target);
11488 /* Handle simple ternary operations. */
11490 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11491 if (d->code == fcode)
11492 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11494 gcc_unreachable ();
11498 rs6000_init_builtins (void)
11503 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11504 V2SF_type_node = build_vector_type (float_type_node, 2);
11505 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11506 V2DF_type_node = build_vector_type (double_type_node, 2);
11507 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11508 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11509 V4SF_type_node = build_vector_type (float_type_node, 4);
11510 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11511 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11513 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11514 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11515 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11516 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11518 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11519 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11520 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11521 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11523 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11524 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11525 'vector unsigned short'. */
11527 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11528 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11529 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11530 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11531 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11533 long_integer_type_internal_node = long_integer_type_node;
11534 long_unsigned_type_internal_node = long_unsigned_type_node;
11535 intQI_type_internal_node = intQI_type_node;
11536 uintQI_type_internal_node = unsigned_intQI_type_node;
11537 intHI_type_internal_node = intHI_type_node;
11538 uintHI_type_internal_node = unsigned_intHI_type_node;
11539 intSI_type_internal_node = intSI_type_node;
11540 uintSI_type_internal_node = unsigned_intSI_type_node;
11541 intDI_type_internal_node = intDI_type_node;
11542 uintDI_type_internal_node = unsigned_intDI_type_node;
11543 float_type_internal_node = float_type_node;
11544 double_type_internal_node = float_type_node;
11545 void_type_internal_node = void_type_node;
11547 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11549 builtin_mode_to_type[QImode][0] = integer_type_node;
11550 builtin_mode_to_type[HImode][0] = integer_type_node;
11551 builtin_mode_to_type[SImode][0] = intSI_type_node;
11552 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
11553 builtin_mode_to_type[DImode][0] = intDI_type_node;
11554 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
11555 builtin_mode_to_type[SFmode][0] = float_type_node;
11556 builtin_mode_to_type[DFmode][0] = double_type_node;
11557 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
11558 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
11559 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
11560 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
11561 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
11562 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
11563 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11564 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11565 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11566 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11567 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11568 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11569 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11571 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11572 get_identifier ("__bool char"),
11573 bool_char_type_node);
11574 TYPE_NAME (bool_char_type_node) = tdecl;
11575 (*lang_hooks.decls.pushdecl) (tdecl);
11576 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11577 get_identifier ("__bool short"),
11578 bool_short_type_node);
11579 TYPE_NAME (bool_short_type_node) = tdecl;
11580 (*lang_hooks.decls.pushdecl) (tdecl);
11581 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11582 get_identifier ("__bool int"),
11583 bool_int_type_node);
11584 TYPE_NAME (bool_int_type_node) = tdecl;
11585 (*lang_hooks.decls.pushdecl) (tdecl);
11586 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
11588 TYPE_NAME (pixel_type_node) = tdecl;
11589 (*lang_hooks.decls.pushdecl) (tdecl);
11591 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
11592 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11593 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11594 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11595 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11597 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11598 get_identifier ("__vector unsigned char"),
11599 unsigned_V16QI_type_node);
11600 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11601 (*lang_hooks.decls.pushdecl) (tdecl);
11602 tdecl = build_decl (BUILTINS_LOCATION,
11603 TYPE_DECL, get_identifier ("__vector signed char"),
11605 TYPE_NAME (V16QI_type_node) = tdecl;
11606 (*lang_hooks.decls.pushdecl) (tdecl);
11607 tdecl = build_decl (BUILTINS_LOCATION,
11608 TYPE_DECL, get_identifier ("__vector __bool char"),
11609 bool_V16QI_type_node);
11610 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11611 (*lang_hooks.decls.pushdecl) (tdecl);
11613 tdecl = build_decl (BUILTINS_LOCATION,
11614 TYPE_DECL, get_identifier ("__vector unsigned short"),
11615 unsigned_V8HI_type_node);
11616 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11617 (*lang_hooks.decls.pushdecl) (tdecl);
11618 tdecl = build_decl (BUILTINS_LOCATION,
11619 TYPE_DECL, get_identifier ("__vector signed short"),
11621 TYPE_NAME (V8HI_type_node) = tdecl;
11622 (*lang_hooks.decls.pushdecl) (tdecl);
11623 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11624 get_identifier ("__vector __bool short"),
11625 bool_V8HI_type_node);
11626 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11627 (*lang_hooks.decls.pushdecl) (tdecl);
11629 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11630 get_identifier ("__vector unsigned int"),
11631 unsigned_V4SI_type_node);
11632 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11633 (*lang_hooks.decls.pushdecl) (tdecl);
11634 tdecl = build_decl (BUILTINS_LOCATION,
11635 TYPE_DECL, get_identifier ("__vector signed int"),
11637 TYPE_NAME (V4SI_type_node) = tdecl;
11638 (*lang_hooks.decls.pushdecl) (tdecl);
11639 tdecl = build_decl (BUILTINS_LOCATION,
11640 TYPE_DECL, get_identifier ("__vector __bool int"),
11641 bool_V4SI_type_node);
11642 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11643 (*lang_hooks.decls.pushdecl) (tdecl);
11645 tdecl = build_decl (BUILTINS_LOCATION,
11646 TYPE_DECL, get_identifier ("__vector float"),
11648 TYPE_NAME (V4SF_type_node) = tdecl;
11649 (*lang_hooks.decls.pushdecl) (tdecl);
11650 tdecl = build_decl (BUILTINS_LOCATION,
11651 TYPE_DECL, get_identifier ("__vector __pixel"),
11652 pixel_V8HI_type_node);
11653 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11654 (*lang_hooks.decls.pushdecl) (tdecl);
11658 tdecl = build_decl (BUILTINS_LOCATION,
11659 TYPE_DECL, get_identifier ("__vector double"),
11661 TYPE_NAME (V2DF_type_node) = tdecl;
11662 (*lang_hooks.decls.pushdecl) (tdecl);
11664 tdecl = build_decl (BUILTINS_LOCATION,
11665 TYPE_DECL, get_identifier ("__vector long"),
11667 TYPE_NAME (V2DI_type_node) = tdecl;
11668 (*lang_hooks.decls.pushdecl) (tdecl);
11670 tdecl = build_decl (BUILTINS_LOCATION,
11671 TYPE_DECL, get_identifier ("__vector unsigned long"),
11672 unsigned_V2DI_type_node);
11673 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11674 (*lang_hooks.decls.pushdecl) (tdecl);
11676 tdecl = build_decl (BUILTINS_LOCATION,
11677 TYPE_DECL, get_identifier ("__vector __bool long"),
11678 bool_V2DI_type_node);
11679 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11680 (*lang_hooks.decls.pushdecl) (tdecl);
11683 if (TARGET_PAIRED_FLOAT)
11684 paired_init_builtins ();
11686 spe_init_builtins ();
11687 if (TARGET_ALTIVEC)
11688 altivec_init_builtins ();
11689 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11690 rs6000_common_init_builtins ();
11693 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11694 RS6000_BUILTIN_RECIP,
11695 "__builtin_recipdiv");
11696 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11697 RS6000_BUILTIN_RECIP);
11701 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11702 RS6000_BUILTIN_RECIPF,
11703 "__builtin_recipdivf");
11704 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11705 RS6000_BUILTIN_RECIPF);
11707 if (TARGET_FRSQRTE)
11709 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
11710 RS6000_BUILTIN_RSQRT,
11711 "__builtin_rsqrt");
11712 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
11713 RS6000_BUILTIN_RSQRT);
11715 if (TARGET_FRSQRTES)
11717 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11718 RS6000_BUILTIN_RSQRTF,
11719 "__builtin_rsqrtf");
11720 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11721 RS6000_BUILTIN_RSQRTF);
11723 if (TARGET_POPCNTD)
11725 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11726 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11727 POWER7_BUILTIN_BPERMD,
11728 "__builtin_bpermd");
11729 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11730 POWER7_BUILTIN_BPERMD);
11732 if (TARGET_POWERPC)
11734 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11735 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11736 unsigned_intHI_type_node,
11738 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11739 RS6000_BUILTIN_BSWAP_HI);
11743 /* AIX libm provides clog as __clog. */
11744 if (built_in_decls [BUILT_IN_CLOG])
11745 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11748 #ifdef SUBTARGET_INIT_BUILTINS
11749 SUBTARGET_INIT_BUILTINS;
11753 /* Returns the rs6000 builtin decl for CODE. */
11756 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
11758 if (code >= RS6000_BUILTIN_COUNT)
11759 return error_mark_node;
11761 return rs6000_builtin_decls[code];
11764 /* Search through a set of builtins and enable the mask bits.
11765 DESC is an array of builtins.
11766 SIZE is the total number of builtins.
11767 START is the builtin enum at which to start.
11768 END is the builtin enum at which to end. */
11770 enable_mask_for_builtins (struct builtin_description *desc, int size,
11771 enum rs6000_builtins start,
11772 enum rs6000_builtins end)
11776 for (i = 0; i < size; ++i)
11777 if (desc[i].code == start)
11783 for (; i < size; ++i)
11785 /* Flip all the bits on. */
11786 desc[i].mask = target_flags;
11787 if (desc[i].code == end)
11793 spe_init_builtins (void)
11795 tree endlink = void_list_node;
11796 tree puint_type_node = build_pointer_type (unsigned_type_node);
11797 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11798 struct builtin_description *d;
11801 tree v2si_ftype_4_v2si
11802 = build_function_type
11803 (opaque_V2SI_type_node,
11804 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11805 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11806 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11807 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11810 tree v2sf_ftype_4_v2sf
11811 = build_function_type
11812 (opaque_V2SF_type_node,
11813 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11814 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11815 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11816 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11819 tree int_ftype_int_v2si_v2si
11820 = build_function_type
11821 (integer_type_node,
11822 tree_cons (NULL_TREE, integer_type_node,
11823 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11824 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11827 tree int_ftype_int_v2sf_v2sf
11828 = build_function_type
11829 (integer_type_node,
11830 tree_cons (NULL_TREE, integer_type_node,
11831 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11832 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11835 tree void_ftype_v2si_puint_int
11836 = build_function_type (void_type_node,
11837 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11838 tree_cons (NULL_TREE, puint_type_node,
11839 tree_cons (NULL_TREE,
11843 tree void_ftype_v2si_puint_char
11844 = build_function_type (void_type_node,
11845 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11846 tree_cons (NULL_TREE, puint_type_node,
11847 tree_cons (NULL_TREE,
11851 tree void_ftype_v2si_pv2si_int
11852 = build_function_type (void_type_node,
11853 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11854 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11855 tree_cons (NULL_TREE,
11859 tree void_ftype_v2si_pv2si_char
11860 = build_function_type (void_type_node,
11861 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11862 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11863 tree_cons (NULL_TREE,
11867 tree void_ftype_int
11868 = build_function_type (void_type_node,
11869 tree_cons (NULL_TREE, integer_type_node, endlink));
11871 tree int_ftype_void
11872 = build_function_type (integer_type_node, endlink);
11874 tree v2si_ftype_pv2si_int
11875 = build_function_type (opaque_V2SI_type_node,
11876 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11877 tree_cons (NULL_TREE, integer_type_node,
11880 tree v2si_ftype_puint_int
11881 = build_function_type (opaque_V2SI_type_node,
11882 tree_cons (NULL_TREE, puint_type_node,
11883 tree_cons (NULL_TREE, integer_type_node,
11886 tree v2si_ftype_pushort_int
11887 = build_function_type (opaque_V2SI_type_node,
11888 tree_cons (NULL_TREE, pushort_type_node,
11889 tree_cons (NULL_TREE, integer_type_node,
11892 tree v2si_ftype_signed_char
11893 = build_function_type (opaque_V2SI_type_node,
11894 tree_cons (NULL_TREE, signed_char_type_node,
11897 /* The initialization of the simple binary and unary builtins is
11898 done in rs6000_common_init_builtins, but we have to enable the
11899 mask bits here manually because we have run out of `target_flags'
11900 bits. We really need to redesign this mask business. */
11902 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11903 ARRAY_SIZE (bdesc_2arg),
11904 SPE_BUILTIN_EVADDW,
11905 SPE_BUILTIN_EVXOR);
11906 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11907 ARRAY_SIZE (bdesc_1arg),
11909 SPE_BUILTIN_EVSUBFUSIAAW);
11910 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11911 ARRAY_SIZE (bdesc_spe_predicates),
11912 SPE_BUILTIN_EVCMPEQ,
11913 SPE_BUILTIN_EVFSTSTLT);
11914 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11915 ARRAY_SIZE (bdesc_spe_evsel),
11916 SPE_BUILTIN_EVSEL_CMPGTS,
11917 SPE_BUILTIN_EVSEL_FSTSTEQ);
11919 (*lang_hooks.decls.pushdecl)
11920 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11921 get_identifier ("__ev64_opaque__"),
11922 opaque_V2SI_type_node));
11924 /* Initialize irregular SPE builtins. */
11926 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11927 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11928 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11929 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11930 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11931 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11932 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11933 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11934 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11935 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11936 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11937 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11938 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11939 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11940 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11941 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11942 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11943 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11946 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11947 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11948 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11949 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11950 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11951 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11952 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11953 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11954 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11955 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11956 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11957 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11958 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11959 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11960 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11961 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11962 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11963 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11964 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11965 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11966 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11967 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11970 d = (struct builtin_description *) bdesc_spe_predicates;
11971 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11975 switch (insn_data[d->icode].operand[1].mode)
11978 type = int_ftype_int_v2si_v2si;
11981 type = int_ftype_int_v2sf_v2sf;
11984 gcc_unreachable ();
11987 def_builtin (d->mask, d->name, type, d->code);
11990 /* Evsel predicates. */
11991 d = (struct builtin_description *) bdesc_spe_evsel;
11992 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11996 switch (insn_data[d->icode].operand[1].mode)
11999 type = v2si_ftype_4_v2si;
12002 type = v2sf_ftype_4_v2sf;
12005 gcc_unreachable ();
12008 def_builtin (d->mask, d->name, type, d->code);
12013 paired_init_builtins (void)
12015 const struct builtin_description *d;
12017 tree endlink = void_list_node;
12019 tree int_ftype_int_v2sf_v2sf
12020 = build_function_type
12021 (integer_type_node,
12022 tree_cons (NULL_TREE, integer_type_node,
12023 tree_cons (NULL_TREE, V2SF_type_node,
12024 tree_cons (NULL_TREE, V2SF_type_node,
12026 tree pcfloat_type_node =
12027 build_pointer_type (build_qualified_type
12028 (float_type_node, TYPE_QUAL_CONST));
12030 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12031 long_integer_type_node,
12034 tree void_ftype_v2sf_long_pcfloat =
12035 build_function_type_list (void_type_node,
12037 long_integer_type_node,
12042 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12043 PAIRED_BUILTIN_LX);
12046 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12047 PAIRED_BUILTIN_STX);
12050 d = bdesc_paired_preds;
12051 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12055 switch (insn_data[d->icode].operand[1].mode)
12058 type = int_ftype_int_v2sf_v2sf;
12061 gcc_unreachable ();
12064 def_builtin (d->mask, d->name, type, d->code);
12069 altivec_init_builtins (void)
12071 const struct builtin_description *d;
12072 const struct builtin_description_predicates *dp;
12076 tree pfloat_type_node = build_pointer_type (float_type_node);
12077 tree pint_type_node = build_pointer_type (integer_type_node);
12078 tree pshort_type_node = build_pointer_type (short_integer_type_node);
12079 tree pchar_type_node = build_pointer_type (char_type_node);
12081 tree pvoid_type_node = build_pointer_type (void_type_node);
12083 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
12084 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
12085 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
12086 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
12088 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
12090 tree int_ftype_opaque
12091 = build_function_type_list (integer_type_node,
12092 opaque_V4SI_type_node, NULL_TREE);
12093 tree opaque_ftype_opaque
12094 = build_function_type (integer_type_node,
12096 tree opaque_ftype_opaque_int
12097 = build_function_type_list (opaque_V4SI_type_node,
12098 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12099 tree opaque_ftype_opaque_opaque_int
12100 = build_function_type_list (opaque_V4SI_type_node,
12101 opaque_V4SI_type_node, opaque_V4SI_type_node,
12102 integer_type_node, NULL_TREE);
12103 tree int_ftype_int_opaque_opaque
12104 = build_function_type_list (integer_type_node,
12105 integer_type_node, opaque_V4SI_type_node,
12106 opaque_V4SI_type_node, NULL_TREE);
12107 tree int_ftype_int_v4si_v4si
12108 = build_function_type_list (integer_type_node,
12109 integer_type_node, V4SI_type_node,
12110 V4SI_type_node, NULL_TREE);
12111 tree v4sf_ftype_pcfloat
12112 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
12113 tree void_ftype_pfloat_v4sf
12114 = build_function_type_list (void_type_node,
12115 pfloat_type_node, V4SF_type_node, NULL_TREE);
12116 tree v4si_ftype_pcint
12117 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
12118 tree void_ftype_pint_v4si
12119 = build_function_type_list (void_type_node,
12120 pint_type_node, V4SI_type_node, NULL_TREE);
12121 tree v8hi_ftype_pcshort
12122 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
12123 tree void_ftype_pshort_v8hi
12124 = build_function_type_list (void_type_node,
12125 pshort_type_node, V8HI_type_node, NULL_TREE);
12126 tree v16qi_ftype_pcchar
12127 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
12128 tree void_ftype_pchar_v16qi
12129 = build_function_type_list (void_type_node,
12130 pchar_type_node, V16QI_type_node, NULL_TREE);
12131 tree void_ftype_v4si
12132 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12133 tree v8hi_ftype_void
12134 = build_function_type (V8HI_type_node, void_list_node);
12135 tree void_ftype_void
12136 = build_function_type (void_type_node, void_list_node);
12137 tree void_ftype_int
12138 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12140 tree opaque_ftype_long_pcvoid
12141 = build_function_type_list (opaque_V4SI_type_node,
12142 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12143 tree v16qi_ftype_long_pcvoid
12144 = build_function_type_list (V16QI_type_node,
12145 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12146 tree v8hi_ftype_long_pcvoid
12147 = build_function_type_list (V8HI_type_node,
12148 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12149 tree v4si_ftype_long_pcvoid
12150 = build_function_type_list (V4SI_type_node,
12151 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12153 tree void_ftype_opaque_long_pvoid
12154 = build_function_type_list (void_type_node,
12155 opaque_V4SI_type_node, long_integer_type_node,
12156 pvoid_type_node, NULL_TREE);
12157 tree void_ftype_v4si_long_pvoid
12158 = build_function_type_list (void_type_node,
12159 V4SI_type_node, long_integer_type_node,
12160 pvoid_type_node, NULL_TREE);
12161 tree void_ftype_v16qi_long_pvoid
12162 = build_function_type_list (void_type_node,
12163 V16QI_type_node, long_integer_type_node,
12164 pvoid_type_node, NULL_TREE);
12165 tree void_ftype_v8hi_long_pvoid
12166 = build_function_type_list (void_type_node,
12167 V8HI_type_node, long_integer_type_node,
12168 pvoid_type_node, NULL_TREE);
12169 tree int_ftype_int_v8hi_v8hi
12170 = build_function_type_list (integer_type_node,
12171 integer_type_node, V8HI_type_node,
12172 V8HI_type_node, NULL_TREE);
12173 tree int_ftype_int_v16qi_v16qi
12174 = build_function_type_list (integer_type_node,
12175 integer_type_node, V16QI_type_node,
12176 V16QI_type_node, NULL_TREE);
12177 tree int_ftype_int_v4sf_v4sf
12178 = build_function_type_list (integer_type_node,
12179 integer_type_node, V4SF_type_node,
12180 V4SF_type_node, NULL_TREE);
12181 tree int_ftype_int_v2df_v2df
12182 = build_function_type_list (integer_type_node,
12183 integer_type_node, V2DF_type_node,
12184 V2DF_type_node, NULL_TREE);
12185 tree v4si_ftype_v4si
12186 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12187 tree v8hi_ftype_v8hi
12188 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12189 tree v16qi_ftype_v16qi
12190 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12191 tree v4sf_ftype_v4sf
12192 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12193 tree v2df_ftype_v2df
12194 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12195 tree void_ftype_pcvoid_int_int
12196 = build_function_type_list (void_type_node,
12197 pcvoid_type_node, integer_type_node,
12198 integer_type_node, NULL_TREE);
12200 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
12201 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
12202 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
12203 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
12204 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
12205 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
12206 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
12207 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
12208 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
12209 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
12210 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
12211 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
12212 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
12213 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
12214 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
12215 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
12216 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12217 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12218 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12219 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12220 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12221 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12222 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12223 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12224 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12225 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12226 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12227 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12228 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12229 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12230 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12231 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12232 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12233 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12234 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12235 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12236 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12237 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12238 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12239 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12240 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12241 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12242 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12243 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12244 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12245 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12247 if (rs6000_cpu == PROCESSOR_CELL)
12249 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12250 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12251 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12252 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12254 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12255 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12256 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12257 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12259 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12260 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12261 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12262 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12264 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12265 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12266 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12267 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12269 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12270 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12271 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12273 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12274 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12275 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12276 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12277 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12278 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12279 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12280 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12281 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12282 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12283 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12284 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12286 /* Add the DST variants. */
12288 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12289 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12291 /* Initialize the predicates. */
12292 dp = bdesc_altivec_preds;
12293 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12295 enum machine_mode mode1;
12297 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12298 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12299 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12300 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12305 mode1 = insn_data[dp->icode].operand[1].mode;
12310 type = int_ftype_int_opaque_opaque;
12313 type = int_ftype_int_v4si_v4si;
12316 type = int_ftype_int_v8hi_v8hi;
12319 type = int_ftype_int_v16qi_v16qi;
12322 type = int_ftype_int_v4sf_v4sf;
12325 type = int_ftype_int_v2df_v2df;
12328 gcc_unreachable ();
12331 def_builtin (dp->mask, dp->name, type, dp->code);
12334 /* Initialize the abs* operators. */
12336 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12338 enum machine_mode mode0;
12341 mode0 = insn_data[d->icode].operand[0].mode;
12346 type = v4si_ftype_v4si;
12349 type = v8hi_ftype_v8hi;
12352 type = v16qi_ftype_v16qi;
12355 type = v4sf_ftype_v4sf;
12358 type = v2df_ftype_v2df;
12361 gcc_unreachable ();
12364 def_builtin (d->mask, d->name, type, d->code);
12367 if (TARGET_ALTIVEC)
12371 /* Initialize target builtin that implements
12372 targetm.vectorize.builtin_mask_for_load. */
12374 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12375 v16qi_ftype_long_pcvoid,
12376 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12377 BUILT_IN_MD, NULL, NULL_TREE);
12378 TREE_READONLY (decl) = 1;
12379 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12380 altivec_builtin_mask_for_load = decl;
12383 /* Access to the vec_init patterns. */
12384 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12385 integer_type_node, integer_type_node,
12386 integer_type_node, NULL_TREE);
12387 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12388 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12390 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12391 short_integer_type_node,
12392 short_integer_type_node,
12393 short_integer_type_node,
12394 short_integer_type_node,
12395 short_integer_type_node,
12396 short_integer_type_node,
12397 short_integer_type_node, NULL_TREE);
12398 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12399 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12401 ftype = build_function_type_list (V16QI_type_node, char_type_node,
12402 char_type_node, char_type_node,
12403 char_type_node, char_type_node,
12404 char_type_node, char_type_node,
12405 char_type_node, char_type_node,
12406 char_type_node, char_type_node,
12407 char_type_node, char_type_node,
12408 char_type_node, char_type_node,
12409 char_type_node, NULL_TREE);
12410 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
12411 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
12413 ftype = build_function_type_list (V4SF_type_node, float_type_node,
12414 float_type_node, float_type_node,
12415 float_type_node, NULL_TREE);
12416 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
12417 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12421 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12422 double_type_node, NULL_TREE);
12423 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12424 VSX_BUILTIN_VEC_INIT_V2DF);
12426 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12427 intDI_type_node, NULL_TREE);
12428 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12429 VSX_BUILTIN_VEC_INIT_V2DI);
12432 /* Access to the vec_set patterns. */
12433 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12435 integer_type_node, NULL_TREE);
12436 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12437 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12439 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12441 integer_type_node, NULL_TREE);
12442 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12443 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12445 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12447 integer_type_node, NULL_TREE);
12448 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12449 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12451 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12453 integer_type_node, NULL_TREE);
12454 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12455 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12459 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12461 integer_type_node, NULL_TREE);
12462 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12463 VSX_BUILTIN_VEC_SET_V2DF);
12465 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12467 integer_type_node, NULL_TREE);
12468 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12469 VSX_BUILTIN_VEC_SET_V2DI);
12472 /* Access to the vec_extract patterns. */
12473 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12474 integer_type_node, NULL_TREE);
12475 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12476 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12478 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12479 integer_type_node, NULL_TREE);
12480 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12481 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12483 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12484 integer_type_node, NULL_TREE);
12485 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12486 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12488 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12489 integer_type_node, NULL_TREE);
12490 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12491 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12495 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12496 integer_type_node, NULL_TREE);
12497 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12498 VSX_BUILTIN_VEC_EXT_V2DF);
12500 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12501 integer_type_node, NULL_TREE);
12502 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12503 VSX_BUILTIN_VEC_EXT_V2DI);
12507 /* Hash function for builtin functions with up to 3 arguments and a return
12510 builtin_hash_function (const void *hash_entry)
12514 const struct builtin_hash_struct *bh =
12515 (const struct builtin_hash_struct *) hash_entry;
12517 for (i = 0; i < 4; i++)
12519 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12520 ret = (ret * 2) + bh->uns_p[i];
12526 /* Compare builtin hash entries H1 and H2 for equivalence. */
12528 builtin_hash_eq (const void *h1, const void *h2)
12530 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12531 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
12533 return ((p1->mode[0] == p2->mode[0])
12534 && (p1->mode[1] == p2->mode[1])
12535 && (p1->mode[2] == p2->mode[2])
12536 && (p1->mode[3] == p2->mode[3])
12537 && (p1->uns_p[0] == p2->uns_p[0])
12538 && (p1->uns_p[1] == p2->uns_p[1])
12539 && (p1->uns_p[2] == p2->uns_p[2])
12540 && (p1->uns_p[3] == p2->uns_p[3]));
12543 /* Map types for builtin functions with an explicit return type and up to 3
12544 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12545 of the argument. */
12547 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
12548 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
12549 enum rs6000_builtins builtin, const char *name)
12551 struct builtin_hash_struct h;
12552 struct builtin_hash_struct *h2;
12556 tree ret_type = NULL_TREE;
12557 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
12560 /* Create builtin_hash_table. */
12561 if (builtin_hash_table == NULL)
12562 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
12563 builtin_hash_eq, NULL);
12565 h.type = NULL_TREE;
12566 h.mode[0] = mode_ret;
12567 h.mode[1] = mode_arg0;
12568 h.mode[2] = mode_arg1;
12569 h.mode[3] = mode_arg2;
12575 /* If the builtin is a type that produces unsigned results or takes unsigned
12576 arguments, and it is returned as a decl for the vectorizer (such as
12577 widening multiplies, permute), make sure the arguments and return value
12578 are type correct. */
12581 /* unsigned 2 argument functions. */
12582 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12583 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12584 case ALTIVEC_BUILTIN_VMULOUB_UNS:
12585 case ALTIVEC_BUILTIN_VMULOUH_UNS:
12591 /* unsigned 3 argument functions. */
12592 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
12593 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
12594 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
12595 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
12596 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
12597 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
12598 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
12599 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
12600 case VSX_BUILTIN_VPERM_16QI_UNS:
12601 case VSX_BUILTIN_VPERM_8HI_UNS:
12602 case VSX_BUILTIN_VPERM_4SI_UNS:
12603 case VSX_BUILTIN_VPERM_2DI_UNS:
12604 case VSX_BUILTIN_XXSEL_16QI_UNS:
12605 case VSX_BUILTIN_XXSEL_8HI_UNS:
12606 case VSX_BUILTIN_XXSEL_4SI_UNS:
12607 case VSX_BUILTIN_XXSEL_2DI_UNS:
12614 /* signed permute functions with unsigned char mask. */
12615 case ALTIVEC_BUILTIN_VPERM_16QI:
12616 case ALTIVEC_BUILTIN_VPERM_8HI:
12617 case ALTIVEC_BUILTIN_VPERM_4SI:
12618 case ALTIVEC_BUILTIN_VPERM_4SF:
12619 case ALTIVEC_BUILTIN_VPERM_2DI:
12620 case ALTIVEC_BUILTIN_VPERM_2DF:
12621 case VSX_BUILTIN_VPERM_16QI:
12622 case VSX_BUILTIN_VPERM_8HI:
12623 case VSX_BUILTIN_VPERM_4SI:
12624 case VSX_BUILTIN_VPERM_4SF:
12625 case VSX_BUILTIN_VPERM_2DI:
12626 case VSX_BUILTIN_VPERM_2DF:
12630 /* unsigned args, signed return. */
12631 case VSX_BUILTIN_XVCVUXDDP_UNS:
12632 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12636 /* signed args, unsigned return. */
12637 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12638 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12646 /* Figure out how many args are present. */
12647 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12651 fatal_error ("internal error: builtin function %s had no type", name);
12653 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12654 if (!ret_type && h.uns_p[0])
12655 ret_type = builtin_mode_to_type[h.mode[0]][0];
12658 fatal_error ("internal error: builtin function %s had an unexpected "
12659 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12661 for (i = 0; i < num_args; i++)
12663 int m = (int) h.mode[i+1];
12664 int uns_p = h.uns_p[i+1];
12666 arg_type[i] = builtin_mode_to_type[m][uns_p];
12667 if (!arg_type[i] && uns_p)
12668 arg_type[i] = builtin_mode_to_type[m][0];
12671 fatal_error ("internal error: builtin function %s, argument %d "
12672 "had unexpected argument type %s", name, i,
12673 GET_MODE_NAME (m));
12676 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12677 if (*found == NULL)
12679 h2 = ggc_alloc_builtin_hash_struct ();
12681 *found = (void *)h2;
12682 args = void_list_node;
12684 for (i = num_args - 1; i >= 0; i--)
12685 args = tree_cons (NULL_TREE, arg_type[i], args);
12687 h2->type = build_function_type (ret_type, args);
12690 return ((struct builtin_hash_struct *)(*found))->type;
12694 rs6000_common_init_builtins (void)
12696 const struct builtin_description *d;
12699 tree opaque_ftype_opaque = NULL_TREE;
12700 tree opaque_ftype_opaque_opaque = NULL_TREE;
12701 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12702 tree v2si_ftype_qi = NULL_TREE;
12703 tree v2si_ftype_v2si_qi = NULL_TREE;
12704 tree v2si_ftype_int_qi = NULL_TREE;
12706 if (!TARGET_PAIRED_FLOAT)
12708 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12709 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12712 /* Add the ternary operators. */
12714 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12717 int mask = d->mask;
12719 if ((mask != 0 && (mask & target_flags) == 0)
12720 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12723 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12724 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12725 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12726 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12728 if (! (type = opaque_ftype_opaque_opaque_opaque))
12729 type = opaque_ftype_opaque_opaque_opaque
12730 = build_function_type_list (opaque_V4SI_type_node,
12731 opaque_V4SI_type_node,
12732 opaque_V4SI_type_node,
12733 opaque_V4SI_type_node,
12738 enum insn_code icode = d->icode;
12739 if (d->name == 0 || icode == CODE_FOR_nothing)
12742 type = builtin_function_type (insn_data[icode].operand[0].mode,
12743 insn_data[icode].operand[1].mode,
12744 insn_data[icode].operand[2].mode,
12745 insn_data[icode].operand[3].mode,
12749 def_builtin (d->mask, d->name, type, d->code);
12752 /* Add the binary operators. */
12754 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12756 enum machine_mode mode0, mode1, mode2;
12758 int mask = d->mask;
12760 if ((mask != 0 && (mask & target_flags) == 0)
12761 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12764 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12765 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12766 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12767 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12769 if (! (type = opaque_ftype_opaque_opaque))
12770 type = opaque_ftype_opaque_opaque
12771 = build_function_type_list (opaque_V4SI_type_node,
12772 opaque_V4SI_type_node,
12773 opaque_V4SI_type_node,
12778 enum insn_code icode = d->icode;
12779 if (d->name == 0 || icode == CODE_FOR_nothing)
12782 mode0 = insn_data[icode].operand[0].mode;
12783 mode1 = insn_data[icode].operand[1].mode;
12784 mode2 = insn_data[icode].operand[2].mode;
12786 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12788 if (! (type = v2si_ftype_v2si_qi))
12789 type = v2si_ftype_v2si_qi
12790 = build_function_type_list (opaque_V2SI_type_node,
12791 opaque_V2SI_type_node,
12796 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12797 && mode2 == QImode)
12799 if (! (type = v2si_ftype_int_qi))
12800 type = v2si_ftype_int_qi
12801 = build_function_type_list (opaque_V2SI_type_node,
12808 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12812 def_builtin (d->mask, d->name, type, d->code);
12815 /* Add the simple unary operators. */
12816 d = (struct builtin_description *) bdesc_1arg;
12817 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12819 enum machine_mode mode0, mode1;
12821 int mask = d->mask;
12823 if ((mask != 0 && (mask & target_flags) == 0)
12824 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12827 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12828 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12829 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12830 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12832 if (! (type = opaque_ftype_opaque))
12833 type = opaque_ftype_opaque
12834 = build_function_type_list (opaque_V4SI_type_node,
12835 opaque_V4SI_type_node,
12840 enum insn_code icode = d->icode;
12841 if (d->name == 0 || icode == CODE_FOR_nothing)
12844 mode0 = insn_data[icode].operand[0].mode;
12845 mode1 = insn_data[icode].operand[1].mode;
12847 if (mode0 == V2SImode && mode1 == QImode)
12849 if (! (type = v2si_ftype_qi))
12850 type = v2si_ftype_qi
12851 = build_function_type_list (opaque_V2SI_type_node,
12857 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12861 def_builtin (d->mask, d->name, type, d->code);
12866 rs6000_init_libfuncs (void)
12868 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12869 && !TARGET_POWER2 && !TARGET_POWERPC)
12871 /* AIX library routines for float->int conversion. */
12872 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12873 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12874 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12875 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12878 if (!TARGET_IEEEQUAD)
12879 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12880 if (!TARGET_XL_COMPAT)
12882 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12883 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12884 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12885 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12887 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12889 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12890 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12891 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12892 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12893 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12894 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12895 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12897 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12898 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12899 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12900 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12901 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12902 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12903 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12904 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12907 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12908 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12912 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12913 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12914 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12915 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12919 /* 32-bit SVR4 quad floating point routines. */
12921 set_optab_libfunc (add_optab, TFmode, "_q_add");
12922 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12923 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12924 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12925 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12926 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12927 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12929 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12930 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12931 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12932 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12933 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12934 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12936 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12937 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12938 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12939 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12940 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12941 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12942 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12943 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12948 /* Expand a block clear operation, and return 1 if successful. Return 0
12949 if we should let the compiler generate normal code.
12951 operands[0] is the destination
12952 operands[1] is the length
12953 operands[3] is the alignment */
12956 expand_block_clear (rtx operands[])
12958 rtx orig_dest = operands[0];
12959 rtx bytes_rtx = operands[1];
12960 rtx align_rtx = operands[3];
12961 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12962 HOST_WIDE_INT align;
12963 HOST_WIDE_INT bytes;
12968 /* If this is not a fixed size move, just call memcpy */
12972 /* This must be a fixed size alignment */
12973 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12974 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12976 /* Anything to clear? */
12977 bytes = INTVAL (bytes_rtx);
12981 /* Use the builtin memset after a point, to avoid huge code bloat.
12982 When optimize_size, avoid any significant code bloat; calling
12983 memset is about 4 instructions, so allow for one instruction to
12984 load zero and three to do clearing. */
12985 if (TARGET_ALTIVEC && align >= 128)
12987 else if (TARGET_POWERPC64 && align >= 32)
12989 else if (TARGET_SPE && align >= 64)
12994 if (optimize_size && bytes > 3 * clear_step)
12996 if (! optimize_size && bytes > 8 * clear_step)
12999 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13001 enum machine_mode mode = BLKmode;
13004 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13009 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13014 else if (bytes >= 8 && TARGET_POWERPC64
13015 /* 64-bit loads and stores require word-aligned
13017 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13022 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13023 { /* move 4 bytes */
13027 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13028 { /* move 2 bytes */
13032 else /* move 1 byte at a time */
13038 dest = adjust_address (orig_dest, mode, offset);
13040 emit_move_insn (dest, CONST0_RTX (mode));
13047 /* Expand a block move operation, and return 1 if successful. Return 0
13048 if we should let the compiler generate normal code.
13050 operands[0] is the destination
13051 operands[1] is the source
13052 operands[2] is the length
13053 operands[3] is the alignment */
13055 #define MAX_MOVE_REG 4
13058 expand_block_move (rtx operands[])
13060 rtx orig_dest = operands[0];
13061 rtx orig_src = operands[1];
13062 rtx bytes_rtx = operands[2];
13063 rtx align_rtx = operands[3];
13064 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13069 rtx stores[MAX_MOVE_REG];
13072 /* If this is not a fixed size move, just call memcpy */
13076 /* This must be a fixed size alignment */
13077 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13078 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13080 /* Anything to move? */
13081 bytes = INTVAL (bytes_rtx);
13085 /* store_one_arg depends on expand_block_move to handle at least the size of
13086 reg_parm_stack_space. */
13087 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
13090 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13093 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13094 rtx (*mov) (rtx, rtx);
13096 enum machine_mode mode = BLKmode;
13099 /* Altivec first, since it will be faster than a string move
13100 when it applies, and usually not significantly larger. */
13101 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13105 gen_func.mov = gen_movv4si;
13107 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13111 gen_func.mov = gen_movv2si;
13113 else if (TARGET_STRING
13114 && bytes > 24 /* move up to 32 bytes at a time */
13120 && ! fixed_regs[10]
13121 && ! fixed_regs[11]
13122 && ! fixed_regs[12])
13124 move_bytes = (bytes > 32) ? 32 : bytes;
13125 gen_func.movmemsi = gen_movmemsi_8reg;
13127 else if (TARGET_STRING
13128 && bytes > 16 /* move up to 24 bytes at a time */
13134 && ! fixed_regs[10])
13136 move_bytes = (bytes > 24) ? 24 : bytes;
13137 gen_func.movmemsi = gen_movmemsi_6reg;
13139 else if (TARGET_STRING
13140 && bytes > 8 /* move up to 16 bytes at a time */
13144 && ! fixed_regs[8])
13146 move_bytes = (bytes > 16) ? 16 : bytes;
13147 gen_func.movmemsi = gen_movmemsi_4reg;
13149 else if (bytes >= 8 && TARGET_POWERPC64
13150 /* 64-bit loads and stores require word-aligned
13152 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13156 gen_func.mov = gen_movdi;
13158 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13159 { /* move up to 8 bytes at a time */
13160 move_bytes = (bytes > 8) ? 8 : bytes;
13161 gen_func.movmemsi = gen_movmemsi_2reg;
13163 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13164 { /* move 4 bytes */
13167 gen_func.mov = gen_movsi;
13169 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13170 { /* move 2 bytes */
13173 gen_func.mov = gen_movhi;
13175 else if (TARGET_STRING && bytes > 1)
13176 { /* move up to 4 bytes at a time */
13177 move_bytes = (bytes > 4) ? 4 : bytes;
13178 gen_func.movmemsi = gen_movmemsi_1reg;
13180 else /* move 1 byte at a time */
13184 gen_func.mov = gen_movqi;
13187 src = adjust_address (orig_src, mode, offset);
13188 dest = adjust_address (orig_dest, mode, offset);
13190 if (mode != BLKmode)
13192 rtx tmp_reg = gen_reg_rtx (mode);
13194 emit_insn ((*gen_func.mov) (tmp_reg, src));
13195 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13198 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13201 for (i = 0; i < num_reg; i++)
13202 emit_insn (stores[i]);
13206 if (mode == BLKmode)
13208 /* Move the address into scratch registers. The movmemsi
13209 patterns require zero offset. */
13210 if (!REG_P (XEXP (src, 0)))
13212 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13213 src = replace_equiv_address (src, src_reg);
13215 set_mem_size (src, GEN_INT (move_bytes));
13217 if (!REG_P (XEXP (dest, 0)))
13219 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13220 dest = replace_equiv_address (dest, dest_reg);
13222 set_mem_size (dest, GEN_INT (move_bytes));
13224 emit_insn ((*gen_func.movmemsi) (dest, src,
13225 GEN_INT (move_bytes & 31),
13234 /* Return a string to perform a load_multiple operation.
13235 operands[0] is the vector.
13236 operands[1] is the source address.
13237 operands[2] is the first destination register. */
13240 rs6000_output_load_multiple (rtx operands[3])
13242 /* We have to handle the case where the pseudo used to contain the address
13243 is assigned to one of the output registers. */
13245 int words = XVECLEN (operands[0], 0);
13248 if (XVECLEN (operands[0], 0) == 1)
13249 return "{l|lwz} %2,0(%1)";
13251 for (i = 0; i < words; i++)
13252 if (refers_to_regno_p (REGNO (operands[2]) + i,
13253 REGNO (operands[2]) + i + 1, operands[1], 0))
13257 xop[0] = GEN_INT (4 * (words-1));
13258 xop[1] = operands[1];
13259 xop[2] = operands[2];
13260 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13265 xop[0] = GEN_INT (4 * (words-1));
13266 xop[1] = operands[1];
13267 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13268 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);
13273 for (j = 0; j < words; j++)
13276 xop[0] = GEN_INT (j * 4);
13277 xop[1] = operands[1];
13278 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13279 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13281 xop[0] = GEN_INT (i * 4);
13282 xop[1] = operands[1];
13283 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13288 return "{lsi|lswi} %2,%1,%N0";
13292 /* A validation routine: say whether CODE, a condition code, and MODE
13293 match. The other alternatives either don't make sense or should
13294 never be generated. */
13297 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13299 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13300 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13301 && GET_MODE_CLASS (mode) == MODE_CC);
13303 /* These don't make sense. */
13304 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13305 || mode != CCUNSmode);
13307 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13308 || mode == CCUNSmode);
13310 gcc_assert (mode == CCFPmode
13311 || (code != ORDERED && code != UNORDERED
13312 && code != UNEQ && code != LTGT
13313 && code != UNGT && code != UNLT
13314 && code != UNGE && code != UNLE));
13316 /* These should never be generated except for
13317 flag_finite_math_only. */
13318 gcc_assert (mode != CCFPmode
13319 || flag_finite_math_only
13320 || (code != LE && code != GE
13321 && code != UNEQ && code != LTGT
13322 && code != UNGT && code != UNLT));
13324 /* These are invalid; the information is not there. */
13325 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13329 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13330 mask required to convert the result of a rotate insn into a shift
13331 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13334 includes_lshift_p (rtx shiftop, rtx andop)
13336 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13338 shift_mask <<= INTVAL (shiftop);
13340 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13343 /* Similar, but for right shift. */
13346 includes_rshift_p (rtx shiftop, rtx andop)
13348 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13350 shift_mask >>= INTVAL (shiftop);
13352 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13355 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13356 to perform a left shift. It must have exactly SHIFTOP least
13357 significant 0's, then one or more 1's, then zero or more 0's. */
13360 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13362 if (GET_CODE (andop) == CONST_INT)
13364 HOST_WIDE_INT c, lsb, shift_mask;
13366 c = INTVAL (andop);
13367 if (c == 0 || c == ~0)
13371 shift_mask <<= INTVAL (shiftop);
13373 /* Find the least significant one bit. */
13376 /* It must coincide with the LSB of the shift mask. */
13377 if (-lsb != shift_mask)
13380 /* Invert to look for the next transition (if any). */
13383 /* Remove the low group of ones (originally low group of zeros). */
13386 /* Again find the lsb, and check we have all 1's above. */
13390 else if (GET_CODE (andop) == CONST_DOUBLE
13391 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13393 HOST_WIDE_INT low, high, lsb;
13394 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13396 low = CONST_DOUBLE_LOW (andop);
13397 if (HOST_BITS_PER_WIDE_INT < 64)
13398 high = CONST_DOUBLE_HIGH (andop);
13400 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13401 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13404 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13406 shift_mask_high = ~0;
13407 if (INTVAL (shiftop) > 32)
13408 shift_mask_high <<= INTVAL (shiftop) - 32;
13410 lsb = high & -high;
13412 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13418 lsb = high & -high;
13419 return high == -lsb;
13422 shift_mask_low = ~0;
13423 shift_mask_low <<= INTVAL (shiftop);
13427 if (-lsb != shift_mask_low)
13430 if (HOST_BITS_PER_WIDE_INT < 64)
13435 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13437 lsb = high & -high;
13438 return high == -lsb;
13442 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13448 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13449 to perform a left shift. It must have SHIFTOP or more least
13450 significant 0's, with the remainder of the word 1's. */
13453 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13455 if (GET_CODE (andop) == CONST_INT)
13457 HOST_WIDE_INT c, lsb, shift_mask;
13460 shift_mask <<= INTVAL (shiftop);
13461 c = INTVAL (andop);
13463 /* Find the least significant one bit. */
13466 /* It must be covered by the shift mask.
13467 This test also rejects c == 0. */
13468 if ((lsb & shift_mask) == 0)
13471 /* Check we have all 1's above the transition, and reject all 1's. */
13472 return c == -lsb && lsb != 1;
13474 else if (GET_CODE (andop) == CONST_DOUBLE
13475 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13477 HOST_WIDE_INT low, lsb, shift_mask_low;
13479 low = CONST_DOUBLE_LOW (andop);
13481 if (HOST_BITS_PER_WIDE_INT < 64)
13483 HOST_WIDE_INT high, shift_mask_high;
13485 high = CONST_DOUBLE_HIGH (andop);
13489 shift_mask_high = ~0;
13490 if (INTVAL (shiftop) > 32)
13491 shift_mask_high <<= INTVAL (shiftop) - 32;
13493 lsb = high & -high;
13495 if ((lsb & shift_mask_high) == 0)
13498 return high == -lsb;
13504 shift_mask_low = ~0;
13505 shift_mask_low <<= INTVAL (shiftop);
13509 if ((lsb & shift_mask_low) == 0)
13512 return low == -lsb && lsb != 1;
13518 /* Return 1 if operands will generate a valid arguments to rlwimi
13519 instruction for insert with right shift in 64-bit mode. The mask may
13520 not start on the first bit or stop on the last bit because wrap-around
13521 effects of instruction do not correspond to semantics of RTL insn. */
13524 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13526 if (INTVAL (startop) > 32
13527 && INTVAL (startop) < 64
13528 && INTVAL (sizeop) > 1
13529 && INTVAL (sizeop) + INTVAL (startop) < 64
13530 && INTVAL (shiftop) > 0
13531 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13532 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
13538 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13539 for lfq and stfq insns iff the registers are hard registers. */
13542 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
13544 /* We might have been passed a SUBREG. */
13545 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
13548 /* We might have been passed non floating point registers. */
13549 if (!FP_REGNO_P (REGNO (reg1))
13550 || !FP_REGNO_P (REGNO (reg2)))
13553 return (REGNO (reg1) == REGNO (reg2) - 1);
13556 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13557 addr1 and addr2 must be in consecutive memory locations
13558 (addr2 == addr1 + 8). */
13561 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
13564 unsigned int reg1, reg2;
13565 int offset1, offset2;
13567 /* The mems cannot be volatile. */
13568 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
13571 addr1 = XEXP (mem1, 0);
13572 addr2 = XEXP (mem2, 0);
13574 /* Extract an offset (if used) from the first addr. */
13575 if (GET_CODE (addr1) == PLUS)
13577 /* If not a REG, return zero. */
13578 if (GET_CODE (XEXP (addr1, 0)) != REG)
13582 reg1 = REGNO (XEXP (addr1, 0));
13583 /* The offset must be constant! */
13584 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13586 offset1 = INTVAL (XEXP (addr1, 1));
13589 else if (GET_CODE (addr1) != REG)
13593 reg1 = REGNO (addr1);
13594 /* This was a simple (mem (reg)) expression. Offset is 0. */
13598 /* And now for the second addr. */
13599 if (GET_CODE (addr2) == PLUS)
13601 /* If not a REG, return zero. */
13602 if (GET_CODE (XEXP (addr2, 0)) != REG)
13606 reg2 = REGNO (XEXP (addr2, 0));
13607 /* The offset must be constant. */
13608 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
13610 offset2 = INTVAL (XEXP (addr2, 1));
13613 else if (GET_CODE (addr2) != REG)
13617 reg2 = REGNO (addr2);
13618 /* This was a simple (mem (reg)) expression. Offset is 0. */
13622 /* Both of these must have the same base register. */
13626 /* The offset for the second addr must be 8 more than the first addr. */
13627 if (offset2 != offset1 + 8)
13630 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13637 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13639 static bool eliminated = false;
13642 if (mode != SDmode)
13643 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13646 rtx mem = cfun->machine->sdmode_stack_slot;
13647 gcc_assert (mem != NULL_RTX);
13651 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13652 cfun->machine->sdmode_stack_slot = mem;
13658 if (TARGET_DEBUG_ADDR)
13660 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13661 GET_MODE_NAME (mode));
13663 fprintf (stderr, "\tNULL_RTX\n");
13672 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13674 /* Don't walk into types. */
13675 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13677 *walk_subtrees = 0;
13681 switch (TREE_CODE (*tp))
13690 case ALIGN_INDIRECT_REF:
13691 case MISALIGNED_INDIRECT_REF:
13692 case VIEW_CONVERT_EXPR:
13693 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13703 enum reload_reg_type {
13705 VECTOR_REGISTER_TYPE,
13706 OTHER_REGISTER_TYPE
13709 static enum reload_reg_type
13710 rs6000_reload_register_type (enum reg_class rclass)
13716 return GPR_REGISTER_TYPE;
13721 return VECTOR_REGISTER_TYPE;
13724 return OTHER_REGISTER_TYPE;
13728 /* Inform reload about cases where moving X with a mode MODE to a register in
13729 RCLASS requires an extra scratch or immediate register. Return the class
13730 needed for the immediate register.
13732 For VSX and Altivec, we may need a register to convert sp+offset into
13735 static enum reg_class
13736 rs6000_secondary_reload (bool in_p,
13738 enum reg_class rclass,
13739 enum machine_mode mode,
13740 secondary_reload_info *sri)
13742 enum reg_class ret = ALL_REGS;
13743 enum insn_code icode;
13744 bool default_p = false;
13746 sri->icode = CODE_FOR_nothing;
13748 /* Convert vector loads and stores into gprs to use an additional base
13750 icode = rs6000_vector_reload[mode][in_p != false];
13751 if (icode != CODE_FOR_nothing)
13754 sri->icode = CODE_FOR_nothing;
13755 sri->extra_cost = 0;
13757 if (GET_CODE (x) == MEM)
13759 rtx addr = XEXP (x, 0);
13761 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13762 an extra register in that case, but it would need an extra
13763 register if the addressing is reg+reg or (reg+reg)&(-16). */
13764 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13766 if (!legitimate_indirect_address_p (addr, false)
13767 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13769 sri->icode = icode;
13770 /* account for splitting the loads, and converting the
13771 address from reg+reg to reg. */
13772 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13773 + ((GET_CODE (addr) == AND) ? 1 : 0));
13776 /* Loads to and stores from vector registers can only do reg+reg
13777 addressing. Altivec registers can also do (reg+reg)&(-16). */
13778 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13779 || rclass == FLOAT_REGS || rclass == NO_REGS)
13781 if (!VECTOR_MEM_ALTIVEC_P (mode)
13782 && GET_CODE (addr) == AND
13783 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13784 && INTVAL (XEXP (addr, 1)) == -16
13785 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13786 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13788 sri->icode = icode;
13789 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13792 else if (!legitimate_indirect_address_p (addr, false)
13793 && (rclass == NO_REGS
13794 || !legitimate_indexed_address_p (addr, false)))
13796 sri->icode = icode;
13797 sri->extra_cost = 1;
13800 icode = CODE_FOR_nothing;
13802 /* Any other loads, including to pseudo registers which haven't been
13803 assigned to a register yet, default to require a scratch
13807 sri->icode = icode;
13808 sri->extra_cost = 2;
13811 else if (REG_P (x))
13813 int regno = true_regnum (x);
13815 icode = CODE_FOR_nothing;
13816 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13820 enum reg_class xclass = REGNO_REG_CLASS (regno);
13821 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13822 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13824 /* If memory is needed, use default_secondary_reload to create the
13826 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13839 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13841 gcc_assert (ret != ALL_REGS);
13843 if (TARGET_DEBUG_ADDR)
13846 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13848 reg_class_names[ret],
13849 in_p ? "true" : "false",
13850 reg_class_names[rclass],
13851 GET_MODE_NAME (mode));
13854 fprintf (stderr, ", default secondary reload");
13856 if (sri->icode != CODE_FOR_nothing)
13857 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13858 insn_data[sri->icode].name, sri->extra_cost);
13860 fprintf (stderr, "\n");
13868 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13869 to SP+reg addressing. */
13872 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13874 int regno = true_regnum (reg);
13875 enum machine_mode mode = GET_MODE (reg);
13876 enum reg_class rclass;
13878 rtx and_op2 = NULL_RTX;
13881 rtx scratch_or_premodify = scratch;
13885 if (TARGET_DEBUG_ADDR)
13887 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13888 store_p ? "store" : "load");
13889 fprintf (stderr, "reg:\n");
13891 fprintf (stderr, "mem:\n");
13893 fprintf (stderr, "scratch:\n");
13894 debug_rtx (scratch);
13897 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13898 gcc_assert (GET_CODE (mem) == MEM);
13899 rclass = REGNO_REG_CLASS (regno);
13900 addr = XEXP (mem, 0);
13904 /* GPRs can handle reg + small constant, all other addresses need to use
13905 the scratch register. */
13908 if (GET_CODE (addr) == AND)
13910 and_op2 = XEXP (addr, 1);
13911 addr = XEXP (addr, 0);
13914 if (GET_CODE (addr) == PRE_MODIFY)
13916 scratch_or_premodify = XEXP (addr, 0);
13917 gcc_assert (REG_P (scratch_or_premodify));
13918 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13919 addr = XEXP (addr, 1);
13922 if (GET_CODE (addr) == PLUS
13923 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13924 || and_op2 != NULL_RTX))
13926 addr_op1 = XEXP (addr, 0);
13927 addr_op2 = XEXP (addr, 1);
13928 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13930 if (!REG_P (addr_op2)
13931 && (GET_CODE (addr_op2) != CONST_INT
13932 || !satisfies_constraint_I (addr_op2)))
13934 if (TARGET_DEBUG_ADDR)
13937 "\nMove plus addr to register %s, mode = %s: ",
13938 rs6000_reg_names[REGNO (scratch)],
13939 GET_MODE_NAME (mode));
13940 debug_rtx (addr_op2);
13942 rs6000_emit_move (scratch, addr_op2, Pmode);
13943 addr_op2 = scratch;
13946 emit_insn (gen_rtx_SET (VOIDmode,
13947 scratch_or_premodify,
13948 gen_rtx_PLUS (Pmode,
13952 addr = scratch_or_premodify;
13953 scratch_or_premodify = scratch;
13955 else if (!legitimate_indirect_address_p (addr, false)
13956 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13958 if (TARGET_DEBUG_ADDR)
13960 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13961 rs6000_reg_names[REGNO (scratch_or_premodify)],
13962 GET_MODE_NAME (mode));
13965 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13966 addr = scratch_or_premodify;
13967 scratch_or_premodify = scratch;
13971 /* Float/Altivec registers can only handle reg+reg addressing. Move
13972 other addresses into a scratch register. */
13977 /* With float regs, we need to handle the AND ourselves, since we can't
13978 use the Altivec instruction with an implicit AND -16. Allow scalar
13979 loads to float registers to use reg+offset even if VSX. */
13980 if (GET_CODE (addr) == AND
13981 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13982 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13983 || INTVAL (XEXP (addr, 1)) != -16
13984 || !VECTOR_MEM_ALTIVEC_P (mode)))
13986 and_op2 = XEXP (addr, 1);
13987 addr = XEXP (addr, 0);
13990 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13991 as the address later. */
13992 if (GET_CODE (addr) == PRE_MODIFY
13993 && (!VECTOR_MEM_VSX_P (mode)
13994 || and_op2 != NULL_RTX
13995 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13997 scratch_or_premodify = XEXP (addr, 0);
13998 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14000 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14001 addr = XEXP (addr, 1);
14004 if (legitimate_indirect_address_p (addr, false) /* reg */
14005 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14006 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14007 || (GET_CODE (addr) == AND /* Altivec memory */
14008 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14009 && INTVAL (XEXP (addr, 1)) == -16
14010 && VECTOR_MEM_ALTIVEC_P (mode))
14011 || (rclass == FLOAT_REGS /* legacy float mem */
14012 && GET_MODE_SIZE (mode) == 8
14013 && and_op2 == NULL_RTX
14014 && scratch_or_premodify == scratch
14015 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14018 else if (GET_CODE (addr) == PLUS)
14020 addr_op1 = XEXP (addr, 0);
14021 addr_op2 = XEXP (addr, 1);
14022 gcc_assert (REG_P (addr_op1));
14024 if (TARGET_DEBUG_ADDR)
14026 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14027 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14028 debug_rtx (addr_op2);
14030 rs6000_emit_move (scratch, addr_op2, Pmode);
14031 emit_insn (gen_rtx_SET (VOIDmode,
14032 scratch_or_premodify,
14033 gen_rtx_PLUS (Pmode,
14036 addr = scratch_or_premodify;
14037 scratch_or_premodify = scratch;
14040 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14041 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14043 if (TARGET_DEBUG_ADDR)
14045 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14046 rs6000_reg_names[REGNO (scratch_or_premodify)],
14047 GET_MODE_NAME (mode));
14051 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14052 addr = scratch_or_premodify;
14053 scratch_or_premodify = scratch;
14057 gcc_unreachable ();
14062 gcc_unreachable ();
14065 /* If the original address involved a pre-modify that we couldn't use the VSX
14066 memory instruction with update, and we haven't taken care of already,
14067 store the address in the pre-modify register and use that as the
14069 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14071 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14072 addr = scratch_or_premodify;
14075 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14076 memory instruction, recreate the AND now, including the clobber which is
14077 generated by the general ANDSI3/ANDDI3 patterns for the
14078 andi. instruction. */
14079 if (and_op2 != NULL_RTX)
14081 if (! legitimate_indirect_address_p (addr, false))
14083 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14087 if (TARGET_DEBUG_ADDR)
14089 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14090 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14091 debug_rtx (and_op2);
14094 and_rtx = gen_rtx_SET (VOIDmode,
14096 gen_rtx_AND (Pmode,
14100 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14101 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14102 gen_rtvec (2, and_rtx, cc_clobber)));
14106 /* Adjust the address if it changed. */
14107 if (addr != XEXP (mem, 0))
14109 mem = change_address (mem, mode, addr);
14110 if (TARGET_DEBUG_ADDR)
14111 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14114 /* Now create the move. */
14116 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14118 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14123 /* Target hook to return the cover classes for Integrated Register Allocator.
14124 Cover classes is a set of non-intersected register classes covering all hard
14125 registers used for register allocation purpose. Any move between two
14126 registers of a cover class should be cheaper than load or store of the
14127 registers. The value is array of register classes with LIM_REG_CLASSES used
14130 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14131 account for the Altivec and Floating registers being subsets of the VSX
14132 register set under VSX, but distinct register sets on pre-VSX machines. */
14134 static const enum reg_class *
14135 rs6000_ira_cover_classes (void)
14137 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
14138 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
14140 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
14143 /* Allocate a 64-bit stack slot to be used for copying SDmode
14144 values through if this function has any SDmode references. */
14147 rs6000_alloc_sdmode_stack_slot (void)
14151 gimple_stmt_iterator gsi;
14153 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14156 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14158 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14161 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14162 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14168 /* Check for any SDmode parameters of the function. */
14169 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
14171 if (TREE_TYPE (t) == error_mark_node)
14174 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14175 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14177 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14178 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14186 rs6000_instantiate_decls (void)
14188 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14189 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14192 /* Given an rtx X being reloaded into a reg required to be
14193 in class CLASS, return the class of reg to actually use.
14194 In general this is just CLASS; but on some machines
14195 in some cases it is preferable to use a more restrictive class.
14197 On the RS/6000, we have to return NO_REGS when we want to reload a
14198 floating-point CONST_DOUBLE to force it to be copied to memory.
14200 We also don't want to reload integer values into floating-point
14201 registers if we can at all help it. In fact, this can
14202 cause reload to die, if it tries to generate a reload of CTR
14203 into a FP register and discovers it doesn't have the memory location
14206 ??? Would it be a good idea to have reload do the converse, that is
14207 try to reload floating modes into FP registers if possible?
14210 static enum reg_class
14211 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14213 enum machine_mode mode = GET_MODE (x);
14215 if (VECTOR_UNIT_VSX_P (mode)
14216 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14219 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14220 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14221 && easy_vector_constant (x, mode))
14222 return ALTIVEC_REGS;
14224 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14227 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14228 return GENERAL_REGS;
14230 /* For VSX, prefer the traditional registers for 64-bit values because we can
14231 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14232 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14233 prefer Altivec loads.. */
14234 if (rclass == VSX_REGS)
14236 if (GET_MODE_SIZE (mode) <= 8)
14239 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14240 return ALTIVEC_REGS;
14248 /* Debug version of rs6000_preferred_reload_class. */
14249 static enum reg_class
14250 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14252 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14255 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14257 reg_class_names[ret], reg_class_names[rclass],
14258 GET_MODE_NAME (GET_MODE (x)));
14264 /* If we are copying between FP or AltiVec registers and anything else, we need
14265 a memory location. The exception is when we are targeting ppc64 and the
14266 move to/from fpr to gpr instructions are available. Also, under VSX, you
14267 can copy vector registers from the FP register set to the Altivec register
14268 set and vice versa. */
14271 rs6000_secondary_memory_needed (enum reg_class class1,
14272 enum reg_class class2,
14273 enum machine_mode mode)
14275 if (class1 == class2)
14278 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14279 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14280 between these classes. But we need memory for other things that can go in
14281 FLOAT_REGS like SFmode. */
14283 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14284 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14285 || class1 == FLOAT_REGS))
14286 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14287 && class2 != FLOAT_REGS);
14289 if (class1 == VSX_REGS || class2 == VSX_REGS)
14292 if (class1 == FLOAT_REGS
14293 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14294 || ((mode != DFmode)
14295 && (mode != DDmode)
14296 && (mode != DImode))))
14299 if (class2 == FLOAT_REGS
14300 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14301 || ((mode != DFmode)
14302 && (mode != DDmode)
14303 && (mode != DImode))))
14306 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14312 /* Debug version of rs6000_secondary_memory_needed. */
14314 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14315 enum reg_class class2,
14316 enum machine_mode mode)
14318 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14321 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14322 "class2 = %s, mode = %s\n",
14323 ret ? "true" : "false", reg_class_names[class1],
14324 reg_class_names[class2], GET_MODE_NAME (mode));
14329 /* Return the register class of a scratch register needed to copy IN into
14330 or out of a register in RCLASS in MODE. If it can be done directly,
14331 NO_REGS is returned. */
14333 static enum reg_class
14334 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14339 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14341 && MACHOPIC_INDIRECT
14345 /* We cannot copy a symbolic operand directly into anything
14346 other than BASE_REGS for TARGET_ELF. So indicate that a
14347 register from BASE_REGS is needed as an intermediate
14350 On Darwin, pic addresses require a load from memory, which
14351 needs a base register. */
14352 if (rclass != BASE_REGS
14353 && (GET_CODE (in) == SYMBOL_REF
14354 || GET_CODE (in) == HIGH
14355 || GET_CODE (in) == LABEL_REF
14356 || GET_CODE (in) == CONST))
14360 if (GET_CODE (in) == REG)
14362 regno = REGNO (in);
14363 if (regno >= FIRST_PSEUDO_REGISTER)
14365 regno = true_regnum (in);
14366 if (regno >= FIRST_PSEUDO_REGISTER)
14370 else if (GET_CODE (in) == SUBREG)
14372 regno = true_regnum (in);
14373 if (regno >= FIRST_PSEUDO_REGISTER)
14379 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14381 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14382 || (regno >= 0 && INT_REGNO_P (regno)))
14385 /* Constants, memory, and FP registers can go into FP registers. */
14386 if ((regno == -1 || FP_REGNO_P (regno))
14387 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14388 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14390 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14393 && (regno == -1 || VSX_REGNO_P (regno))
14394 && VSX_REG_CLASS_P (rclass))
14397 /* Memory, and AltiVec registers can go into AltiVec registers. */
14398 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14399 && rclass == ALTIVEC_REGS)
14402 /* We can copy among the CR registers. */
14403 if ((rclass == CR_REGS || rclass == CR0_REGS)
14404 && regno >= 0 && CR_REGNO_P (regno))
14407 /* Otherwise, we need GENERAL_REGS. */
14408 return GENERAL_REGS;
14411 /* Debug version of rs6000_secondary_reload_class. */
14412 static enum reg_class
14413 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14414 enum machine_mode mode, rtx in)
14416 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14418 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14419 "mode = %s, input rtx:\n",
14420 reg_class_names[ret], reg_class_names[rclass],
14421 GET_MODE_NAME (mode));
14427 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14430 rs6000_cannot_change_mode_class (enum machine_mode from,
14431 enum machine_mode to,
14432 enum reg_class rclass)
14434 unsigned from_size = GET_MODE_SIZE (from);
14435 unsigned to_size = GET_MODE_SIZE (to);
14437 if (from_size != to_size)
14439 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14440 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14441 && reg_classes_intersect_p (xclass, rclass));
14444 if (TARGET_E500_DOUBLE
14445 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14446 || (((to) == TFmode) + ((from) == TFmode)) == 1
14447 || (((to) == DDmode) + ((from) == DDmode)) == 1
14448 || (((to) == TDmode) + ((from) == TDmode)) == 1
14449 || (((to) == DImode) + ((from) == DImode)) == 1))
14452 /* Since the VSX register set includes traditional floating point registers
14453 and altivec registers, just check for the size being different instead of
14454 trying to check whether the modes are vector modes. Otherwise it won't
14455 allow say DF and DI to change classes. */
14456 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14457 return (from_size != 8 && from_size != 16);
14459 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14460 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14463 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14464 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14470 /* Debug version of rs6000_cannot_change_mode_class. */
14472 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14473 enum machine_mode to,
14474 enum reg_class rclass)
14476 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
14479 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14480 "to = %s, rclass = %s\n",
14481 ret ? "true" : "false",
14482 GET_MODE_NAME (from), GET_MODE_NAME (to),
14483 reg_class_names[rclass]);
14488 /* Given a comparison operation, return the bit number in CCR to test. We
14489 know this is a valid comparison.
14491 SCC_P is 1 if this is for an scc. That means that %D will have been
14492 used instead of %C, so the bits will be in different places.
14494 Return -1 if OP isn't a valid comparison for some reason. */
14497 ccr_bit (rtx op, int scc_p)
14499 enum rtx_code code = GET_CODE (op);
14500 enum machine_mode cc_mode;
14505 if (!COMPARISON_P (op))
14508 reg = XEXP (op, 0);
14510 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14512 cc_mode = GET_MODE (reg);
14513 cc_regnum = REGNO (reg);
14514 base_bit = 4 * (cc_regnum - CR0_REGNO);
14516 validate_condition_mode (code, cc_mode);
14518 /* When generating a sCOND operation, only positive conditions are
14521 || code == EQ || code == GT || code == LT || code == UNORDERED
14522 || code == GTU || code == LTU);
14527 return scc_p ? base_bit + 3 : base_bit + 2;
14529 return base_bit + 2;
14530 case GT: case GTU: case UNLE:
14531 return base_bit + 1;
14532 case LT: case LTU: case UNGE:
14534 case ORDERED: case UNORDERED:
14535 return base_bit + 3;
14538 /* If scc, we will have done a cror to put the bit in the
14539 unordered position. So test that bit. For integer, this is ! LT
14540 unless this is an scc insn. */
14541 return scc_p ? base_bit + 3 : base_bit;
14544 return scc_p ? base_bit + 3 : base_bit + 1;
14547 gcc_unreachable ();
14551 /* Return the GOT register. */
14554 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
14556 /* The second flow pass currently (June 1999) can't update
14557 regs_ever_live without disturbing other parts of the compiler, so
14558 update it here to make the prolog/epilogue code happy. */
14559 if (!can_create_pseudo_p ()
14560 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
14561 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
14563 crtl->uses_pic_offset_table = 1;
14565 return pic_offset_table_rtx;
14568 /* Function to init struct machine_function.
14569 This will be called, via a pointer variable,
14570 from push_function_context. */
14572 static struct machine_function *
14573 rs6000_init_machine_status (void)
14575 return ggc_alloc_cleared_machine_function ();
14578 /* These macros test for integers and extract the low-order bits. */
14580 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
14581 && GET_MODE (X) == VOIDmode)
14583 #define INT_LOWPART(X) \
14584 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
14587 extract_MB (rtx op)
14590 unsigned long val = INT_LOWPART (op);
14592 /* If the high bit is zero, the value is the first 1 bit we find
14594 if ((val & 0x80000000) == 0)
14596 gcc_assert (val & 0xffffffff);
14599 while (((val <<= 1) & 0x80000000) == 0)
14604 /* If the high bit is set and the low bit is not, or the mask is all
14605 1's, the value is zero. */
14606 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14609 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14612 while (((val >>= 1) & 1) != 0)
14619 extract_ME (rtx op)
14622 unsigned long val = INT_LOWPART (op);
14624 /* If the low bit is zero, the value is the first 1 bit we find from
14626 if ((val & 1) == 0)
14628 gcc_assert (val & 0xffffffff);
14631 while (((val >>= 1) & 1) == 0)
14637 /* If the low bit is set and the high bit is not, or the mask is all
14638 1's, the value is 31. */
14639 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14642 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14645 while (((val <<= 1) & 0x80000000) != 0)
14651 /* Locate some local-dynamic symbol still in use by this function
14652 so that we can print its name in some tls_ld pattern. */
14654 static const char *
14655 rs6000_get_some_local_dynamic_name (void)
14659 if (cfun->machine->some_ld_name)
14660 return cfun->machine->some_ld_name;
14662 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14664 && for_each_rtx (&PATTERN (insn),
14665 rs6000_get_some_local_dynamic_name_1, 0))
14666 return cfun->machine->some_ld_name;
14668 gcc_unreachable ();
14671 /* Helper function for rs6000_get_some_local_dynamic_name. */
14674 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14678 if (GET_CODE (x) == SYMBOL_REF)
14680 const char *str = XSTR (x, 0);
14681 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14683 cfun->machine->some_ld_name = str;
14691 /* Write out a function code label. */
14694 rs6000_output_function_entry (FILE *file, const char *fname)
14696 if (fname[0] != '.')
14698 switch (DEFAULT_ABI)
14701 gcc_unreachable ();
14707 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14716 RS6000_OUTPUT_BASENAME (file, fname);
14719 /* Print an operand. Recognize special options, documented below. */
14722 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14723 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14725 #define SMALL_DATA_RELOC "sda21"
14726 #define SMALL_DATA_REG 0
14730 print_operand (FILE *file, rtx x, int code)
14734 unsigned HOST_WIDE_INT uval;
14739 /* Write out an instruction after the call which may be replaced
14740 with glue code by the loader. This depends on the AIX version. */
14741 asm_fprintf (file, RS6000_CALL_GLUE);
14744 /* %a is output_address. */
14747 /* If X is a constant integer whose low-order 5 bits are zero,
14748 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14749 in the AIX assembler where "sri" with a zero shift count
14750 writes a trash instruction. */
14751 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14758 /* If constant, low-order 16 bits of constant, unsigned.
14759 Otherwise, write normally. */
14761 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14763 print_operand (file, x, 0);
14767 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14768 for 64-bit mask direction. */
14769 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14772 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14776 /* X is a CR register. Print the number of the GT bit of the CR. */
14777 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14778 output_operand_lossage ("invalid %%c value");
14780 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14784 /* Like 'J' but get to the GT bit only. */
14785 gcc_assert (GET_CODE (x) == REG);
14787 /* Bit 1 is GT bit. */
14788 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14790 /* Add one for shift count in rlinm for scc. */
14791 fprintf (file, "%d", i + 1);
14795 /* X is a CR register. Print the number of the EQ bit of the CR */
14796 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14797 output_operand_lossage ("invalid %%E value");
14799 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14803 /* X is a CR register. Print the shift count needed to move it
14804 to the high-order four bits. */
14805 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14806 output_operand_lossage ("invalid %%f value");
14808 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14812 /* Similar, but print the count for the rotate in the opposite
14814 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14815 output_operand_lossage ("invalid %%F value");
14817 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14821 /* X is a constant integer. If it is negative, print "m",
14822 otherwise print "z". This is to make an aze or ame insn. */
14823 if (GET_CODE (x) != CONST_INT)
14824 output_operand_lossage ("invalid %%G value");
14825 else if (INTVAL (x) >= 0)
14832 /* If constant, output low-order five bits. Otherwise, write
14835 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14837 print_operand (file, x, 0);
14841 /* If constant, output low-order six bits. Otherwise, write
14844 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14846 print_operand (file, x, 0);
14850 /* Print `i' if this is a constant, else nothing. */
14856 /* Write the bit number in CCR for jump. */
14857 i = ccr_bit (x, 0);
14859 output_operand_lossage ("invalid %%j code");
14861 fprintf (file, "%d", i);
14865 /* Similar, but add one for shift count in rlinm for scc and pass
14866 scc flag to `ccr_bit'. */
14867 i = ccr_bit (x, 1);
14869 output_operand_lossage ("invalid %%J code");
14871 /* If we want bit 31, write a shift count of zero, not 32. */
14872 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14876 /* X must be a constant. Write the 1's complement of the
14879 output_operand_lossage ("invalid %%k value");
14881 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14885 /* X must be a symbolic constant on ELF. Write an
14886 expression suitable for an 'addi' that adds in the low 16
14887 bits of the MEM. */
14888 if (GET_CODE (x) == CONST)
14890 if (GET_CODE (XEXP (x, 0)) != PLUS
14891 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14892 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14893 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14894 output_operand_lossage ("invalid %%K value");
14896 print_operand_address (file, x);
14897 fputs ("@l", file);
14900 /* %l is output_asm_label. */
14903 /* Write second word of DImode or DFmode reference. Works on register
14904 or non-indexed memory only. */
14905 if (GET_CODE (x) == REG)
14906 fputs (reg_names[REGNO (x) + 1], file);
14907 else if (GET_CODE (x) == MEM)
14909 /* Handle possible auto-increment. Since it is pre-increment and
14910 we have already done it, we can just use an offset of word. */
14911 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14912 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14913 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14915 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14916 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14919 output_address (XEXP (adjust_address_nv (x, SImode,
14923 if (small_data_operand (x, GET_MODE (x)))
14924 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14925 reg_names[SMALL_DATA_REG]);
14930 /* MB value for a mask operand. */
14931 if (! mask_operand (x, SImode))
14932 output_operand_lossage ("invalid %%m value");
14934 fprintf (file, "%d", extract_MB (x));
14938 /* ME value for a mask operand. */
14939 if (! mask_operand (x, SImode))
14940 output_operand_lossage ("invalid %%M value");
14942 fprintf (file, "%d", extract_ME (x));
14945 /* %n outputs the negative of its operand. */
14948 /* Write the number of elements in the vector times 4. */
14949 if (GET_CODE (x) != PARALLEL)
14950 output_operand_lossage ("invalid %%N value");
14952 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14956 /* Similar, but subtract 1 first. */
14957 if (GET_CODE (x) != PARALLEL)
14958 output_operand_lossage ("invalid %%O value");
14960 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14964 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14966 || INT_LOWPART (x) < 0
14967 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14968 output_operand_lossage ("invalid %%p value");
14970 fprintf (file, "%d", i);
14974 /* The operand must be an indirect memory reference. The result
14975 is the register name. */
14976 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14977 || REGNO (XEXP (x, 0)) >= 32)
14978 output_operand_lossage ("invalid %%P value");
14980 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14984 /* This outputs the logical code corresponding to a boolean
14985 expression. The expression may have one or both operands
14986 negated (if one, only the first one). For condition register
14987 logical operations, it will also treat the negated
14988 CR codes as NOTs, but not handle NOTs of them. */
14990 const char *const *t = 0;
14992 enum rtx_code code = GET_CODE (x);
14993 static const char * const tbl[3][3] = {
14994 { "and", "andc", "nor" },
14995 { "or", "orc", "nand" },
14996 { "xor", "eqv", "xor" } };
15000 else if (code == IOR)
15002 else if (code == XOR)
15005 output_operand_lossage ("invalid %%q value");
15007 if (GET_CODE (XEXP (x, 0)) != NOT)
15011 if (GET_CODE (XEXP (x, 1)) == NOT)
15029 /* X is a CR register. Print the mask for `mtcrf'. */
15030 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15031 output_operand_lossage ("invalid %%R value");
15033 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15037 /* Low 5 bits of 32 - value */
15039 output_operand_lossage ("invalid %%s value");
15041 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15045 /* PowerPC64 mask position. All 0's is excluded.
15046 CONST_INT 32-bit mask is considered sign-extended so any
15047 transition must occur within the CONST_INT, not on the boundary. */
15048 if (! mask64_operand (x, DImode))
15049 output_operand_lossage ("invalid %%S value");
15051 uval = INT_LOWPART (x);
15053 if (uval & 1) /* Clear Left */
15055 #if HOST_BITS_PER_WIDE_INT > 64
15056 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15060 else /* Clear Right */
15063 #if HOST_BITS_PER_WIDE_INT > 64
15064 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15070 gcc_assert (i >= 0);
15071 fprintf (file, "%d", i);
15075 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15076 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15078 /* Bit 3 is OV bit. */
15079 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15081 /* If we want bit 31, write a shift count of zero, not 32. */
15082 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15086 /* Print the symbolic name of a branch target register. */
15087 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15088 && REGNO (x) != CTR_REGNO))
15089 output_operand_lossage ("invalid %%T value");
15090 else if (REGNO (x) == LR_REGNO)
15091 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15093 fputs ("ctr", file);
15097 /* High-order 16 bits of constant for use in unsigned operand. */
15099 output_operand_lossage ("invalid %%u value");
15101 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15102 (INT_LOWPART (x) >> 16) & 0xffff);
15106 /* High-order 16 bits of constant for use in signed operand. */
15108 output_operand_lossage ("invalid %%v value");
15110 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15111 (INT_LOWPART (x) >> 16) & 0xffff);
15115 /* Print `u' if this has an auto-increment or auto-decrement. */
15116 if (GET_CODE (x) == MEM
15117 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15118 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15119 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15124 /* Print the trap code for this operand. */
15125 switch (GET_CODE (x))
15128 fputs ("eq", file); /* 4 */
15131 fputs ("ne", file); /* 24 */
15134 fputs ("lt", file); /* 16 */
15137 fputs ("le", file); /* 20 */
15140 fputs ("gt", file); /* 8 */
15143 fputs ("ge", file); /* 12 */
15146 fputs ("llt", file); /* 2 */
15149 fputs ("lle", file); /* 6 */
15152 fputs ("lgt", file); /* 1 */
15155 fputs ("lge", file); /* 5 */
15158 gcc_unreachable ();
15163 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15166 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15167 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15169 print_operand (file, x, 0);
15173 /* MB value for a PowerPC64 rldic operand. */
15174 val = (GET_CODE (x) == CONST_INT
15175 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15180 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15181 if ((val <<= 1) < 0)
15184 #if HOST_BITS_PER_WIDE_INT == 32
15185 if (GET_CODE (x) == CONST_INT && i >= 0)
15186 i += 32; /* zero-extend high-part was all 0's */
15187 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15189 val = CONST_DOUBLE_LOW (x);
15195 for ( ; i < 64; i++)
15196 if ((val <<= 1) < 0)
15201 fprintf (file, "%d", i + 1);
15205 /* X is a FPR or Altivec register used in a VSX context. */
15206 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15207 output_operand_lossage ("invalid %%x value");
15210 int reg = REGNO (x);
15211 int vsx_reg = (FP_REGNO_P (reg)
15213 : reg - FIRST_ALTIVEC_REGNO + 32);
15215 #ifdef TARGET_REGNAMES
15216 if (TARGET_REGNAMES)
15217 fprintf (file, "%%vs%d", vsx_reg);
15220 fprintf (file, "%d", vsx_reg);
15225 if (GET_CODE (x) == MEM
15226 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15227 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15228 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15233 /* Like 'L', for third word of TImode */
15234 if (GET_CODE (x) == REG)
15235 fputs (reg_names[REGNO (x) + 2], file);
15236 else if (GET_CODE (x) == MEM)
15238 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15239 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15240 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15241 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15242 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15244 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15245 if (small_data_operand (x, GET_MODE (x)))
15246 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15247 reg_names[SMALL_DATA_REG]);
15252 /* X is a SYMBOL_REF. Write out the name preceded by a
15253 period and without any trailing data in brackets. Used for function
15254 names. If we are configured for System V (or the embedded ABI) on
15255 the PowerPC, do not emit the period, since those systems do not use
15256 TOCs and the like. */
15257 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15259 /* Mark the decl as referenced so that cgraph will output the
15261 if (SYMBOL_REF_DECL (x))
15262 mark_decl_referenced (SYMBOL_REF_DECL (x));
15264 /* For macho, check to see if we need a stub. */
15267 const char *name = XSTR (x, 0);
15269 if (MACHOPIC_INDIRECT
15270 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15271 name = machopic_indirection_name (x, /*stub_p=*/true);
15273 assemble_name (file, name);
15275 else if (!DOT_SYMBOLS)
15276 assemble_name (file, XSTR (x, 0));
15278 rs6000_output_function_entry (file, XSTR (x, 0));
15282 /* Like 'L', for last word of TImode. */
15283 if (GET_CODE (x) == REG)
15284 fputs (reg_names[REGNO (x) + 3], file);
15285 else if (GET_CODE (x) == MEM)
15287 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15288 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15289 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15290 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15291 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15293 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15294 if (small_data_operand (x, GET_MODE (x)))
15295 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15296 reg_names[SMALL_DATA_REG]);
15300 /* Print AltiVec or SPE memory operand. */
15305 gcc_assert (GET_CODE (x) == MEM);
15309 /* Ugly hack because %y is overloaded. */
15310 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15311 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15312 || GET_MODE (x) == TFmode
15313 || GET_MODE (x) == TImode))
15315 /* Handle [reg]. */
15316 if (GET_CODE (tmp) == REG)
15318 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15321 /* Handle [reg+UIMM]. */
15322 else if (GET_CODE (tmp) == PLUS &&
15323 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15327 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15329 x = INTVAL (XEXP (tmp, 1));
15330 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15334 /* Fall through. Must be [reg+reg]. */
15336 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15337 && GET_CODE (tmp) == AND
15338 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15339 && INTVAL (XEXP (tmp, 1)) == -16)
15340 tmp = XEXP (tmp, 0);
15341 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15342 && GET_CODE (tmp) == PRE_MODIFY)
15343 tmp = XEXP (tmp, 1);
15344 if (GET_CODE (tmp) == REG)
15345 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15348 if (!GET_CODE (tmp) == PLUS
15349 || !REG_P (XEXP (tmp, 0))
15350 || !REG_P (XEXP (tmp, 1)))
15352 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15356 if (REGNO (XEXP (tmp, 0)) == 0)
15357 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15358 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15360 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15361 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15367 if (GET_CODE (x) == REG)
15368 fprintf (file, "%s", reg_names[REGNO (x)]);
15369 else if (GET_CODE (x) == MEM)
15371 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15372 know the width from the mode. */
15373 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15374 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15375 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15376 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15377 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15378 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15379 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15380 output_address (XEXP (XEXP (x, 0), 1));
15382 output_address (XEXP (x, 0));
15385 output_addr_const (file, x);
15389 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15393 output_operand_lossage ("invalid %%xn code");
15397 /* Print the address of an operand. */
15400 print_operand_address (FILE *file, rtx x)
15402 if (GET_CODE (x) == REG)
15403 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15404 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15405 || GET_CODE (x) == LABEL_REF)
15407 output_addr_const (file, x);
15408 if (small_data_operand (x, GET_MODE (x)))
15409 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15410 reg_names[SMALL_DATA_REG]);
15412 gcc_assert (!TARGET_TOC);
15414 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15416 gcc_assert (REG_P (XEXP (x, 0)));
15417 if (REGNO (XEXP (x, 0)) == 0)
15418 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15419 reg_names[ REGNO (XEXP (x, 0)) ]);
15421 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15422 reg_names[ REGNO (XEXP (x, 1)) ]);
15424 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15425 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15426 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15428 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15429 && CONSTANT_P (XEXP (x, 1)))
15431 fprintf (file, "lo16(");
15432 output_addr_const (file, XEXP (x, 1));
15433 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15436 else if (legitimate_constant_pool_address_p (x, true))
15438 /* This hack along with a corresponding hack in
15439 rs6000_output_addr_const_extra arranges to output addends
15440 where the assembler expects to find them. eg.
15442 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
15443 without this hack would be output as "x@toc+8@l(9)". We
15444 want "x+8@toc@l(9)". */
15445 output_addr_const (file, tocrel_base);
15446 if (GET_CODE (x) == LO_SUM)
15447 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15449 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15452 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15453 && CONSTANT_P (XEXP (x, 1)))
15455 output_addr_const (file, XEXP (x, 1));
15456 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15460 gcc_unreachable ();
15463 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
15466 rs6000_output_addr_const_extra (FILE *file, rtx x)
15468 if (GET_CODE (x) == UNSPEC)
15469 switch (XINT (x, 1))
15471 case UNSPEC_TOCREL:
15472 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
15473 output_addr_const (file, XVECEXP (x, 0, 0));
15474 if (x == tocrel_base && tocrel_offset != const0_rtx)
15476 if (INTVAL (tocrel_offset) >= 0)
15477 fprintf (file, "+");
15478 output_addr_const (file, tocrel_offset);
15480 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
15483 assemble_name (file, toc_label_name);
15485 else if (TARGET_ELF)
15486 fputs ("@toc", file);
15490 case UNSPEC_MACHOPIC_OFFSET:
15491 output_addr_const (file, XVECEXP (x, 0, 0));
15493 machopic_output_function_base_name (file);
15500 /* Target hook for assembling integer objects. The PowerPC version has
15501 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15502 is defined. It also needs to handle DI-mode objects on 64-bit
15506 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15508 #ifdef RELOCATABLE_NEEDS_FIXUP
15509 /* Special handling for SI values. */
15510 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
15512 static int recurse = 0;
15514 /* For -mrelocatable, we mark all addresses that need to be fixed up
15515 in the .fixup section. */
15516 if (TARGET_RELOCATABLE
15517 && in_section != toc_section
15518 && in_section != text_section
15519 && !unlikely_text_section_p (in_section)
15521 && GET_CODE (x) != CONST_INT
15522 && GET_CODE (x) != CONST_DOUBLE
15528 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
15530 ASM_OUTPUT_LABEL (asm_out_file, buf);
15531 fprintf (asm_out_file, "\t.long\t(");
15532 output_addr_const (asm_out_file, x);
15533 fprintf (asm_out_file, ")@fixup\n");
15534 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
15535 ASM_OUTPUT_ALIGN (asm_out_file, 2);
15536 fprintf (asm_out_file, "\t.long\t");
15537 assemble_name (asm_out_file, buf);
15538 fprintf (asm_out_file, "\n\t.previous\n");
15542 /* Remove initial .'s to turn a -mcall-aixdesc function
15543 address into the address of the descriptor, not the function
15545 else if (GET_CODE (x) == SYMBOL_REF
15546 && XSTR (x, 0)[0] == '.'
15547 && DEFAULT_ABI == ABI_AIX)
15549 const char *name = XSTR (x, 0);
15550 while (*name == '.')
15553 fprintf (asm_out_file, "\t.long\t%s\n", name);
15557 #endif /* RELOCATABLE_NEEDS_FIXUP */
15558 return default_assemble_integer (x, size, aligned_p);
15561 #ifdef HAVE_GAS_HIDDEN
15562 /* Emit an assembler directive to set symbol visibility for DECL to
15563 VISIBILITY_TYPE. */
15566 rs6000_assemble_visibility (tree decl, int vis)
15568 /* Functions need to have their entry point symbol visibility set as
15569 well as their descriptor symbol visibility. */
15570 if (DEFAULT_ABI == ABI_AIX
15572 && TREE_CODE (decl) == FUNCTION_DECL)
15574 static const char * const visibility_types[] = {
15575 NULL, "internal", "hidden", "protected"
15578 const char *name, *type;
15580 name = ((* targetm.strip_name_encoding)
15581 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
15582 type = visibility_types[vis];
15584 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
15585 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
15588 default_assemble_visibility (decl, vis);
15593 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15595 /* Reversal of FP compares takes care -- an ordered compare
15596 becomes an unordered compare and vice versa. */
15597 if (mode == CCFPmode
15598 && (!flag_finite_math_only
15599 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15600 || code == UNEQ || code == LTGT))
15601 return reverse_condition_maybe_unordered (code);
15603 return reverse_condition (code);
15606 /* Generate a compare for CODE. Return a brand-new rtx that
15607 represents the result of the compare. */
15610 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15612 enum machine_mode comp_mode;
15613 rtx compare_result;
15614 enum rtx_code code = GET_CODE (cmp);
15615 rtx op0 = XEXP (cmp, 0);
15616 rtx op1 = XEXP (cmp, 1);
15618 if (FLOAT_MODE_P (mode))
15619 comp_mode = CCFPmode;
15620 else if (code == GTU || code == LTU
15621 || code == GEU || code == LEU)
15622 comp_mode = CCUNSmode;
15623 else if ((code == EQ || code == NE)
15624 && GET_CODE (op0) == SUBREG
15625 && GET_CODE (op1) == SUBREG
15626 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15627 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15628 /* These are unsigned values, perhaps there will be a later
15629 ordering compare that can be shared with this one.
15630 Unfortunately we cannot detect the signedness of the operands
15631 for non-subregs. */
15632 comp_mode = CCUNSmode;
15634 comp_mode = CCmode;
15636 /* First, the compare. */
15637 compare_result = gen_reg_rtx (comp_mode);
15639 /* E500 FP compare instructions on the GPRs. Yuck! */
15640 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15641 && FLOAT_MODE_P (mode))
15643 rtx cmp, or_result, compare_result2;
15644 enum machine_mode op_mode = GET_MODE (op0);
15646 if (op_mode == VOIDmode)
15647 op_mode = GET_MODE (op1);
15649 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15650 This explains the following mess. */
15654 case EQ: case UNEQ: case NE: case LTGT:
15658 cmp = (flag_finite_math_only && !flag_trapping_math)
15659 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15660 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15664 cmp = (flag_finite_math_only && !flag_trapping_math)
15665 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15666 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15670 cmp = (flag_finite_math_only && !flag_trapping_math)
15671 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15672 : gen_cmptfeq_gpr (compare_result, op0, op1);
15676 gcc_unreachable ();
15680 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15684 cmp = (flag_finite_math_only && !flag_trapping_math)
15685 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15686 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15690 cmp = (flag_finite_math_only && !flag_trapping_math)
15691 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15692 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15696 cmp = (flag_finite_math_only && !flag_trapping_math)
15697 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15698 : gen_cmptfgt_gpr (compare_result, op0, op1);
15702 gcc_unreachable ();
15706 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15710 cmp = (flag_finite_math_only && !flag_trapping_math)
15711 ? gen_tstsflt_gpr (compare_result, op0, op1)
15712 : gen_cmpsflt_gpr (compare_result, op0, op1);
15716 cmp = (flag_finite_math_only && !flag_trapping_math)
15717 ? gen_tstdflt_gpr (compare_result, op0, op1)
15718 : gen_cmpdflt_gpr (compare_result, op0, op1);
15722 cmp = (flag_finite_math_only && !flag_trapping_math)
15723 ? gen_tsttflt_gpr (compare_result, op0, op1)
15724 : gen_cmptflt_gpr (compare_result, op0, op1);
15728 gcc_unreachable ();
15732 gcc_unreachable ();
15735 /* Synthesize LE and GE from LT/GT || EQ. */
15736 if (code == LE || code == GE || code == LEU || code == GEU)
15742 case LE: code = LT; break;
15743 case GE: code = GT; break;
15744 case LEU: code = LT; break;
15745 case GEU: code = GT; break;
15746 default: gcc_unreachable ();
15749 compare_result2 = gen_reg_rtx (CCFPmode);
15755 cmp = (flag_finite_math_only && !flag_trapping_math)
15756 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15757 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15761 cmp = (flag_finite_math_only && !flag_trapping_math)
15762 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15763 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15767 cmp = (flag_finite_math_only && !flag_trapping_math)
15768 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15769 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15773 gcc_unreachable ();
15777 /* OR them together. */
15778 or_result = gen_reg_rtx (CCFPmode);
15779 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15781 compare_result = or_result;
15786 if (code == NE || code == LTGT)
15796 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15797 CLOBBERs to match cmptf_internal2 pattern. */
15798 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15799 && GET_MODE (op0) == TFmode
15800 && !TARGET_IEEEQUAD
15801 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15802 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15804 gen_rtx_SET (VOIDmode,
15806 gen_rtx_COMPARE (comp_mode, op0, op1)),
15807 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15808 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15809 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15810 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15811 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15812 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15813 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15814 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15815 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
15816 else if (GET_CODE (op1) == UNSPEC
15817 && XINT (op1, 1) == UNSPEC_SP_TEST)
15819 rtx op1b = XVECEXP (op1, 0, 0);
15820 comp_mode = CCEQmode;
15821 compare_result = gen_reg_rtx (CCEQmode);
15823 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15825 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15828 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15829 gen_rtx_COMPARE (comp_mode, op0, op1)));
15832 /* Some kinds of FP comparisons need an OR operation;
15833 under flag_finite_math_only we don't bother. */
15834 if (FLOAT_MODE_P (mode)
15835 && !flag_finite_math_only
15836 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15837 && (code == LE || code == GE
15838 || code == UNEQ || code == LTGT
15839 || code == UNGT || code == UNLT))
15841 enum rtx_code or1, or2;
15842 rtx or1_rtx, or2_rtx, compare2_rtx;
15843 rtx or_result = gen_reg_rtx (CCEQmode);
15847 case LE: or1 = LT; or2 = EQ; break;
15848 case GE: or1 = GT; or2 = EQ; break;
15849 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15850 case LTGT: or1 = LT; or2 = GT; break;
15851 case UNGT: or1 = UNORDERED; or2 = GT; break;
15852 case UNLT: or1 = UNORDERED; or2 = LT; break;
15853 default: gcc_unreachable ();
15855 validate_condition_mode (or1, comp_mode);
15856 validate_condition_mode (or2, comp_mode);
15857 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15858 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15859 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15860 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15862 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15864 compare_result = or_result;
15868 validate_condition_mode (code, GET_MODE (compare_result));
15870 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15874 /* Emit the RTL for an sCOND pattern. */
15877 rs6000_emit_sISEL (enum machine_mode mode, rtx operands[])
15880 enum machine_mode op_mode;
15881 enum rtx_code cond_code;
15882 rtx result = operands[0];
15884 condition_rtx = rs6000_generate_compare (operands[1], mode);
15885 cond_code = GET_CODE (condition_rtx);
15887 op_mode = GET_MODE (XEXP (operands[1], 0));
15888 if (op_mode == VOIDmode)
15889 op_mode = GET_MODE (XEXP (operands[1], 1));
15891 if (TARGET_POWERPC64 && GET_MODE (result) == DImode)
15893 PUT_MODE (condition_rtx, DImode);
15894 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15895 || cond_code == LTU)
15896 emit_insn (gen_isel_unsigned_di (result, condition_rtx,
15897 force_reg (DImode, const1_rtx),
15898 force_reg (DImode, const0_rtx),
15899 XEXP (condition_rtx, 0)));
15901 emit_insn (gen_isel_signed_di (result, condition_rtx,
15902 force_reg (DImode, const1_rtx),
15903 force_reg (DImode, const0_rtx),
15904 XEXP (condition_rtx, 0)));
15908 PUT_MODE (condition_rtx, SImode);
15909 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15910 || cond_code == LTU)
15911 emit_insn (gen_isel_unsigned_si (result, condition_rtx,
15912 force_reg (SImode, const1_rtx),
15913 force_reg (SImode, const0_rtx),
15914 XEXP (condition_rtx, 0)));
15916 emit_insn (gen_isel_signed_si (result, condition_rtx,
15917 force_reg (SImode, const1_rtx),
15918 force_reg (SImode, const0_rtx),
15919 XEXP (condition_rtx, 0)));
15924 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15927 enum machine_mode op_mode;
15928 enum rtx_code cond_code;
15929 rtx result = operands[0];
15931 if (TARGET_ISEL && (mode == SImode || mode == DImode))
15933 rs6000_emit_sISEL (mode, operands);
15937 condition_rtx = rs6000_generate_compare (operands[1], mode);
15938 cond_code = GET_CODE (condition_rtx);
15940 if (FLOAT_MODE_P (mode)
15941 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15945 PUT_MODE (condition_rtx, SImode);
15946 t = XEXP (condition_rtx, 0);
15948 gcc_assert (cond_code == NE || cond_code == EQ);
15950 if (cond_code == NE)
15951 emit_insn (gen_e500_flip_gt_bit (t, t));
15953 emit_insn (gen_move_from_CR_gt_bit (result, t));
15957 if (cond_code == NE
15958 || cond_code == GE || cond_code == LE
15959 || cond_code == GEU || cond_code == LEU
15960 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15962 rtx not_result = gen_reg_rtx (CCEQmode);
15963 rtx not_op, rev_cond_rtx;
15964 enum machine_mode cc_mode;
15966 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15968 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15969 SImode, XEXP (condition_rtx, 0), const0_rtx);
15970 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15971 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15972 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15975 op_mode = GET_MODE (XEXP (operands[1], 0));
15976 if (op_mode == VOIDmode)
15977 op_mode = GET_MODE (XEXP (operands[1], 1));
15979 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15981 PUT_MODE (condition_rtx, DImode);
15982 convert_move (result, condition_rtx, 0);
15986 PUT_MODE (condition_rtx, SImode);
15987 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15991 /* Emit a branch of kind CODE to location LOC. */
15994 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15996 rtx condition_rtx, loc_ref;
15998 condition_rtx = rs6000_generate_compare (operands[0], mode);
15999 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16000 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16001 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16002 loc_ref, pc_rtx)));
16005 /* Return the string to output a conditional branch to LABEL, which is
16006 the operand number of the label, or -1 if the branch is really a
16007 conditional return.
16009 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16010 condition code register and its mode specifies what kind of
16011 comparison we made.
16013 REVERSED is nonzero if we should reverse the sense of the comparison.
16015 INSN is the insn. */
16018 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16020 static char string[64];
16021 enum rtx_code code = GET_CODE (op);
16022 rtx cc_reg = XEXP (op, 0);
16023 enum machine_mode mode = GET_MODE (cc_reg);
16024 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16025 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16026 int really_reversed = reversed ^ need_longbranch;
16032 validate_condition_mode (code, mode);
16034 /* Work out which way this really branches. We could use
16035 reverse_condition_maybe_unordered here always but this
16036 makes the resulting assembler clearer. */
16037 if (really_reversed)
16039 /* Reversal of FP compares takes care -- an ordered compare
16040 becomes an unordered compare and vice versa. */
16041 if (mode == CCFPmode)
16042 code = reverse_condition_maybe_unordered (code);
16044 code = reverse_condition (code);
16047 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16049 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16054 /* Opposite of GT. */
16063 gcc_unreachable ();
16069 /* Not all of these are actually distinct opcodes, but
16070 we distinguish them for clarity of the resulting assembler. */
16071 case NE: case LTGT:
16072 ccode = "ne"; break;
16073 case EQ: case UNEQ:
16074 ccode = "eq"; break;
16076 ccode = "ge"; break;
16077 case GT: case GTU: case UNGT:
16078 ccode = "gt"; break;
16080 ccode = "le"; break;
16081 case LT: case LTU: case UNLT:
16082 ccode = "lt"; break;
16083 case UNORDERED: ccode = "un"; break;
16084 case ORDERED: ccode = "nu"; break;
16085 case UNGE: ccode = "nl"; break;
16086 case UNLE: ccode = "ng"; break;
16088 gcc_unreachable ();
16091 /* Maybe we have a guess as to how likely the branch is.
16092 The old mnemonics don't have a way to specify this information. */
16094 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16095 if (note != NULL_RTX)
16097 /* PROB is the difference from 50%. */
16098 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16100 /* Only hint for highly probable/improbable branches on newer
16101 cpus as static prediction overrides processor dynamic
16102 prediction. For older cpus we may as well always hint, but
16103 assume not taken for branches that are very close to 50% as a
16104 mispredicted taken branch is more expensive than a
16105 mispredicted not-taken branch. */
16106 if (rs6000_always_hint
16107 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16108 && br_prob_note_reliable_p (note)))
16110 if (abs (prob) > REG_BR_PROB_BASE / 20
16111 && ((prob > 0) ^ need_longbranch))
16119 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16121 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16123 /* We need to escape any '%' characters in the reg_names string.
16124 Assume they'd only be the first character.... */
16125 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16127 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16131 /* If the branch distance was too far, we may have to use an
16132 unconditional branch to go the distance. */
16133 if (need_longbranch)
16134 s += sprintf (s, ",$+8\n\tb %s", label);
16136 s += sprintf (s, ",%s", label);
16142 /* Return the string to flip the GT bit on a CR. */
16144 output_e500_flip_gt_bit (rtx dst, rtx src)
16146 static char string[64];
16149 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16150 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16153 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16154 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16156 sprintf (string, "crnot %d,%d", a, b);
16160 /* Return insn for VSX or Altivec comparisons. */
16163 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16166 enum machine_mode mode = GET_MODE (op0);
16174 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16180 mask = gen_reg_rtx (mode);
16181 emit_insn (gen_rtx_SET (VOIDmode,
16183 gen_rtx_fmt_ee (code, mode, op0, op1)));
16190 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16191 DMODE is expected destination mode. This is a recursive function. */
16194 rs6000_emit_vector_compare (enum rtx_code rcode,
16196 enum machine_mode dmode)
16199 bool swap_operands = false;
16200 bool try_again = false;
16202 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16203 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16205 /* See if the comparison works as is. */
16206 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16214 swap_operands = true;
16219 swap_operands = true;
16227 /* Invert condition and try again.
16228 e.g., A != B becomes ~(A==B). */
16230 enum rtx_code rev_code;
16231 enum insn_code nor_code;
16234 rev_code = reverse_condition_maybe_unordered (rcode);
16235 if (rev_code == UNKNOWN)
16238 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
16239 if (nor_code == CODE_FOR_nothing)
16242 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16246 mask = gen_reg_rtx (dmode);
16247 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16255 /* Try GT/GTU/LT/LTU OR EQ */
16258 enum insn_code ior_code;
16259 enum rtx_code new_code;
16280 gcc_unreachable ();
16283 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
16284 if (ior_code == CODE_FOR_nothing)
16287 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16291 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16295 mask = gen_reg_rtx (dmode);
16296 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16314 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16319 /* You only get two chances. */
16323 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16324 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16325 operands for the relation operation COND. */
16328 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16329 rtx cond, rtx cc_op0, rtx cc_op1)
16331 enum machine_mode dest_mode = GET_MODE (dest);
16332 enum rtx_code rcode = GET_CODE (cond);
16333 enum machine_mode cc_mode = CCmode;
16337 bool invert_move = false;
16339 if (VECTOR_UNIT_NONE_P (dest_mode))
16344 /* Swap operands if we can, and fall back to doing the operation as
16345 specified, and doing a NOR to invert the test. */
16351 /* Invert condition and try again.
16352 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16353 invert_move = true;
16354 rcode = reverse_condition_maybe_unordered (rcode);
16355 if (rcode == UNKNOWN)
16359 /* Mark unsigned tests with CCUNSmode. */
16364 cc_mode = CCUNSmode;
16371 /* Get the vector mask for the given relational operations. */
16372 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16380 op_true = op_false;
16384 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
16385 emit_insn (gen_rtx_SET (VOIDmode,
16387 gen_rtx_IF_THEN_ELSE (dest_mode,
16394 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16395 operands of the last comparison is nonzero/true, FALSE_COND if it
16396 is zero/false. Return 0 if the hardware has no such operation. */
16399 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16401 enum rtx_code code = GET_CODE (op);
16402 rtx op0 = XEXP (op, 0);
16403 rtx op1 = XEXP (op, 1);
16404 REAL_VALUE_TYPE c1;
16405 enum machine_mode compare_mode = GET_MODE (op0);
16406 enum machine_mode result_mode = GET_MODE (dest);
16408 bool is_against_zero;
16410 /* These modes should always match. */
16411 if (GET_MODE (op1) != compare_mode
16412 /* In the isel case however, we can use a compare immediate, so
16413 op1 may be a small constant. */
16414 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16416 if (GET_MODE (true_cond) != result_mode)
16418 if (GET_MODE (false_cond) != result_mode)
16421 /* First, work out if the hardware can do this at all, or
16422 if it's too slow.... */
16423 if (!FLOAT_MODE_P (compare_mode))
16426 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16429 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16430 && SCALAR_FLOAT_MODE_P (compare_mode))
16433 is_against_zero = op1 == CONST0_RTX (compare_mode);
16435 /* A floating-point subtract might overflow, underflow, or produce
16436 an inexact result, thus changing the floating-point flags, so it
16437 can't be generated if we care about that. It's safe if one side
16438 of the construct is zero, since then no subtract will be
16440 if (SCALAR_FLOAT_MODE_P (compare_mode)
16441 && flag_trapping_math && ! is_against_zero)
16444 /* Eliminate half of the comparisons by switching operands, this
16445 makes the remaining code simpler. */
16446 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16447 || code == LTGT || code == LT || code == UNLE)
16449 code = reverse_condition_maybe_unordered (code);
16451 true_cond = false_cond;
16455 /* UNEQ and LTGT take four instructions for a comparison with zero,
16456 it'll probably be faster to use a branch here too. */
16457 if (code == UNEQ && HONOR_NANS (compare_mode))
16460 if (GET_CODE (op1) == CONST_DOUBLE)
16461 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16463 /* We're going to try to implement comparisons by performing
16464 a subtract, then comparing against zero. Unfortunately,
16465 Inf - Inf is NaN which is not zero, and so if we don't
16466 know that the operand is finite and the comparison
16467 would treat EQ different to UNORDERED, we can't do it. */
16468 if (HONOR_INFINITIES (compare_mode)
16469 && code != GT && code != UNGE
16470 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16471 /* Constructs of the form (a OP b ? a : b) are safe. */
16472 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16473 || (! rtx_equal_p (op0, true_cond)
16474 && ! rtx_equal_p (op1, true_cond))))
16477 /* At this point we know we can use fsel. */
16479 /* Reduce the comparison to a comparison against zero. */
16480 if (! is_against_zero)
16482 temp = gen_reg_rtx (compare_mode);
16483 emit_insn (gen_rtx_SET (VOIDmode, temp,
16484 gen_rtx_MINUS (compare_mode, op0, op1)));
16486 op1 = CONST0_RTX (compare_mode);
16489 /* If we don't care about NaNs we can reduce some of the comparisons
16490 down to faster ones. */
16491 if (! HONOR_NANS (compare_mode))
16497 true_cond = false_cond;
16510 /* Now, reduce everything down to a GE. */
16517 temp = gen_reg_rtx (compare_mode);
16518 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16523 temp = gen_reg_rtx (compare_mode);
16524 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
16529 temp = gen_reg_rtx (compare_mode);
16530 emit_insn (gen_rtx_SET (VOIDmode, temp,
16531 gen_rtx_NEG (compare_mode,
16532 gen_rtx_ABS (compare_mode, op0))));
16537 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16538 temp = gen_reg_rtx (result_mode);
16539 emit_insn (gen_rtx_SET (VOIDmode, temp,
16540 gen_rtx_IF_THEN_ELSE (result_mode,
16541 gen_rtx_GE (VOIDmode,
16543 true_cond, false_cond)));
16544 false_cond = true_cond;
16547 temp = gen_reg_rtx (compare_mode);
16548 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16553 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
16554 temp = gen_reg_rtx (result_mode);
16555 emit_insn (gen_rtx_SET (VOIDmode, temp,
16556 gen_rtx_IF_THEN_ELSE (result_mode,
16557 gen_rtx_GE (VOIDmode,
16559 true_cond, false_cond)));
16560 true_cond = false_cond;
16563 temp = gen_reg_rtx (compare_mode);
16564 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16569 gcc_unreachable ();
16572 emit_insn (gen_rtx_SET (VOIDmode, dest,
16573 gen_rtx_IF_THEN_ELSE (result_mode,
16574 gen_rtx_GE (VOIDmode,
16576 true_cond, false_cond)));
16580 /* Same as above, but for ints (isel). */
16583 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16585 rtx condition_rtx, cr;
16586 enum machine_mode mode = GET_MODE (dest);
16588 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
16591 /* We still have to do the compare, because isel doesn't do a
16592 compare, it just looks at the CRx bits set by a previous compare
16594 condition_rtx = rs6000_generate_compare (op, mode);
16595 cr = XEXP (condition_rtx, 0);
16597 if (mode == SImode)
16599 if (GET_MODE (cr) == CCmode)
16600 emit_insn (gen_isel_signed_si (dest, condition_rtx,
16601 true_cond, false_cond, cr));
16603 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
16604 true_cond, false_cond, cr));
16608 if (GET_MODE (cr) == CCmode)
16609 emit_insn (gen_isel_signed_di (dest, condition_rtx,
16610 true_cond, false_cond, cr));
16612 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
16613 true_cond, false_cond, cr));
16620 output_isel (rtx *operands)
16622 enum rtx_code code;
16624 code = GET_CODE (operands[1]);
16625 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
16627 PUT_CODE (operands[1], reverse_condition (code));
16628 return "isel %0,%3,%2,%j1";
16631 return "isel %0,%2,%3,%j1";
16635 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
16637 enum machine_mode mode = GET_MODE (op0);
16641 /* VSX/altivec have direct min/max insns. */
16642 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
16644 emit_insn (gen_rtx_SET (VOIDmode,
16646 gen_rtx_fmt_ee (code, mode, op0, op1)));
16650 if (code == SMAX || code == SMIN)
16655 if (code == SMAX || code == UMAX)
16656 target = emit_conditional_move (dest, c, op0, op1, mode,
16657 op0, op1, mode, 0);
16659 target = emit_conditional_move (dest, c, op0, op1, mode,
16660 op1, op0, mode, 0);
16661 gcc_assert (target);
16662 if (target != dest)
16663 emit_move_insn (dest, target);
16666 /* Emit instructions to perform a load-reserved/store-conditional operation.
16667 The operation performed is an atomic
16668 (set M (CODE:MODE M OP))
16669 If not NULL, BEFORE is atomically set to M before the operation, and
16670 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16671 If SYNC_P then a memory barrier is emitted before the operation.
16672 Either OP or M may be wrapped in a NOT operation. */
16675 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16676 rtx m, rtx op, rtx before_param, rtx after_param,
16679 enum machine_mode used_mode;
16680 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16683 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16684 rtx shift = NULL_RTX;
16687 emit_insn (gen_lwsync ());
16691 /* If this is smaller than SImode, we'll have to use SImode with
16693 if (mode == QImode || mode == HImode)
16697 if (MEM_ALIGN (used_m) >= 32)
16700 if (BYTES_BIG_ENDIAN)
16701 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16703 shift = GEN_INT (ishift);
16704 used_m = change_address (used_m, SImode, 0);
16708 rtx addrSI, aligned_addr;
16709 int shift_mask = mode == QImode ? 0x18 : 0x10;
16711 addrSI = gen_lowpart_common (SImode,
16712 force_reg (Pmode, XEXP (used_m, 0)));
16713 addrSI = force_reg (SImode, addrSI);
16714 shift = gen_reg_rtx (SImode);
16716 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16717 GEN_INT (shift_mask)));
16718 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16720 aligned_addr = expand_binop (Pmode, and_optab,
16722 GEN_INT (-4), NULL_RTX,
16723 1, OPTAB_LIB_WIDEN);
16724 used_m = change_address (used_m, SImode, aligned_addr);
16725 set_mem_align (used_m, 32);
16727 /* It's safe to keep the old alias set of USED_M, because
16728 the operation is atomic and only affects the original
16732 if (GET_CODE (op) == NOT)
16734 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16735 oldop = gen_rtx_NOT (SImode, oldop);
16738 oldop = lowpart_subreg (SImode, op, mode);
16744 newop = expand_binop (SImode, and_optab,
16745 oldop, GEN_INT (imask), NULL_RTX,
16746 1, OPTAB_LIB_WIDEN);
16747 emit_insn (gen_ashlsi3 (newop, newop, shift));
16750 case NOT: /* NAND */
16751 newop = expand_binop (SImode, ior_optab,
16752 oldop, GEN_INT (~imask), NULL_RTX,
16753 1, OPTAB_LIB_WIDEN);
16754 emit_insn (gen_rotlsi3 (newop, newop, shift));
16758 newop = expand_binop (SImode, ior_optab,
16759 oldop, GEN_INT (~imask), NULL_RTX,
16760 1, OPTAB_LIB_WIDEN);
16761 emit_insn (gen_rotlsi3 (newop, newop, shift));
16769 newop = expand_binop (SImode, and_optab,
16770 oldop, GEN_INT (imask), NULL_RTX,
16771 1, OPTAB_LIB_WIDEN);
16772 emit_insn (gen_ashlsi3 (newop, newop, shift));
16774 mask = gen_reg_rtx (SImode);
16775 emit_move_insn (mask, GEN_INT (imask));
16776 emit_insn (gen_ashlsi3 (mask, mask, shift));
16779 newop = gen_rtx_PLUS (SImode, m, newop);
16781 newop = gen_rtx_MINUS (SImode, m, newop);
16782 newop = gen_rtx_AND (SImode, newop, mask);
16783 newop = gen_rtx_IOR (SImode, newop,
16784 gen_rtx_AND (SImode,
16785 gen_rtx_NOT (SImode, mask),
16791 gcc_unreachable ();
16795 used_mode = SImode;
16796 before = gen_reg_rtx (used_mode);
16797 after = gen_reg_rtx (used_mode);
16802 before = before_param;
16803 after = after_param;
16805 if (before == NULL_RTX)
16806 before = gen_reg_rtx (used_mode);
16807 if (after == NULL_RTX)
16808 after = gen_reg_rtx (used_mode);
16811 if ((code == PLUS || code == MINUS)
16812 && used_mode != mode)
16813 the_op = op; /* Computed above. */
16814 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16815 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16816 else if (code == NOT)
16817 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16818 gen_rtx_NOT (used_mode, m),
16819 gen_rtx_NOT (used_mode, op));
16821 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16823 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16824 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16825 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16826 gen_rtx_UNSPEC (used_mode,
16827 gen_rtvec (1, the_op),
16829 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16831 if ((code == PLUS || code == MINUS) && used_mode != mode)
16832 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16833 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16835 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16836 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16838 /* Shift and mask the return values properly. */
16839 if (used_mode != mode && before_param)
16841 emit_insn (gen_lshrsi3 (before, before, shift));
16842 convert_move (before_param, before, 1);
16845 if (used_mode != mode && after_param)
16847 emit_insn (gen_lshrsi3 (after, after, shift));
16848 convert_move (after_param, after, 1);
16851 /* The previous sequence will end with a branch that's dependent on
16852 the conditional store, so placing an isync will ensure that no
16853 other instructions (especially, no load or store instructions)
16854 can start before the atomic operation completes. */
16856 emit_insn (gen_isync ());
16859 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16860 COND is true. Mark the jump as unlikely to be taken. */
16863 emit_unlikely_jump (rtx cond, rtx label)
16865 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16868 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16869 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16870 add_reg_note (x, REG_BR_PROB, very_unlikely);
16873 /* A subroutine of the atomic operation splitters. Emit a load-locked
16874 instruction in MODE. */
16877 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16879 rtx (*fn) (rtx, rtx) = NULL;
16880 if (mode == SImode)
16881 fn = gen_load_locked_si;
16882 else if (mode == DImode)
16883 fn = gen_load_locked_di;
16884 emit_insn (fn (reg, mem));
16887 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16888 instruction in MODE. */
16891 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16893 rtx (*fn) (rtx, rtx, rtx) = NULL;
16894 if (mode == SImode)
16895 fn = gen_store_conditional_si;
16896 else if (mode == DImode)
16897 fn = gen_store_conditional_di;
16899 /* Emit sync before stwcx. to address PPC405 Erratum. */
16900 if (PPC405_ERRATUM77)
16901 emit_insn (gen_memory_barrier ());
16903 emit_insn (fn (res, mem, val));
16906 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16907 to perform. MEM is the memory on which to operate. VAL is the second
16908 operand of the binary operator. BEFORE and AFTER are optional locations to
16909 return the value of MEM either before of after the operation. SCRATCH is
16910 a scratch register. */
16913 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16914 rtx before, rtx after, rtx scratch)
16916 enum machine_mode mode = GET_MODE (mem);
16917 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16919 emit_insn (gen_lwsync ());
16921 label = gen_label_rtx ();
16922 emit_label (label);
16923 label = gen_rtx_LABEL_REF (VOIDmode, label);
16925 if (before == NULL_RTX)
16927 emit_load_locked (mode, before, mem);
16930 x = gen_rtx_IOR (mode,
16931 gen_rtx_NOT (mode, before),
16932 gen_rtx_NOT (mode, val));
16933 else if (code == AND)
16934 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16936 x = gen_rtx_fmt_ee (code, mode, before, val);
16938 if (after != NULL_RTX)
16939 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16940 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16942 emit_store_conditional (mode, cond, mem, scratch);
16944 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16945 emit_unlikely_jump (x, label);
16947 emit_insn (gen_isync ());
16950 /* Expand an atomic compare and swap operation. MEM is the memory on which
16951 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16952 value to be stored. SCRATCH is a scratch GPR. */
16955 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16958 enum machine_mode mode = GET_MODE (mem);
16959 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16961 emit_insn (gen_lwsync ());
16963 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16964 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16965 emit_label (XEXP (label1, 0));
16967 emit_load_locked (mode, retval, mem);
16969 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16970 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16972 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16973 emit_unlikely_jump (x, label2);
16975 emit_move_insn (scratch, newval);
16976 emit_store_conditional (mode, cond, mem, scratch);
16978 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16979 emit_unlikely_jump (x, label1);
16981 emit_insn (gen_isync ());
16982 emit_label (XEXP (label2, 0));
16985 /* Expand an atomic test and set operation. MEM is the memory on which
16986 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16989 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16991 enum machine_mode mode = GET_MODE (mem);
16992 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16994 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16995 emit_label (XEXP (label, 0));
16997 emit_load_locked (mode, retval, mem);
16998 emit_move_insn (scratch, val);
16999 emit_store_conditional (mode, cond, mem, scratch);
17001 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17002 emit_unlikely_jump (x, label);
17004 emit_insn (gen_isync ());
17008 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17010 enum machine_mode mode = GET_MODE (mem);
17011 rtx addrSI, align, wdst, shift, mask;
17012 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17013 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17015 /* Shift amount for subword relative to aligned word. */
17016 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17017 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17018 shift = gen_reg_rtx (SImode);
17019 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17020 GEN_INT (shift_mask)));
17021 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17023 /* Shift and mask old value into position within word. */
17024 oldval = convert_modes (SImode, mode, oldval, 1);
17025 oldval = expand_binop (SImode, and_optab,
17026 oldval, GEN_INT (imask), NULL_RTX,
17027 1, OPTAB_LIB_WIDEN);
17028 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17030 /* Shift and mask new value into position within word. */
17031 newval = convert_modes (SImode, mode, newval, 1);
17032 newval = expand_binop (SImode, and_optab,
17033 newval, GEN_INT (imask), NULL_RTX,
17034 1, OPTAB_LIB_WIDEN);
17035 emit_insn (gen_ashlsi3 (newval, newval, shift));
17037 /* Mask for insertion. */
17038 mask = gen_reg_rtx (SImode);
17039 emit_move_insn (mask, GEN_INT (imask));
17040 emit_insn (gen_ashlsi3 (mask, mask, shift));
17042 /* Address of aligned word containing subword. */
17043 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17044 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17045 mem = change_address (mem, SImode, align);
17046 set_mem_align (mem, 32);
17047 MEM_VOLATILE_P (mem) = 1;
17049 wdst = gen_reg_rtx (SImode);
17050 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17051 oldval, newval, mem));
17053 /* Shift the result back. */
17054 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17056 emit_move_insn (dst, gen_lowpart (mode, wdst));
17060 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17061 rtx oldval, rtx newval, rtx mem,
17064 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17066 emit_insn (gen_lwsync ());
17067 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17068 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17069 emit_label (XEXP (label1, 0));
17071 emit_load_locked (SImode, scratch, mem);
17073 /* Mask subword within loaded value for comparison with oldval.
17074 Use UNSPEC_AND to avoid clobber.*/
17075 emit_insn (gen_rtx_SET (SImode, dest,
17076 gen_rtx_UNSPEC (SImode,
17077 gen_rtvec (2, scratch, mask),
17080 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17081 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17083 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17084 emit_unlikely_jump (x, label2);
17086 /* Clear subword within loaded value for insertion of new value. */
17087 emit_insn (gen_rtx_SET (SImode, scratch,
17088 gen_rtx_AND (SImode,
17089 gen_rtx_NOT (SImode, mask), scratch)));
17090 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17091 emit_store_conditional (SImode, cond, mem, scratch);
17093 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17094 emit_unlikely_jump (x, label1);
17096 emit_insn (gen_isync ());
17097 emit_label (XEXP (label2, 0));
17101 /* Emit instructions to move SRC to DST. Called by splitters for
17102 multi-register moves. It will emit at most one instruction for
17103 each register that is accessed; that is, it won't emit li/lis pairs
17104 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17108 rs6000_split_multireg_move (rtx dst, rtx src)
17110 /* The register number of the first register being moved. */
17112 /* The mode that is to be moved. */
17113 enum machine_mode mode;
17114 /* The mode that the move is being done in, and its size. */
17115 enum machine_mode reg_mode;
17117 /* The number of registers that will be moved. */
17120 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17121 mode = GET_MODE (dst);
17122 nregs = hard_regno_nregs[reg][mode];
17123 if (FP_REGNO_P (reg))
17124 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17125 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17126 else if (ALTIVEC_REGNO_P (reg))
17127 reg_mode = V16QImode;
17128 else if (TARGET_E500_DOUBLE && mode == TFmode)
17131 reg_mode = word_mode;
17132 reg_mode_size = GET_MODE_SIZE (reg_mode);
17134 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17136 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17138 /* Move register range backwards, if we might have destructive
17141 for (i = nregs - 1; i >= 0; i--)
17142 emit_insn (gen_rtx_SET (VOIDmode,
17143 simplify_gen_subreg (reg_mode, dst, mode,
17144 i * reg_mode_size),
17145 simplify_gen_subreg (reg_mode, src, mode,
17146 i * reg_mode_size)));
17152 bool used_update = false;
17153 rtx restore_basereg = NULL_RTX;
17155 if (MEM_P (src) && INT_REGNO_P (reg))
17159 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17160 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17163 breg = XEXP (XEXP (src, 0), 0);
17164 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17165 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17166 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17167 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17168 src = replace_equiv_address (src, breg);
17170 else if (! rs6000_offsettable_memref_p (src))
17172 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17174 rtx basereg = XEXP (XEXP (src, 0), 0);
17177 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17178 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17179 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17180 used_update = true;
17183 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17184 XEXP (XEXP (src, 0), 1)));
17185 src = replace_equiv_address (src, basereg);
17189 rtx basereg = gen_rtx_REG (Pmode, reg);
17190 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17191 src = replace_equiv_address (src, basereg);
17195 breg = XEXP (src, 0);
17196 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17197 breg = XEXP (breg, 0);
17199 /* If the base register we are using to address memory is
17200 also a destination reg, then change that register last. */
17202 && REGNO (breg) >= REGNO (dst)
17203 && REGNO (breg) < REGNO (dst) + nregs)
17204 j = REGNO (breg) - REGNO (dst);
17206 else if (MEM_P (dst) && INT_REGNO_P (reg))
17210 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17211 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17214 breg = XEXP (XEXP (dst, 0), 0);
17215 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17216 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17217 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17219 /* We have to update the breg before doing the store.
17220 Use store with update, if available. */
17224 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17225 emit_insn (TARGET_32BIT
17226 ? (TARGET_POWERPC64
17227 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17228 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17229 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17230 used_update = true;
17233 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17234 dst = replace_equiv_address (dst, breg);
17236 else if (!rs6000_offsettable_memref_p (dst)
17237 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17239 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17241 rtx basereg = XEXP (XEXP (dst, 0), 0);
17244 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17245 emit_insn (gen_rtx_SET (VOIDmode,
17246 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17247 used_update = true;
17250 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17251 XEXP (XEXP (dst, 0), 1)));
17252 dst = replace_equiv_address (dst, basereg);
17256 rtx basereg = XEXP (XEXP (dst, 0), 0);
17257 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17258 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17260 && REG_P (offsetreg)
17261 && REGNO (basereg) != REGNO (offsetreg));
17262 if (REGNO (basereg) == 0)
17264 rtx tmp = offsetreg;
17265 offsetreg = basereg;
17268 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17269 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17270 dst = replace_equiv_address (dst, basereg);
17273 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17274 gcc_assert (rs6000_offsettable_memref_p (dst));
17277 for (i = 0; i < nregs; i++)
17279 /* Calculate index to next subword. */
17284 /* If compiler already emitted move of first word by
17285 store with update, no need to do anything. */
17286 if (j == 0 && used_update)
17289 emit_insn (gen_rtx_SET (VOIDmode,
17290 simplify_gen_subreg (reg_mode, dst, mode,
17291 j * reg_mode_size),
17292 simplify_gen_subreg (reg_mode, src, mode,
17293 j * reg_mode_size)));
17295 if (restore_basereg != NULL_RTX)
17296 emit_insn (restore_basereg);
17301 /* This page contains routines that are used to determine what the
17302 function prologue and epilogue code will do and write them out. */
17304 /* Return the first fixed-point register that is required to be
17305 saved. 32 if none. */
17308 first_reg_to_save (void)
17312 /* Find lowest numbered live register. */
17313 for (first_reg = 13; first_reg <= 31; first_reg++)
17314 if (df_regs_ever_live_p (first_reg)
17315 && (! call_used_regs[first_reg]
17316 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17317 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17318 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17319 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17324 && crtl->uses_pic_offset_table
17325 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17326 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17332 /* Similar, for FP regs. */
17335 first_fp_reg_to_save (void)
17339 /* Find lowest numbered live register. */
17340 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17341 if (df_regs_ever_live_p (first_reg))
17347 /* Similar, for AltiVec regs. */
17350 first_altivec_reg_to_save (void)
17354 /* Stack frame remains as is unless we are in AltiVec ABI. */
17355 if (! TARGET_ALTIVEC_ABI)
17356 return LAST_ALTIVEC_REGNO + 1;
17358 /* On Darwin, the unwind routines are compiled without
17359 TARGET_ALTIVEC, and use save_world to save/restore the
17360 altivec registers when necessary. */
17361 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17362 && ! TARGET_ALTIVEC)
17363 return FIRST_ALTIVEC_REGNO + 20;
17365 /* Find lowest numbered live register. */
17366 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17367 if (df_regs_ever_live_p (i))
17373 /* Return a 32-bit mask of the AltiVec registers we need to set in
17374 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17375 the 32-bit word is 0. */
17377 static unsigned int
17378 compute_vrsave_mask (void)
17380 unsigned int i, mask = 0;
17382 /* On Darwin, the unwind routines are compiled without
17383 TARGET_ALTIVEC, and use save_world to save/restore the
17384 call-saved altivec registers when necessary. */
17385 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17386 && ! TARGET_ALTIVEC)
17389 /* First, find out if we use _any_ altivec registers. */
17390 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17391 if (df_regs_ever_live_p (i))
17392 mask |= ALTIVEC_REG_BIT (i);
17397 /* Next, remove the argument registers from the set. These must
17398 be in the VRSAVE mask set by the caller, so we don't need to add
17399 them in again. More importantly, the mask we compute here is
17400 used to generate CLOBBERs in the set_vrsave insn, and we do not
17401 wish the argument registers to die. */
17402 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17403 mask &= ~ALTIVEC_REG_BIT (i);
17405 /* Similarly, remove the return value from the set. */
17408 diddle_return_value (is_altivec_return_reg, &yes);
17410 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17416 /* For a very restricted set of circumstances, we can cut down the
17417 size of prologues/epilogues by calling our own save/restore-the-world
17421 compute_save_world_info (rs6000_stack_t *info_ptr)
17423 info_ptr->world_save_p = 1;
17424 info_ptr->world_save_p
17425 = (WORLD_SAVE_P (info_ptr)
17426 && DEFAULT_ABI == ABI_DARWIN
17427 && ! (cfun->calls_setjmp && flag_exceptions)
17428 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17429 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17430 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17431 && info_ptr->cr_save_p);
17433 /* This will not work in conjunction with sibcalls. Make sure there
17434 are none. (This check is expensive, but seldom executed.) */
17435 if (WORLD_SAVE_P (info_ptr))
17438 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17439 if ( GET_CODE (insn) == CALL_INSN
17440 && SIBLING_CALL_P (insn))
17442 info_ptr->world_save_p = 0;
17447 if (WORLD_SAVE_P (info_ptr))
17449 /* Even if we're not touching VRsave, make sure there's room on the
17450 stack for it, if it looks like we're calling SAVE_WORLD, which
17451 will attempt to save it. */
17452 info_ptr->vrsave_size = 4;
17454 /* If we are going to save the world, we need to save the link register too. */
17455 info_ptr->lr_save_p = 1;
17457 /* "Save" the VRsave register too if we're saving the world. */
17458 if (info_ptr->vrsave_mask == 0)
17459 info_ptr->vrsave_mask = compute_vrsave_mask ();
17461 /* Because the Darwin register save/restore routines only handle
17462 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17464 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17465 && (info_ptr->first_altivec_reg_save
17466 >= FIRST_SAVED_ALTIVEC_REGNO));
17473 is_altivec_return_reg (rtx reg, void *xyes)
17475 bool *yes = (bool *) xyes;
17476 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17481 /* Calculate the stack information for the current function. This is
17482 complicated by having two separate calling sequences, the AIX calling
17483 sequence and the V.4 calling sequence.
17485 AIX (and Darwin/Mac OS X) stack frames look like:
17487 SP----> +---------------------------------------+
17488 | back chain to caller | 0 0
17489 +---------------------------------------+
17490 | saved CR | 4 8 (8-11)
17491 +---------------------------------------+
17493 +---------------------------------------+
17494 | reserved for compilers | 12 24
17495 +---------------------------------------+
17496 | reserved for binders | 16 32
17497 +---------------------------------------+
17498 | saved TOC pointer | 20 40
17499 +---------------------------------------+
17500 | Parameter save area (P) | 24 48
17501 +---------------------------------------+
17502 | Alloca space (A) | 24+P etc.
17503 +---------------------------------------+
17504 | Local variable space (L) | 24+P+A
17505 +---------------------------------------+
17506 | Float/int conversion temporary (X) | 24+P+A+L
17507 +---------------------------------------+
17508 | Save area for AltiVec registers (W) | 24+P+A+L+X
17509 +---------------------------------------+
17510 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
17511 +---------------------------------------+
17512 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
17513 +---------------------------------------+
17514 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
17515 +---------------------------------------+
17516 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
17517 +---------------------------------------+
17518 old SP->| back chain to caller's caller |
17519 +---------------------------------------+
17521 The required alignment for AIX configurations is two words (i.e., 8
17525 V.4 stack frames look like:
17527 SP----> +---------------------------------------+
17528 | back chain to caller | 0
17529 +---------------------------------------+
17530 | caller's saved LR | 4
17531 +---------------------------------------+
17532 | Parameter save area (P) | 8
17533 +---------------------------------------+
17534 | Alloca space (A) | 8+P
17535 +---------------------------------------+
17536 | Varargs save area (V) | 8+P+A
17537 +---------------------------------------+
17538 | Local variable space (L) | 8+P+A+V
17539 +---------------------------------------+
17540 | Float/int conversion temporary (X) | 8+P+A+V+L
17541 +---------------------------------------+
17542 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
17543 +---------------------------------------+
17544 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
17545 +---------------------------------------+
17546 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
17547 +---------------------------------------+
17548 | SPE: area for 64-bit GP registers |
17549 +---------------------------------------+
17550 | SPE alignment padding |
17551 +---------------------------------------+
17552 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
17553 +---------------------------------------+
17554 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
17555 +---------------------------------------+
17556 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
17557 +---------------------------------------+
17558 old SP->| back chain to caller's caller |
17559 +---------------------------------------+
17561 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
17562 given. (But note below and in sysv4.h that we require only 8 and
17563 may round up the size of our stack frame anyways. The historical
17564 reason is early versions of powerpc-linux which didn't properly
17565 align the stack at program startup. A happy side-effect is that
17566 -mno-eabi libraries can be used with -meabi programs.)
17568 The EABI configuration defaults to the V.4 layout. However,
17569 the stack alignment requirements may differ. If -mno-eabi is not
17570 given, the required stack alignment is 8 bytes; if -mno-eabi is
17571 given, the required alignment is 16 bytes. (But see V.4 comment
17574 #ifndef ABI_STACK_BOUNDARY
17575 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
17578 static rs6000_stack_t *
17579 rs6000_stack_info (void)
17581 static rs6000_stack_t info;
17582 rs6000_stack_t *info_ptr = &info;
17583 int reg_size = TARGET_32BIT ? 4 : 8;
17587 HOST_WIDE_INT non_fixed_size;
17589 memset (&info, 0, sizeof (info));
17593 /* Cache value so we don't rescan instruction chain over and over. */
17594 if (cfun->machine->insn_chain_scanned_p == 0)
17595 cfun->machine->insn_chain_scanned_p
17596 = spe_func_has_64bit_regs_p () + 1;
17597 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
17600 /* Select which calling sequence. */
17601 info_ptr->abi = DEFAULT_ABI;
17603 /* Calculate which registers need to be saved & save area size. */
17604 info_ptr->first_gp_reg_save = first_reg_to_save ();
17605 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
17606 even if it currently looks like we won't. Reload may need it to
17607 get at a constant; if so, it will have already created a constant
17608 pool entry for it. */
17609 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
17610 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
17611 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
17612 && crtl->uses_const_pool
17613 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
17614 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
17616 first_gp = info_ptr->first_gp_reg_save;
17618 info_ptr->gp_size = reg_size * (32 - first_gp);
17620 /* For the SPE, we have an additional upper 32-bits on each GPR.
17621 Ideally we should save the entire 64-bits only when the upper
17622 half is used in SIMD instructions. Since we only record
17623 registers live (not the size they are used in), this proves
17624 difficult because we'd have to traverse the instruction chain at
17625 the right time, taking reload into account. This is a real pain,
17626 so we opt to save the GPRs in 64-bits always if but one register
17627 gets used in 64-bits. Otherwise, all the registers in the frame
17628 get saved in 32-bits.
17630 So... since when we save all GPRs (except the SP) in 64-bits, the
17631 traditional GP save area will be empty. */
17632 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17633 info_ptr->gp_size = 0;
17635 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
17636 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
17638 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
17639 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
17640 - info_ptr->first_altivec_reg_save);
17642 /* Does this function call anything? */
17643 info_ptr->calls_p = (! current_function_is_leaf
17644 || cfun->machine->ra_needs_full_frame);
17646 /* Determine if we need to save the link register. */
17647 if ((DEFAULT_ABI == ABI_AIX
17649 && !TARGET_PROFILE_KERNEL)
17650 #ifdef TARGET_RELOCATABLE
17651 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
17653 || (info_ptr->first_fp_reg_save != 64
17654 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
17655 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
17656 || info_ptr->calls_p
17657 || rs6000_ra_ever_killed ())
17659 info_ptr->lr_save_p = 1;
17660 df_set_regs_ever_live (LR_REGNO, true);
17663 /* Determine if we need to save the condition code registers. */
17664 if (df_regs_ever_live_p (CR2_REGNO)
17665 || df_regs_ever_live_p (CR3_REGNO)
17666 || df_regs_ever_live_p (CR4_REGNO))
17668 info_ptr->cr_save_p = 1;
17669 if (DEFAULT_ABI == ABI_V4)
17670 info_ptr->cr_size = reg_size;
17673 /* If the current function calls __builtin_eh_return, then we need
17674 to allocate stack space for registers that will hold data for
17675 the exception handler. */
17676 if (crtl->calls_eh_return)
17679 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
17682 /* SPE saves EH registers in 64-bits. */
17683 ehrd_size = i * (TARGET_SPE_ABI
17684 && info_ptr->spe_64bit_regs_used != 0
17685 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
17690 /* Determine various sizes. */
17691 info_ptr->reg_size = reg_size;
17692 info_ptr->fixed_size = RS6000_SAVE_AREA;
17693 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
17694 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
17695 TARGET_ALTIVEC ? 16 : 8);
17696 if (FRAME_GROWS_DOWNWARD)
17697 info_ptr->vars_size
17698 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
17699 + info_ptr->parm_size,
17700 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
17701 - (info_ptr->fixed_size + info_ptr->vars_size
17702 + info_ptr->parm_size);
17704 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17705 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17707 info_ptr->spe_gp_size = 0;
17709 if (TARGET_ALTIVEC_ABI)
17710 info_ptr->vrsave_mask = compute_vrsave_mask ();
17712 info_ptr->vrsave_mask = 0;
17714 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17715 info_ptr->vrsave_size = 4;
17717 info_ptr->vrsave_size = 0;
17719 compute_save_world_info (info_ptr);
17721 /* Calculate the offsets. */
17722 switch (DEFAULT_ABI)
17726 gcc_unreachable ();
17730 info_ptr->fp_save_offset = - info_ptr->fp_size;
17731 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17733 if (TARGET_ALTIVEC_ABI)
17735 info_ptr->vrsave_save_offset
17736 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17738 /* Align stack so vector save area is on a quadword boundary.
17739 The padding goes above the vectors. */
17740 if (info_ptr->altivec_size != 0)
17741 info_ptr->altivec_padding_size
17742 = info_ptr->vrsave_save_offset & 0xF;
17744 info_ptr->altivec_padding_size = 0;
17746 info_ptr->altivec_save_offset
17747 = info_ptr->vrsave_save_offset
17748 - info_ptr->altivec_padding_size
17749 - info_ptr->altivec_size;
17750 gcc_assert (info_ptr->altivec_size == 0
17751 || info_ptr->altivec_save_offset % 16 == 0);
17753 /* Adjust for AltiVec case. */
17754 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17757 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17758 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17759 info_ptr->lr_save_offset = 2*reg_size;
17763 info_ptr->fp_save_offset = - info_ptr->fp_size;
17764 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17765 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17767 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17769 /* Align stack so SPE GPR save area is aligned on a
17770 double-word boundary. */
17771 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17772 info_ptr->spe_padding_size
17773 = 8 - (-info_ptr->cr_save_offset % 8);
17775 info_ptr->spe_padding_size = 0;
17777 info_ptr->spe_gp_save_offset
17778 = info_ptr->cr_save_offset
17779 - info_ptr->spe_padding_size
17780 - info_ptr->spe_gp_size;
17782 /* Adjust for SPE case. */
17783 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17785 else if (TARGET_ALTIVEC_ABI)
17787 info_ptr->vrsave_save_offset
17788 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17790 /* Align stack so vector save area is on a quadword boundary. */
17791 if (info_ptr->altivec_size != 0)
17792 info_ptr->altivec_padding_size
17793 = 16 - (-info_ptr->vrsave_save_offset % 16);
17795 info_ptr->altivec_padding_size = 0;
17797 info_ptr->altivec_save_offset
17798 = info_ptr->vrsave_save_offset
17799 - info_ptr->altivec_padding_size
17800 - info_ptr->altivec_size;
17802 /* Adjust for AltiVec case. */
17803 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17806 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17807 info_ptr->ehrd_offset -= ehrd_size;
17808 info_ptr->lr_save_offset = reg_size;
17812 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17813 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17814 + info_ptr->gp_size
17815 + info_ptr->altivec_size
17816 + info_ptr->altivec_padding_size
17817 + info_ptr->spe_gp_size
17818 + info_ptr->spe_padding_size
17820 + info_ptr->cr_size
17821 + info_ptr->vrsave_size,
17824 non_fixed_size = (info_ptr->vars_size
17825 + info_ptr->parm_size
17826 + info_ptr->save_size);
17828 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17829 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17831 /* Determine if we need to allocate any stack frame:
17833 For AIX we need to push the stack if a frame pointer is needed
17834 (because the stack might be dynamically adjusted), if we are
17835 debugging, if we make calls, or if the sum of fp_save, gp_save,
17836 and local variables are more than the space needed to save all
17837 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17838 + 18*8 = 288 (GPR13 reserved).
17840 For V.4 we don't have the stack cushion that AIX uses, but assume
17841 that the debugger can handle stackless frames. */
17843 if (info_ptr->calls_p)
17844 info_ptr->push_p = 1;
17846 else if (DEFAULT_ABI == ABI_V4)
17847 info_ptr->push_p = non_fixed_size != 0;
17849 else if (frame_pointer_needed)
17850 info_ptr->push_p = 1;
17852 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17853 info_ptr->push_p = 1;
17856 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17858 /* Zero offsets if we're not saving those registers. */
17859 if (info_ptr->fp_size == 0)
17860 info_ptr->fp_save_offset = 0;
17862 if (info_ptr->gp_size == 0)
17863 info_ptr->gp_save_offset = 0;
17865 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17866 info_ptr->altivec_save_offset = 0;
17868 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17869 info_ptr->vrsave_save_offset = 0;
17871 if (! TARGET_SPE_ABI
17872 || info_ptr->spe_64bit_regs_used == 0
17873 || info_ptr->spe_gp_size == 0)
17874 info_ptr->spe_gp_save_offset = 0;
17876 if (! info_ptr->lr_save_p)
17877 info_ptr->lr_save_offset = 0;
17879 if (! info_ptr->cr_save_p)
17880 info_ptr->cr_save_offset = 0;
17885 /* Return true if the current function uses any GPRs in 64-bit SIMD
17889 spe_func_has_64bit_regs_p (void)
17893 /* Functions that save and restore all the call-saved registers will
17894 need to save/restore the registers in 64-bits. */
17895 if (crtl->calls_eh_return
17896 || cfun->calls_setjmp
17897 || crtl->has_nonlocal_goto)
17900 insns = get_insns ();
17902 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17908 /* FIXME: This should be implemented with attributes...
17910 (set_attr "spe64" "true")....then,
17911 if (get_spe64(insn)) return true;
17913 It's the only reliable way to do the stuff below. */
17915 i = PATTERN (insn);
17916 if (GET_CODE (i) == SET)
17918 enum machine_mode mode = GET_MODE (SET_SRC (i));
17920 if (SPE_VECTOR_MODE (mode))
17922 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17932 debug_stack_info (rs6000_stack_t *info)
17934 const char *abi_string;
17937 info = rs6000_stack_info ();
17939 fprintf (stderr, "\nStack information for function %s:\n",
17940 ((current_function_decl && DECL_NAME (current_function_decl))
17941 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17946 default: abi_string = "Unknown"; break;
17947 case ABI_NONE: abi_string = "NONE"; break;
17948 case ABI_AIX: abi_string = "AIX"; break;
17949 case ABI_DARWIN: abi_string = "Darwin"; break;
17950 case ABI_V4: abi_string = "V.4"; break;
17953 fprintf (stderr, "\tABI = %5s\n", abi_string);
17955 if (TARGET_ALTIVEC_ABI)
17956 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17958 if (TARGET_SPE_ABI)
17959 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17961 if (info->first_gp_reg_save != 32)
17962 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17964 if (info->first_fp_reg_save != 64)
17965 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17967 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17968 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17969 info->first_altivec_reg_save);
17971 if (info->lr_save_p)
17972 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17974 if (info->cr_save_p)
17975 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17977 if (info->vrsave_mask)
17978 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17981 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17984 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17986 if (info->gp_save_offset)
17987 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17989 if (info->fp_save_offset)
17990 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17992 if (info->altivec_save_offset)
17993 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17994 info->altivec_save_offset);
17996 if (info->spe_gp_save_offset)
17997 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17998 info->spe_gp_save_offset);
18000 if (info->vrsave_save_offset)
18001 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18002 info->vrsave_save_offset);
18004 if (info->lr_save_offset)
18005 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18007 if (info->cr_save_offset)
18008 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18010 if (info->varargs_save_offset)
18011 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18013 if (info->total_size)
18014 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18017 if (info->vars_size)
18018 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18021 if (info->parm_size)
18022 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18024 if (info->fixed_size)
18025 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18028 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18030 if (info->spe_gp_size)
18031 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18034 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18036 if (info->altivec_size)
18037 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18039 if (info->vrsave_size)
18040 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18042 if (info->altivec_padding_size)
18043 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18044 info->altivec_padding_size);
18046 if (info->spe_padding_size)
18047 fprintf (stderr, "\tspe_padding_size = %5d\n",
18048 info->spe_padding_size);
18051 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18053 if (info->save_size)
18054 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18056 if (info->reg_size != 4)
18057 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18059 fprintf (stderr, "\n");
18063 rs6000_return_addr (int count, rtx frame)
18065 /* Currently we don't optimize very well between prolog and body
18066 code and for PIC code the code can be actually quite bad, so
18067 don't try to be too clever here. */
18068 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18070 cfun->machine->ra_needs_full_frame = 1;
18077 plus_constant (copy_to_reg
18078 (gen_rtx_MEM (Pmode,
18079 memory_address (Pmode, frame))),
18080 RETURN_ADDRESS_OFFSET)));
18083 cfun->machine->ra_need_lr = 1;
18084 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18087 /* Say whether a function is a candidate for sibcall handling or not.
18088 We do not allow indirect calls to be optimized into sibling calls.
18089 Also, we can't do it if there are any vector parameters; there's
18090 nowhere to put the VRsave code so it works; note that functions with
18091 vector parameters are required to have a prototype, so the argument
18092 type info must be available here. (The tail recursion case can work
18093 with vector parameters, but there's no way to distinguish here.) */
18095 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
18100 if (TARGET_ALTIVEC_VRSAVE)
18102 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
18103 type; type = TREE_CHAIN (type))
18105 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
18109 if (DEFAULT_ABI == ABI_DARWIN
18110 || ((*targetm.binds_local_p) (decl)
18111 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
18113 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
18115 if (!lookup_attribute ("longcall", attr_list)
18116 || lookup_attribute ("shortcall", attr_list))
18123 /* NULL if INSN insn is valid within a low-overhead loop.
18124 Otherwise return why doloop cannot be applied.
18125 PowerPC uses the COUNT register for branch on table instructions. */
18127 static const char *
18128 rs6000_invalid_within_doloop (const_rtx insn)
18131 return "Function call in the loop.";
18134 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18135 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18136 return "Computed branch in the loop.";
18142 rs6000_ra_ever_killed (void)
18148 if (cfun->is_thunk)
18151 if (cfun->machine->lr_save_state)
18152 return cfun->machine->lr_save_state - 1;
18154 /* regs_ever_live has LR marked as used if any sibcalls are present,
18155 but this should not force saving and restoring in the
18156 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18157 clobbers LR, so that is inappropriate. */
18159 /* Also, the prologue can generate a store into LR that
18160 doesn't really count, like this:
18163 bcl to set PIC register
18167 When we're called from the epilogue, we need to avoid counting
18168 this as a store. */
18170 push_topmost_sequence ();
18171 top = get_insns ();
18172 pop_topmost_sequence ();
18173 reg = gen_rtx_REG (Pmode, LR_REGNO);
18175 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18181 if (!SIBLING_CALL_P (insn))
18184 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18186 else if (set_of (reg, insn) != NULL_RTX
18187 && !prologue_epilogue_contains (insn))
18194 /* Emit instructions needed to load the TOC register.
18195 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18196 a constant pool; or for SVR4 -fpic. */
18199 rs6000_emit_load_toc_table (int fromprolog)
18202 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18204 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18207 rtx lab, tmp1, tmp2, got;
18209 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18210 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18212 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18214 got = rs6000_got_sym ();
18215 tmp1 = tmp2 = dest;
18218 tmp1 = gen_reg_rtx (Pmode);
18219 tmp2 = gen_reg_rtx (Pmode);
18221 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18222 emit_move_insn (tmp1,
18223 gen_rtx_REG (Pmode, LR_REGNO));
18224 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18225 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18227 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18229 emit_insn (gen_load_toc_v4_pic_si ());
18230 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18232 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18235 rtx temp0 = (fromprolog
18236 ? gen_rtx_REG (Pmode, 0)
18237 : gen_reg_rtx (Pmode));
18243 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18244 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18246 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18247 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18249 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18250 emit_move_insn (dest,
18251 gen_rtx_REG (Pmode, LR_REGNO));
18252 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18258 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18259 lab = gen_label_rtx ();
18260 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18261 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18262 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18264 emit_insn (gen_addsi3 (dest, temp0, dest));
18266 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18268 /* This is for AIX code running in non-PIC ELF32. */
18271 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18272 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18274 emit_insn (gen_elf_high (dest, realsym));
18275 emit_insn (gen_elf_low (dest, dest, realsym));
18279 gcc_assert (DEFAULT_ABI == ABI_AIX);
18282 emit_insn (gen_load_toc_aix_si (dest));
18284 emit_insn (gen_load_toc_aix_di (dest));
18288 /* Emit instructions to restore the link register after determining where
18289 its value has been stored. */
18292 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18294 rs6000_stack_t *info = rs6000_stack_info ();
18297 operands[0] = source;
18298 operands[1] = scratch;
18300 if (info->lr_save_p)
18302 rtx frame_rtx = stack_pointer_rtx;
18303 HOST_WIDE_INT sp_offset = 0;
18306 if (frame_pointer_needed
18307 || cfun->calls_alloca
18308 || info->total_size > 32767)
18310 tmp = gen_frame_mem (Pmode, frame_rtx);
18311 emit_move_insn (operands[1], tmp);
18312 frame_rtx = operands[1];
18314 else if (info->push_p)
18315 sp_offset = info->total_size;
18317 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18318 tmp = gen_frame_mem (Pmode, tmp);
18319 emit_move_insn (tmp, operands[0]);
18322 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
18324 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18325 state of lr_save_p so any change from here on would be a bug. In
18326 particular, stop rs6000_ra_ever_killed from considering the SET
18327 of lr we may have added just above. */
18328 cfun->machine->lr_save_state = info->lr_save_p + 1;
18331 static GTY(()) alias_set_type set = -1;
18334 get_TOC_alias_set (void)
18337 set = new_alias_set ();
18341 /* This returns nonzero if the current function uses the TOC. This is
18342 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
18343 is generated by the ABI_V4 load_toc_* patterns. */
18350 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
18353 rtx pat = PATTERN (insn);
18356 if (GET_CODE (pat) == PARALLEL)
18357 for (i = 0; i < XVECLEN (pat, 0); i++)
18359 rtx sub = XVECEXP (pat, 0, i);
18360 if (GET_CODE (sub) == USE)
18362 sub = XEXP (sub, 0);
18363 if (GET_CODE (sub) == UNSPEC
18364 && XINT (sub, 1) == UNSPEC_TOC)
18374 create_TOC_reference (rtx symbol, rtx largetoc_reg)
18376 rtx tocrel, tocreg;
18378 if (TARGET_DEBUG_ADDR)
18380 if (GET_CODE (symbol) == SYMBOL_REF)
18381 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
18385 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
18386 GET_RTX_NAME (GET_CODE (symbol)));
18387 debug_rtx (symbol);
18391 if (!can_create_pseudo_p ())
18392 df_set_regs_ever_live (TOC_REGISTER, true);
18394 tocrel = gen_rtx_CONST (Pmode,
18395 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
18397 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
18398 if (TARGET_CMODEL != CMODEL_SMALL)
18400 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
18401 if (largetoc_reg != NULL)
18403 emit_move_insn (largetoc_reg, hi);
18406 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
18409 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
18412 /* Issue assembly directives that create a reference to the given DWARF
18413 FRAME_TABLE_LABEL from the current function section. */
18415 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
18417 fprintf (asm_out_file, "\t.ref %s\n",
18418 TARGET_STRIP_NAME_ENCODING (frame_table_label));
18421 /* If _Unwind_* has been called from within the same module,
18422 toc register is not guaranteed to be saved to 40(1) on function
18423 entry. Save it there in that case. */
18426 rs6000_aix_emit_builtin_unwind_init (void)
18429 rtx stack_top = gen_reg_rtx (Pmode);
18430 rtx opcode_addr = gen_reg_rtx (Pmode);
18431 rtx opcode = gen_reg_rtx (SImode);
18432 rtx tocompare = gen_reg_rtx (SImode);
18433 rtx no_toc_save_needed = gen_label_rtx ();
18435 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
18436 emit_move_insn (stack_top, mem);
18438 mem = gen_frame_mem (Pmode,
18439 gen_rtx_PLUS (Pmode, stack_top,
18440 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
18441 emit_move_insn (opcode_addr, mem);
18442 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
18443 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
18444 : 0xE8410028, SImode));
18446 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
18447 SImode, NULL_RTX, NULL_RTX,
18448 no_toc_save_needed, -1);
18450 mem = gen_frame_mem (Pmode,
18451 gen_rtx_PLUS (Pmode, stack_top,
18452 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
18453 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
18454 emit_label (no_toc_save_needed);
18457 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18458 and the change to the stack pointer. */
18461 rs6000_emit_stack_tie (void)
18463 rtx mem = gen_frame_mem (BLKmode,
18464 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
18466 emit_insn (gen_stack_tie (mem));
18469 /* Emit the correct code for allocating stack space, as insns.
18470 If COPY_REG, make sure a copy of the old frame is left there.
18471 The generated code may use hard register 0 as a temporary. */
18474 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
18477 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18478 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
18479 rtx todec = gen_int_mode (-size, Pmode);
18482 if (INTVAL (todec) != -size)
18484 warning (0, "stack frame too large");
18485 emit_insn (gen_trap ());
18489 if (crtl->limit_stack)
18491 if (REG_P (stack_limit_rtx)
18492 && REGNO (stack_limit_rtx) > 1
18493 && REGNO (stack_limit_rtx) <= 31)
18495 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
18496 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18499 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
18501 && DEFAULT_ABI == ABI_V4)
18503 rtx toload = gen_rtx_CONST (VOIDmode,
18504 gen_rtx_PLUS (Pmode,
18508 emit_insn (gen_elf_high (tmp_reg, toload));
18509 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
18510 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18514 warning (0, "stack limit expression is not supported");
18518 emit_move_insn (copy_reg, stack_reg);
18522 /* Need a note here so that try_split doesn't get confused. */
18523 if (get_last_insn () == NULL_RTX)
18524 emit_note (NOTE_INSN_DELETED);
18525 insn = emit_move_insn (tmp_reg, todec);
18526 try_split (PATTERN (insn), insn, 0);
18530 insn = emit_insn (TARGET_32BIT
18531 ? gen_movsi_update_stack (stack_reg, stack_reg,
18533 : gen_movdi_di_update_stack (stack_reg, stack_reg,
18534 todec, stack_reg));
18535 /* Since we didn't use gen_frame_mem to generate the MEM, grab
18536 it now and set the alias set/attributes. The above gen_*_update
18537 calls will generate a PARALLEL with the MEM set being the first
18539 par = PATTERN (insn);
18540 gcc_assert (GET_CODE (par) == PARALLEL);
18541 set = XVECEXP (par, 0, 0);
18542 gcc_assert (GET_CODE (set) == SET);
18543 mem = SET_DEST (set);
18544 gcc_assert (MEM_P (mem));
18545 MEM_NOTRAP_P (mem) = 1;
18546 set_mem_alias_set (mem, get_frame_alias_set ());
18548 RTX_FRAME_RELATED_P (insn) = 1;
18549 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
18550 gen_rtx_SET (VOIDmode, stack_reg,
18551 gen_rtx_PLUS (Pmode, stack_reg,
18552 GEN_INT (-size))));
18555 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
18556 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
18557 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
18558 deduce these equivalences by itself so it wasn't necessary to hold
18559 its hand so much. */
18562 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
18563 rtx reg2, rtx rreg)
18567 /* copy_rtx will not make unique copies of registers, so we need to
18568 ensure we don't have unwanted sharing here. */
18570 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18573 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18575 real = copy_rtx (PATTERN (insn));
18577 if (reg2 != NULL_RTX)
18578 real = replace_rtx (real, reg2, rreg);
18580 real = replace_rtx (real, reg,
18581 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
18582 STACK_POINTER_REGNUM),
18585 /* We expect that 'real' is either a SET or a PARALLEL containing
18586 SETs (and possibly other stuff). In a PARALLEL, all the SETs
18587 are important so they all have to be marked RTX_FRAME_RELATED_P. */
18589 if (GET_CODE (real) == SET)
18593 temp = simplify_rtx (SET_SRC (set));
18595 SET_SRC (set) = temp;
18596 temp = simplify_rtx (SET_DEST (set));
18598 SET_DEST (set) = temp;
18599 if (GET_CODE (SET_DEST (set)) == MEM)
18601 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18603 XEXP (SET_DEST (set), 0) = temp;
18610 gcc_assert (GET_CODE (real) == PARALLEL);
18611 for (i = 0; i < XVECLEN (real, 0); i++)
18612 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
18614 rtx set = XVECEXP (real, 0, i);
18616 temp = simplify_rtx (SET_SRC (set));
18618 SET_SRC (set) = temp;
18619 temp = simplify_rtx (SET_DEST (set));
18621 SET_DEST (set) = temp;
18622 if (GET_CODE (SET_DEST (set)) == MEM)
18624 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18626 XEXP (SET_DEST (set), 0) = temp;
18628 RTX_FRAME_RELATED_P (set) = 1;
18632 RTX_FRAME_RELATED_P (insn) = 1;
18633 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
18636 /* Returns an insn that has a vrsave set operation with the
18637 appropriate CLOBBERs. */
18640 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
18643 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
18644 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18647 = gen_rtx_SET (VOIDmode,
18649 gen_rtx_UNSPEC_VOLATILE (SImode,
18650 gen_rtvec (2, reg, vrsave),
18651 UNSPECV_SET_VRSAVE));
18655 /* We need to clobber the registers in the mask so the scheduler
18656 does not move sets to VRSAVE before sets of AltiVec registers.
18658 However, if the function receives nonlocal gotos, reload will set
18659 all call saved registers live. We will end up with:
18661 (set (reg 999) (mem))
18662 (parallel [ (set (reg vrsave) (unspec blah))
18663 (clobber (reg 999))])
18665 The clobber will cause the store into reg 999 to be dead, and
18666 flow will attempt to delete an epilogue insn. In this case, we
18667 need an unspec use/set of the register. */
18669 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18670 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18672 if (!epiloguep || call_used_regs [i])
18673 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
18674 gen_rtx_REG (V4SImode, i));
18677 rtx reg = gen_rtx_REG (V4SImode, i);
18680 = gen_rtx_SET (VOIDmode,
18682 gen_rtx_UNSPEC (V4SImode,
18683 gen_rtvec (1, reg), 27));
18687 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
18689 for (i = 0; i < nclobs; ++i)
18690 XVECEXP (insn, 0, i) = clobs[i];
18695 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
18696 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
18699 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
18700 unsigned int regno, int offset, HOST_WIDE_INT total_size)
18702 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
18703 rtx replacea, replaceb;
18705 int_rtx = GEN_INT (offset);
18707 /* Some cases that need register indexed addressing. */
18708 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
18709 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
18710 || (TARGET_E500_DOUBLE && mode == DFmode)
18712 && SPE_VECTOR_MODE (mode)
18713 && !SPE_CONST_OFFSET_OK (offset)))
18715 /* Whomever calls us must make sure r11 is available in the
18716 flow path of instructions in the prologue. */
18717 offset_rtx = gen_rtx_REG (Pmode, 11);
18718 emit_move_insn (offset_rtx, int_rtx);
18720 replacea = offset_rtx;
18721 replaceb = int_rtx;
18725 offset_rtx = int_rtx;
18726 replacea = NULL_RTX;
18727 replaceb = NULL_RTX;
18730 reg = gen_rtx_REG (mode, regno);
18731 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18732 mem = gen_frame_mem (mode, addr);
18734 insn = emit_move_insn (mem, reg);
18736 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18739 /* Emit an offset memory reference suitable for a frame store, while
18740 converting to a valid addressing mode. */
18743 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18745 rtx int_rtx, offset_rtx;
18747 int_rtx = GEN_INT (offset);
18749 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18750 || (TARGET_E500_DOUBLE && mode == DFmode))
18752 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18753 emit_move_insn (offset_rtx, int_rtx);
18756 offset_rtx = int_rtx;
18758 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18761 /* Look for user-defined global regs. We should not save and restore these,
18762 and cannot use stmw/lmw if there are any in its range. */
18765 no_global_regs_above (int first, bool gpr)
18768 int last = gpr ? 32 : 64;
18769 for (i = first; i < last; i++)
18770 if (global_regs[i])
18775 #ifndef TARGET_FIX_AND_CONTINUE
18776 #define TARGET_FIX_AND_CONTINUE 0
18779 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18780 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18781 #define LAST_SAVRES_REGISTER 31
18782 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18784 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18786 /* Temporary holding space for an out-of-line register save/restore
18788 static char savres_routine_name[30];
18790 /* Return the name for an out-of-line register save/restore routine.
18791 We are saving/restoring GPRs if GPR is true. */
18794 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18795 bool savep, bool gpr, bool lr)
18797 const char *prefix = "";
18798 const char *suffix = "";
18800 /* Different targets are supposed to define
18801 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18802 routine name could be defined with:
18804 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18806 This is a nice idea in practice, but in reality, things are
18807 complicated in several ways:
18809 - ELF targets have save/restore routines for GPRs.
18811 - SPE targets use different prefixes for 32/64-bit registers, and
18812 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18814 - PPC64 ELF targets have routines for save/restore of GPRs that
18815 differ in what they do with the link register, so having a set
18816 prefix doesn't work. (We only use one of the save routines at
18817 the moment, though.)
18819 - PPC32 elf targets have "exit" versions of the restore routines
18820 that restore the link register and can save some extra space.
18821 These require an extra suffix. (There are also "tail" versions
18822 of the restore routines and "GOT" versions of the save routines,
18823 but we don't generate those at present. Same problems apply,
18826 We deal with all this by synthesizing our own prefix/suffix and
18827 using that for the simple sprintf call shown above. */
18830 /* No floating point saves on the SPE. */
18834 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
18836 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
18841 else if (DEFAULT_ABI == ABI_V4)
18847 prefix = savep ? "_savegpr_" : "_restgpr_";
18849 prefix = savep ? "_savefpr_" : "_restfpr_";
18854 else if (DEFAULT_ABI == ABI_AIX)
18856 #ifndef POWERPC_LINUX
18857 /* No out-of-line save/restore routines for GPRs on AIX. */
18858 gcc_assert (!TARGET_AIX || !gpr);
18864 ? (lr ? "_savegpr0_" : "_savegpr1_")
18865 : (lr ? "_restgpr0_" : "_restgpr1_"));
18866 #ifdef POWERPC_LINUX
18868 prefix = (savep ? "_savefpr_" : "_restfpr_");
18872 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
18873 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
18876 else if (DEFAULT_ABI == ABI_DARWIN)
18877 sorry ("Out-of-line save/restore routines not supported on Darwin");
18879 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
18881 return savres_routine_name;
18884 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18885 We are saving/restoring GPRs if GPR is true. */
18888 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
18891 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18893 int select = ((savep ? 1 : 0) << 2
18895 /* On the SPE, we never have any FPRs, but we do have
18896 32/64-bit versions of the routines. */
18897 ? (info->spe_64bit_regs_used ? 1 : 0)
18898 : (gpr ? 1 : 0)) << 1)
18901 /* Don't generate bogus routine names. */
18902 gcc_assert (FIRST_SAVRES_REGISTER <= regno
18903 && regno <= LAST_SAVRES_REGISTER);
18905 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18911 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
18913 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18914 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18915 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
18921 /* Emit a sequence of insns, including a stack tie if needed, for
18922 resetting the stack pointer. If SAVRES is true, then don't reset the
18923 stack pointer, but move the base of the frame into r11 for use by
18924 out-of-line register restore routines. */
18927 rs6000_emit_stack_reset (rs6000_stack_t *info,
18928 rtx sp_reg_rtx, rtx frame_reg_rtx,
18929 int sp_offset, bool savres)
18931 /* This blockage is needed so that sched doesn't decide to move
18932 the sp change before the register restores. */
18933 if (frame_reg_rtx != sp_reg_rtx
18935 && info->spe_64bit_regs_used != 0
18936 && info->first_gp_reg_save != 32))
18937 rs6000_emit_stack_tie ();
18939 if (frame_reg_rtx != sp_reg_rtx)
18941 if (sp_offset != 0)
18943 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
18944 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
18945 GEN_INT (sp_offset)));
18948 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18950 else if (sp_offset != 0)
18952 /* If we are restoring registers out-of-line, we will be using the
18953 "exit" variants of the restore routines, which will reset the
18954 stack for us. But we do need to point r11 into the right place
18955 for those routines. */
18956 rtx dest_reg = (savres
18957 ? gen_rtx_REG (Pmode, 11)
18960 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18961 GEN_INT (sp_offset)));
18968 /* Construct a parallel rtx describing the effect of a call to an
18969 out-of-line register save/restore routine. */
18972 rs6000_make_savres_rtx (rs6000_stack_t *info,
18973 rtx frame_reg_rtx, int save_area_offset,
18974 enum machine_mode reg_mode,
18975 bool savep, bool gpr, bool lr)
18978 int offset, start_reg, end_reg, n_regs;
18979 int reg_size = GET_MODE_SIZE (reg_mode);
18985 ? info->first_gp_reg_save
18986 : info->first_fp_reg_save);
18987 end_reg = gpr ? 32 : 64;
18988 n_regs = end_reg - start_reg;
18989 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
18992 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18994 RTVEC_ELT (p, offset++)
18995 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18997 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
18998 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18999 RTVEC_ELT (p, offset++)
19000 = gen_rtx_USE (VOIDmode,
19001 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19005 for (i = 0; i < end_reg - start_reg; i++)
19007 rtx addr, reg, mem;
19008 reg = gen_rtx_REG (reg_mode, start_reg + i);
19009 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19010 GEN_INT (save_area_offset + reg_size*i));
19011 mem = gen_frame_mem (reg_mode, addr);
19013 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19015 savep ? reg : mem);
19020 rtx addr, reg, mem;
19021 reg = gen_rtx_REG (Pmode, 0);
19022 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19023 GEN_INT (info->lr_save_offset));
19024 mem = gen_frame_mem (Pmode, addr);
19025 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19028 return gen_rtx_PARALLEL (VOIDmode, p);
19031 /* Determine whether the gp REG is really used. */
19034 rs6000_reg_live_or_pic_offset_p (int reg)
19036 return ((df_regs_ever_live_p (reg)
19037 && (!call_used_regs[reg]
19038 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19039 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19040 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19041 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19042 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19046 SAVRES_MULTIPLE = 0x1,
19047 SAVRES_INLINE_FPRS = 0x2,
19048 SAVRES_INLINE_GPRS = 0x4,
19049 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
19050 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
19051 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
19054 /* Determine the strategy for savings/restoring registers. */
19057 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
19058 int using_static_chain_p, int sibcall)
19060 bool using_multiple_p;
19062 bool savres_fprs_inline;
19063 bool savres_gprs_inline;
19064 bool noclobber_global_gprs
19065 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
19068 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
19069 && (!TARGET_SPE_ABI
19070 || info->spe_64bit_regs_used == 0)
19071 && info->first_gp_reg_save < 31
19072 && noclobber_global_gprs);
19073 /* Don't bother to try to save things out-of-line if r11 is occupied
19074 by the static chain. It would require too much fiddling and the
19075 static chain is rarely used anyway. */
19076 common = (using_static_chain_p
19078 || crtl->calls_eh_return
19079 || !info->lr_save_p
19080 || cfun->machine->ra_need_lr
19081 || info->total_size > 32767);
19082 savres_fprs_inline = (common
19083 || info->first_fp_reg_save == 64
19084 || !no_global_regs_above (info->first_fp_reg_save,
19086 /* The out-of-line FP routines use
19087 double-precision stores; we can't use those
19088 routines if we don't have such stores. */
19089 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
19090 || FP_SAVE_INLINE (info->first_fp_reg_save));
19091 savres_gprs_inline = (common
19092 /* Saving CR interferes with the exit routines
19093 used on the SPE, so just punt here. */
19096 && info->spe_64bit_regs_used != 0
19097 && info->cr_save_p != 0)
19098 || info->first_gp_reg_save == 32
19099 || !noclobber_global_gprs
19100 || GP_SAVE_INLINE (info->first_gp_reg_save));
19103 /* If we are going to use store multiple, then don't even bother
19104 with the out-of-line routines, since the store-multiple instruction
19105 will always be smaller. */
19106 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19109 /* The situation is more complicated with load multiple. We'd
19110 prefer to use the out-of-line routines for restores, since the
19111 "exit" out-of-line routines can handle the restore of LR and
19112 the frame teardown. But we can only use the out-of-line
19113 routines if we know that we've used store multiple or
19114 out-of-line routines in the prologue, i.e. if we've saved all
19115 the registers from first_gp_reg_save. Otherwise, we risk
19116 loading garbage from the stack. Furthermore, we can only use
19117 the "exit" out-of-line gpr restore if we haven't saved any
19119 bool saved_all = !savres_gprs_inline || using_multiple_p;
19121 if (saved_all && info->first_fp_reg_save != 64)
19122 /* We can't use the exit routine; use load multiple if it's
19124 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19127 strategy = (using_multiple_p
19128 | (savres_fprs_inline << 1)
19129 | (savres_gprs_inline << 2));
19130 #ifdef POWERPC_LINUX
19133 if (!savres_fprs_inline)
19134 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
19135 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
19136 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
19139 if (TARGET_AIX && !savres_fprs_inline)
19140 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
19145 /* Emit function prologue as insns. */
19148 rs6000_emit_prologue (void)
19150 rs6000_stack_t *info = rs6000_stack_info ();
19151 enum machine_mode reg_mode = Pmode;
19152 int reg_size = TARGET_32BIT ? 4 : 8;
19153 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19154 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19155 rtx frame_reg_rtx = sp_reg_rtx;
19156 rtx cr_save_rtx = NULL_RTX;
19159 int saving_FPRs_inline;
19160 int saving_GPRs_inline;
19161 int using_store_multiple;
19162 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19163 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19164 && call_used_regs[STATIC_CHAIN_REGNUM]);
19165 HOST_WIDE_INT sp_offset = 0;
19167 if (TARGET_FIX_AND_CONTINUE)
19169 /* gdb on darwin arranges to forward a function from the old
19170 address by modifying the first 5 instructions of the function
19171 to branch to the overriding function. This is necessary to
19172 permit function pointers that point to the old function to
19173 actually forward to the new function. */
19174 emit_insn (gen_nop ());
19175 emit_insn (gen_nop ());
19176 emit_insn (gen_nop ());
19177 emit_insn (gen_nop ());
19178 emit_insn (gen_nop ());
19181 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19183 reg_mode = V2SImode;
19187 strategy = rs6000_savres_strategy (info, /*savep=*/true,
19188 /*static_chain_p=*/using_static_chain_p,
19190 using_store_multiple = strategy & SAVRES_MULTIPLE;
19191 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19192 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19194 /* For V.4, update stack before we do any saving and set back pointer. */
19195 if (! WORLD_SAVE_P (info)
19197 && (DEFAULT_ABI == ABI_V4
19198 || crtl->calls_eh_return))
19200 bool need_r11 = (TARGET_SPE
19201 ? (!saving_GPRs_inline
19202 && info->spe_64bit_regs_used == 0)
19203 : (!saving_FPRs_inline || !saving_GPRs_inline));
19204 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19206 if (info->total_size < 32767)
19207 sp_offset = info->total_size;
19209 frame_reg_rtx = copy_reg;
19210 else if (info->cr_save_p
19212 || info->first_fp_reg_save < 64
19213 || info->first_gp_reg_save < 32
19214 || info->altivec_size != 0
19215 || info->vrsave_mask != 0
19216 || crtl->calls_eh_return)
19218 copy_reg = frame_ptr_rtx;
19219 frame_reg_rtx = copy_reg;
19223 /* The prologue won't be saving any regs so there is no need
19224 to set up a frame register to access any frame save area.
19225 We also won't be using sp_offset anywhere below, but set
19226 the correct value anyway to protect against future
19227 changes to this function. */
19228 sp_offset = info->total_size;
19230 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19231 if (frame_reg_rtx != sp_reg_rtx)
19232 rs6000_emit_stack_tie ();
19235 /* Handle world saves specially here. */
19236 if (WORLD_SAVE_P (info))
19243 /* save_world expects lr in r0. */
19244 reg0 = gen_rtx_REG (Pmode, 0);
19245 if (info->lr_save_p)
19247 insn = emit_move_insn (reg0,
19248 gen_rtx_REG (Pmode, LR_REGNO));
19249 RTX_FRAME_RELATED_P (insn) = 1;
19252 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19253 assumptions about the offsets of various bits of the stack
19255 gcc_assert (info->gp_save_offset == -220
19256 && info->fp_save_offset == -144
19257 && info->lr_save_offset == 8
19258 && info->cr_save_offset == 4
19261 && (!crtl->calls_eh_return
19262 || info->ehrd_offset == -432)
19263 && info->vrsave_save_offset == -224
19264 && info->altivec_save_offset == -416);
19266 treg = gen_rtx_REG (SImode, 11);
19267 emit_move_insn (treg, GEN_INT (-info->total_size));
19269 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19270 in R11. It also clobbers R12, so beware! */
19272 /* Preserve CR2 for save_world prologues */
19274 sz += 32 - info->first_gp_reg_save;
19275 sz += 64 - info->first_fp_reg_save;
19276 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19277 p = rtvec_alloc (sz);
19279 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19280 gen_rtx_REG (SImode,
19282 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19283 gen_rtx_SYMBOL_REF (Pmode,
19285 /* We do floats first so that the instruction pattern matches
19287 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19289 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19290 ? DFmode : SFmode),
19291 info->first_fp_reg_save + i);
19292 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19293 GEN_INT (info->fp_save_offset
19294 + sp_offset + 8 * i));
19295 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19296 ? DFmode : SFmode), addr);
19298 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19300 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19302 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19303 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19304 GEN_INT (info->altivec_save_offset
19305 + sp_offset + 16 * i));
19306 rtx mem = gen_frame_mem (V4SImode, addr);
19308 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19310 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19312 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19313 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19314 GEN_INT (info->gp_save_offset
19315 + sp_offset + reg_size * i));
19316 rtx mem = gen_frame_mem (reg_mode, addr);
19318 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19322 /* CR register traditionally saved as CR2. */
19323 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19324 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19325 GEN_INT (info->cr_save_offset
19327 rtx mem = gen_frame_mem (reg_mode, addr);
19329 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19331 /* Explain about use of R0. */
19332 if (info->lr_save_p)
19334 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19335 GEN_INT (info->lr_save_offset
19337 rtx mem = gen_frame_mem (reg_mode, addr);
19339 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
19341 /* Explain what happens to the stack pointer. */
19343 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
19344 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
19347 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19348 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19349 treg, GEN_INT (-info->total_size));
19350 sp_offset = info->total_size;
19353 /* If we use the link register, get it into r0. */
19354 if (!WORLD_SAVE_P (info) && info->lr_save_p)
19356 rtx addr, reg, mem;
19358 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
19359 gen_rtx_REG (Pmode, LR_REGNO));
19360 RTX_FRAME_RELATED_P (insn) = 1;
19362 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
19363 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
19365 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19366 GEN_INT (info->lr_save_offset + sp_offset));
19367 reg = gen_rtx_REG (Pmode, 0);
19368 mem = gen_rtx_MEM (Pmode, addr);
19369 /* This should not be of rs6000_sr_alias_set, because of
19370 __builtin_return_address. */
19372 insn = emit_move_insn (mem, reg);
19373 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19374 NULL_RTX, NULL_RTX);
19378 /* If we need to save CR, put it into r12 or r11. */
19379 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
19384 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
19386 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19387 RTX_FRAME_RELATED_P (insn) = 1;
19388 /* Now, there's no way that dwarf2out_frame_debug_expr is going
19389 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
19390 But that's OK. All we have to do is specify that _one_ condition
19391 code register is saved in this stack slot. The thrower's epilogue
19392 will then restore all the call-saved registers.
19393 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
19394 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
19395 gen_rtx_REG (SImode, CR2_REGNO));
19396 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19399 /* Do any required saving of fpr's. If only one or two to save, do
19400 it ourselves. Otherwise, call function. */
19401 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
19404 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19405 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
19406 && ! call_used_regs[info->first_fp_reg_save+i]))
19407 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
19408 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19410 info->first_fp_reg_save + i,
19411 info->fp_save_offset + sp_offset + 8 * i,
19414 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
19418 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19419 info->fp_save_offset + sp_offset,
19421 /*savep=*/true, /*gpr=*/false,
19423 & SAVRES_NOINLINE_FPRS_SAVES_LR)
19425 insn = emit_insn (par);
19426 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19427 NULL_RTX, NULL_RTX);
19430 /* Save GPRs. This is done as a PARALLEL if we are using
19431 the store-multiple instructions. */
19432 if (!WORLD_SAVE_P (info)
19434 && info->spe_64bit_regs_used != 0
19435 && info->first_gp_reg_save != 32)
19438 rtx spe_save_area_ptr;
19440 /* Determine whether we can address all of the registers that need
19441 to be saved with an offset from the stack pointer that fits in
19442 the small const field for SPE memory instructions. */
19443 int spe_regs_addressable_via_sp
19444 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19445 + (32 - info->first_gp_reg_save - 1) * reg_size)
19446 && saving_GPRs_inline);
19449 if (spe_regs_addressable_via_sp)
19451 spe_save_area_ptr = frame_reg_rtx;
19452 spe_offset = info->spe_gp_save_offset + sp_offset;
19456 /* Make r11 point to the start of the SPE save area. We need
19457 to be careful here if r11 is holding the static chain. If
19458 it is, then temporarily save it in r0. We would use r0 as
19459 our base register here, but using r0 as a base register in
19460 loads and stores means something different from what we
19462 int ool_adjust = (saving_GPRs_inline
19464 : (info->first_gp_reg_save
19465 - (FIRST_SAVRES_REGISTER+1))*8);
19466 HOST_WIDE_INT offset = (info->spe_gp_save_offset
19467 + sp_offset - ool_adjust);
19469 if (using_static_chain_p)
19471 rtx r0 = gen_rtx_REG (Pmode, 0);
19472 gcc_assert (info->first_gp_reg_save > 11);
19474 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
19477 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
19478 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
19480 GEN_INT (offset)));
19481 /* We need to make sure the move to r11 gets noted for
19482 properly outputting unwind information. */
19483 if (!saving_GPRs_inline)
19484 rs6000_frame_related (insn, frame_reg_rtx, offset,
19485 NULL_RTX, NULL_RTX);
19489 if (saving_GPRs_inline)
19491 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19492 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19494 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19495 rtx offset, addr, mem;
19497 /* We're doing all this to ensure that the offset fits into
19498 the immediate offset of 'evstdd'. */
19499 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
19501 offset = GEN_INT (reg_size * i + spe_offset);
19502 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
19503 mem = gen_rtx_MEM (V2SImode, addr);
19505 insn = emit_move_insn (mem, reg);
19507 rs6000_frame_related (insn, spe_save_area_ptr,
19508 info->spe_gp_save_offset
19509 + sp_offset + reg_size * i,
19510 offset, const0_rtx);
19517 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19519 /*savep=*/true, /*gpr=*/true,
19521 insn = emit_insn (par);
19522 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19523 NULL_RTX, NULL_RTX);
19527 /* Move the static chain pointer back. */
19528 if (using_static_chain_p && !spe_regs_addressable_via_sp)
19529 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
19531 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
19535 /* Need to adjust r11 (r12) if we saved any FPRs. */
19536 if (info->first_fp_reg_save != 64)
19538 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
19540 rtx offset = GEN_INT (sp_offset
19541 + (-8 * (64-info->first_fp_reg_save)));
19542 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
19545 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19546 info->gp_save_offset + sp_offset,
19548 /*savep=*/true, /*gpr=*/true,
19550 & SAVRES_NOINLINE_GPRS_SAVES_LR)
19552 insn = emit_insn (par);
19553 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19554 NULL_RTX, NULL_RTX);
19556 else if (!WORLD_SAVE_P (info) && using_store_multiple)
19560 p = rtvec_alloc (32 - info->first_gp_reg_save);
19561 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19563 rtx addr, reg, mem;
19564 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19565 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19566 GEN_INT (info->gp_save_offset
19569 mem = gen_frame_mem (reg_mode, addr);
19571 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
19573 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19574 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19575 NULL_RTX, NULL_RTX);
19577 else if (!WORLD_SAVE_P (info))
19580 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19581 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19583 rtx addr, reg, mem;
19584 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19586 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19587 GEN_INT (info->gp_save_offset
19590 mem = gen_frame_mem (reg_mode, addr);
19592 insn = emit_move_insn (mem, reg);
19593 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19594 NULL_RTX, NULL_RTX);
19598 /* ??? There's no need to emit actual instructions here, but it's the
19599 easiest way to get the frame unwind information emitted. */
19600 if (crtl->calls_eh_return)
19602 unsigned int i, regno;
19604 /* In AIX ABI we need to pretend we save r2 here. */
19607 rtx addr, reg, mem;
19609 reg = gen_rtx_REG (reg_mode, 2);
19610 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19611 GEN_INT (sp_offset + 5 * reg_size));
19612 mem = gen_frame_mem (reg_mode, addr);
19614 insn = emit_move_insn (mem, reg);
19615 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19616 NULL_RTX, NULL_RTX);
19617 PATTERN (insn) = gen_blockage ();
19622 regno = EH_RETURN_DATA_REGNO (i);
19623 if (regno == INVALID_REGNUM)
19626 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
19627 info->ehrd_offset + sp_offset
19628 + reg_size * (int) i,
19633 /* Save CR if we use any that must be preserved. */
19634 if (!WORLD_SAVE_P (info) && info->cr_save_p)
19636 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19637 GEN_INT (info->cr_save_offset + sp_offset));
19638 rtx mem = gen_frame_mem (SImode, addr);
19639 /* See the large comment above about why CR2_REGNO is used. */
19640 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
19642 /* If r12 was used to hold the original sp, copy cr into r0 now
19644 if (REGNO (frame_reg_rtx) == 12)
19648 cr_save_rtx = gen_rtx_REG (SImode, 0);
19649 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19650 RTX_FRAME_RELATED_P (insn) = 1;
19651 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
19652 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19654 insn = emit_move_insn (mem, cr_save_rtx);
19656 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19657 NULL_RTX, NULL_RTX);
19660 /* Update stack and set back pointer unless this is V.4,
19661 for which it was done previously. */
19662 if (!WORLD_SAVE_P (info) && info->push_p
19663 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
19665 rtx copy_reg = NULL;
19667 if (info->total_size < 32767)
19668 sp_offset = info->total_size;
19669 else if (info->altivec_size != 0
19670 || info->vrsave_mask != 0)
19672 copy_reg = frame_ptr_rtx;
19673 frame_reg_rtx = copy_reg;
19676 sp_offset = info->total_size;
19677 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19678 if (frame_reg_rtx != sp_reg_rtx)
19679 rs6000_emit_stack_tie ();
19682 /* Set frame pointer, if needed. */
19683 if (frame_pointer_needed)
19685 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
19687 RTX_FRAME_RELATED_P (insn) = 1;
19690 /* Save AltiVec registers if needed. Save here because the red zone does
19691 not include AltiVec registers. */
19692 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
19696 /* There should be a non inline version of this, for when we
19697 are saving lots of vector registers. */
19698 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19699 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19701 rtx areg, savereg, mem;
19704 offset = info->altivec_save_offset + sp_offset
19705 + 16 * (i - info->first_altivec_reg_save);
19707 savereg = gen_rtx_REG (V4SImode, i);
19709 areg = gen_rtx_REG (Pmode, 0);
19710 emit_move_insn (areg, GEN_INT (offset));
19712 /* AltiVec addressing mode is [reg+reg]. */
19713 mem = gen_frame_mem (V4SImode,
19714 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
19716 insn = emit_move_insn (mem, savereg);
19718 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19719 areg, GEN_INT (offset));
19723 /* VRSAVE is a bit vector representing which AltiVec registers
19724 are used. The OS uses this to determine which vector
19725 registers to save on a context switch. We need to save
19726 VRSAVE on the stack frame, add whatever AltiVec registers we
19727 used in this function, and do the corresponding magic in the
19730 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
19731 && info->vrsave_mask != 0)
19733 rtx reg, mem, vrsave;
19736 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
19737 as frame_reg_rtx and r11 as the static chain pointer for
19738 nested functions. */
19739 reg = gen_rtx_REG (SImode, 0);
19740 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19742 emit_insn (gen_get_vrsave_internal (reg));
19744 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19746 if (!WORLD_SAVE_P (info))
19749 offset = info->vrsave_save_offset + sp_offset;
19750 mem = gen_frame_mem (SImode,
19751 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19752 GEN_INT (offset)));
19753 insn = emit_move_insn (mem, reg);
19756 /* Include the registers in the mask. */
19757 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19759 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19762 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19763 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19764 || (DEFAULT_ABI == ABI_V4
19765 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19766 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19768 /* If emit_load_toc_table will use the link register, we need to save
19769 it. We use R12 for this purpose because emit_load_toc_table
19770 can use register 0. This allows us to use a plain 'blr' to return
19771 from the procedure more often. */
19772 int save_LR_around_toc_setup = (TARGET_ELF
19773 && DEFAULT_ABI != ABI_AIX
19775 && ! info->lr_save_p
19776 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19777 if (save_LR_around_toc_setup)
19779 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19781 insn = emit_move_insn (frame_ptr_rtx, lr);
19782 RTX_FRAME_RELATED_P (insn) = 1;
19784 rs6000_emit_load_toc_table (TRUE);
19786 insn = emit_move_insn (lr, frame_ptr_rtx);
19787 RTX_FRAME_RELATED_P (insn) = 1;
19790 rs6000_emit_load_toc_table (TRUE);
19794 if (DEFAULT_ABI == ABI_DARWIN
19795 && flag_pic && crtl->uses_pic_offset_table)
19797 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19798 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19800 /* Save and restore LR locally around this call (in R0). */
19801 if (!info->lr_save_p)
19802 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19804 emit_insn (gen_load_macho_picbase (src));
19806 emit_move_insn (gen_rtx_REG (Pmode,
19807 RS6000_PIC_OFFSET_TABLE_REGNUM),
19810 if (!info->lr_save_p)
19811 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19816 /* Write function prologue. */
19819 rs6000_output_function_prologue (FILE *file,
19820 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19822 rs6000_stack_t *info = rs6000_stack_info ();
19824 if (TARGET_DEBUG_STACK)
19825 debug_stack_info (info);
19827 /* Write .extern for any function we will call to save and restore
19829 if (info->first_fp_reg_save < 64
19830 && !FP_SAVE_INLINE (info->first_fp_reg_save))
19833 int regno = info->first_fp_reg_save - 32;
19835 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
19836 /*gpr=*/false, /*lr=*/false);
19837 fprintf (file, "\t.extern %s\n", name);
19839 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
19840 /*gpr=*/false, /*lr=*/true);
19841 fprintf (file, "\t.extern %s\n", name);
19844 /* Write .extern for AIX common mode routines, if needed. */
19845 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
19847 fputs ("\t.extern __mulh\n", file);
19848 fputs ("\t.extern __mull\n", file);
19849 fputs ("\t.extern __divss\n", file);
19850 fputs ("\t.extern __divus\n", file);
19851 fputs ("\t.extern __quoss\n", file);
19852 fputs ("\t.extern __quous\n", file);
19853 common_mode_defined = 1;
19856 if (! HAVE_prologue)
19862 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19863 the "toplevel" insn chain. */
19864 emit_note (NOTE_INSN_DELETED);
19865 rs6000_emit_prologue ();
19866 emit_note (NOTE_INSN_DELETED);
19868 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19872 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19874 INSN_ADDRESSES_NEW (insn, addr);
19879 prologue = get_insns ();
19882 if (TARGET_DEBUG_STACK)
19883 debug_rtx_list (prologue, 100);
19885 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
19889 rs6000_pic_labelno++;
19892 /* Non-zero if vmx regs are restored before the frame pop, zero if
19893 we restore after the pop when possible. */
19894 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19896 /* Reload CR from REG. */
19899 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
19904 if (using_mfcr_multiple)
19906 for (i = 0; i < 8; i++)
19907 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19909 gcc_assert (count);
19912 if (using_mfcr_multiple && count > 1)
19917 p = rtvec_alloc (count);
19920 for (i = 0; i < 8; i++)
19921 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19923 rtvec r = rtvec_alloc (2);
19924 RTVEC_ELT (r, 0) = reg;
19925 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19926 RTVEC_ELT (p, ndx) =
19927 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19928 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19931 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19932 gcc_assert (ndx == count);
19935 for (i = 0; i < 8; i++)
19936 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19938 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19944 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19945 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19946 below stack pointer not cloberred by signals. */
19949 offset_below_red_zone_p (HOST_WIDE_INT offset)
19951 return offset < (DEFAULT_ABI == ABI_V4
19953 : TARGET_32BIT ? -220 : -288);
19956 /* Emit function epilogue as insns. */
19959 rs6000_emit_epilogue (int sibcall)
19961 rs6000_stack_t *info;
19962 int restoring_GPRs_inline;
19963 int restoring_FPRs_inline;
19964 int using_load_multiple;
19965 int using_mtcr_multiple;
19966 int use_backchain_to_restore_sp;
19970 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19971 rtx frame_reg_rtx = sp_reg_rtx;
19972 rtx cfa_restores = NULL_RTX;
19974 rtx cr_save_reg = NULL_RTX;
19975 enum machine_mode reg_mode = Pmode;
19976 int reg_size = TARGET_32BIT ? 4 : 8;
19979 info = rs6000_stack_info ();
19981 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19983 reg_mode = V2SImode;
19987 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19988 /*static_chain_p=*/0, sibcall);
19989 using_load_multiple = strategy & SAVRES_MULTIPLE;
19990 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19991 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19992 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19993 || rs6000_cpu == PROCESSOR_PPC603
19994 || rs6000_cpu == PROCESSOR_PPC750
19996 /* Restore via the backchain when we have a large frame, since this
19997 is more efficient than an addis, addi pair. The second condition
19998 here will not trigger at the moment; We don't actually need a
19999 frame pointer for alloca, but the generic parts of the compiler
20000 give us one anyway. */
20001 use_backchain_to_restore_sp = (info->total_size > 32767
20002 || info->total_size
20003 + (info->lr_save_p ? info->lr_save_offset : 0)
20005 || (cfun->calls_alloca
20006 && !frame_pointer_needed));
20007 restore_lr = (info->lr_save_p
20008 && (restoring_FPRs_inline
20009 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20010 && (restoring_GPRs_inline
20011 || info->first_fp_reg_save < 64));
20013 if (WORLD_SAVE_P (info))
20017 const char *alloc_rname;
20020 /* eh_rest_world_r10 will return to the location saved in the LR
20021 stack slot (which is not likely to be our caller.)
20022 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20023 rest_world is similar, except any R10 parameter is ignored.
20024 The exception-handling stuff that was here in 2.95 is no
20025 longer necessary. */
20029 + 32 - info->first_gp_reg_save
20030 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20031 + 63 + 1 - info->first_fp_reg_save);
20033 strcpy (rname, ((crtl->calls_eh_return) ?
20034 "*eh_rest_world_r10" : "*rest_world"));
20035 alloc_rname = ggc_strdup (rname);
20038 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
20039 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20040 gen_rtx_REG (Pmode,
20043 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20044 /* The instruction pattern requires a clobber here;
20045 it is shared with the restVEC helper. */
20047 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20050 /* CR register traditionally saved as CR2. */
20051 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20052 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20053 GEN_INT (info->cr_save_offset));
20054 rtx mem = gen_frame_mem (reg_mode, addr);
20056 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20059 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20061 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20062 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20063 GEN_INT (info->gp_save_offset
20065 rtx mem = gen_frame_mem (reg_mode, addr);
20067 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20069 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20071 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20072 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20073 GEN_INT (info->altivec_save_offset
20075 rtx mem = gen_frame_mem (V4SImode, addr);
20077 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20079 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20081 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20082 ? DFmode : SFmode),
20083 info->first_fp_reg_save + i);
20084 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20085 GEN_INT (info->fp_save_offset
20087 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20088 ? DFmode : SFmode), addr);
20090 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20093 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20095 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20097 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20099 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20101 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20102 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20107 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20109 sp_offset = info->total_size;
20111 /* Restore AltiVec registers if we must do so before adjusting the
20113 if (TARGET_ALTIVEC_ABI
20114 && info->altivec_size != 0
20115 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20116 || (DEFAULT_ABI != ABI_V4
20117 && offset_below_red_zone_p (info->altivec_save_offset))))
20121 if (use_backchain_to_restore_sp)
20123 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20124 emit_move_insn (frame_reg_rtx,
20125 gen_rtx_MEM (Pmode, sp_reg_rtx));
20128 else if (frame_pointer_needed)
20129 frame_reg_rtx = hard_frame_pointer_rtx;
20131 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20132 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20134 rtx addr, areg, mem, reg;
20136 areg = gen_rtx_REG (Pmode, 0);
20138 (areg, GEN_INT (info->altivec_save_offset
20140 + 16 * (i - info->first_altivec_reg_save)));
20142 /* AltiVec addressing mode is [reg+reg]. */
20143 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20144 mem = gen_frame_mem (V4SImode, addr);
20146 reg = gen_rtx_REG (V4SImode, i);
20147 emit_move_insn (reg, mem);
20148 if (offset_below_red_zone_p (info->altivec_save_offset
20149 + (i - info->first_altivec_reg_save)
20151 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20156 /* Restore VRSAVE if we must do so before adjusting the stack. */
20158 && TARGET_ALTIVEC_VRSAVE
20159 && info->vrsave_mask != 0
20160 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20161 || (DEFAULT_ABI != ABI_V4
20162 && offset_below_red_zone_p (info->vrsave_save_offset))))
20164 rtx addr, mem, reg;
20166 if (frame_reg_rtx == sp_reg_rtx)
20168 if (use_backchain_to_restore_sp)
20170 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20171 emit_move_insn (frame_reg_rtx,
20172 gen_rtx_MEM (Pmode, sp_reg_rtx));
20175 else if (frame_pointer_needed)
20176 frame_reg_rtx = hard_frame_pointer_rtx;
20179 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20180 GEN_INT (info->vrsave_save_offset + sp_offset));
20181 mem = gen_frame_mem (SImode, addr);
20182 reg = gen_rtx_REG (SImode, 12);
20183 emit_move_insn (reg, mem);
20185 emit_insn (generate_set_vrsave (reg, info, 1));
20189 /* If we have a large stack frame, restore the old stack pointer
20190 using the backchain. */
20191 if (use_backchain_to_restore_sp)
20193 if (frame_reg_rtx == sp_reg_rtx)
20195 /* Under V.4, don't reset the stack pointer until after we're done
20196 loading the saved registers. */
20197 if (DEFAULT_ABI == ABI_V4)
20198 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20200 insn = emit_move_insn (frame_reg_rtx,
20201 gen_rtx_MEM (Pmode, sp_reg_rtx));
20204 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20205 && DEFAULT_ABI == ABI_V4)
20206 /* frame_reg_rtx has been set up by the altivec restore. */
20210 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20211 frame_reg_rtx = sp_reg_rtx;
20214 /* If we have a frame pointer, we can restore the old stack pointer
20216 else if (frame_pointer_needed)
20218 frame_reg_rtx = sp_reg_rtx;
20219 if (DEFAULT_ABI == ABI_V4)
20220 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20221 /* Prevent reordering memory accesses against stack pointer restore. */
20222 else if (cfun->calls_alloca
20223 || offset_below_red_zone_p (-info->total_size))
20225 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20226 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20227 MEM_NOTRAP_P (mem1) = 1;
20228 MEM_NOTRAP_P (mem2) = 1;
20229 emit_insn (gen_frame_tie (mem1, mem2));
20232 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20233 GEN_INT (info->total_size)));
20236 else if (info->push_p
20237 && DEFAULT_ABI != ABI_V4
20238 && !crtl->calls_eh_return)
20240 /* Prevent reordering memory accesses against stack pointer restore. */
20241 if (cfun->calls_alloca
20242 || offset_below_red_zone_p (-info->total_size))
20244 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20245 MEM_NOTRAP_P (mem) = 1;
20246 emit_insn (gen_stack_tie (mem));
20248 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20249 GEN_INT (info->total_size)));
20252 if (insn && frame_reg_rtx == sp_reg_rtx)
20256 REG_NOTES (insn) = cfa_restores;
20257 cfa_restores = NULL_RTX;
20259 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20260 RTX_FRAME_RELATED_P (insn) = 1;
20263 /* Restore AltiVec registers if we have not done so already. */
20264 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20265 && TARGET_ALTIVEC_ABI
20266 && info->altivec_size != 0
20267 && (DEFAULT_ABI == ABI_V4
20268 || !offset_below_red_zone_p (info->altivec_save_offset)))
20272 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20273 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20275 rtx addr, areg, mem, reg;
20277 areg = gen_rtx_REG (Pmode, 0);
20279 (areg, GEN_INT (info->altivec_save_offset
20281 + 16 * (i - info->first_altivec_reg_save)));
20283 /* AltiVec addressing mode is [reg+reg]. */
20284 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20285 mem = gen_frame_mem (V4SImode, addr);
20287 reg = gen_rtx_REG (V4SImode, i);
20288 emit_move_insn (reg, mem);
20289 if (DEFAULT_ABI == ABI_V4)
20290 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20295 /* Restore VRSAVE if we have not done so already. */
20296 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20298 && TARGET_ALTIVEC_VRSAVE
20299 && info->vrsave_mask != 0
20300 && (DEFAULT_ABI == ABI_V4
20301 || !offset_below_red_zone_p (info->vrsave_save_offset)))
20303 rtx addr, mem, reg;
20305 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20306 GEN_INT (info->vrsave_save_offset + sp_offset));
20307 mem = gen_frame_mem (SImode, addr);
20308 reg = gen_rtx_REG (SImode, 12);
20309 emit_move_insn (reg, mem);
20311 emit_insn (generate_set_vrsave (reg, info, 1));
20314 /* Get the old lr if we saved it. If we are restoring registers
20315 out-of-line, then the out-of-line routines can do this for us. */
20316 if (restore_lr && restoring_GPRs_inline)
20318 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20319 info->lr_save_offset + sp_offset);
20321 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20324 /* Get the old cr if we saved it. */
20325 if (info->cr_save_p)
20327 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20328 GEN_INT (info->cr_save_offset + sp_offset));
20329 rtx mem = gen_frame_mem (SImode, addr);
20331 cr_save_reg = gen_rtx_REG (SImode,
20332 DEFAULT_ABI == ABI_AIX
20333 && !restoring_GPRs_inline
20334 && info->first_fp_reg_save < 64
20336 emit_move_insn (cr_save_reg, mem);
20339 /* Set LR here to try to overlap restores below. LR is always saved
20340 above incoming stack, so it never needs REG_CFA_RESTORE. */
20341 if (restore_lr && restoring_GPRs_inline)
20342 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20343 gen_rtx_REG (Pmode, 0));
20345 /* Load exception handler data registers, if needed. */
20346 if (crtl->calls_eh_return)
20348 unsigned int i, regno;
20352 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20353 GEN_INT (sp_offset + 5 * reg_size));
20354 rtx mem = gen_frame_mem (reg_mode, addr);
20356 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
20363 regno = EH_RETURN_DATA_REGNO (i);
20364 if (regno == INVALID_REGNUM)
20367 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
20368 info->ehrd_offset + sp_offset
20369 + reg_size * (int) i);
20371 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
20375 /* Restore GPRs. This is done as a PARALLEL if we are using
20376 the load-multiple instructions. */
20378 && info->spe_64bit_regs_used != 0
20379 && info->first_gp_reg_save != 32)
20381 /* Determine whether we can address all of the registers that need
20382 to be saved with an offset from the stack pointer that fits in
20383 the small const field for SPE memory instructions. */
20384 int spe_regs_addressable_via_sp
20385 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20386 + (32 - info->first_gp_reg_save - 1) * reg_size)
20387 && restoring_GPRs_inline);
20390 if (spe_regs_addressable_via_sp)
20391 spe_offset = info->spe_gp_save_offset + sp_offset;
20394 rtx old_frame_reg_rtx = frame_reg_rtx;
20395 /* Make r11 point to the start of the SPE save area. We worried about
20396 not clobbering it when we were saving registers in the prologue.
20397 There's no need to worry here because the static chain is passed
20398 anew to every function. */
20399 int ool_adjust = (restoring_GPRs_inline
20401 : (info->first_gp_reg_save
20402 - (FIRST_SAVRES_REGISTER+1))*8);
20404 if (frame_reg_rtx == sp_reg_rtx)
20405 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20406 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
20407 GEN_INT (info->spe_gp_save_offset
20410 /* Keep the invariant that frame_reg_rtx + sp_offset points
20411 at the top of the stack frame. */
20412 sp_offset = -info->spe_gp_save_offset;
20417 if (restoring_GPRs_inline)
20419 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20420 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20422 rtx offset, addr, mem, reg;
20424 /* We're doing all this to ensure that the immediate offset
20425 fits into the immediate field of 'evldd'. */
20426 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
20428 offset = GEN_INT (spe_offset + reg_size * i);
20429 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
20430 mem = gen_rtx_MEM (V2SImode, addr);
20431 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20433 insn = emit_move_insn (reg, mem);
20434 if (DEFAULT_ABI == ABI_V4)
20436 if (frame_pointer_needed
20437 && info->first_gp_reg_save + i
20438 == HARD_FRAME_POINTER_REGNUM)
20440 add_reg_note (insn, REG_CFA_DEF_CFA,
20441 plus_constant (frame_reg_rtx,
20443 RTX_FRAME_RELATED_P (insn) = 1;
20446 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20455 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20457 /*savep=*/false, /*gpr=*/true,
20459 emit_jump_insn (par);
20460 /* We don't want anybody else emitting things after we jumped
20465 else if (!restoring_GPRs_inline)
20467 /* We are jumping to an out-of-line function. */
20468 bool can_use_exit = info->first_fp_reg_save == 64;
20471 /* Emit stack reset code if we need it. */
20473 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20474 sp_offset, can_use_exit);
20477 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
20480 GEN_INT (sp_offset - info->fp_size)));
20481 if (REGNO (frame_reg_rtx) == 11)
20482 sp_offset += info->fp_size;
20485 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20486 info->gp_save_offset, reg_mode,
20487 /*savep=*/false, /*gpr=*/true,
20488 /*lr=*/can_use_exit);
20492 if (info->cr_save_p)
20494 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20495 if (DEFAULT_ABI == ABI_V4)
20497 = alloc_reg_note (REG_CFA_RESTORE,
20498 gen_rtx_REG (SImode, CR2_REGNO),
20502 emit_jump_insn (par);
20504 /* We don't want anybody else emitting things after we jumped
20509 insn = emit_insn (par);
20510 if (DEFAULT_ABI == ABI_V4)
20512 if (frame_pointer_needed)
20514 add_reg_note (insn, REG_CFA_DEF_CFA,
20515 plus_constant (frame_reg_rtx, sp_offset));
20516 RTX_FRAME_RELATED_P (insn) = 1;
20519 for (i = info->first_gp_reg_save; i < 32; i++)
20521 = alloc_reg_note (REG_CFA_RESTORE,
20522 gen_rtx_REG (reg_mode, i), cfa_restores);
20525 else if (using_load_multiple)
20528 p = rtvec_alloc (32 - info->first_gp_reg_save);
20529 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20531 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20532 GEN_INT (info->gp_save_offset
20535 rtx mem = gen_frame_mem (reg_mode, addr);
20536 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20538 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
20539 if (DEFAULT_ABI == ABI_V4)
20540 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20543 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20544 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
20546 add_reg_note (insn, REG_CFA_DEF_CFA,
20547 plus_constant (frame_reg_rtx, sp_offset));
20548 RTX_FRAME_RELATED_P (insn) = 1;
20553 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20554 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20556 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20557 GEN_INT (info->gp_save_offset
20560 rtx mem = gen_frame_mem (reg_mode, addr);
20561 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20563 insn = emit_move_insn (reg, mem);
20564 if (DEFAULT_ABI == ABI_V4)
20566 if (frame_pointer_needed
20567 && info->first_gp_reg_save + i
20568 == HARD_FRAME_POINTER_REGNUM)
20570 add_reg_note (insn, REG_CFA_DEF_CFA,
20571 plus_constant (frame_reg_rtx, sp_offset));
20572 RTX_FRAME_RELATED_P (insn) = 1;
20575 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20581 if (restore_lr && !restoring_GPRs_inline)
20583 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20584 info->lr_save_offset + sp_offset);
20586 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20587 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20588 gen_rtx_REG (Pmode, 0));
20591 /* Restore fpr's if we need to do it without calling a function. */
20592 if (restoring_FPRs_inline)
20593 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20594 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20595 && ! call_used_regs[info->first_fp_reg_save+i]))
20597 rtx addr, mem, reg;
20598 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20599 GEN_INT (info->fp_save_offset
20602 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20603 ? DFmode : SFmode), addr);
20604 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20605 ? DFmode : SFmode),
20606 info->first_fp_reg_save + i);
20608 emit_move_insn (reg, mem);
20609 if (DEFAULT_ABI == ABI_V4)
20610 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20614 /* If we saved cr, restore it here. Just those that were used. */
20615 if (info->cr_save_p)
20617 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20618 if (DEFAULT_ABI == ABI_V4)
20620 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
20624 /* If this is V.4, unwind the stack pointer after all of the loads
20626 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20627 sp_offset, !restoring_FPRs_inline);
20632 REG_NOTES (insn) = cfa_restores;
20633 cfa_restores = NULL_RTX;
20635 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20636 RTX_FRAME_RELATED_P (insn) = 1;
20639 if (crtl->calls_eh_return)
20641 rtx sa = EH_RETURN_STACKADJ_RTX;
20642 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
20648 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
20649 if (! restoring_FPRs_inline)
20650 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
20652 p = rtvec_alloc (2);
20654 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
20655 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
20656 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
20657 : gen_rtx_CLOBBER (VOIDmode,
20658 gen_rtx_REG (Pmode, 65)));
20660 /* If we have to restore more than two FP registers, branch to the
20661 restore function. It will return to our caller. */
20662 if (! restoring_FPRs_inline)
20667 sym = rs6000_savres_routine_sym (info,
20671 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
20672 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
20673 gen_rtx_REG (Pmode,
20674 DEFAULT_ABI == ABI_AIX
20676 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20679 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
20680 GEN_INT (info->fp_save_offset + 8*i));
20681 mem = gen_frame_mem (DFmode, addr);
20683 RTVEC_ELT (p, i+4) =
20684 gen_rtx_SET (VOIDmode,
20685 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
20690 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20694 /* Write function epilogue. */
20697 rs6000_output_function_epilogue (FILE *file,
20698 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20700 if (! HAVE_epilogue)
20702 rtx insn = get_last_insn ();
20703 /* If the last insn was a BARRIER, we don't have to write anything except
20704 the trace table. */
20705 if (GET_CODE (insn) == NOTE)
20706 insn = prev_nonnote_insn (insn);
20707 if (insn == 0 || GET_CODE (insn) != BARRIER)
20709 /* This is slightly ugly, but at least we don't have two
20710 copies of the epilogue-emitting code. */
20713 /* A NOTE_INSN_DELETED is supposed to be at the start
20714 and end of the "toplevel" insn chain. */
20715 emit_note (NOTE_INSN_DELETED);
20716 rs6000_emit_epilogue (FALSE);
20717 emit_note (NOTE_INSN_DELETED);
20719 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20723 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20725 INSN_ADDRESSES_NEW (insn, addr);
20730 if (TARGET_DEBUG_STACK)
20731 debug_rtx_list (get_insns (), 100);
20732 final (get_insns (), file, FALSE);
20738 macho_branch_islands ();
20739 /* Mach-O doesn't support labels at the end of objects, so if
20740 it looks like we might want one, insert a NOP. */
20742 rtx insn = get_last_insn ();
20745 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
20746 insn = PREV_INSN (insn);
20750 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
20751 fputs ("\tnop\n", file);
20755 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20758 We don't output a traceback table if -finhibit-size-directive was
20759 used. The documentation for -finhibit-size-directive reads
20760 ``don't output a @code{.size} assembler directive, or anything
20761 else that would cause trouble if the function is split in the
20762 middle, and the two halves are placed at locations far apart in
20763 memory.'' The traceback table has this property, since it
20764 includes the offset from the start of the function to the
20765 traceback table itself.
20767 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20768 different traceback table. */
20769 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20770 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20772 const char *fname = NULL;
20773 const char *language_string = lang_hooks.name;
20774 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20776 int optional_tbtab;
20777 rs6000_stack_t *info = rs6000_stack_info ();
20779 if (rs6000_traceback == traceback_full)
20780 optional_tbtab = 1;
20781 else if (rs6000_traceback == traceback_part)
20782 optional_tbtab = 0;
20784 optional_tbtab = !optimize_size && !TARGET_ELF;
20786 if (optional_tbtab)
20788 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20789 while (*fname == '.') /* V.4 encodes . in the name */
20792 /* Need label immediately before tbtab, so we can compute
20793 its offset from the function start. */
20794 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20795 ASM_OUTPUT_LABEL (file, fname);
20798 /* The .tbtab pseudo-op can only be used for the first eight
20799 expressions, since it can't handle the possibly variable
20800 length fields that follow. However, if you omit the optional
20801 fields, the assembler outputs zeros for all optional fields
20802 anyways, giving each variable length field is minimum length
20803 (as defined in sys/debug.h). Thus we can not use the .tbtab
20804 pseudo-op at all. */
20806 /* An all-zero word flags the start of the tbtab, for debuggers
20807 that have to find it by searching forward from the entry
20808 point or from the current pc. */
20809 fputs ("\t.long 0\n", file);
20811 /* Tbtab format type. Use format type 0. */
20812 fputs ("\t.byte 0,", file);
20814 /* Language type. Unfortunately, there does not seem to be any
20815 official way to discover the language being compiled, so we
20816 use language_string.
20817 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20818 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20819 a number, so for now use 9. LTO isn't assigned a number either,
20820 so for now use 0. */
20821 if (! strcmp (language_string, "GNU C")
20822 || ! strcmp (language_string, "GNU GIMPLE"))
20824 else if (! strcmp (language_string, "GNU F77")
20825 || ! strcmp (language_string, "GNU Fortran"))
20827 else if (! strcmp (language_string, "GNU Pascal"))
20829 else if (! strcmp (language_string, "GNU Ada"))
20831 else if (! strcmp (language_string, "GNU C++")
20832 || ! strcmp (language_string, "GNU Objective-C++"))
20834 else if (! strcmp (language_string, "GNU Java"))
20836 else if (! strcmp (language_string, "GNU Objective-C"))
20839 gcc_unreachable ();
20840 fprintf (file, "%d,", i);
20842 /* 8 single bit fields: global linkage (not set for C extern linkage,
20843 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20844 from start of procedure stored in tbtab, internal function, function
20845 has controlled storage, function has no toc, function uses fp,
20846 function logs/aborts fp operations. */
20847 /* Assume that fp operations are used if any fp reg must be saved. */
20848 fprintf (file, "%d,",
20849 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
20851 /* 6 bitfields: function is interrupt handler, name present in
20852 proc table, function calls alloca, on condition directives
20853 (controls stack walks, 3 bits), saves condition reg, saves
20855 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20856 set up as a frame pointer, even when there is no alloca call. */
20857 fprintf (file, "%d,",
20858 ((optional_tbtab << 6)
20859 | ((optional_tbtab & frame_pointer_needed) << 5)
20860 | (info->cr_save_p << 1)
20861 | (info->lr_save_p)));
20863 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20865 fprintf (file, "%d,",
20866 (info->push_p << 7) | (64 - info->first_fp_reg_save));
20868 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20869 fprintf (file, "%d,", (32 - first_reg_to_save ()));
20871 if (optional_tbtab)
20873 /* Compute the parameter info from the function decl argument
20876 int next_parm_info_bit = 31;
20878 for (decl = DECL_ARGUMENTS (current_function_decl);
20879 decl; decl = TREE_CHAIN (decl))
20881 rtx parameter = DECL_INCOMING_RTL (decl);
20882 enum machine_mode mode = GET_MODE (parameter);
20884 if (GET_CODE (parameter) == REG)
20886 if (SCALAR_FLOAT_MODE_P (mode))
20907 gcc_unreachable ();
20910 /* If only one bit will fit, don't or in this entry. */
20911 if (next_parm_info_bit > 0)
20912 parm_info |= (bits << (next_parm_info_bit - 1));
20913 next_parm_info_bit -= 2;
20917 fixed_parms += ((GET_MODE_SIZE (mode)
20918 + (UNITS_PER_WORD - 1))
20920 next_parm_info_bit -= 1;
20926 /* Number of fixed point parameters. */
20927 /* This is actually the number of words of fixed point parameters; thus
20928 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20929 fprintf (file, "%d,", fixed_parms);
20931 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20933 /* This is actually the number of fp registers that hold parameters;
20934 and thus the maximum value is 13. */
20935 /* Set parameters on stack bit if parameters are not in their original
20936 registers, regardless of whether they are on the stack? Xlc
20937 seems to set the bit when not optimizing. */
20938 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
20940 if (! optional_tbtab)
20943 /* Optional fields follow. Some are variable length. */
20945 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20946 11 double float. */
20947 /* There is an entry for each parameter in a register, in the order that
20948 they occur in the parameter list. Any intervening arguments on the
20949 stack are ignored. If the list overflows a long (max possible length
20950 34 bits) then completely leave off all elements that don't fit. */
20951 /* Only emit this long if there was at least one parameter. */
20952 if (fixed_parms || float_parms)
20953 fprintf (file, "\t.long %d\n", parm_info);
20955 /* Offset from start of code to tb table. */
20956 fputs ("\t.long ", file);
20957 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20958 RS6000_OUTPUT_BASENAME (file, fname);
20960 rs6000_output_function_entry (file, fname);
20963 /* Interrupt handler mask. */
20964 /* Omit this long, since we never set the interrupt handler bit
20967 /* Number of CTL (controlled storage) anchors. */
20968 /* Omit this long, since the has_ctl bit is never set above. */
20970 /* Displacement into stack of each CTL anchor. */
20971 /* Omit this list of longs, because there are no CTL anchors. */
20973 /* Length of function name. */
20976 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20978 /* Function name. */
20979 assemble_string (fname, strlen (fname));
20981 /* Register for alloca automatic storage; this is always reg 31.
20982 Only emit this if the alloca bit was set above. */
20983 if (frame_pointer_needed)
20984 fputs ("\t.byte 31\n", file);
20986 fputs ("\t.align 2\n", file);
20990 /* A C compound statement that outputs the assembler code for a thunk
20991 function, used to implement C++ virtual function calls with
20992 multiple inheritance. The thunk acts as a wrapper around a virtual
20993 function, adjusting the implicit object parameter before handing
20994 control off to the real function.
20996 First, emit code to add the integer DELTA to the location that
20997 contains the incoming first argument. Assume that this argument
20998 contains a pointer, and is the one used to pass the `this' pointer
20999 in C++. This is the incoming argument *before* the function
21000 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21001 values of all other incoming arguments.
21003 After the addition, emit code to jump to FUNCTION, which is a
21004 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21005 not touch the return address. Hence returning from FUNCTION will
21006 return to whoever called the current `thunk'.
21008 The effect must be as if FUNCTION had been called directly with the
21009 adjusted first argument. This macro is responsible for emitting
21010 all of the code for a thunk function; output_function_prologue()
21011 and output_function_epilogue() are not invoked.
21013 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21014 been extracted from it.) It might possibly be useful on some
21015 targets, but probably not.
21017 If you do not define this macro, the target-independent code in the
21018 C++ frontend will generate a less efficient heavyweight thunk that
21019 calls FUNCTION instead of jumping to it. The generic approach does
21020 not support varargs. */
21023 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21024 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21027 rtx this_rtx, insn, funexp;
21029 reload_completed = 1;
21030 epilogue_completed = 1;
21032 /* Mark the end of the (empty) prologue. */
21033 emit_note (NOTE_INSN_PROLOGUE_END);
21035 /* Find the "this" pointer. If the function returns a structure,
21036 the structure return pointer is in r3. */
21037 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21038 this_rtx = gen_rtx_REG (Pmode, 4);
21040 this_rtx = gen_rtx_REG (Pmode, 3);
21042 /* Apply the constant offset, if required. */
21044 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21046 /* Apply the offset from the vtable, if required. */
21049 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21050 rtx tmp = gen_rtx_REG (Pmode, 12);
21052 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21053 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21055 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21056 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21060 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21062 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21064 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21067 /* Generate a tail call to the target function. */
21068 if (!TREE_USED (function))
21070 assemble_external (function);
21071 TREE_USED (function) = 1;
21073 funexp = XEXP (DECL_RTL (function), 0);
21074 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21077 if (MACHOPIC_INDIRECT)
21078 funexp = machopic_indirect_call_target (funexp);
21081 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21082 generate sibcall RTL explicitly. */
21083 insn = emit_call_insn (
21084 gen_rtx_PARALLEL (VOIDmode,
21086 gen_rtx_CALL (VOIDmode,
21087 funexp, const0_rtx),
21088 gen_rtx_USE (VOIDmode, const0_rtx),
21089 gen_rtx_USE (VOIDmode,
21090 gen_rtx_REG (SImode,
21092 gen_rtx_RETURN (VOIDmode))));
21093 SIBLING_CALL_P (insn) = 1;
21096 /* Run just enough of rest_of_compilation to get the insns emitted.
21097 There's not really enough bulk here to make other passes such as
21098 instruction scheduling worth while. Note that use_thunk calls
21099 assemble_start_function and assemble_end_function. */
21100 insn = get_insns ();
21101 insn_locators_alloc ();
21102 shorten_branches (insn);
21103 final_start_function (insn, file, 1);
21104 final (insn, file, 1);
21105 final_end_function ();
21107 reload_completed = 0;
21108 epilogue_completed = 0;
21111 /* A quick summary of the various types of 'constant-pool tables'
21114 Target Flags Name One table per
21115 AIX (none) AIX TOC object file
21116 AIX -mfull-toc AIX TOC object file
21117 AIX -mminimal-toc AIX minimal TOC translation unit
21118 SVR4/EABI (none) SVR4 SDATA object file
21119 SVR4/EABI -fpic SVR4 pic object file
21120 SVR4/EABI -fPIC SVR4 PIC translation unit
21121 SVR4/EABI -mrelocatable EABI TOC function
21122 SVR4/EABI -maix AIX TOC object file
21123 SVR4/EABI -maix -mminimal-toc
21124 AIX minimal TOC translation unit
21126 Name Reg. Set by entries contains:
21127 made by addrs? fp? sum?
21129 AIX TOC 2 crt0 as Y option option
21130 AIX minimal TOC 30 prolog gcc Y Y option
21131 SVR4 SDATA 13 crt0 gcc N Y N
21132 SVR4 pic 30 prolog ld Y not yet N
21133 SVR4 PIC 30 prolog gcc Y option option
21134 EABI TOC 30 prolog gcc Y option option
21138 /* Hash functions for the hash table. */
21141 rs6000_hash_constant (rtx k)
21143 enum rtx_code code = GET_CODE (k);
21144 enum machine_mode mode = GET_MODE (k);
21145 unsigned result = (code << 3) ^ mode;
21146 const char *format;
21149 format = GET_RTX_FORMAT (code);
21150 flen = strlen (format);
21156 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21159 if (mode != VOIDmode)
21160 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21172 for (; fidx < flen; fidx++)
21173 switch (format[fidx])
21178 const char *str = XSTR (k, fidx);
21179 len = strlen (str);
21180 result = result * 613 + len;
21181 for (i = 0; i < len; i++)
21182 result = result * 613 + (unsigned) str[i];
21187 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21191 result = result * 613 + (unsigned) XINT (k, fidx);
21194 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21195 result = result * 613 + (unsigned) XWINT (k, fidx);
21199 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21200 result = result * 613 + (unsigned) (XWINT (k, fidx)
21207 gcc_unreachable ();
21214 toc_hash_function (const void *hash_entry)
21216 const struct toc_hash_struct *thc =
21217 (const struct toc_hash_struct *) hash_entry;
21218 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21221 /* Compare H1 and H2 for equivalence. */
21224 toc_hash_eq (const void *h1, const void *h2)
21226 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21227 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21229 if (((const struct toc_hash_struct *) h1)->key_mode
21230 != ((const struct toc_hash_struct *) h2)->key_mode)
21233 return rtx_equal_p (r1, r2);
21236 /* These are the names given by the C++ front-end to vtables, and
21237 vtable-like objects. Ideally, this logic should not be here;
21238 instead, there should be some programmatic way of inquiring as
21239 to whether or not an object is a vtable. */
21241 #define VTABLE_NAME_P(NAME) \
21242 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21243 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21244 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21245 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21246 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21248 #ifdef NO_DOLLAR_IN_LABEL
21249 /* Return a GGC-allocated character string translating dollar signs in
21250 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21253 rs6000_xcoff_strip_dollar (const char *name)
21258 p = strchr (name, '$');
21260 if (p == 0 || p == name)
21263 len = strlen (name);
21264 strip = (char *) alloca (len + 1);
21265 strcpy (strip, name);
21266 p = strchr (strip, '$');
21270 p = strchr (p + 1, '$');
21273 return ggc_alloc_string (strip, len);
21278 rs6000_output_symbol_ref (FILE *file, rtx x)
21280 /* Currently C++ toc references to vtables can be emitted before it
21281 is decided whether the vtable is public or private. If this is
21282 the case, then the linker will eventually complain that there is
21283 a reference to an unknown section. Thus, for vtables only,
21284 we emit the TOC reference to reference the symbol and not the
21286 const char *name = XSTR (x, 0);
21288 if (VTABLE_NAME_P (name))
21290 RS6000_OUTPUT_BASENAME (file, name);
21293 assemble_name (file, name);
21296 /* Output a TOC entry. We derive the entry name from what is being
21300 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
21303 const char *name = buf;
21305 HOST_WIDE_INT offset = 0;
21307 gcc_assert (!TARGET_NO_TOC);
21309 /* When the linker won't eliminate them, don't output duplicate
21310 TOC entries (this happens on AIX if there is any kind of TOC,
21311 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
21313 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
21315 struct toc_hash_struct *h;
21318 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
21319 time because GGC is not initialized at that point. */
21320 if (toc_hash_table == NULL)
21321 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
21322 toc_hash_eq, NULL);
21324 h = ggc_alloc_toc_hash_struct ();
21326 h->key_mode = mode;
21327 h->labelno = labelno;
21329 found = htab_find_slot (toc_hash_table, h, INSERT);
21330 if (*found == NULL)
21332 else /* This is indeed a duplicate.
21333 Set this label equal to that label. */
21335 fputs ("\t.set ", file);
21336 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21337 fprintf (file, "%d,", labelno);
21338 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21339 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
21345 /* If we're going to put a double constant in the TOC, make sure it's
21346 aligned properly when strict alignment is on. */
21347 if (GET_CODE (x) == CONST_DOUBLE
21348 && STRICT_ALIGNMENT
21349 && GET_MODE_BITSIZE (mode) >= 64
21350 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
21351 ASM_OUTPUT_ALIGN (file, 3);
21354 (*targetm.asm_out.internal_label) (file, "LC", labelno);
21356 /* Handle FP constants specially. Note that if we have a minimal
21357 TOC, things we put here aren't actually in the TOC, so we can allow
21359 if (GET_CODE (x) == CONST_DOUBLE &&
21360 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
21362 REAL_VALUE_TYPE rv;
21365 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21366 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21367 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
21369 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
21373 if (TARGET_MINIMAL_TOC)
21374 fputs (DOUBLE_INT_ASM_OP, file);
21376 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
21377 k[0] & 0xffffffff, k[1] & 0xffffffff,
21378 k[2] & 0xffffffff, k[3] & 0xffffffff);
21379 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
21380 k[0] & 0xffffffff, k[1] & 0xffffffff,
21381 k[2] & 0xffffffff, k[3] & 0xffffffff);
21386 if (TARGET_MINIMAL_TOC)
21387 fputs ("\t.long ", file);
21389 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
21390 k[0] & 0xffffffff, k[1] & 0xffffffff,
21391 k[2] & 0xffffffff, k[3] & 0xffffffff);
21392 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
21393 k[0] & 0xffffffff, k[1] & 0xffffffff,
21394 k[2] & 0xffffffff, k[3] & 0xffffffff);
21398 else if (GET_CODE (x) == CONST_DOUBLE &&
21399 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
21401 REAL_VALUE_TYPE rv;
21404 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21406 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21407 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
21409 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
21413 if (TARGET_MINIMAL_TOC)
21414 fputs (DOUBLE_INT_ASM_OP, file);
21416 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
21417 k[0] & 0xffffffff, k[1] & 0xffffffff);
21418 fprintf (file, "0x%lx%08lx\n",
21419 k[0] & 0xffffffff, k[1] & 0xffffffff);
21424 if (TARGET_MINIMAL_TOC)
21425 fputs ("\t.long ", file);
21427 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
21428 k[0] & 0xffffffff, k[1] & 0xffffffff);
21429 fprintf (file, "0x%lx,0x%lx\n",
21430 k[0] & 0xffffffff, k[1] & 0xffffffff);
21434 else if (GET_CODE (x) == CONST_DOUBLE &&
21435 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
21437 REAL_VALUE_TYPE rv;
21440 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21441 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21442 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
21444 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
21448 if (TARGET_MINIMAL_TOC)
21449 fputs (DOUBLE_INT_ASM_OP, file);
21451 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
21452 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
21457 if (TARGET_MINIMAL_TOC)
21458 fputs ("\t.long ", file);
21460 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
21461 fprintf (file, "0x%lx\n", l & 0xffffffff);
21465 else if (GET_MODE (x) == VOIDmode
21466 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
21468 unsigned HOST_WIDE_INT low;
21469 HOST_WIDE_INT high;
21471 if (GET_CODE (x) == CONST_DOUBLE)
21473 low = CONST_DOUBLE_LOW (x);
21474 high = CONST_DOUBLE_HIGH (x);
21477 #if HOST_BITS_PER_WIDE_INT == 32
21480 high = (low & 0x80000000) ? ~0 : 0;
21484 low = INTVAL (x) & 0xffffffff;
21485 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
21489 /* TOC entries are always Pmode-sized, but since this
21490 is a bigendian machine then if we're putting smaller
21491 integer constants in the TOC we have to pad them.
21492 (This is still a win over putting the constants in
21493 a separate constant pool, because then we'd have
21494 to have both a TOC entry _and_ the actual constant.)
21496 For a 32-bit target, CONST_INT values are loaded and shifted
21497 entirely within `low' and can be stored in one TOC entry. */
21499 /* It would be easy to make this work, but it doesn't now. */
21500 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
21502 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
21504 #if HOST_BITS_PER_WIDE_INT == 32
21505 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
21506 POINTER_SIZE, &low, &high, 0);
21509 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
21510 high = (HOST_WIDE_INT) low >> 32;
21517 if (TARGET_MINIMAL_TOC)
21518 fputs (DOUBLE_INT_ASM_OP, file);
21520 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21521 (long) high & 0xffffffff, (long) low & 0xffffffff);
21522 fprintf (file, "0x%lx%08lx\n",
21523 (long) high & 0xffffffff, (long) low & 0xffffffff);
21528 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
21530 if (TARGET_MINIMAL_TOC)
21531 fputs ("\t.long ", file);
21533 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21534 (long) high & 0xffffffff, (long) low & 0xffffffff);
21535 fprintf (file, "0x%lx,0x%lx\n",
21536 (long) high & 0xffffffff, (long) low & 0xffffffff);
21540 if (TARGET_MINIMAL_TOC)
21541 fputs ("\t.long ", file);
21543 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
21544 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
21550 if (GET_CODE (x) == CONST)
21552 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
21553 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
21555 base = XEXP (XEXP (x, 0), 0);
21556 offset = INTVAL (XEXP (XEXP (x, 0), 1));
21559 switch (GET_CODE (base))
21562 name = XSTR (base, 0);
21566 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
21567 CODE_LABEL_NUMBER (XEXP (base, 0)));
21571 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
21575 gcc_unreachable ();
21578 if (TARGET_MINIMAL_TOC)
21579 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
21582 fputs ("\t.tc ", file);
21583 RS6000_OUTPUT_BASENAME (file, name);
21586 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
21588 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
21590 fputs ("[TC],", file);
21593 /* Currently C++ toc references to vtables can be emitted before it
21594 is decided whether the vtable is public or private. If this is
21595 the case, then the linker will eventually complain that there is
21596 a TOC reference to an unknown section. Thus, for vtables only,
21597 we emit the TOC reference to reference the symbol and not the
21599 if (VTABLE_NAME_P (name))
21601 RS6000_OUTPUT_BASENAME (file, name);
21603 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
21604 else if (offset > 0)
21605 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
21608 output_addr_const (file, x);
21612 /* Output an assembler pseudo-op to write an ASCII string of N characters
21613 starting at P to FILE.
21615 On the RS/6000, we have to do this using the .byte operation and
21616 write out special characters outside the quoted string.
21617 Also, the assembler is broken; very long strings are truncated,
21618 so we must artificially break them up early. */
21621 output_ascii (FILE *file, const char *p, int n)
21624 int i, count_string;
21625 const char *for_string = "\t.byte \"";
21626 const char *for_decimal = "\t.byte ";
21627 const char *to_close = NULL;
21630 for (i = 0; i < n; i++)
21633 if (c >= ' ' && c < 0177)
21636 fputs (for_string, file);
21639 /* Write two quotes to get one. */
21647 for_decimal = "\"\n\t.byte ";
21651 if (count_string >= 512)
21653 fputs (to_close, file);
21655 for_string = "\t.byte \"";
21656 for_decimal = "\t.byte ";
21664 fputs (for_decimal, file);
21665 fprintf (file, "%d", c);
21667 for_string = "\n\t.byte \"";
21668 for_decimal = ", ";
21674 /* Now close the string if we have written one. Then end the line. */
21676 fputs (to_close, file);
21679 /* Generate a unique section name for FILENAME for a section type
21680 represented by SECTION_DESC. Output goes into BUF.
21682 SECTION_DESC can be any string, as long as it is different for each
21683 possible section type.
21685 We name the section in the same manner as xlc. The name begins with an
21686 underscore followed by the filename (after stripping any leading directory
21687 names) with the last period replaced by the string SECTION_DESC. If
21688 FILENAME does not contain a period, SECTION_DESC is appended to the end of
21692 rs6000_gen_section_name (char **buf, const char *filename,
21693 const char *section_desc)
21695 const char *q, *after_last_slash, *last_period = 0;
21699 after_last_slash = filename;
21700 for (q = filename; *q; q++)
21703 after_last_slash = q + 1;
21704 else if (*q == '.')
21708 len = strlen (after_last_slash) + strlen (section_desc) + 2;
21709 *buf = (char *) xmalloc (len);
21714 for (q = after_last_slash; *q; q++)
21716 if (q == last_period)
21718 strcpy (p, section_desc);
21719 p += strlen (section_desc);
21723 else if (ISALNUM (*q))
21727 if (last_period == 0)
21728 strcpy (p, section_desc);
21733 /* Emit profile function. */
21736 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
21738 /* Non-standard profiling for kernels, which just saves LR then calls
21739 _mcount without worrying about arg saves. The idea is to change
21740 the function prologue as little as possible as it isn't easy to
21741 account for arg save/restore code added just for _mcount. */
21742 if (TARGET_PROFILE_KERNEL)
21745 if (DEFAULT_ABI == ABI_AIX)
21747 #ifndef NO_PROFILE_COUNTERS
21748 # define NO_PROFILE_COUNTERS 0
21750 if (NO_PROFILE_COUNTERS)
21751 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21752 LCT_NORMAL, VOIDmode, 0);
21756 const char *label_name;
21759 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21760 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21761 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21763 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21764 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21767 else if (DEFAULT_ABI == ABI_DARWIN)
21769 const char *mcount_name = RS6000_MCOUNT;
21770 int caller_addr_regno = LR_REGNO;
21772 /* Be conservative and always set this, at least for now. */
21773 crtl->uses_pic_offset_table = 1;
21776 /* For PIC code, set up a stub and collect the caller's address
21777 from r0, which is where the prologue puts it. */
21778 if (MACHOPIC_INDIRECT
21779 && crtl->uses_pic_offset_table)
21780 caller_addr_regno = 0;
21782 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21783 LCT_NORMAL, VOIDmode, 1,
21784 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21788 /* Write function profiler code. */
21791 output_function_profiler (FILE *file, int labelno)
21795 switch (DEFAULT_ABI)
21798 gcc_unreachable ();
21803 warning (0, "no profiling of 64-bit code for this ABI");
21806 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21807 fprintf (file, "\tmflr %s\n", reg_names[0]);
21808 if (NO_PROFILE_COUNTERS)
21810 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21811 reg_names[0], reg_names[1]);
21813 else if (TARGET_SECURE_PLT && flag_pic)
21815 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21816 reg_names[0], reg_names[1]);
21817 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21818 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21819 reg_names[12], reg_names[12]);
21820 assemble_name (file, buf);
21821 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21822 assemble_name (file, buf);
21823 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21825 else if (flag_pic == 1)
21827 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21828 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21829 reg_names[0], reg_names[1]);
21830 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21831 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
21832 assemble_name (file, buf);
21833 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
21835 else if (flag_pic > 1)
21837 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21838 reg_names[0], reg_names[1]);
21839 /* Now, we need to get the address of the label. */
21840 fputs ("\tbcl 20,31,1f\n\t.long ", file);
21841 assemble_name (file, buf);
21842 fputs ("-.\n1:", file);
21843 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
21844 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
21845 reg_names[0], reg_names[11]);
21846 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
21847 reg_names[0], reg_names[0], reg_names[11]);
21851 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
21852 assemble_name (file, buf);
21853 fputs ("@ha\n", file);
21854 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21855 reg_names[0], reg_names[1]);
21856 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
21857 assemble_name (file, buf);
21858 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
21861 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21862 fprintf (file, "\tbl %s%s\n",
21863 RS6000_MCOUNT, flag_pic ? "@plt" : "");
21868 if (!TARGET_PROFILE_KERNEL)
21870 /* Don't do anything, done in output_profile_hook (). */
21874 gcc_assert (!TARGET_32BIT);
21876 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
21877 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
21879 if (cfun->static_chain_decl != NULL)
21881 asm_fprintf (file, "\tstd %s,24(%s)\n",
21882 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21883 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21884 asm_fprintf (file, "\tld %s,24(%s)\n",
21885 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21888 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21896 /* The following variable value is the last issued insn. */
21898 static rtx last_scheduled_insn;
21900 /* The following variable helps to balance issuing of load and
21901 store instructions */
21903 static int load_store_pendulum;
21905 /* Power4 load update and store update instructions are cracked into a
21906 load or store and an integer insn which are executed in the same cycle.
21907 Branches have their own dispatch slot which does not count against the
21908 GCC issue rate, but it changes the program flow so there are no other
21909 instructions to issue in this cycle. */
21912 rs6000_variable_issue_1 (rtx insn, int more)
21914 last_scheduled_insn = insn;
21915 if (GET_CODE (PATTERN (insn)) == USE
21916 || GET_CODE (PATTERN (insn)) == CLOBBER)
21918 cached_can_issue_more = more;
21919 return cached_can_issue_more;
21922 if (insn_terminates_group_p (insn, current_group))
21924 cached_can_issue_more = 0;
21925 return cached_can_issue_more;
21928 /* If no reservation, but reach here */
21929 if (recog_memoized (insn) < 0)
21932 if (rs6000_sched_groups)
21934 if (is_microcoded_insn (insn))
21935 cached_can_issue_more = 0;
21936 else if (is_cracked_insn (insn))
21937 cached_can_issue_more = more > 2 ? more - 2 : 0;
21939 cached_can_issue_more = more - 1;
21941 return cached_can_issue_more;
21944 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21947 cached_can_issue_more = more - 1;
21948 return cached_can_issue_more;
21952 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
21954 int r = rs6000_variable_issue_1 (insn, more);
21956 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
21960 /* Adjust the cost of a scheduling dependency. Return the new cost of
21961 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21964 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21966 enum attr_type attr_type;
21968 if (! recog_memoized (insn))
21971 switch (REG_NOTE_KIND (link))
21975 /* Data dependency; DEP_INSN writes a register that INSN reads
21976 some cycles later. */
21978 /* Separate a load from a narrower, dependent store. */
21979 if (rs6000_sched_groups
21980 && GET_CODE (PATTERN (insn)) == SET
21981 && GET_CODE (PATTERN (dep_insn)) == SET
21982 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21983 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21984 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21985 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21988 attr_type = get_attr_type (insn);
21993 /* Tell the first scheduling pass about the latency between
21994 a mtctr and bctr (and mtlr and br/blr). The first
21995 scheduling pass will not know about this latency since
21996 the mtctr instruction, which has the latency associated
21997 to it, will be generated by reload. */
21998 return TARGET_POWER ? 5 : 4;
22000 /* Leave some extra cycles between a compare and its
22001 dependent branch, to inhibit expensive mispredicts. */
22002 if ((rs6000_cpu_attr == CPU_PPC603
22003 || rs6000_cpu_attr == CPU_PPC604
22004 || rs6000_cpu_attr == CPU_PPC604E
22005 || rs6000_cpu_attr == CPU_PPC620
22006 || rs6000_cpu_attr == CPU_PPC630
22007 || rs6000_cpu_attr == CPU_PPC750
22008 || rs6000_cpu_attr == CPU_PPC7400
22009 || rs6000_cpu_attr == CPU_PPC7450
22010 || rs6000_cpu_attr == CPU_POWER4
22011 || rs6000_cpu_attr == CPU_POWER5
22012 || rs6000_cpu_attr == CPU_POWER7
22013 || rs6000_cpu_attr == CPU_CELL)
22014 && recog_memoized (dep_insn)
22015 && (INSN_CODE (dep_insn) >= 0))
22017 switch (get_attr_type (dep_insn))
22021 case TYPE_DELAYED_COMPARE:
22022 case TYPE_IMUL_COMPARE:
22023 case TYPE_LMUL_COMPARE:
22024 case TYPE_FPCOMPARE:
22025 case TYPE_CR_LOGICAL:
22026 case TYPE_DELAYED_CR:
22035 case TYPE_STORE_UX:
22037 case TYPE_FPSTORE_U:
22038 case TYPE_FPSTORE_UX:
22039 if ((rs6000_cpu == PROCESSOR_POWER6)
22040 && recog_memoized (dep_insn)
22041 && (INSN_CODE (dep_insn) >= 0))
22044 if (GET_CODE (PATTERN (insn)) != SET)
22045 /* If this happens, we have to extend this to schedule
22046 optimally. Return default for now. */
22049 /* Adjust the cost for the case where the value written
22050 by a fixed point operation is used as the address
22051 gen value on a store. */
22052 switch (get_attr_type (dep_insn))
22059 if (! store_data_bypass_p (dep_insn, insn))
22063 case TYPE_LOAD_EXT:
22064 case TYPE_LOAD_EXT_U:
22065 case TYPE_LOAD_EXT_UX:
22066 case TYPE_VAR_SHIFT_ROTATE:
22067 case TYPE_VAR_DELAYED_COMPARE:
22069 if (! store_data_bypass_p (dep_insn, insn))
22075 case TYPE_FAST_COMPARE:
22078 case TYPE_INSERT_WORD:
22079 case TYPE_INSERT_DWORD:
22080 case TYPE_FPLOAD_U:
22081 case TYPE_FPLOAD_UX:
22083 case TYPE_STORE_UX:
22084 case TYPE_FPSTORE_U:
22085 case TYPE_FPSTORE_UX:
22087 if (! store_data_bypass_p (dep_insn, insn))
22095 case TYPE_IMUL_COMPARE:
22096 case TYPE_LMUL_COMPARE:
22098 if (! store_data_bypass_p (dep_insn, insn))
22104 if (! store_data_bypass_p (dep_insn, insn))
22110 if (! store_data_bypass_p (dep_insn, insn))
22123 case TYPE_LOAD_EXT:
22124 case TYPE_LOAD_EXT_U:
22125 case TYPE_LOAD_EXT_UX:
22126 if ((rs6000_cpu == PROCESSOR_POWER6)
22127 && recog_memoized (dep_insn)
22128 && (INSN_CODE (dep_insn) >= 0))
22131 /* Adjust the cost for the case where the value written
22132 by a fixed point instruction is used within the address
22133 gen portion of a subsequent load(u)(x) */
22134 switch (get_attr_type (dep_insn))
22141 if (set_to_load_agen (dep_insn, insn))
22145 case TYPE_LOAD_EXT:
22146 case TYPE_LOAD_EXT_U:
22147 case TYPE_LOAD_EXT_UX:
22148 case TYPE_VAR_SHIFT_ROTATE:
22149 case TYPE_VAR_DELAYED_COMPARE:
22151 if (set_to_load_agen (dep_insn, insn))
22157 case TYPE_FAST_COMPARE:
22160 case TYPE_INSERT_WORD:
22161 case TYPE_INSERT_DWORD:
22162 case TYPE_FPLOAD_U:
22163 case TYPE_FPLOAD_UX:
22165 case TYPE_STORE_UX:
22166 case TYPE_FPSTORE_U:
22167 case TYPE_FPSTORE_UX:
22169 if (set_to_load_agen (dep_insn, insn))
22177 case TYPE_IMUL_COMPARE:
22178 case TYPE_LMUL_COMPARE:
22180 if (set_to_load_agen (dep_insn, insn))
22186 if (set_to_load_agen (dep_insn, insn))
22192 if (set_to_load_agen (dep_insn, insn))
22203 if ((rs6000_cpu == PROCESSOR_POWER6)
22204 && recog_memoized (dep_insn)
22205 && (INSN_CODE (dep_insn) >= 0)
22206 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22213 /* Fall out to return default cost. */
22217 case REG_DEP_OUTPUT:
22218 /* Output dependency; DEP_INSN writes a register that INSN writes some
22220 if ((rs6000_cpu == PROCESSOR_POWER6)
22221 && recog_memoized (dep_insn)
22222 && (INSN_CODE (dep_insn) >= 0))
22224 attr_type = get_attr_type (insn);
22229 if (get_attr_type (dep_insn) == TYPE_FP)
22233 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22241 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22246 gcc_unreachable ();
22252 /* Debug version of rs6000_adjust_cost. */
22255 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22257 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
22263 switch (REG_NOTE_KIND (link))
22265 default: dep = "unknown depencency"; break;
22266 case REG_DEP_TRUE: dep = "data dependency"; break;
22267 case REG_DEP_OUTPUT: dep = "output dependency"; break;
22268 case REG_DEP_ANTI: dep = "anti depencency"; break;
22272 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22273 "%s, insn:\n", ret, cost, dep);
22281 /* The function returns a true if INSN is microcoded.
22282 Return false otherwise. */
22285 is_microcoded_insn (rtx insn)
22287 if (!insn || !NONDEBUG_INSN_P (insn)
22288 || GET_CODE (PATTERN (insn)) == USE
22289 || GET_CODE (PATTERN (insn)) == CLOBBER)
22292 if (rs6000_cpu_attr == CPU_CELL)
22293 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
22295 if (rs6000_sched_groups)
22297 enum attr_type type = get_attr_type (insn);
22298 if (type == TYPE_LOAD_EXT_U
22299 || type == TYPE_LOAD_EXT_UX
22300 || type == TYPE_LOAD_UX
22301 || type == TYPE_STORE_UX
22302 || type == TYPE_MFCR)
22309 /* The function returns true if INSN is cracked into 2 instructions
22310 by the processor (and therefore occupies 2 issue slots). */
22313 is_cracked_insn (rtx insn)
22315 if (!insn || !NONDEBUG_INSN_P (insn)
22316 || GET_CODE (PATTERN (insn)) == USE
22317 || GET_CODE (PATTERN (insn)) == CLOBBER)
22320 if (rs6000_sched_groups)
22322 enum attr_type type = get_attr_type (insn);
22323 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
22324 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
22325 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
22326 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
22327 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
22328 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
22329 || type == TYPE_IDIV || type == TYPE_LDIV
22330 || type == TYPE_INSERT_WORD)
22337 /* The function returns true if INSN can be issued only from
22338 the branch slot. */
22341 is_branch_slot_insn (rtx insn)
22343 if (!insn || !NONDEBUG_INSN_P (insn)
22344 || GET_CODE (PATTERN (insn)) == USE
22345 || GET_CODE (PATTERN (insn)) == CLOBBER)
22348 if (rs6000_sched_groups)
22350 enum attr_type type = get_attr_type (insn);
22351 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
22359 /* The function returns true if out_inst sets a value that is
22360 used in the address generation computation of in_insn */
22362 set_to_load_agen (rtx out_insn, rtx in_insn)
22364 rtx out_set, in_set;
22366 /* For performance reasons, only handle the simple case where
22367 both loads are a single_set. */
22368 out_set = single_set (out_insn);
22371 in_set = single_set (in_insn);
22373 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
22379 /* The function returns true if the target storage location of
22380 out_insn is adjacent to the target storage location of in_insn */
22381 /* Return 1 if memory locations are adjacent. */
22384 adjacent_mem_locations (rtx insn1, rtx insn2)
22387 rtx a = get_store_dest (PATTERN (insn1));
22388 rtx b = get_store_dest (PATTERN (insn2));
22390 if ((GET_CODE (XEXP (a, 0)) == REG
22391 || (GET_CODE (XEXP (a, 0)) == PLUS
22392 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
22393 && (GET_CODE (XEXP (b, 0)) == REG
22394 || (GET_CODE (XEXP (b, 0)) == PLUS
22395 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
22397 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
22400 if (GET_CODE (XEXP (a, 0)) == PLUS)
22402 reg0 = XEXP (XEXP (a, 0), 0);
22403 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
22406 reg0 = XEXP (a, 0);
22408 if (GET_CODE (XEXP (b, 0)) == PLUS)
22410 reg1 = XEXP (XEXP (b, 0), 0);
22411 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
22414 reg1 = XEXP (b, 0);
22416 val_diff = val1 - val0;
22418 return ((REGNO (reg0) == REGNO (reg1))
22419 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
22420 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
22426 /* A C statement (sans semicolon) to update the integer scheduling
22427 priority INSN_PRIORITY (INSN). Increase the priority to execute the
22428 INSN earlier, reduce the priority to execute INSN later. Do not
22429 define this macro if you do not need to adjust the scheduling
22430 priorities of insns. */
22433 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
22435 /* On machines (like the 750) which have asymmetric integer units,
22436 where one integer unit can do multiply and divides and the other
22437 can't, reduce the priority of multiply/divide so it is scheduled
22438 before other integer operations. */
22441 if (! INSN_P (insn))
22444 if (GET_CODE (PATTERN (insn)) == USE)
22447 switch (rs6000_cpu_attr) {
22449 switch (get_attr_type (insn))
22456 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
22457 priority, priority);
22458 if (priority >= 0 && priority < 0x01000000)
22465 if (insn_must_be_first_in_group (insn)
22466 && reload_completed
22467 && current_sched_info->sched_max_insns_priority
22468 && rs6000_sched_restricted_insns_priority)
22471 /* Prioritize insns that can be dispatched only in the first
22473 if (rs6000_sched_restricted_insns_priority == 1)
22474 /* Attach highest priority to insn. This means that in
22475 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
22476 precede 'priority' (critical path) considerations. */
22477 return current_sched_info->sched_max_insns_priority;
22478 else if (rs6000_sched_restricted_insns_priority == 2)
22479 /* Increase priority of insn by a minimal amount. This means that in
22480 haifa-sched.c:ready_sort(), only 'priority' (critical path)
22481 considerations precede dispatch-slot restriction considerations. */
22482 return (priority + 1);
22485 if (rs6000_cpu == PROCESSOR_POWER6
22486 && ((load_store_pendulum == -2 && is_load_insn (insn))
22487 || (load_store_pendulum == 2 && is_store_insn (insn))))
22488 /* Attach highest priority to insn if the scheduler has just issued two
22489 stores and this instruction is a load, or two loads and this instruction
22490 is a store. Power6 wants loads and stores scheduled alternately
22492 return current_sched_info->sched_max_insns_priority;
22497 /* Return true if the instruction is nonpipelined on the Cell. */
22499 is_nonpipeline_insn (rtx insn)
22501 enum attr_type type;
22502 if (!insn || !NONDEBUG_INSN_P (insn)
22503 || GET_CODE (PATTERN (insn)) == USE
22504 || GET_CODE (PATTERN (insn)) == CLOBBER)
22507 type = get_attr_type (insn);
22508 if (type == TYPE_IMUL
22509 || type == TYPE_IMUL2
22510 || type == TYPE_IMUL3
22511 || type == TYPE_LMUL
22512 || type == TYPE_IDIV
22513 || type == TYPE_LDIV
22514 || type == TYPE_SDIV
22515 || type == TYPE_DDIV
22516 || type == TYPE_SSQRT
22517 || type == TYPE_DSQRT
22518 || type == TYPE_MFCR
22519 || type == TYPE_MFCRF
22520 || type == TYPE_MFJMPR)
22528 /* Return how many instructions the machine can issue per cycle. */
22531 rs6000_issue_rate (void)
22533 /* Unless scheduling for register pressure, use issue rate of 1 for
22534 first scheduling pass to decrease degradation. */
22535 if (!reload_completed && !flag_sched_pressure)
22538 switch (rs6000_cpu_attr) {
22539 case CPU_RIOS1: /* ? */
22541 case CPU_PPC601: /* ? */
22550 case CPU_PPCE300C2:
22551 case CPU_PPCE300C3:
22552 case CPU_PPCE500MC:
22553 case CPU_PPCE500MC64:
22572 /* Return how many instructions to look ahead for better insn
22576 rs6000_use_sched_lookahead (void)
22578 if (rs6000_cpu_attr == CPU_PPC8540)
22580 if (rs6000_cpu_attr == CPU_CELL)
22581 return (reload_completed ? 8 : 0);
22585 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
22587 rs6000_use_sched_lookahead_guard (rtx insn)
22589 if (rs6000_cpu_attr != CPU_CELL)
22592 if (insn == NULL_RTX || !INSN_P (insn))
22595 if (!reload_completed
22596 || is_nonpipeline_insn (insn)
22597 || is_microcoded_insn (insn))
22603 /* Determine is PAT refers to memory. */
22606 is_mem_ref (rtx pat)
22612 /* stack_tie does not produce any real memory traffic. */
22613 if (GET_CODE (pat) == UNSPEC
22614 && XINT (pat, 1) == UNSPEC_TIE)
22617 if (GET_CODE (pat) == MEM)
22620 /* Recursively process the pattern. */
22621 fmt = GET_RTX_FORMAT (GET_CODE (pat));
22623 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
22626 ret |= is_mem_ref (XEXP (pat, i));
22627 else if (fmt[i] == 'E')
22628 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
22629 ret |= is_mem_ref (XVECEXP (pat, i, j));
22635 /* Determine if PAT is a PATTERN of a load insn. */
22638 is_load_insn1 (rtx pat)
22640 if (!pat || pat == NULL_RTX)
22643 if (GET_CODE (pat) == SET)
22644 return is_mem_ref (SET_SRC (pat));
22646 if (GET_CODE (pat) == PARALLEL)
22650 for (i = 0; i < XVECLEN (pat, 0); i++)
22651 if (is_load_insn1 (XVECEXP (pat, 0, i)))
22658 /* Determine if INSN loads from memory. */
22661 is_load_insn (rtx insn)
22663 if (!insn || !INSN_P (insn))
22666 if (GET_CODE (insn) == CALL_INSN)
22669 return is_load_insn1 (PATTERN (insn));
22672 /* Determine if PAT is a PATTERN of a store insn. */
22675 is_store_insn1 (rtx pat)
22677 if (!pat || pat == NULL_RTX)
22680 if (GET_CODE (pat) == SET)
22681 return is_mem_ref (SET_DEST (pat));
22683 if (GET_CODE (pat) == PARALLEL)
22687 for (i = 0; i < XVECLEN (pat, 0); i++)
22688 if (is_store_insn1 (XVECEXP (pat, 0, i)))
22695 /* Determine if INSN stores to memory. */
22698 is_store_insn (rtx insn)
22700 if (!insn || !INSN_P (insn))
22703 return is_store_insn1 (PATTERN (insn));
22706 /* Return the dest of a store insn. */
22709 get_store_dest (rtx pat)
22711 gcc_assert (is_store_insn1 (pat));
22713 if (GET_CODE (pat) == SET)
22714 return SET_DEST (pat);
22715 else if (GET_CODE (pat) == PARALLEL)
22719 for (i = 0; i < XVECLEN (pat, 0); i++)
22721 rtx inner_pat = XVECEXP (pat, 0, i);
22722 if (GET_CODE (inner_pat) == SET
22723 && is_mem_ref (SET_DEST (inner_pat)))
22727 /* We shouldn't get here, because we should have either a simple
22728 store insn or a store with update which are covered above. */
22732 /* Returns whether the dependence between INSN and NEXT is considered
22733 costly by the given target. */
22736 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
22741 /* If the flag is not enabled - no dependence is considered costly;
22742 allow all dependent insns in the same group.
22743 This is the most aggressive option. */
22744 if (rs6000_sched_costly_dep == no_dep_costly)
22747 /* If the flag is set to 1 - a dependence is always considered costly;
22748 do not allow dependent instructions in the same group.
22749 This is the most conservative option. */
22750 if (rs6000_sched_costly_dep == all_deps_costly)
22753 insn = DEP_PRO (dep);
22754 next = DEP_CON (dep);
22756 if (rs6000_sched_costly_dep == store_to_load_dep_costly
22757 && is_load_insn (next)
22758 && is_store_insn (insn))
22759 /* Prevent load after store in the same group. */
22762 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
22763 && is_load_insn (next)
22764 && is_store_insn (insn)
22765 && DEP_TYPE (dep) == REG_DEP_TRUE)
22766 /* Prevent load after store in the same group if it is a true
22770 /* The flag is set to X; dependences with latency >= X are considered costly,
22771 and will not be scheduled in the same group. */
22772 if (rs6000_sched_costly_dep <= max_dep_latency
22773 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22779 /* Return the next insn after INSN that is found before TAIL is reached,
22780 skipping any "non-active" insns - insns that will not actually occupy
22781 an issue slot. Return NULL_RTX if such an insn is not found. */
22784 get_next_active_insn (rtx insn, rtx tail)
22786 if (insn == NULL_RTX || insn == tail)
22791 insn = NEXT_INSN (insn);
22792 if (insn == NULL_RTX || insn == tail)
22797 || (NONJUMP_INSN_P (insn)
22798 && GET_CODE (PATTERN (insn)) != USE
22799 && GET_CODE (PATTERN (insn)) != CLOBBER
22800 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22806 /* We are about to begin issuing insns for this clock cycle. */
22809 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22810 rtx *ready ATTRIBUTE_UNUSED,
22811 int *pn_ready ATTRIBUTE_UNUSED,
22812 int clock_var ATTRIBUTE_UNUSED)
22814 int n_ready = *pn_ready;
22817 fprintf (dump, "// rs6000_sched_reorder :\n");
22819 /* Reorder the ready list, if the second to last ready insn
22820 is a nonepipeline insn. */
22821 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22823 if (is_nonpipeline_insn (ready[n_ready - 1])
22824 && (recog_memoized (ready[n_ready - 2]) > 0))
22825 /* Simply swap first two insns. */
22827 rtx tmp = ready[n_ready - 1];
22828 ready[n_ready - 1] = ready[n_ready - 2];
22829 ready[n_ready - 2] = tmp;
22833 if (rs6000_cpu == PROCESSOR_POWER6)
22834 load_store_pendulum = 0;
22836 return rs6000_issue_rate ();
22839 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22842 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
22843 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
22846 fprintf (dump, "// rs6000_sched_reorder2 :\n");
22848 /* For Power6, we need to handle some special cases to try and keep the
22849 store queue from overflowing and triggering expensive flushes.
22851 This code monitors how load and store instructions are being issued
22852 and skews the ready list one way or the other to increase the likelihood
22853 that a desired instruction is issued at the proper time.
22855 A couple of things are done. First, we maintain a "load_store_pendulum"
22856 to track the current state of load/store issue.
22858 - If the pendulum is at zero, then no loads or stores have been
22859 issued in the current cycle so we do nothing.
22861 - If the pendulum is 1, then a single load has been issued in this
22862 cycle and we attempt to locate another load in the ready list to
22865 - If the pendulum is -2, then two stores have already been
22866 issued in this cycle, so we increase the priority of the first load
22867 in the ready list to increase it's likelihood of being chosen first
22870 - If the pendulum is -1, then a single store has been issued in this
22871 cycle and we attempt to locate another store in the ready list to
22872 issue with it, preferring a store to an adjacent memory location to
22873 facilitate store pairing in the store queue.
22875 - If the pendulum is 2, then two loads have already been
22876 issued in this cycle, so we increase the priority of the first store
22877 in the ready list to increase it's likelihood of being chosen first
22880 - If the pendulum < -2 or > 2, then do nothing.
22882 Note: This code covers the most common scenarios. There exist non
22883 load/store instructions which make use of the LSU and which
22884 would need to be accounted for to strictly model the behavior
22885 of the machine. Those instructions are currently unaccounted
22886 for to help minimize compile time overhead of this code.
22888 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
22894 if (is_store_insn (last_scheduled_insn))
22895 /* Issuing a store, swing the load_store_pendulum to the left */
22896 load_store_pendulum--;
22897 else if (is_load_insn (last_scheduled_insn))
22898 /* Issuing a load, swing the load_store_pendulum to the right */
22899 load_store_pendulum++;
22901 return cached_can_issue_more;
22903 /* If the pendulum is balanced, or there is only one instruction on
22904 the ready list, then all is well, so return. */
22905 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
22906 return cached_can_issue_more;
22908 if (load_store_pendulum == 1)
22910 /* A load has been issued in this cycle. Scan the ready list
22911 for another load to issue with it */
22916 if (is_load_insn (ready[pos]))
22918 /* Found a load. Move it to the head of the ready list,
22919 and adjust it's priority so that it is more likely to
22922 for (i=pos; i<*pn_ready-1; i++)
22923 ready[i] = ready[i + 1];
22924 ready[*pn_ready-1] = tmp;
22926 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22927 INSN_PRIORITY (tmp)++;
22933 else if (load_store_pendulum == -2)
22935 /* Two stores have been issued in this cycle. Increase the
22936 priority of the first load in the ready list to favor it for
22937 issuing in the next cycle. */
22942 if (is_load_insn (ready[pos])
22944 && INSN_PRIORITY_KNOWN (ready[pos]))
22946 INSN_PRIORITY (ready[pos])++;
22948 /* Adjust the pendulum to account for the fact that a load
22949 was found and increased in priority. This is to prevent
22950 increasing the priority of multiple loads */
22951 load_store_pendulum--;
22958 else if (load_store_pendulum == -1)
22960 /* A store has been issued in this cycle. Scan the ready list for
22961 another store to issue with it, preferring a store to an adjacent
22963 int first_store_pos = -1;
22969 if (is_store_insn (ready[pos]))
22971 /* Maintain the index of the first store found on the
22973 if (first_store_pos == -1)
22974 first_store_pos = pos;
22976 if (is_store_insn (last_scheduled_insn)
22977 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22979 /* Found an adjacent store. Move it to the head of the
22980 ready list, and adjust it's priority so that it is
22981 more likely to stay there */
22983 for (i=pos; i<*pn_ready-1; i++)
22984 ready[i] = ready[i + 1];
22985 ready[*pn_ready-1] = tmp;
22987 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22988 INSN_PRIORITY (tmp)++;
22990 first_store_pos = -1;
22998 if (first_store_pos >= 0)
23000 /* An adjacent store wasn't found, but a non-adjacent store was,
23001 so move the non-adjacent store to the front of the ready
23002 list, and adjust its priority so that it is more likely to
23004 tmp = ready[first_store_pos];
23005 for (i=first_store_pos; i<*pn_ready-1; i++)
23006 ready[i] = ready[i + 1];
23007 ready[*pn_ready-1] = tmp;
23008 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23009 INSN_PRIORITY (tmp)++;
23012 else if (load_store_pendulum == 2)
23014 /* Two loads have been issued in this cycle. Increase the priority
23015 of the first store in the ready list to favor it for issuing in
23021 if (is_store_insn (ready[pos])
23023 && INSN_PRIORITY_KNOWN (ready[pos]))
23025 INSN_PRIORITY (ready[pos])++;
23027 /* Adjust the pendulum to account for the fact that a store
23028 was found and increased in priority. This is to prevent
23029 increasing the priority of multiple stores */
23030 load_store_pendulum++;
23039 return cached_can_issue_more;
23042 /* Return whether the presence of INSN causes a dispatch group termination
23043 of group WHICH_GROUP.
23045 If WHICH_GROUP == current_group, this function will return true if INSN
23046 causes the termination of the current group (i.e, the dispatch group to
23047 which INSN belongs). This means that INSN will be the last insn in the
23048 group it belongs to.
23050 If WHICH_GROUP == previous_group, this function will return true if INSN
23051 causes the termination of the previous group (i.e, the dispatch group that
23052 precedes the group to which INSN belongs). This means that INSN will be
23053 the first insn in the group it belongs to). */
23056 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23063 first = insn_must_be_first_in_group (insn);
23064 last = insn_must_be_last_in_group (insn);
23069 if (which_group == current_group)
23071 else if (which_group == previous_group)
23079 insn_must_be_first_in_group (rtx insn)
23081 enum attr_type type;
23084 || GET_CODE (insn) == NOTE
23085 || DEBUG_INSN_P (insn)
23086 || GET_CODE (PATTERN (insn)) == USE
23087 || GET_CODE (PATTERN (insn)) == CLOBBER)
23090 switch (rs6000_cpu)
23092 case PROCESSOR_POWER5:
23093 if (is_cracked_insn (insn))
23095 case PROCESSOR_POWER4:
23096 if (is_microcoded_insn (insn))
23099 if (!rs6000_sched_groups)
23102 type = get_attr_type (insn);
23109 case TYPE_DELAYED_CR:
23110 case TYPE_CR_LOGICAL:
23124 case PROCESSOR_POWER6:
23125 type = get_attr_type (insn);
23129 case TYPE_INSERT_DWORD:
23133 case TYPE_VAR_SHIFT_ROTATE:
23140 case TYPE_INSERT_WORD:
23141 case TYPE_DELAYED_COMPARE:
23142 case TYPE_IMUL_COMPARE:
23143 case TYPE_LMUL_COMPARE:
23144 case TYPE_FPCOMPARE:
23155 case TYPE_LOAD_EXT_UX:
23157 case TYPE_STORE_UX:
23158 case TYPE_FPLOAD_U:
23159 case TYPE_FPLOAD_UX:
23160 case TYPE_FPSTORE_U:
23161 case TYPE_FPSTORE_UX:
23167 case PROCESSOR_POWER7:
23168 type = get_attr_type (insn);
23172 case TYPE_CR_LOGICAL:
23179 case TYPE_DELAYED_COMPARE:
23180 case TYPE_VAR_DELAYED_COMPARE:
23186 case TYPE_LOAD_EXT:
23187 case TYPE_LOAD_EXT_U:
23188 case TYPE_LOAD_EXT_UX:
23190 case TYPE_STORE_UX:
23191 case TYPE_FPLOAD_U:
23192 case TYPE_FPLOAD_UX:
23193 case TYPE_FPSTORE_U:
23194 case TYPE_FPSTORE_UX:
23210 insn_must_be_last_in_group (rtx insn)
23212 enum attr_type type;
23215 || GET_CODE (insn) == NOTE
23216 || DEBUG_INSN_P (insn)
23217 || GET_CODE (PATTERN (insn)) == USE
23218 || GET_CODE (PATTERN (insn)) == CLOBBER)
23221 switch (rs6000_cpu) {
23222 case PROCESSOR_POWER4:
23223 case PROCESSOR_POWER5:
23224 if (is_microcoded_insn (insn))
23227 if (is_branch_slot_insn (insn))
23231 case PROCESSOR_POWER6:
23232 type = get_attr_type (insn);
23239 case TYPE_VAR_SHIFT_ROTATE:
23246 case TYPE_DELAYED_COMPARE:
23247 case TYPE_IMUL_COMPARE:
23248 case TYPE_LMUL_COMPARE:
23249 case TYPE_FPCOMPARE:
23263 case PROCESSOR_POWER7:
23264 type = get_attr_type (insn);
23272 case TYPE_LOAD_EXT_U:
23273 case TYPE_LOAD_EXT_UX:
23274 case TYPE_STORE_UX:
23287 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
23288 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
23291 is_costly_group (rtx *group_insns, rtx next_insn)
23294 int issue_rate = rs6000_issue_rate ();
23296 for (i = 0; i < issue_rate; i++)
23298 sd_iterator_def sd_it;
23300 rtx insn = group_insns[i];
23305 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
23307 rtx next = DEP_CON (dep);
23309 if (next == next_insn
23310 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
23318 /* Utility of the function redefine_groups.
23319 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
23320 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
23321 to keep it "far" (in a separate group) from GROUP_INSNS, following
23322 one of the following schemes, depending on the value of the flag
23323 -minsert_sched_nops = X:
23324 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
23325 in order to force NEXT_INSN into a separate group.
23326 (2) X < sched_finish_regroup_exact: insert exactly X nops.
23327 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
23328 insertion (has a group just ended, how many vacant issue slots remain in the
23329 last group, and how many dispatch groups were encountered so far). */
23332 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
23333 rtx next_insn, bool *group_end, int can_issue_more,
23338 int issue_rate = rs6000_issue_rate ();
23339 bool end = *group_end;
23342 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
23343 return can_issue_more;
23345 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
23346 return can_issue_more;
23348 force = is_costly_group (group_insns, next_insn);
23350 return can_issue_more;
23352 if (sched_verbose > 6)
23353 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
23354 *group_count ,can_issue_more);
23356 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
23359 can_issue_more = 0;
23361 /* Since only a branch can be issued in the last issue_slot, it is
23362 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
23363 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
23364 in this case the last nop will start a new group and the branch
23365 will be forced to the new group. */
23366 if (can_issue_more && !is_branch_slot_insn (next_insn))
23369 while (can_issue_more > 0)
23372 emit_insn_before (nop, next_insn);
23380 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
23382 int n_nops = rs6000_sched_insert_nops;
23384 /* Nops can't be issued from the branch slot, so the effective
23385 issue_rate for nops is 'issue_rate - 1'. */
23386 if (can_issue_more == 0)
23387 can_issue_more = issue_rate;
23389 if (can_issue_more == 0)
23391 can_issue_more = issue_rate - 1;
23394 for (i = 0; i < issue_rate; i++)
23396 group_insns[i] = 0;
23403 emit_insn_before (nop, next_insn);
23404 if (can_issue_more == issue_rate - 1) /* new group begins */
23407 if (can_issue_more == 0)
23409 can_issue_more = issue_rate - 1;
23412 for (i = 0; i < issue_rate; i++)
23414 group_insns[i] = 0;
23420 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
23423 /* Is next_insn going to start a new group? */
23426 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23427 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23428 || (can_issue_more < issue_rate &&
23429 insn_terminates_group_p (next_insn, previous_group)));
23430 if (*group_end && end)
23433 if (sched_verbose > 6)
23434 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
23435 *group_count, can_issue_more);
23436 return can_issue_more;
23439 return can_issue_more;
23442 /* This function tries to synch the dispatch groups that the compiler "sees"
23443 with the dispatch groups that the processor dispatcher is expected to
23444 form in practice. It tries to achieve this synchronization by forcing the
23445 estimated processor grouping on the compiler (as opposed to the function
23446 'pad_goups' which tries to force the scheduler's grouping on the processor).
23448 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
23449 examines the (estimated) dispatch groups that will be formed by the processor
23450 dispatcher. It marks these group boundaries to reflect the estimated
23451 processor grouping, overriding the grouping that the scheduler had marked.
23452 Depending on the value of the flag '-minsert-sched-nops' this function can
23453 force certain insns into separate groups or force a certain distance between
23454 them by inserting nops, for example, if there exists a "costly dependence"
23457 The function estimates the group boundaries that the processor will form as
23458 follows: It keeps track of how many vacant issue slots are available after
23459 each insn. A subsequent insn will start a new group if one of the following
23461 - no more vacant issue slots remain in the current dispatch group.
23462 - only the last issue slot, which is the branch slot, is vacant, but the next
23463 insn is not a branch.
23464 - only the last 2 or less issue slots, including the branch slot, are vacant,
23465 which means that a cracked insn (which occupies two issue slots) can't be
23466 issued in this group.
23467 - less than 'issue_rate' slots are vacant, and the next insn always needs to
23468 start a new group. */
23471 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23473 rtx insn, next_insn;
23475 int can_issue_more;
23478 int group_count = 0;
23482 issue_rate = rs6000_issue_rate ();
23483 group_insns = XALLOCAVEC (rtx, issue_rate);
23484 for (i = 0; i < issue_rate; i++)
23486 group_insns[i] = 0;
23488 can_issue_more = issue_rate;
23490 insn = get_next_active_insn (prev_head_insn, tail);
23493 while (insn != NULL_RTX)
23495 slot = (issue_rate - can_issue_more);
23496 group_insns[slot] = insn;
23498 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23499 if (insn_terminates_group_p (insn, current_group))
23500 can_issue_more = 0;
23502 next_insn = get_next_active_insn (insn, tail);
23503 if (next_insn == NULL_RTX)
23504 return group_count + 1;
23506 /* Is next_insn going to start a new group? */
23508 = (can_issue_more == 0
23509 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23510 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23511 || (can_issue_more < issue_rate &&
23512 insn_terminates_group_p (next_insn, previous_group)));
23514 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
23515 next_insn, &group_end, can_issue_more,
23521 can_issue_more = 0;
23522 for (i = 0; i < issue_rate; i++)
23524 group_insns[i] = 0;
23528 if (GET_MODE (next_insn) == TImode && can_issue_more)
23529 PUT_MODE (next_insn, VOIDmode);
23530 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
23531 PUT_MODE (next_insn, TImode);
23534 if (can_issue_more == 0)
23535 can_issue_more = issue_rate;
23538 return group_count;
23541 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
23542 dispatch group boundaries that the scheduler had marked. Pad with nops
23543 any dispatch groups which have vacant issue slots, in order to force the
23544 scheduler's grouping on the processor dispatcher. The function
23545 returns the number of dispatch groups found. */
23548 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23550 rtx insn, next_insn;
23553 int can_issue_more;
23555 int group_count = 0;
23557 /* Initialize issue_rate. */
23558 issue_rate = rs6000_issue_rate ();
23559 can_issue_more = issue_rate;
23561 insn = get_next_active_insn (prev_head_insn, tail);
23562 next_insn = get_next_active_insn (insn, tail);
23564 while (insn != NULL_RTX)
23567 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23569 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
23571 if (next_insn == NULL_RTX)
23576 /* If the scheduler had marked group termination at this location
23577 (between insn and next_insn), and neither insn nor next_insn will
23578 force group termination, pad the group with nops to force group
23581 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
23582 && !insn_terminates_group_p (insn, current_group)
23583 && !insn_terminates_group_p (next_insn, previous_group))
23585 if (!is_branch_slot_insn (next_insn))
23588 while (can_issue_more)
23591 emit_insn_before (nop, next_insn);
23596 can_issue_more = issue_rate;
23601 next_insn = get_next_active_insn (insn, tail);
23604 return group_count;
23607 /* We're beginning a new block. Initialize data structures as necessary. */
23610 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
23611 int sched_verbose ATTRIBUTE_UNUSED,
23612 int max_ready ATTRIBUTE_UNUSED)
23614 last_scheduled_insn = NULL_RTX;
23615 load_store_pendulum = 0;
23618 /* The following function is called at the end of scheduling BB.
23619 After reload, it inserts nops at insn group bundling. */
23622 rs6000_sched_finish (FILE *dump, int sched_verbose)
23627 fprintf (dump, "=== Finishing schedule.\n");
23629 if (reload_completed && rs6000_sched_groups)
23631 /* Do not run sched_finish hook when selective scheduling enabled. */
23632 if (sel_sched_p ())
23635 if (rs6000_sched_insert_nops == sched_finish_none)
23638 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
23639 n_groups = pad_groups (dump, sched_verbose,
23640 current_sched_info->prev_head,
23641 current_sched_info->next_tail);
23643 n_groups = redefine_groups (dump, sched_verbose,
23644 current_sched_info->prev_head,
23645 current_sched_info->next_tail);
23647 if (sched_verbose >= 6)
23649 fprintf (dump, "ngroups = %d\n", n_groups);
23650 print_rtl (dump, current_sched_info->prev_head);
23651 fprintf (dump, "Done finish_sched\n");
23656 struct _rs6000_sched_context
23658 short cached_can_issue_more;
23659 rtx last_scheduled_insn;
23660 int load_store_pendulum;
23663 typedef struct _rs6000_sched_context rs6000_sched_context_def;
23664 typedef rs6000_sched_context_def *rs6000_sched_context_t;
23666 /* Allocate store for new scheduling context. */
23668 rs6000_alloc_sched_context (void)
23670 return xmalloc (sizeof (rs6000_sched_context_def));
23673 /* If CLEAN_P is true then initializes _SC with clean data,
23674 and from the global context otherwise. */
23676 rs6000_init_sched_context (void *_sc, bool clean_p)
23678 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23682 sc->cached_can_issue_more = 0;
23683 sc->last_scheduled_insn = NULL_RTX;
23684 sc->load_store_pendulum = 0;
23688 sc->cached_can_issue_more = cached_can_issue_more;
23689 sc->last_scheduled_insn = last_scheduled_insn;
23690 sc->load_store_pendulum = load_store_pendulum;
23694 /* Sets the global scheduling context to the one pointed to by _SC. */
23696 rs6000_set_sched_context (void *_sc)
23698 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23700 gcc_assert (sc != NULL);
23702 cached_can_issue_more = sc->cached_can_issue_more;
23703 last_scheduled_insn = sc->last_scheduled_insn;
23704 load_store_pendulum = sc->load_store_pendulum;
23709 rs6000_free_sched_context (void *_sc)
23711 gcc_assert (_sc != NULL);
23717 /* Length in units of the trampoline for entering a nested function. */
23720 rs6000_trampoline_size (void)
23724 switch (DEFAULT_ABI)
23727 gcc_unreachable ();
23730 ret = (TARGET_32BIT) ? 12 : 24;
23735 ret = (TARGET_32BIT) ? 40 : 48;
23742 /* Emit RTL insns to initialize the variable parts of a trampoline.
23743 FNADDR is an RTX for the address of the function's pure code.
23744 CXT is an RTX for the static chain value for the function. */
23747 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
23749 int regsize = (TARGET_32BIT) ? 4 : 8;
23750 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
23751 rtx ctx_reg = force_reg (Pmode, cxt);
23752 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
23754 switch (DEFAULT_ABI)
23757 gcc_unreachable ();
23759 /* Under AIX, just build the 3 word function descriptor */
23762 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
23763 rtx fn_reg = gen_reg_rtx (Pmode);
23764 rtx toc_reg = gen_reg_rtx (Pmode);
23766 /* Macro to shorten the code expansions below. */
23767 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23769 m_tramp = replace_equiv_address (m_tramp, addr);
23771 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
23772 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23773 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23774 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23775 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23781 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23784 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23785 LCT_NORMAL, VOIDmode, 4,
23787 GEN_INT (rs6000_trampoline_size ()), SImode,
23795 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
23796 identifier as an argument, so the front end shouldn't look it up. */
23799 rs6000_attribute_takes_identifier_p (const_tree attr_id)
23801 return is_attribute_p ("altivec", attr_id);
23804 /* Handle the "altivec" attribute. The attribute may have
23805 arguments as follows:
23807 __attribute__((altivec(vector__)))
23808 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23809 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23811 and may appear more than once (e.g., 'vector bool char') in a
23812 given declaration. */
23815 rs6000_handle_altivec_attribute (tree *node,
23816 tree name ATTRIBUTE_UNUSED,
23818 int flags ATTRIBUTE_UNUSED,
23819 bool *no_add_attrs)
23821 tree type = *node, result = NULL_TREE;
23822 enum machine_mode mode;
23825 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23826 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23827 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23830 while (POINTER_TYPE_P (type)
23831 || TREE_CODE (type) == FUNCTION_TYPE
23832 || TREE_CODE (type) == METHOD_TYPE
23833 || TREE_CODE (type) == ARRAY_TYPE)
23834 type = TREE_TYPE (type);
23836 mode = TYPE_MODE (type);
23838 /* Check for invalid AltiVec type qualifiers. */
23839 if (type == long_double_type_node)
23840 error ("use of %<long double%> in AltiVec types is invalid");
23841 else if (type == boolean_type_node)
23842 error ("use of boolean types in AltiVec types is invalid");
23843 else if (TREE_CODE (type) == COMPLEX_TYPE)
23844 error ("use of %<complex%> in AltiVec types is invalid");
23845 else if (DECIMAL_FLOAT_MODE_P (mode))
23846 error ("use of decimal floating point types in AltiVec types is invalid");
23847 else if (!TARGET_VSX)
23849 if (type == long_unsigned_type_node || type == long_integer_type_node)
23852 error ("use of %<long%> in AltiVec types is invalid for "
23853 "64-bit code without -mvsx");
23854 else if (rs6000_warn_altivec_long)
23855 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23858 else if (type == long_long_unsigned_type_node
23859 || type == long_long_integer_type_node)
23860 error ("use of %<long long%> in AltiVec types is invalid without "
23862 else if (type == double_type_node)
23863 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23866 switch (altivec_type)
23869 unsigned_p = TYPE_UNSIGNED (type);
23873 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
23876 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
23879 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
23882 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
23884 case SFmode: result = V4SF_type_node; break;
23885 case DFmode: result = V2DF_type_node; break;
23886 /* If the user says 'vector int bool', we may be handed the 'bool'
23887 attribute _before_ the 'vector' attribute, and so select the
23888 proper type in the 'b' case below. */
23889 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
23890 case V2DImode: case V2DFmode:
23898 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
23899 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
23900 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
23901 case QImode: case V16QImode: result = bool_V16QI_type_node;
23908 case V8HImode: result = pixel_V8HI_type_node;
23914 /* Propagate qualifiers attached to the element type
23915 onto the vector type. */
23916 if (result && result != type && TYPE_QUALS (type))
23917 result = build_qualified_type (result, TYPE_QUALS (type));
23919 *no_add_attrs = true; /* No need to hang on to the attribute. */
23922 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
23927 /* AltiVec defines four built-in scalar types that serve as vector
23928 elements; we must teach the compiler how to mangle them. */
23930 static const char *
23931 rs6000_mangle_type (const_tree type)
23933 type = TYPE_MAIN_VARIANT (type);
23935 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
23936 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
23939 if (type == bool_char_type_node) return "U6__boolc";
23940 if (type == bool_short_type_node) return "U6__bools";
23941 if (type == pixel_type_node) return "u7__pixel";
23942 if (type == bool_int_type_node) return "U6__booli";
23943 if (type == bool_long_type_node) return "U6__booll";
23945 /* Mangle IBM extended float long double as `g' (__float128) on
23946 powerpc*-linux where long-double-64 previously was the default. */
23947 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
23949 && TARGET_LONG_DOUBLE_128
23950 && !TARGET_IEEEQUAD)
23953 /* For all other types, use normal C++ mangling. */
23957 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23958 struct attribute_spec.handler. */
23961 rs6000_handle_longcall_attribute (tree *node, tree name,
23962 tree args ATTRIBUTE_UNUSED,
23963 int flags ATTRIBUTE_UNUSED,
23964 bool *no_add_attrs)
23966 if (TREE_CODE (*node) != FUNCTION_TYPE
23967 && TREE_CODE (*node) != FIELD_DECL
23968 && TREE_CODE (*node) != TYPE_DECL)
23970 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23972 *no_add_attrs = true;
23978 /* Set longcall attributes on all functions declared when
23979 rs6000_default_long_calls is true. */
23981 rs6000_set_default_type_attributes (tree type)
23983 if (rs6000_default_long_calls
23984 && (TREE_CODE (type) == FUNCTION_TYPE
23985 || TREE_CODE (type) == METHOD_TYPE))
23986 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23988 TYPE_ATTRIBUTES (type));
23991 darwin_set_default_type_attributes (type);
23995 /* Return a reference suitable for calling a function with the
23996 longcall attribute. */
23999 rs6000_longcall_ref (rtx call_ref)
24001 const char *call_name;
24004 if (GET_CODE (call_ref) != SYMBOL_REF)
24007 /* System V adds '.' to the internal name, so skip them. */
24008 call_name = XSTR (call_ref, 0);
24009 if (*call_name == '.')
24011 while (*call_name == '.')
24014 node = get_identifier (call_name);
24015 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24018 return force_reg (Pmode, call_ref);
24021 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24022 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24025 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24026 struct attribute_spec.handler. */
24028 rs6000_handle_struct_attribute (tree *node, tree name,
24029 tree args ATTRIBUTE_UNUSED,
24030 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24033 if (DECL_P (*node))
24035 if (TREE_CODE (*node) == TYPE_DECL)
24036 type = &TREE_TYPE (*node);
24041 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24042 || TREE_CODE (*type) == UNION_TYPE)))
24044 warning (OPT_Wattributes, "%qE attribute ignored", name);
24045 *no_add_attrs = true;
24048 else if ((is_attribute_p ("ms_struct", name)
24049 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24050 || ((is_attribute_p ("gcc_struct", name)
24051 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24053 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24055 *no_add_attrs = true;
24062 rs6000_ms_bitfield_layout_p (const_tree record_type)
24064 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24065 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24066 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24069 #ifdef USING_ELFOS_H
24071 /* A get_unnamed_section callback, used for switching to toc_section. */
24074 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24076 if (DEFAULT_ABI == ABI_AIX
24077 && TARGET_MINIMAL_TOC
24078 && !TARGET_RELOCATABLE)
24080 if (!toc_initialized)
24082 toc_initialized = 1;
24083 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24084 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24085 fprintf (asm_out_file, "\t.tc ");
24086 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24087 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24088 fprintf (asm_out_file, "\n");
24090 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24091 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24092 fprintf (asm_out_file, " = .+32768\n");
24095 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24097 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24098 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24101 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24102 if (!toc_initialized)
24104 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24105 fprintf (asm_out_file, " = .+32768\n");
24106 toc_initialized = 1;
24111 /* Implement TARGET_ASM_INIT_SECTIONS. */
24114 rs6000_elf_asm_init_sections (void)
24117 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24120 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24121 SDATA2_SECTION_ASM_OP);
24124 /* Implement TARGET_SELECT_RTX_SECTION. */
24127 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24128 unsigned HOST_WIDE_INT align)
24130 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24131 return toc_section;
24133 return default_elf_select_rtx_section (mode, x, align);
24136 /* For a SYMBOL_REF, set generic flags and then perform some
24137 target-specific processing.
24139 When the AIX ABI is requested on a non-AIX system, replace the
24140 function name with the real name (with a leading .) rather than the
24141 function descriptor name. This saves a lot of overriding code to
24142 read the prefixes. */
24145 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24147 default_encode_section_info (decl, rtl, first);
24150 && TREE_CODE (decl) == FUNCTION_DECL
24152 && DEFAULT_ABI == ABI_AIX)
24154 rtx sym_ref = XEXP (rtl, 0);
24155 size_t len = strlen (XSTR (sym_ref, 0));
24156 char *str = XALLOCAVEC (char, len + 2);
24158 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24159 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24164 compare_section_name (const char *section, const char *templ)
24168 len = strlen (templ);
24169 return (strncmp (section, templ, len) == 0
24170 && (section[len] == 0 || section[len] == '.'));
24174 rs6000_elf_in_small_data_p (const_tree decl)
24176 if (rs6000_sdata == SDATA_NONE)
24179 /* We want to merge strings, so we never consider them small data. */
24180 if (TREE_CODE (decl) == STRING_CST)
24183 /* Functions are never in the small data area. */
24184 if (TREE_CODE (decl) == FUNCTION_DECL)
24187 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24189 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24190 if (compare_section_name (section, ".sdata")
24191 || compare_section_name (section, ".sdata2")
24192 || compare_section_name (section, ".gnu.linkonce.s")
24193 || compare_section_name (section, ".sbss")
24194 || compare_section_name (section, ".sbss2")
24195 || compare_section_name (section, ".gnu.linkonce.sb")
24196 || strcmp (section, ".PPC.EMB.sdata0") == 0
24197 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24202 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24205 && (unsigned HOST_WIDE_INT) size <= g_switch_value
24206 /* If it's not public, and we're not going to reference it there,
24207 there's no need to put it in the small data section. */
24208 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24215 #endif /* USING_ELFOS_H */
24217 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24220 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24222 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24225 /* Return a REG that occurs in ADDR with coefficient 1.
24226 ADDR can be effectively incremented by incrementing REG.
24228 r0 is special and we must not select it as an address
24229 register by this routine since our caller will try to
24230 increment the returned register via an "la" instruction. */
24233 find_addr_reg (rtx addr)
24235 while (GET_CODE (addr) == PLUS)
24237 if (GET_CODE (XEXP (addr, 0)) == REG
24238 && REGNO (XEXP (addr, 0)) != 0)
24239 addr = XEXP (addr, 0);
24240 else if (GET_CODE (XEXP (addr, 1)) == REG
24241 && REGNO (XEXP (addr, 1)) != 0)
24242 addr = XEXP (addr, 1);
24243 else if (CONSTANT_P (XEXP (addr, 0)))
24244 addr = XEXP (addr, 1);
24245 else if (CONSTANT_P (XEXP (addr, 1)))
24246 addr = XEXP (addr, 0);
24248 gcc_unreachable ();
24250 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
24255 rs6000_fatal_bad_address (rtx op)
24257 fatal_insn ("bad address", op);
24262 static tree branch_island_list = 0;
24264 /* Remember to generate a branch island for far calls to the given
24268 add_compiler_branch_island (tree label_name, tree function_name,
24271 tree branch_island = build_tree_list (function_name, label_name);
24272 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
24273 TREE_CHAIN (branch_island) = branch_island_list;
24274 branch_island_list = branch_island;
24277 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
24278 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
24279 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
24280 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
24282 /* Generate far-jump branch islands for everything on the
24283 branch_island_list. Invoked immediately after the last instruction
24284 of the epilogue has been emitted; the branch-islands must be
24285 appended to, and contiguous with, the function body. Mach-O stubs
24286 are generated in machopic_output_stub(). */
24289 macho_branch_islands (void)
24292 tree branch_island;
24294 for (branch_island = branch_island_list;
24296 branch_island = TREE_CHAIN (branch_island))
24298 const char *label =
24299 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
24301 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
24302 char name_buf[512];
24303 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
24304 if (name[0] == '*' || name[0] == '&')
24305 strcpy (name_buf, name+1);
24309 strcpy (name_buf+1, name);
24311 strcpy (tmp_buf, "\n");
24312 strcat (tmp_buf, label);
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 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
24320 strcat (tmp_buf, label);
24321 strcat (tmp_buf, "_pic\n");
24322 strcat (tmp_buf, label);
24323 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
24325 strcat (tmp_buf, "\taddis r11,r11,ha16(");
24326 strcat (tmp_buf, name_buf);
24327 strcat (tmp_buf, " - ");
24328 strcat (tmp_buf, label);
24329 strcat (tmp_buf, "_pic)\n");
24331 strcat (tmp_buf, "\tmtlr r0\n");
24333 strcat (tmp_buf, "\taddi r12,r11,lo16(");
24334 strcat (tmp_buf, name_buf);
24335 strcat (tmp_buf, " - ");
24336 strcat (tmp_buf, label);
24337 strcat (tmp_buf, "_pic)\n");
24339 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
24343 strcat (tmp_buf, ":\nlis r12,hi16(");
24344 strcat (tmp_buf, name_buf);
24345 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
24346 strcat (tmp_buf, name_buf);
24347 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
24349 output_asm_insn (tmp_buf, 0);
24350 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24351 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24352 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
24353 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24356 branch_island_list = 0;
24359 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
24360 already there or not. */
24363 no_previous_def (tree function_name)
24365 tree branch_island;
24366 for (branch_island = branch_island_list;
24368 branch_island = TREE_CHAIN (branch_island))
24369 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
24374 /* GET_PREV_LABEL gets the label name from the previous definition of
24378 get_prev_label (tree function_name)
24380 tree branch_island;
24381 for (branch_island = branch_island_list;
24383 branch_island = TREE_CHAIN (branch_island))
24384 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
24385 return BRANCH_ISLAND_LABEL_NAME (branch_island);
24389 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
24390 #define DARWIN_LINKER_GENERATES_ISLANDS 0
24393 /* KEXTs still need branch islands. */
24394 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
24395 || flag_mkernel || flag_apple_kext)
24397 /* INSN is either a function call or a millicode call. It may have an
24398 unconditional jump in its delay slot.
24400 CALL_DEST is the routine we are calling. */
24403 output_call (rtx insn, rtx *operands, int dest_operand_number,
24404 int cookie_operand_number)
24406 static char buf[256];
24407 if (DARWIN_GENERATE_ISLANDS
24408 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
24409 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
24412 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
24414 if (no_previous_def (funname))
24416 rtx label_rtx = gen_label_rtx ();
24417 char *label_buf, temp_buf[256];
24418 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
24419 CODE_LABEL_NUMBER (label_rtx));
24420 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
24421 labelname = get_identifier (label_buf);
24422 add_compiler_branch_island (labelname, funname, insn_line (insn));
24425 labelname = get_prev_label (funname);
24427 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
24428 instruction will reach 'foo', otherwise link as 'bl L42'".
24429 "L42" should be a 'branch island', that will do a far jump to
24430 'foo'. Branch islands are generated in
24431 macho_branch_islands(). */
24432 sprintf (buf, "jbsr %%z%d,%.246s",
24433 dest_operand_number, IDENTIFIER_POINTER (labelname));
24436 sprintf (buf, "bl %%z%d", dest_operand_number);
24440 /* Generate PIC and indirect symbol stubs. */
24443 machopic_output_stub (FILE *file, const char *symb, const char *stub)
24445 unsigned int length;
24446 char *symbol_name, *lazy_ptr_name;
24447 char *local_label_0;
24448 static int label = 0;
24450 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
24451 symb = (*targetm.strip_name_encoding) (symb);
24454 length = strlen (symb);
24455 symbol_name = XALLOCAVEC (char, length + 32);
24456 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
24458 lazy_ptr_name = XALLOCAVEC (char, length + 32);
24459 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
24462 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
24464 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
24468 fprintf (file, "\t.align 5\n");
24470 fprintf (file, "%s:\n", stub);
24471 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24474 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
24475 sprintf (local_label_0, "\"L%011d$spb\"", label);
24477 fprintf (file, "\tmflr r0\n");
24478 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
24479 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
24480 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
24481 lazy_ptr_name, local_label_0);
24482 fprintf (file, "\tmtlr r0\n");
24483 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
24484 (TARGET_64BIT ? "ldu" : "lwzu"),
24485 lazy_ptr_name, local_label_0);
24486 fprintf (file, "\tmtctr r12\n");
24487 fprintf (file, "\tbctr\n");
24491 fprintf (file, "\t.align 4\n");
24493 fprintf (file, "%s:\n", stub);
24494 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24496 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
24497 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
24498 (TARGET_64BIT ? "ldu" : "lwzu"),
24500 fprintf (file, "\tmtctr r12\n");
24501 fprintf (file, "\tbctr\n");
24504 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
24505 fprintf (file, "%s:\n", lazy_ptr_name);
24506 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24507 fprintf (file, "%sdyld_stub_binding_helper\n",
24508 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
24511 /* Legitimize PIC addresses. If the address is already
24512 position-independent, we return ORIG. Newly generated
24513 position-independent addresses go into a reg. This is REG if non
24514 zero, otherwise we allocate register(s) as necessary. */
24516 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
24519 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
24524 if (reg == NULL && ! reload_in_progress && ! reload_completed)
24525 reg = gen_reg_rtx (Pmode);
24527 if (GET_CODE (orig) == CONST)
24531 if (GET_CODE (XEXP (orig, 0)) == PLUS
24532 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
24535 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
24537 /* Use a different reg for the intermediate value, as
24538 it will be marked UNCHANGING. */
24539 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
24540 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
24543 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
24546 if (GET_CODE (offset) == CONST_INT)
24548 if (SMALL_INT (offset))
24549 return plus_constant (base, INTVAL (offset));
24550 else if (! reload_in_progress && ! reload_completed)
24551 offset = force_reg (Pmode, offset);
24554 rtx mem = force_const_mem (Pmode, orig);
24555 return machopic_legitimize_pic_address (mem, Pmode, reg);
24558 return gen_rtx_PLUS (Pmode, base, offset);
24561 /* Fall back on generic machopic code. */
24562 return machopic_legitimize_pic_address (orig, mode, reg);
24565 /* Output a .machine directive for the Darwin assembler, and call
24566 the generic start_file routine. */
24569 rs6000_darwin_file_start (void)
24571 static const struct
24577 { "ppc64", "ppc64", MASK_64BIT },
24578 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
24579 { "power4", "ppc970", 0 },
24580 { "G5", "ppc970", 0 },
24581 { "7450", "ppc7450", 0 },
24582 { "7400", "ppc7400", MASK_ALTIVEC },
24583 { "G4", "ppc7400", 0 },
24584 { "750", "ppc750", 0 },
24585 { "740", "ppc750", 0 },
24586 { "G3", "ppc750", 0 },
24587 { "604e", "ppc604e", 0 },
24588 { "604", "ppc604", 0 },
24589 { "603e", "ppc603", 0 },
24590 { "603", "ppc603", 0 },
24591 { "601", "ppc601", 0 },
24592 { NULL, "ppc", 0 } };
24593 const char *cpu_id = "";
24596 rs6000_file_start ();
24597 darwin_file_start ();
24599 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
24600 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
24601 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
24602 && rs6000_select[i].string[0] != '\0')
24603 cpu_id = rs6000_select[i].string;
24605 /* Look through the mapping array. Pick the first name that either
24606 matches the argument, has a bit set in IF_SET that is also set
24607 in the target flags, or has a NULL name. */
24610 while (mapping[i].arg != NULL
24611 && strcmp (mapping[i].arg, cpu_id) != 0
24612 && (mapping[i].if_set & target_flags) == 0)
24615 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
24618 #endif /* TARGET_MACHO */
24622 rs6000_elf_reloc_rw_mask (void)
24626 else if (DEFAULT_ABI == ABI_AIX)
24632 /* Record an element in the table of global constructors. SYMBOL is
24633 a SYMBOL_REF of the function to be called; PRIORITY is a number
24634 between 0 and MAX_INIT_PRIORITY.
24636 This differs from default_named_section_asm_out_constructor in
24637 that we have special handling for -mrelocatable. */
24640 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
24642 const char *section = ".ctors";
24645 if (priority != DEFAULT_INIT_PRIORITY)
24647 sprintf (buf, ".ctors.%.5u",
24648 /* Invert the numbering so the linker puts us in the proper
24649 order; constructors are run from right to left, and the
24650 linker sorts in increasing order. */
24651 MAX_INIT_PRIORITY - priority);
24655 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24656 assemble_align (POINTER_SIZE);
24658 if (TARGET_RELOCATABLE)
24660 fputs ("\t.long (", asm_out_file);
24661 output_addr_const (asm_out_file, symbol);
24662 fputs (")@fixup\n", asm_out_file);
24665 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24669 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
24671 const char *section = ".dtors";
24674 if (priority != DEFAULT_INIT_PRIORITY)
24676 sprintf (buf, ".dtors.%.5u",
24677 /* Invert the numbering so the linker puts us in the proper
24678 order; constructors are run from right to left, and the
24679 linker sorts in increasing order. */
24680 MAX_INIT_PRIORITY - priority);
24684 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24685 assemble_align (POINTER_SIZE);
24687 if (TARGET_RELOCATABLE)
24689 fputs ("\t.long (", asm_out_file);
24690 output_addr_const (asm_out_file, symbol);
24691 fputs (")@fixup\n", asm_out_file);
24694 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24698 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
24702 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
24703 ASM_OUTPUT_LABEL (file, name);
24704 fputs (DOUBLE_INT_ASM_OP, file);
24705 rs6000_output_function_entry (file, name);
24706 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
24709 fputs ("\t.size\t", file);
24710 assemble_name (file, name);
24711 fputs (",24\n\t.type\t.", file);
24712 assemble_name (file, name);
24713 fputs (",@function\n", file);
24714 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
24716 fputs ("\t.globl\t.", file);
24717 assemble_name (file, name);
24722 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24723 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24724 rs6000_output_function_entry (file, name);
24725 fputs (":\n", file);
24729 if (TARGET_RELOCATABLE
24730 && !TARGET_SECURE_PLT
24731 && (get_pool_size () != 0 || crtl->profile)
24736 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
24738 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
24739 fprintf (file, "\t.long ");
24740 assemble_name (file, buf);
24742 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
24743 assemble_name (file, buf);
24747 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24748 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24750 if (DEFAULT_ABI == ABI_AIX)
24752 const char *desc_name, *orig_name;
24754 orig_name = (*targetm.strip_name_encoding) (name);
24755 desc_name = orig_name;
24756 while (*desc_name == '.')
24759 if (TREE_PUBLIC (decl))
24760 fprintf (file, "\t.globl %s\n", desc_name);
24762 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24763 fprintf (file, "%s:\n", desc_name);
24764 fprintf (file, "\t.long %s\n", orig_name);
24765 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
24766 if (DEFAULT_ABI == ABI_AIX)
24767 fputs ("\t.long 0\n", file);
24768 fprintf (file, "\t.previous\n");
24770 ASM_OUTPUT_LABEL (file, name);
24774 rs6000_elf_end_indicate_exec_stack (void)
24777 file_end_indicate_exec_stack ();
24783 rs6000_xcoff_asm_output_anchor (rtx symbol)
24787 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24788 SYMBOL_REF_BLOCK_OFFSET (symbol));
24789 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24793 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24795 fputs (GLOBAL_ASM_OP, stream);
24796 RS6000_OUTPUT_BASENAME (stream, name);
24797 putc ('\n', stream);
24800 /* A get_unnamed_decl callback, used for read-only sections. PTR
24801 points to the section string variable. */
24804 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24806 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24807 *(const char *const *) directive,
24808 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24811 /* Likewise for read-write sections. */
24814 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24816 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24817 *(const char *const *) directive,
24818 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24821 /* A get_unnamed_section callback, used for switching to toc_section. */
24824 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24826 if (TARGET_MINIMAL_TOC)
24828 /* toc_section is always selected at least once from
24829 rs6000_xcoff_file_start, so this is guaranteed to
24830 always be defined once and only once in each file. */
24831 if (!toc_initialized)
24833 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24834 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24835 toc_initialized = 1;
24837 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
24838 (TARGET_32BIT ? "" : ",3"));
24841 fputs ("\t.toc\n", asm_out_file);
24844 /* Implement TARGET_ASM_INIT_SECTIONS. */
24847 rs6000_xcoff_asm_init_sections (void)
24849 read_only_data_section
24850 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24851 &xcoff_read_only_section_name);
24853 private_data_section
24854 = get_unnamed_section (SECTION_WRITE,
24855 rs6000_xcoff_output_readwrite_section_asm_op,
24856 &xcoff_private_data_section_name);
24858 read_only_private_data_section
24859 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24860 &xcoff_private_data_section_name);
24863 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
24865 readonly_data_section = read_only_data_section;
24866 exception_section = data_section;
24870 rs6000_xcoff_reloc_rw_mask (void)
24876 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
24877 tree decl ATTRIBUTE_UNUSED)
24880 static const char * const suffix[3] = { "PR", "RO", "RW" };
24882 if (flags & SECTION_CODE)
24884 else if (flags & SECTION_WRITE)
24889 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
24890 (flags & SECTION_CODE) ? "." : "",
24891 name, suffix[smclass], flags & SECTION_ENTSIZE);
24895 rs6000_xcoff_select_section (tree decl, int reloc,
24896 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24898 if (decl_readonly_section (decl, reloc))
24900 if (TREE_PUBLIC (decl))
24901 return read_only_data_section;
24903 return read_only_private_data_section;
24907 if (TREE_PUBLIC (decl))
24908 return data_section;
24910 return private_data_section;
24915 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
24919 /* Use select_section for private and uninitialized data. */
24920 if (!TREE_PUBLIC (decl)
24921 || DECL_COMMON (decl)
24922 || DECL_INITIAL (decl) == NULL_TREE
24923 || DECL_INITIAL (decl) == error_mark_node
24924 || (flag_zero_initialized_in_bss
24925 && initializer_zerop (DECL_INITIAL (decl))))
24928 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
24929 name = (*targetm.strip_name_encoding) (name);
24930 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
24933 /* Select section for constant in constant pool.
24935 On RS/6000, all constants are in the private read-only data area.
24936 However, if this is being placed in the TOC it must be output as a
24940 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
24941 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24943 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24944 return toc_section;
24946 return read_only_private_data_section;
24949 /* Remove any trailing [DS] or the like from the symbol name. */
24951 static const char *
24952 rs6000_xcoff_strip_name_encoding (const char *name)
24957 len = strlen (name);
24958 if (name[len - 1] == ']')
24959 return ggc_alloc_string (name, len - 4);
24964 /* Section attributes. AIX is always PIC. */
24966 static unsigned int
24967 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24969 unsigned int align;
24970 unsigned int flags = default_section_type_flags (decl, name, reloc);
24972 /* Align to at least UNIT size. */
24973 if (flags & SECTION_CODE)
24974 align = MIN_UNITS_PER_WORD;
24976 /* Increase alignment of large objects if not already stricter. */
24977 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24978 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24979 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24981 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24984 /* Output at beginning of assembler file.
24986 Initialize the section names for the RS/6000 at this point.
24988 Specify filename, including full path, to assembler.
24990 We want to go into the TOC section so at least one .toc will be emitted.
24991 Also, in order to output proper .bs/.es pairs, we need at least one static
24992 [RW] section emitted.
24994 Finally, declare mcount when profiling to make the assembler happy. */
24997 rs6000_xcoff_file_start (void)
24999 rs6000_gen_section_name (&xcoff_bss_section_name,
25000 main_input_filename, ".bss_");
25001 rs6000_gen_section_name (&xcoff_private_data_section_name,
25002 main_input_filename, ".rw_");
25003 rs6000_gen_section_name (&xcoff_read_only_section_name,
25004 main_input_filename, ".ro_");
25006 fputs ("\t.file\t", asm_out_file);
25007 output_quoted_string (asm_out_file, main_input_filename);
25008 fputc ('\n', asm_out_file);
25009 if (write_symbols != NO_DEBUG)
25010 switch_to_section (private_data_section);
25011 switch_to_section (text_section);
25013 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25014 rs6000_file_start ();
25017 /* Output at end of assembler file.
25018 On the RS/6000, referencing data should automatically pull in text. */
25021 rs6000_xcoff_file_end (void)
25023 switch_to_section (text_section);
25024 fputs ("_section_.text:\n", asm_out_file);
25025 switch_to_section (data_section);
25026 fputs (TARGET_32BIT
25027 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25030 #endif /* TARGET_XCOFF */
25032 /* Compute a (partial) cost for rtx X. Return true if the complete
25033 cost has been computed, and false if subexpressions should be
25034 scanned. In either case, *TOTAL contains the cost result. */
25037 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25040 enum machine_mode mode = GET_MODE (x);
25044 /* On the RS/6000, if it is valid in the insn, it is free. */
25046 if (((outer_code == SET
25047 || outer_code == PLUS
25048 || outer_code == MINUS)
25049 && (satisfies_constraint_I (x)
25050 || satisfies_constraint_L (x)))
25051 || (outer_code == AND
25052 && (satisfies_constraint_K (x)
25054 ? satisfies_constraint_L (x)
25055 : satisfies_constraint_J (x))
25056 || mask_operand (x, mode)
25058 && mask64_operand (x, DImode))))
25059 || ((outer_code == IOR || outer_code == XOR)
25060 && (satisfies_constraint_K (x)
25062 ? satisfies_constraint_L (x)
25063 : satisfies_constraint_J (x))))
25064 || outer_code == ASHIFT
25065 || outer_code == ASHIFTRT
25066 || outer_code == LSHIFTRT
25067 || outer_code == ROTATE
25068 || outer_code == ROTATERT
25069 || outer_code == ZERO_EXTRACT
25070 || (outer_code == MULT
25071 && satisfies_constraint_I (x))
25072 || ((outer_code == DIV || outer_code == UDIV
25073 || outer_code == MOD || outer_code == UMOD)
25074 && exact_log2 (INTVAL (x)) >= 0)
25075 || (outer_code == COMPARE
25076 && (satisfies_constraint_I (x)
25077 || satisfies_constraint_K (x)))
25078 || (outer_code == EQ
25079 && (satisfies_constraint_I (x)
25080 || satisfies_constraint_K (x)
25082 ? satisfies_constraint_L (x)
25083 : satisfies_constraint_J (x))))
25084 || (outer_code == GTU
25085 && satisfies_constraint_I (x))
25086 || (outer_code == LTU
25087 && satisfies_constraint_P (x)))
25092 else if ((outer_code == PLUS
25093 && reg_or_add_cint_operand (x, VOIDmode))
25094 || (outer_code == MINUS
25095 && reg_or_sub_cint_operand (x, VOIDmode))
25096 || ((outer_code == SET
25097 || outer_code == IOR
25098 || outer_code == XOR)
25100 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25102 *total = COSTS_N_INSNS (1);
25108 if (mode == DImode && code == CONST_DOUBLE)
25110 if ((outer_code == IOR || outer_code == XOR)
25111 && CONST_DOUBLE_HIGH (x) == 0
25112 && (CONST_DOUBLE_LOW (x)
25113 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25118 else if ((outer_code == AND && and64_2_operand (x, DImode))
25119 || ((outer_code == SET
25120 || outer_code == IOR
25121 || outer_code == XOR)
25122 && CONST_DOUBLE_HIGH (x) == 0))
25124 *total = COSTS_N_INSNS (1);
25134 /* When optimizing for size, MEM should be slightly more expensive
25135 than generating address, e.g., (plus (reg) (const)).
25136 L1 cache latency is about two instructions. */
25137 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25145 if (mode == DFmode)
25147 if (GET_CODE (XEXP (x, 0)) == MULT)
25149 /* FNMA accounted in outer NEG. */
25150 if (outer_code == NEG)
25151 *total = rs6000_cost->dmul - rs6000_cost->fp;
25153 *total = rs6000_cost->dmul;
25156 *total = rs6000_cost->fp;
25158 else if (mode == SFmode)
25160 /* FNMA accounted in outer NEG. */
25161 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25164 *total = rs6000_cost->fp;
25167 *total = COSTS_N_INSNS (1);
25171 if (mode == DFmode)
25173 if (GET_CODE (XEXP (x, 0)) == MULT
25174 || GET_CODE (XEXP (x, 1)) == MULT)
25176 /* FNMA accounted in outer NEG. */
25177 if (outer_code == NEG)
25178 *total = rs6000_cost->dmul - rs6000_cost->fp;
25180 *total = rs6000_cost->dmul;
25183 *total = rs6000_cost->fp;
25185 else if (mode == SFmode)
25187 /* FNMA accounted in outer NEG. */
25188 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25191 *total = rs6000_cost->fp;
25194 *total = COSTS_N_INSNS (1);
25198 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25199 && satisfies_constraint_I (XEXP (x, 1)))
25201 if (INTVAL (XEXP (x, 1)) >= -256
25202 && INTVAL (XEXP (x, 1)) <= 255)
25203 *total = rs6000_cost->mulsi_const9;
25205 *total = rs6000_cost->mulsi_const;
25207 /* FMA accounted in outer PLUS/MINUS. */
25208 else if ((mode == DFmode || mode == SFmode)
25209 && (outer_code == PLUS || outer_code == MINUS))
25211 else if (mode == DFmode)
25212 *total = rs6000_cost->dmul;
25213 else if (mode == SFmode)
25214 *total = rs6000_cost->fp;
25215 else if (mode == DImode)
25216 *total = rs6000_cost->muldi;
25218 *total = rs6000_cost->mulsi;
25223 if (FLOAT_MODE_P (mode))
25225 *total = mode == DFmode ? rs6000_cost->ddiv
25226 : rs6000_cost->sdiv;
25233 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25234 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25236 if (code == DIV || code == MOD)
25238 *total = COSTS_N_INSNS (2);
25241 *total = COSTS_N_INSNS (1);
25245 if (GET_MODE (XEXP (x, 1)) == DImode)
25246 *total = rs6000_cost->divdi;
25248 *total = rs6000_cost->divsi;
25250 /* Add in shift and subtract for MOD. */
25251 if (code == MOD || code == UMOD)
25252 *total += COSTS_N_INSNS (2);
25257 *total = COSTS_N_INSNS (4);
25261 *total = COSTS_N_INSNS (6);
25265 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
25277 *total = COSTS_N_INSNS (1);
25285 /* Handle mul_highpart. */
25286 if (outer_code == TRUNCATE
25287 && GET_CODE (XEXP (x, 0)) == MULT)
25289 if (mode == DImode)
25290 *total = rs6000_cost->muldi;
25292 *total = rs6000_cost->mulsi;
25295 else if (outer_code == AND)
25298 *total = COSTS_N_INSNS (1);
25303 if (GET_CODE (XEXP (x, 0)) == MEM)
25306 *total = COSTS_N_INSNS (1);
25312 if (!FLOAT_MODE_P (mode))
25314 *total = COSTS_N_INSNS (1);
25320 case UNSIGNED_FLOAT:
25323 case FLOAT_TRUNCATE:
25324 *total = rs6000_cost->fp;
25328 if (mode == DFmode)
25331 *total = rs6000_cost->fp;
25335 switch (XINT (x, 1))
25338 *total = rs6000_cost->fp;
25350 *total = COSTS_N_INSNS (1);
25353 else if (FLOAT_MODE_P (mode)
25354 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
25356 *total = rs6000_cost->fp;
25364 /* Carry bit requires mode == Pmode.
25365 NEG or PLUS already counted so only add one. */
25367 && (outer_code == NEG || outer_code == PLUS))
25369 *total = COSTS_N_INSNS (1);
25372 if (outer_code == SET)
25374 if (XEXP (x, 1) == const0_rtx)
25376 if (TARGET_ISEL && !TARGET_MFCRF)
25377 *total = COSTS_N_INSNS (8);
25379 *total = COSTS_N_INSNS (2);
25382 else if (mode == Pmode)
25384 *total = COSTS_N_INSNS (3);
25393 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
25395 if (TARGET_ISEL && !TARGET_MFCRF)
25396 *total = COSTS_N_INSNS (8);
25398 *total = COSTS_N_INSNS (2);
25402 if (outer_code == COMPARE)
25416 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
25419 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
25422 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
25425 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
25426 "total = %d, speed = %s, x:\n",
25427 ret ? "complete" : "scan inner",
25428 GET_RTX_NAME (code),
25429 GET_RTX_NAME (outer_code),
25431 speed ? "true" : "false");
25438 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
25441 rs6000_debug_address_cost (rtx x, bool speed)
25443 int ret = TARGET_ADDRESS_COST (x, speed);
25445 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
25446 ret, speed ? "true" : "false");
25453 /* A C expression returning the cost of moving data from a register of class
25454 CLASS1 to one of CLASS2. */
25457 rs6000_register_move_cost (enum machine_mode mode,
25458 enum reg_class from, enum reg_class to)
25462 /* Moves from/to GENERAL_REGS. */
25463 if (reg_classes_intersect_p (to, GENERAL_REGS)
25464 || reg_classes_intersect_p (from, GENERAL_REGS))
25466 if (! reg_classes_intersect_p (to, GENERAL_REGS))
25469 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
25470 ret = (rs6000_memory_move_cost (mode, from, 0)
25471 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
25473 /* It's more expensive to move CR_REGS than CR0_REGS because of the
25475 else if (from == CR_REGS)
25478 /* Power6 has slower LR/CTR moves so make them more expensive than
25479 memory in order to bias spills to memory .*/
25480 else if (rs6000_cpu == PROCESSOR_POWER6
25481 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
25482 ret = 6 * hard_regno_nregs[0][mode];
25485 /* A move will cost one instruction per GPR moved. */
25486 ret = 2 * hard_regno_nregs[0][mode];
25489 /* If we have VSX, we can easily move between FPR or Altivec registers. */
25490 else if (VECTOR_UNIT_VSX_P (mode)
25491 && reg_classes_intersect_p (to, VSX_REGS)
25492 && reg_classes_intersect_p (from, VSX_REGS))
25493 ret = 2 * hard_regno_nregs[32][mode];
25495 /* Moving between two similar registers is just one instruction. */
25496 else if (reg_classes_intersect_p (to, from))
25497 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
25499 /* Everything else has to go through GENERAL_REGS. */
25501 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
25502 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
25504 if (TARGET_DEBUG_COST)
25506 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
25507 ret, GET_MODE_NAME (mode), reg_class_names[from],
25508 reg_class_names[to]);
25513 /* A C expressions returning the cost of moving data of MODE from a register to
25517 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
25518 int in ATTRIBUTE_UNUSED)
25522 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
25523 ret = 4 * hard_regno_nregs[0][mode];
25524 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
25525 ret = 4 * hard_regno_nregs[32][mode];
25526 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
25527 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
25529 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
25531 if (TARGET_DEBUG_COST)
25533 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
25534 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
25539 /* Returns a code for a target-specific builtin that implements
25540 reciprocal of the function, or NULL_TREE if not available. */
25543 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
25544 bool sqrt ATTRIBUTE_UNUSED)
25546 if (optimize_insn_for_size_p ())
25552 case VSX_BUILTIN_XVSQRTDP:
25553 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
25556 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
25558 case VSX_BUILTIN_XVSQRTSP:
25559 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
25562 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
25571 case BUILT_IN_SQRT:
25572 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
25575 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
25577 case BUILT_IN_SQRTF:
25578 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
25581 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
25588 /* Load up a constant. If the mode is a vector mode, splat the value across
25589 all of the vector elements. */
25592 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
25596 if (mode == SFmode || mode == DFmode)
25598 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
25599 reg = force_reg (mode, d);
25601 else if (mode == V4SFmode)
25603 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
25604 rtvec v = gen_rtvec (4, d, d, d, d);
25605 reg = gen_reg_rtx (mode);
25606 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
25608 else if (mode == V2DFmode)
25610 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
25611 rtvec v = gen_rtvec (2, d, d);
25612 reg = gen_reg_rtx (mode);
25613 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
25616 gcc_unreachable ();
25621 /* Generate a FMADD instruction:
25622 dst = (m1 * m2) + a
25624 generating different RTL based on the fused multiply/add switch. */
25627 rs6000_emit_madd (rtx dst, rtx m1, rtx m2, rtx a)
25629 enum machine_mode mode = GET_MODE (dst);
25631 if (!TARGET_FUSED_MADD)
25633 /* For the simple ops, use the generator function, rather than assuming
25634 that the RTL is standard. */
25635 enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code;
25636 enum insn_code acode = optab_handler (add_optab, mode)->insn_code;
25637 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25638 gen_2arg_fn_t gen_add = (gen_2arg_fn_t) GEN_FCN (acode);
25639 rtx mreg = gen_reg_rtx (mode);
25641 gcc_assert (mcode != CODE_FOR_nothing && acode != CODE_FOR_nothing);
25642 emit_insn (gen_mul (mreg, m1, m2));
25643 emit_insn (gen_add (dst, mreg, a));
25647 emit_insn (gen_rtx_SET (VOIDmode, dst,
25648 gen_rtx_PLUS (mode,
25649 gen_rtx_MULT (mode, m1, m2),
25653 /* Generate a FMSUB instruction:
25654 dst = (m1 * m2) - a
25656 generating different RTL based on the fused multiply/add switch. */
25659 rs6000_emit_msub (rtx dst, rtx m1, rtx m2, rtx a)
25661 enum machine_mode mode = GET_MODE (dst);
25663 if (!TARGET_FUSED_MADD
25664 || (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (V4SFmode)))
25666 /* For the simple ops, use the generator function, rather than assuming
25667 that the RTL is standard. */
25668 enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code;
25669 enum insn_code scode = optab_handler (add_optab, mode)->insn_code;
25670 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25671 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
25672 rtx mreg = gen_reg_rtx (mode);
25674 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
25675 emit_insn (gen_mul (mreg, m1, m2));
25676 emit_insn (gen_sub (dst, mreg, a));
25680 emit_insn (gen_rtx_SET (VOIDmode, dst,
25681 gen_rtx_MINUS (mode,
25682 gen_rtx_MULT (mode, m1, m2),
25686 /* Generate a FNMSUB instruction:
25687 dst = - ((m1 * m2) - a)
25689 Which is equivalent to (except in the prescence of -0.0):
25690 dst = a - (m1 * m2)
25692 generating different RTL based on the fast-math and fused multiply/add
25696 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
25698 enum machine_mode mode = GET_MODE (dst);
25700 if (!TARGET_FUSED_MADD)
25702 /* For the simple ops, use the generator function, rather than assuming
25703 that the RTL is standard. */
25704 enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code;
25705 enum insn_code scode = optab_handler (sub_optab, mode)->insn_code;
25706 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25707 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
25708 rtx mreg = gen_reg_rtx (mode);
25710 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
25711 emit_insn (gen_mul (mreg, m1, m2));
25712 emit_insn (gen_sub (dst, a, mreg));
25717 rtx m = gen_rtx_MULT (mode, m1, m2);
25719 if (!HONOR_SIGNED_ZEROS (mode))
25720 emit_insn (gen_rtx_SET (VOIDmode, dst, gen_rtx_MINUS (mode, a, m)));
25723 emit_insn (gen_rtx_SET (VOIDmode, dst,
25725 gen_rtx_MINUS (mode, m, a))));
25729 /* Newton-Raphson approximation of floating point divide with just 2 passes
25730 (either single precision floating point, or newer machines with higher
25731 accuracy estimates). Support both scalar and vector divide. Assumes no
25732 trapping math and finite arguments. */
25735 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
25737 enum machine_mode mode = GET_MODE (dst);
25738 rtx x0, e0, e1, y1, u0, v0;
25739 enum insn_code code = optab_handler (smul_optab, mode)->insn_code;
25740 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25741 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
25743 gcc_assert (code != CODE_FOR_nothing);
25745 /* x0 = 1./d estimate */
25746 x0 = gen_reg_rtx (mode);
25747 emit_insn (gen_rtx_SET (VOIDmode, x0,
25748 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
25751 e0 = gen_reg_rtx (mode);
25752 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
25754 e1 = gen_reg_rtx (mode);
25755 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
25757 y1 = gen_reg_rtx (mode);
25758 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
25760 u0 = gen_reg_rtx (mode);
25761 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
25763 v0 = gen_reg_rtx (mode);
25764 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
25766 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
25769 /* Newton-Raphson approximation of floating point divide that has a low
25770 precision estimate. Assumes no trapping math and finite arguments. */
25773 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
25775 enum machine_mode mode = GET_MODE (dst);
25776 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
25777 enum insn_code code = optab_handler (smul_optab, mode)->insn_code;
25778 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25780 gcc_assert (code != CODE_FOR_nothing);
25782 one = rs6000_load_constant_and_splat (mode, dconst1);
25784 /* x0 = 1./d estimate */
25785 x0 = gen_reg_rtx (mode);
25786 emit_insn (gen_rtx_SET (VOIDmode, x0,
25787 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
25790 e0 = gen_reg_rtx (mode);
25791 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
25793 y1 = gen_reg_rtx (mode);
25794 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
25796 e1 = gen_reg_rtx (mode);
25797 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
25799 y2 = gen_reg_rtx (mode);
25800 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
25802 e2 = gen_reg_rtx (mode);
25803 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
25805 y3 = gen_reg_rtx (mode);
25806 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
25808 u0 = gen_reg_rtx (mode);
25809 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
25811 v0 = gen_reg_rtx (mode);
25812 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
25814 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
25817 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
25818 add a reg_note saying that this was a division. Support both scalar and
25819 vector divide. Assumes no trapping math and finite arguments. */
25822 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
25824 enum machine_mode mode = GET_MODE (dst);
25826 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
25827 rs6000_emit_swdiv_high_precision (dst, n, d);
25829 rs6000_emit_swdiv_low_precision (dst, n, d);
25832 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
25835 /* Newton-Raphson approximation of single/double-precision floating point
25836 rsqrt. Assumes no trapping math and finite arguments. */
25839 rs6000_emit_swrsqrt (rtx dst, rtx src)
25841 enum machine_mode mode = GET_MODE (src);
25842 rtx x0 = gen_reg_rtx (mode);
25843 rtx y = gen_reg_rtx (mode);
25844 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
25845 REAL_VALUE_TYPE dconst3_2;
25848 enum insn_code code = optab_handler (smul_optab, mode)->insn_code;
25849 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25851 gcc_assert (code != CODE_FOR_nothing);
25853 /* Load up the constant 1.5 either as a scalar, or as a vector. */
25854 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
25855 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
25857 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
25859 /* x0 = rsqrt estimate */
25860 emit_insn (gen_rtx_SET (VOIDmode, x0,
25861 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
25864 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
25865 rs6000_emit_msub (y, src, halfthree, src);
25867 for (i = 0; i < passes; i++)
25869 rtx x1 = gen_reg_rtx (mode);
25870 rtx u = gen_reg_rtx (mode);
25871 rtx v = gen_reg_rtx (mode);
25873 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
25874 emit_insn (gen_mul (u, x0, x0));
25875 rs6000_emit_nmsub (v, y, u, halfthree);
25876 emit_insn (gen_mul (x1, x0, v));
25880 emit_move_insn (dst, x0);
25884 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
25885 (Power7) targets. DST is the target, and SRC is the argument operand. */
25888 rs6000_emit_popcount (rtx dst, rtx src)
25890 enum machine_mode mode = GET_MODE (dst);
25893 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
25894 if (TARGET_POPCNTD)
25896 if (mode == SImode)
25897 emit_insn (gen_popcntwsi2 (dst, src));
25899 emit_insn (gen_popcntddi2 (dst, src));
25903 tmp1 = gen_reg_rtx (mode);
25905 if (mode == SImode)
25907 emit_insn (gen_popcntbsi2 (tmp1, src));
25908 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
25910 tmp2 = force_reg (SImode, tmp2);
25911 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
25915 emit_insn (gen_popcntbdi2 (tmp1, src));
25916 tmp2 = expand_mult (DImode, tmp1,
25917 GEN_INT ((HOST_WIDE_INT)
25918 0x01010101 << 32 | 0x01010101),
25920 tmp2 = force_reg (DImode, tmp2);
25921 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
25926 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25927 target, and SRC is the argument operand. */
25930 rs6000_emit_parity (rtx dst, rtx src)
25932 enum machine_mode mode = GET_MODE (dst);
25935 tmp = gen_reg_rtx (mode);
25936 if (mode == SImode)
25938 /* Is mult+shift >= shift+xor+shift+xor? */
25939 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
25941 rtx tmp1, tmp2, tmp3, tmp4;
25943 tmp1 = gen_reg_rtx (SImode);
25944 emit_insn (gen_popcntbsi2 (tmp1, src));
25946 tmp2 = gen_reg_rtx (SImode);
25947 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
25948 tmp3 = gen_reg_rtx (SImode);
25949 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
25951 tmp4 = gen_reg_rtx (SImode);
25952 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
25953 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
25956 rs6000_emit_popcount (tmp, src);
25957 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
25961 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25962 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
25964 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
25966 tmp1 = gen_reg_rtx (DImode);
25967 emit_insn (gen_popcntbdi2 (tmp1, src));
25969 tmp2 = gen_reg_rtx (DImode);
25970 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
25971 tmp3 = gen_reg_rtx (DImode);
25972 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
25974 tmp4 = gen_reg_rtx (DImode);
25975 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
25976 tmp5 = gen_reg_rtx (DImode);
25977 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
25979 tmp6 = gen_reg_rtx (DImode);
25980 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
25981 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
25984 rs6000_emit_popcount (tmp, src);
25985 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
25989 /* Return an RTX representing where to find the function value of a
25990 function returning MODE. */
25992 rs6000_complex_function_value (enum machine_mode mode)
25994 unsigned int regno;
25996 enum machine_mode inner = GET_MODE_INNER (mode);
25997 unsigned int inner_bytes = GET_MODE_SIZE (inner);
25999 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26000 regno = FP_ARG_RETURN;
26003 regno = GP_ARG_RETURN;
26005 /* 32-bit is OK since it'll go in r3/r4. */
26006 if (TARGET_32BIT && inner_bytes >= 4)
26007 return gen_rtx_REG (mode, regno);
26010 if (inner_bytes >= 8)
26011 return gen_rtx_REG (mode, regno);
26013 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26015 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26016 GEN_INT (inner_bytes));
26017 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26020 /* Target hook for TARGET_FUNCTION_VALUE.
26022 On the SPE, both FPs and vectors are returned in r3.
26024 On RS/6000 an integer value is in r3 and a floating-point value is in
26025 fp1, unless -msoft-float. */
26028 rs6000_function_value (const_tree valtype,
26029 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26030 bool outgoing ATTRIBUTE_UNUSED)
26032 enum machine_mode mode;
26033 unsigned int regno;
26035 /* Special handling for structs in darwin64. */
26036 if (rs6000_darwin64_abi
26037 && TYPE_MODE (valtype) == BLKmode
26038 && TREE_CODE (valtype) == RECORD_TYPE
26039 && int_size_in_bytes (valtype) > 0)
26041 CUMULATIVE_ARGS valcum;
26045 valcum.fregno = FP_ARG_MIN_REG;
26046 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26047 /* Do a trial code generation as if this were going to be passed as
26048 an argument; if any part goes in memory, we return NULL. */
26049 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
26052 /* Otherwise fall through to standard ABI rules. */
26055 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26057 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26058 return gen_rtx_PARALLEL (DImode,
26060 gen_rtx_EXPR_LIST (VOIDmode,
26061 gen_rtx_REG (SImode, GP_ARG_RETURN),
26063 gen_rtx_EXPR_LIST (VOIDmode,
26064 gen_rtx_REG (SImode,
26065 GP_ARG_RETURN + 1),
26068 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26070 return gen_rtx_PARALLEL (DCmode,
26072 gen_rtx_EXPR_LIST (VOIDmode,
26073 gen_rtx_REG (SImode, GP_ARG_RETURN),
26075 gen_rtx_EXPR_LIST (VOIDmode,
26076 gen_rtx_REG (SImode,
26077 GP_ARG_RETURN + 1),
26079 gen_rtx_EXPR_LIST (VOIDmode,
26080 gen_rtx_REG (SImode,
26081 GP_ARG_RETURN + 2),
26083 gen_rtx_EXPR_LIST (VOIDmode,
26084 gen_rtx_REG (SImode,
26085 GP_ARG_RETURN + 3),
26089 mode = TYPE_MODE (valtype);
26090 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26091 || POINTER_TYPE_P (valtype))
26092 mode = TARGET_32BIT ? SImode : DImode;
26094 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26095 /* _Decimal128 must use an even/odd register pair. */
26096 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26097 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26098 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26099 regno = FP_ARG_RETURN;
26100 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26101 && targetm.calls.split_complex_arg)
26102 return rs6000_complex_function_value (mode);
26103 else if (TREE_CODE (valtype) == VECTOR_TYPE
26104 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26105 && ALTIVEC_VECTOR_MODE (mode))
26106 regno = ALTIVEC_ARG_RETURN;
26107 else if (TREE_CODE (valtype) == VECTOR_TYPE
26108 && TARGET_VSX && TARGET_ALTIVEC_ABI
26109 && VSX_VECTOR_MODE (mode))
26110 regno = ALTIVEC_ARG_RETURN;
26111 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26112 && (mode == DFmode || mode == DCmode
26113 || mode == TFmode || mode == TCmode))
26114 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26116 regno = GP_ARG_RETURN;
26118 return gen_rtx_REG (mode, regno);
26121 /* Define how to find the value returned by a library function
26122 assuming the value has mode MODE. */
26124 rs6000_libcall_value (enum machine_mode mode)
26126 unsigned int regno;
26128 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26130 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26131 return gen_rtx_PARALLEL (DImode,
26133 gen_rtx_EXPR_LIST (VOIDmode,
26134 gen_rtx_REG (SImode, GP_ARG_RETURN),
26136 gen_rtx_EXPR_LIST (VOIDmode,
26137 gen_rtx_REG (SImode,
26138 GP_ARG_RETURN + 1),
26142 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26143 /* _Decimal128 must use an even/odd register pair. */
26144 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26145 else if (SCALAR_FLOAT_MODE_P (mode)
26146 && TARGET_HARD_FLOAT && TARGET_FPRS
26147 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26148 regno = FP_ARG_RETURN;
26149 else if (ALTIVEC_VECTOR_MODE (mode)
26150 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26151 regno = ALTIVEC_ARG_RETURN;
26152 else if (VSX_VECTOR_MODE (mode)
26153 && TARGET_VSX && TARGET_ALTIVEC_ABI)
26154 regno = ALTIVEC_ARG_RETURN;
26155 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26156 return rs6000_complex_function_value (mode);
26157 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26158 && (mode == DFmode || mode == DCmode
26159 || mode == TFmode || mode == TCmode))
26160 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26162 regno = GP_ARG_RETURN;
26164 return gen_rtx_REG (mode, regno);
26168 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26169 Frame pointer elimination is automatically handled.
26171 For the RS/6000, if frame pointer elimination is being done, we would like
26172 to convert ap into fp, not sp.
26174 We need r30 if -mminimal-toc was specified, and there are constant pool
26178 rs6000_can_eliminate (const int from, const int to)
26180 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26181 ? ! frame_pointer_needed
26182 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26183 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26187 /* Define the offset between two registers, FROM to be eliminated and its
26188 replacement TO, at the start of a routine. */
26190 rs6000_initial_elimination_offset (int from, int to)
26192 rs6000_stack_t *info = rs6000_stack_info ();
26193 HOST_WIDE_INT offset;
26195 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26196 offset = info->push_p ? 0 : -info->total_size;
26197 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26199 offset = info->push_p ? 0 : -info->total_size;
26200 if (FRAME_GROWS_DOWNWARD)
26201 offset += info->fixed_size + info->vars_size + info->parm_size;
26203 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26204 offset = FRAME_GROWS_DOWNWARD
26205 ? info->fixed_size + info->vars_size + info->parm_size
26207 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26208 offset = info->total_size;
26209 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26210 offset = info->push_p ? info->total_size : 0;
26211 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26214 gcc_unreachable ();
26220 rs6000_dwarf_register_span (rtx reg)
26224 unsigned regno = REGNO (reg);
26225 enum machine_mode mode = GET_MODE (reg);
26229 && (SPE_VECTOR_MODE (GET_MODE (reg))
26230 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26231 && mode != SFmode && mode != SDmode && mode != SCmode)))
26236 regno = REGNO (reg);
26238 /* The duality of the SPE register size wreaks all kinds of havoc.
26239 This is a way of distinguishing r0 in 32-bits from r0 in
26241 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26242 gcc_assert (words <= 4);
26243 for (i = 0; i < words; i++, regno++)
26245 if (BYTES_BIG_ENDIAN)
26247 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26248 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
26252 parts[2 * i] = gen_rtx_REG (SImode, regno);
26253 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
26257 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
26260 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26263 rs6000_init_dwarf_reg_sizes_extra (tree address)
26268 enum machine_mode mode = TYPE_MODE (char_type_node);
26269 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
26270 rtx mem = gen_rtx_MEM (BLKmode, addr);
26271 rtx value = gen_int_mode (4, mode);
26273 for (i = 1201; i < 1232; i++)
26275 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
26276 HOST_WIDE_INT offset
26277 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
26279 emit_move_insn (adjust_address (mem, mode, offset), value);
26284 /* Map internal gcc register numbers to DWARF2 register numbers. */
26287 rs6000_dbx_register_number (unsigned int regno)
26289 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
26291 if (regno == MQ_REGNO)
26293 if (regno == LR_REGNO)
26295 if (regno == CTR_REGNO)
26297 if (CR_REGNO_P (regno))
26298 return regno - CR0_REGNO + 86;
26299 if (regno == CA_REGNO)
26300 return 101; /* XER */
26301 if (ALTIVEC_REGNO_P (regno))
26302 return regno - FIRST_ALTIVEC_REGNO + 1124;
26303 if (regno == VRSAVE_REGNO)
26305 if (regno == VSCR_REGNO)
26307 if (regno == SPE_ACC_REGNO)
26309 if (regno == SPEFSCR_REGNO)
26311 /* SPE high reg number. We get these values of regno from
26312 rs6000_dwarf_register_span. */
26313 gcc_assert (regno >= 1200 && regno < 1232);
26317 /* target hook eh_return_filter_mode */
26318 static enum machine_mode
26319 rs6000_eh_return_filter_mode (void)
26321 return TARGET_32BIT ? SImode : word_mode;
26324 /* Target hook for scalar_mode_supported_p. */
26326 rs6000_scalar_mode_supported_p (enum machine_mode mode)
26328 if (DECIMAL_FLOAT_MODE_P (mode))
26329 return default_decimal_float_supported_p ();
26331 return default_scalar_mode_supported_p (mode);
26334 /* Target hook for vector_mode_supported_p. */
26336 rs6000_vector_mode_supported_p (enum machine_mode mode)
26339 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
26342 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
26345 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
26352 /* Target hook for invalid_arg_for_unprototyped_fn. */
26353 static const char *
26354 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
26356 return (!rs6000_darwin64_abi
26358 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
26359 && (funcdecl == NULL_TREE
26360 || (TREE_CODE (funcdecl) == FUNCTION_DECL
26361 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
26362 ? N_("AltiVec argument passed to unprototyped function")
26366 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
26367 setup by using __stack_chk_fail_local hidden function instead of
26368 calling __stack_chk_fail directly. Otherwise it is better to call
26369 __stack_chk_fail directly. */
26372 rs6000_stack_protect_fail (void)
26374 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
26375 ? default_hidden_stack_protect_fail ()
26376 : default_external_stack_protect_fail ();
26380 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
26381 int num_operands ATTRIBUTE_UNUSED)
26383 if (rs6000_warn_cell_microcode)
26386 int insn_code_number = recog_memoized (insn);
26387 location_t location = locator_location (INSN_LOCATOR (insn));
26389 /* Punt on insns we cannot recognize. */
26390 if (insn_code_number < 0)
26393 temp = get_insn_template (insn_code_number, insn);
26395 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
26396 warning_at (location, OPT_mwarn_cell_microcode,
26397 "emitting microcode insn %s\t[%s] #%d",
26398 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
26399 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
26400 warning_at (location, OPT_mwarn_cell_microcode,
26401 "emitting conditional microcode insn %s\t[%s] #%d",
26402 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
26406 #include "gt-rs6000.h"