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"
44 #include "diagnostic-core.h"
50 #include "target-def.h"
51 #include "langhooks.h"
53 #include "cfglayout.h"
54 #include "sched-int.h"
56 #include "tree-flow.h"
59 #include "tm-constrs.h"
61 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
64 #include "gstab.h" /* for N_SLINE */
67 #ifndef TARGET_NO_PROTOTYPE
68 #define TARGET_NO_PROTOTYPE 0
71 #define min(A,B) ((A) < (B) ? (A) : (B))
72 #define max(A,B) ((A) > (B) ? (A) : (B))
74 /* Structure used to define the rs6000 stack */
75 typedef struct rs6000_stack {
76 int first_gp_reg_save; /* first callee saved GP register used */
77 int first_fp_reg_save; /* first callee saved FP register used */
78 int first_altivec_reg_save; /* first callee saved AltiVec register used */
79 int lr_save_p; /* true if the link reg needs to be saved */
80 int cr_save_p; /* true if the CR reg needs to be saved */
81 unsigned int vrsave_mask; /* mask of vec registers to save */
82 int push_p; /* true if we need to allocate stack space */
83 int calls_p; /* true if the function makes any calls */
84 int world_save_p; /* true if we're saving *everything*:
85 r13-r31, cr, f14-f31, vrsave, v20-v31 */
86 enum rs6000_abi abi; /* which ABI to use */
87 int gp_save_offset; /* offset to save GP regs from initial SP */
88 int fp_save_offset; /* offset to save FP regs from initial SP */
89 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
90 int lr_save_offset; /* offset to save LR from initial SP */
91 int cr_save_offset; /* offset to save CR from initial SP */
92 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
93 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
94 int varargs_save_offset; /* offset to save the varargs registers */
95 int ehrd_offset; /* offset to EH return data */
96 int reg_size; /* register size (4 or 8) */
97 HOST_WIDE_INT vars_size; /* variable save area size */
98 int parm_size; /* outgoing parameter size */
99 int save_size; /* save area size */
100 int fixed_size; /* fixed size of stack frame */
101 int gp_size; /* size of saved GP registers */
102 int fp_size; /* size of saved FP registers */
103 int altivec_size; /* size of saved AltiVec registers */
104 int cr_size; /* size to hold CR if not in save_size */
105 int vrsave_size; /* size to hold VRSAVE if not in save_size */
106 int altivec_padding_size; /* size of altivec alignment padding if
108 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
109 int spe_padding_size;
110 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
111 int spe_64bit_regs_used;
114 /* A C structure for machine-specific, per-function data.
115 This is added to the cfun structure. */
116 typedef struct GTY(()) machine_function
118 /* Some local-dynamic symbol. */
119 const char *some_ld_name;
120 /* Whether the instruction chain has been scanned already. */
121 int insn_chain_scanned_p;
122 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
123 int ra_needs_full_frame;
124 /* Flags if __builtin_return_address (0) was used. */
126 /* Cache lr_save_p after expansion of builtin_eh_return. */
128 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
129 varargs save area. */
130 HOST_WIDE_INT varargs_save_offset;
131 /* Temporary stack slot to use for SDmode copies. This slot is
132 64-bits wide and is allocated early enough so that the offset
133 does not overflow the 16-bit load/store offset field. */
134 rtx sdmode_stack_slot;
137 /* Target cpu type */
139 enum processor_type rs6000_cpu;
140 struct rs6000_cpu_select rs6000_select[3] =
142 /* switch name, tune arch */
143 { (const char *)0, "--with-cpu=", 1, 1 },
144 { (const char *)0, "-mcpu=", 1, 1 },
145 { (const char *)0, "-mtune=", 1, 0 },
148 /* Always emit branch hint bits. */
149 static GTY(()) bool rs6000_always_hint;
151 /* Schedule instructions for group formation. */
152 static GTY(()) bool rs6000_sched_groups;
154 /* Align branch targets. */
155 static GTY(()) bool rs6000_align_branch_targets;
157 /* Support for -msched-costly-dep option. */
158 const char *rs6000_sched_costly_dep_str;
159 enum rs6000_dependence_cost rs6000_sched_costly_dep;
161 /* Support for -minsert-sched-nops option. */
162 const char *rs6000_sched_insert_nops_str;
163 enum rs6000_nop_insertion rs6000_sched_insert_nops;
165 /* Support targetm.vectorize.builtin_mask_for_load. */
166 static GTY(()) tree altivec_builtin_mask_for_load;
168 /* Size of long double. */
169 int rs6000_long_double_type_size;
171 /* IEEE quad extended precision long double. */
174 /* Nonzero to use AltiVec ABI. */
175 int rs6000_altivec_abi;
177 /* Nonzero if we want SPE SIMD instructions. */
180 /* Nonzero if we want SPE ABI extensions. */
183 /* Nonzero if floating point operations are done in the GPRs. */
184 int rs6000_float_gprs = 0;
186 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
187 int rs6000_darwin64_abi;
189 /* Set to nonzero once AIX common-mode calls have been defined. */
190 static GTY(()) int common_mode_defined;
192 /* Label number of label created for -mrelocatable, to call to so we can
193 get the address of the GOT section */
194 int rs6000_pic_labelno;
197 /* Which abi to adhere to */
198 const char *rs6000_abi_name;
200 /* Semantics of the small data area */
201 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
203 /* Which small data model to use */
204 const char *rs6000_sdata_name = (char *)0;
206 /* Counter for labels which are to be placed in .fixup. */
207 int fixuplabelno = 0;
210 /* Bit size of immediate TLS offsets and string from which it is decoded. */
211 int rs6000_tls_size = 32;
212 const char *rs6000_tls_size_string;
214 /* ABI enumeration available for subtarget to use. */
215 enum rs6000_abi rs6000_current_abi;
217 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
221 const char *rs6000_debug_name;
222 int rs6000_debug_stack; /* debug stack applications */
223 int rs6000_debug_arg; /* debug argument handling */
224 int rs6000_debug_reg; /* debug register classes */
225 int rs6000_debug_addr; /* debug memory addressing */
226 int rs6000_debug_cost; /* debug rtx_costs */
228 /* Specify the machine mode that pointers have. After generation of rtl, the
229 compiler makes no further distinction between pointers and any other objects
230 of this machine mode. The type is unsigned since not all things that
231 include rs6000.h also include machmode.h. */
232 unsigned rs6000_pmode;
234 /* Width in bits of a pointer. */
235 unsigned rs6000_pointer_size;
238 /* Value is TRUE if register/mode pair is acceptable. */
239 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
241 /* Maximum number of registers needed for a given register class and mode. */
242 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
244 /* How many registers are needed for a given register and mode. */
245 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
247 /* Map register number to register class. */
248 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
250 /* Reload functions based on the type and the vector unit. */
251 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
253 /* Built in types. */
254 tree rs6000_builtin_types[RS6000_BTI_MAX];
255 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
257 const char *rs6000_traceback_name;
259 traceback_default = 0,
265 /* Flag to say the TOC is initialized */
267 char toc_label_name[10];
269 /* Cached value of rs6000_variable_issue. This is cached in
270 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
271 static short cached_can_issue_more;
273 static GTY(()) section *read_only_data_section;
274 static GTY(()) section *private_data_section;
275 static GTY(()) section *read_only_private_data_section;
276 static GTY(()) section *sdata2_section;
277 static GTY(()) section *toc_section;
279 /* Control alignment for fields within structures. */
280 /* String from -malign-XXXXX. */
281 int rs6000_alignment_flags;
283 /* Code model for 64-bit linux. */
284 enum rs6000_cmodel cmodel;
286 /* True for any options that were explicitly set. */
288 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
289 bool alignment; /* True if -malign- was used. */
290 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
291 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
292 bool spe; /* True if -mspe= was used. */
293 bool float_gprs; /* True if -mfloat-gprs= was used. */
294 bool long_double; /* True if -mlong-double- was used. */
295 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
296 bool vrsave; /* True if -mvrsave was used. */
297 bool cmodel; /* True if -mcmodel was used. */
298 } rs6000_explicit_options;
300 struct builtin_description
302 /* mask is not const because we're going to alter it below. This
303 nonsense will go away when we rewrite the -march infrastructure
304 to give us more target flag bits. */
306 const enum insn_code icode;
307 const char *const name;
308 const enum rs6000_builtins code;
311 /* Describe the vector unit used for modes. */
312 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
313 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
315 /* Register classes for various constraints that are based on the target
317 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
319 /* Describe the alignment of a vector. */
320 int rs6000_vector_align[NUM_MACHINE_MODES];
322 /* Map selected modes to types for builtins. */
323 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
325 /* What modes to automatically generate reciprocal divide estimate (fre) and
326 reciprocal sqrt (frsqrte) for. */
327 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
329 /* Masks to determine which reciprocal esitmate instructions to generate
331 enum rs6000_recip_mask {
332 RECIP_SF_DIV = 0x001, /* Use divide estimate */
333 RECIP_DF_DIV = 0x002,
334 RECIP_V4SF_DIV = 0x004,
335 RECIP_V2DF_DIV = 0x008,
337 RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */
338 RECIP_DF_RSQRT = 0x020,
339 RECIP_V4SF_RSQRT = 0x040,
340 RECIP_V2DF_RSQRT = 0x080,
342 /* Various combination of flags for -mrecip=xxx. */
344 RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
345 | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
346 | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
348 RECIP_HIGH_PRECISION = RECIP_ALL,
350 /* On low precision machines like the power5, don't enable double precision
351 reciprocal square root estimate, since it isn't accurate enough. */
352 RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
355 static unsigned int rs6000_recip_control;
356 static const char *rs6000_recip_name;
358 /* -mrecip options. */
361 const char *string; /* option name */
362 unsigned int mask; /* mask bits to set */
363 } recip_options[] = {
364 { "all", RECIP_ALL },
365 { "none", RECIP_NONE },
366 { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
368 { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) },
369 { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) },
370 { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
371 | RECIP_V2DF_RSQRT) },
372 { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
373 { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
376 /* 2 argument gen function typedef. */
377 typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
380 /* Target cpu costs. */
382 struct processor_costs {
383 const int mulsi; /* cost of SImode multiplication. */
384 const int mulsi_const; /* cost of SImode multiplication by constant. */
385 const int mulsi_const9; /* cost of SImode mult by short constant. */
386 const int muldi; /* cost of DImode multiplication. */
387 const int divsi; /* cost of SImode division. */
388 const int divdi; /* cost of DImode division. */
389 const int fp; /* cost of simple SFmode and DFmode insns. */
390 const int dmul; /* cost of DFmode multiplication (and fmadd). */
391 const int sdiv; /* cost of SFmode division (fdivs). */
392 const int ddiv; /* cost of DFmode division (fdiv). */
393 const int cache_line_size; /* cache line size in bytes. */
394 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
395 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
396 const int simultaneous_prefetches; /* number of parallel prefetch
400 const struct processor_costs *rs6000_cost;
402 /* Processor costs (relative to an add) */
404 /* Instruction size costs on 32bit processors. */
406 struct processor_costs size32_cost = {
407 COSTS_N_INSNS (1), /* mulsi */
408 COSTS_N_INSNS (1), /* mulsi_const */
409 COSTS_N_INSNS (1), /* mulsi_const9 */
410 COSTS_N_INSNS (1), /* muldi */
411 COSTS_N_INSNS (1), /* divsi */
412 COSTS_N_INSNS (1), /* divdi */
413 COSTS_N_INSNS (1), /* fp */
414 COSTS_N_INSNS (1), /* dmul */
415 COSTS_N_INSNS (1), /* sdiv */
416 COSTS_N_INSNS (1), /* ddiv */
423 /* Instruction size costs on 64bit processors. */
425 struct processor_costs size64_cost = {
426 COSTS_N_INSNS (1), /* mulsi */
427 COSTS_N_INSNS (1), /* mulsi_const */
428 COSTS_N_INSNS (1), /* mulsi_const9 */
429 COSTS_N_INSNS (1), /* muldi */
430 COSTS_N_INSNS (1), /* divsi */
431 COSTS_N_INSNS (1), /* divdi */
432 COSTS_N_INSNS (1), /* fp */
433 COSTS_N_INSNS (1), /* dmul */
434 COSTS_N_INSNS (1), /* sdiv */
435 COSTS_N_INSNS (1), /* ddiv */
442 /* Instruction costs on RIOS1 processors. */
444 struct processor_costs rios1_cost = {
445 COSTS_N_INSNS (5), /* mulsi */
446 COSTS_N_INSNS (4), /* mulsi_const */
447 COSTS_N_INSNS (3), /* mulsi_const9 */
448 COSTS_N_INSNS (5), /* muldi */
449 COSTS_N_INSNS (19), /* divsi */
450 COSTS_N_INSNS (19), /* divdi */
451 COSTS_N_INSNS (2), /* fp */
452 COSTS_N_INSNS (2), /* dmul */
453 COSTS_N_INSNS (19), /* sdiv */
454 COSTS_N_INSNS (19), /* ddiv */
455 128, /* cache line size */
461 /* Instruction costs on RIOS2 processors. */
463 struct processor_costs rios2_cost = {
464 COSTS_N_INSNS (2), /* mulsi */
465 COSTS_N_INSNS (2), /* mulsi_const */
466 COSTS_N_INSNS (2), /* mulsi_const9 */
467 COSTS_N_INSNS (2), /* muldi */
468 COSTS_N_INSNS (13), /* divsi */
469 COSTS_N_INSNS (13), /* divdi */
470 COSTS_N_INSNS (2), /* fp */
471 COSTS_N_INSNS (2), /* dmul */
472 COSTS_N_INSNS (17), /* sdiv */
473 COSTS_N_INSNS (17), /* ddiv */
474 256, /* cache line size */
480 /* Instruction costs on RS64A processors. */
482 struct processor_costs rs64a_cost = {
483 COSTS_N_INSNS (20), /* mulsi */
484 COSTS_N_INSNS (12), /* mulsi_const */
485 COSTS_N_INSNS (8), /* mulsi_const9 */
486 COSTS_N_INSNS (34), /* muldi */
487 COSTS_N_INSNS (65), /* divsi */
488 COSTS_N_INSNS (67), /* divdi */
489 COSTS_N_INSNS (4), /* fp */
490 COSTS_N_INSNS (4), /* dmul */
491 COSTS_N_INSNS (31), /* sdiv */
492 COSTS_N_INSNS (31), /* ddiv */
493 128, /* cache line size */
499 /* Instruction costs on MPCCORE processors. */
501 struct processor_costs mpccore_cost = {
502 COSTS_N_INSNS (2), /* mulsi */
503 COSTS_N_INSNS (2), /* mulsi_const */
504 COSTS_N_INSNS (2), /* mulsi_const9 */
505 COSTS_N_INSNS (2), /* muldi */
506 COSTS_N_INSNS (6), /* divsi */
507 COSTS_N_INSNS (6), /* divdi */
508 COSTS_N_INSNS (4), /* fp */
509 COSTS_N_INSNS (5), /* dmul */
510 COSTS_N_INSNS (10), /* sdiv */
511 COSTS_N_INSNS (17), /* ddiv */
512 32, /* cache line size */
518 /* Instruction costs on PPC403 processors. */
520 struct processor_costs ppc403_cost = {
521 COSTS_N_INSNS (4), /* mulsi */
522 COSTS_N_INSNS (4), /* mulsi_const */
523 COSTS_N_INSNS (4), /* mulsi_const9 */
524 COSTS_N_INSNS (4), /* muldi */
525 COSTS_N_INSNS (33), /* divsi */
526 COSTS_N_INSNS (33), /* divdi */
527 COSTS_N_INSNS (11), /* fp */
528 COSTS_N_INSNS (11), /* dmul */
529 COSTS_N_INSNS (11), /* sdiv */
530 COSTS_N_INSNS (11), /* ddiv */
531 32, /* cache line size */
537 /* Instruction costs on PPC405 processors. */
539 struct processor_costs ppc405_cost = {
540 COSTS_N_INSNS (5), /* mulsi */
541 COSTS_N_INSNS (4), /* mulsi_const */
542 COSTS_N_INSNS (3), /* mulsi_const9 */
543 COSTS_N_INSNS (5), /* muldi */
544 COSTS_N_INSNS (35), /* divsi */
545 COSTS_N_INSNS (35), /* divdi */
546 COSTS_N_INSNS (11), /* fp */
547 COSTS_N_INSNS (11), /* dmul */
548 COSTS_N_INSNS (11), /* sdiv */
549 COSTS_N_INSNS (11), /* ddiv */
550 32, /* cache line size */
556 /* Instruction costs on PPC440 processors. */
558 struct processor_costs ppc440_cost = {
559 COSTS_N_INSNS (3), /* mulsi */
560 COSTS_N_INSNS (2), /* mulsi_const */
561 COSTS_N_INSNS (2), /* mulsi_const9 */
562 COSTS_N_INSNS (3), /* muldi */
563 COSTS_N_INSNS (34), /* divsi */
564 COSTS_N_INSNS (34), /* divdi */
565 COSTS_N_INSNS (5), /* fp */
566 COSTS_N_INSNS (5), /* dmul */
567 COSTS_N_INSNS (19), /* sdiv */
568 COSTS_N_INSNS (33), /* ddiv */
569 32, /* cache line size */
575 /* Instruction costs on PPC476 processors. */
577 struct processor_costs ppc476_cost = {
578 COSTS_N_INSNS (4), /* mulsi */
579 COSTS_N_INSNS (4), /* mulsi_const */
580 COSTS_N_INSNS (4), /* mulsi_const9 */
581 COSTS_N_INSNS (4), /* muldi */
582 COSTS_N_INSNS (11), /* divsi */
583 COSTS_N_INSNS (11), /* divdi */
584 COSTS_N_INSNS (6), /* fp */
585 COSTS_N_INSNS (6), /* dmul */
586 COSTS_N_INSNS (19), /* sdiv */
587 COSTS_N_INSNS (33), /* ddiv */
588 32, /* l1 cache line size */
594 /* Instruction costs on PPC601 processors. */
596 struct processor_costs ppc601_cost = {
597 COSTS_N_INSNS (5), /* mulsi */
598 COSTS_N_INSNS (5), /* mulsi_const */
599 COSTS_N_INSNS (5), /* mulsi_const9 */
600 COSTS_N_INSNS (5), /* muldi */
601 COSTS_N_INSNS (36), /* divsi */
602 COSTS_N_INSNS (36), /* divdi */
603 COSTS_N_INSNS (4), /* fp */
604 COSTS_N_INSNS (5), /* dmul */
605 COSTS_N_INSNS (17), /* sdiv */
606 COSTS_N_INSNS (31), /* ddiv */
607 32, /* cache line size */
613 /* Instruction costs on PPC603 processors. */
615 struct processor_costs ppc603_cost = {
616 COSTS_N_INSNS (5), /* mulsi */
617 COSTS_N_INSNS (3), /* mulsi_const */
618 COSTS_N_INSNS (2), /* mulsi_const9 */
619 COSTS_N_INSNS (5), /* muldi */
620 COSTS_N_INSNS (37), /* divsi */
621 COSTS_N_INSNS (37), /* divdi */
622 COSTS_N_INSNS (3), /* fp */
623 COSTS_N_INSNS (4), /* dmul */
624 COSTS_N_INSNS (18), /* sdiv */
625 COSTS_N_INSNS (33), /* ddiv */
626 32, /* cache line size */
632 /* Instruction costs on PPC604 processors. */
634 struct processor_costs ppc604_cost = {
635 COSTS_N_INSNS (4), /* mulsi */
636 COSTS_N_INSNS (4), /* mulsi_const */
637 COSTS_N_INSNS (4), /* mulsi_const9 */
638 COSTS_N_INSNS (4), /* muldi */
639 COSTS_N_INSNS (20), /* divsi */
640 COSTS_N_INSNS (20), /* divdi */
641 COSTS_N_INSNS (3), /* fp */
642 COSTS_N_INSNS (3), /* dmul */
643 COSTS_N_INSNS (18), /* sdiv */
644 COSTS_N_INSNS (32), /* ddiv */
645 32, /* cache line size */
651 /* Instruction costs on PPC604e processors. */
653 struct processor_costs ppc604e_cost = {
654 COSTS_N_INSNS (2), /* mulsi */
655 COSTS_N_INSNS (2), /* mulsi_const */
656 COSTS_N_INSNS (2), /* mulsi_const9 */
657 COSTS_N_INSNS (2), /* muldi */
658 COSTS_N_INSNS (20), /* divsi */
659 COSTS_N_INSNS (20), /* divdi */
660 COSTS_N_INSNS (3), /* fp */
661 COSTS_N_INSNS (3), /* dmul */
662 COSTS_N_INSNS (18), /* sdiv */
663 COSTS_N_INSNS (32), /* ddiv */
664 32, /* cache line size */
670 /* Instruction costs on PPC620 processors. */
672 struct processor_costs ppc620_cost = {
673 COSTS_N_INSNS (5), /* mulsi */
674 COSTS_N_INSNS (4), /* mulsi_const */
675 COSTS_N_INSNS (3), /* mulsi_const9 */
676 COSTS_N_INSNS (7), /* muldi */
677 COSTS_N_INSNS (21), /* divsi */
678 COSTS_N_INSNS (37), /* divdi */
679 COSTS_N_INSNS (3), /* fp */
680 COSTS_N_INSNS (3), /* dmul */
681 COSTS_N_INSNS (18), /* sdiv */
682 COSTS_N_INSNS (32), /* ddiv */
683 128, /* cache line size */
689 /* Instruction costs on PPC630 processors. */
691 struct processor_costs ppc630_cost = {
692 COSTS_N_INSNS (5), /* mulsi */
693 COSTS_N_INSNS (4), /* mulsi_const */
694 COSTS_N_INSNS (3), /* mulsi_const9 */
695 COSTS_N_INSNS (7), /* muldi */
696 COSTS_N_INSNS (21), /* divsi */
697 COSTS_N_INSNS (37), /* divdi */
698 COSTS_N_INSNS (3), /* fp */
699 COSTS_N_INSNS (3), /* dmul */
700 COSTS_N_INSNS (17), /* sdiv */
701 COSTS_N_INSNS (21), /* ddiv */
702 128, /* cache line size */
708 /* Instruction costs on Cell processor. */
709 /* COSTS_N_INSNS (1) ~ one add. */
711 struct processor_costs ppccell_cost = {
712 COSTS_N_INSNS (9/2)+2, /* mulsi */
713 COSTS_N_INSNS (6/2), /* mulsi_const */
714 COSTS_N_INSNS (6/2), /* mulsi_const9 */
715 COSTS_N_INSNS (15/2)+2, /* muldi */
716 COSTS_N_INSNS (38/2), /* divsi */
717 COSTS_N_INSNS (70/2), /* divdi */
718 COSTS_N_INSNS (10/2), /* fp */
719 COSTS_N_INSNS (10/2), /* dmul */
720 COSTS_N_INSNS (74/2), /* sdiv */
721 COSTS_N_INSNS (74/2), /* ddiv */
722 128, /* cache line size */
728 /* Instruction costs on PPC750 and PPC7400 processors. */
730 struct processor_costs ppc750_cost = {
731 COSTS_N_INSNS (5), /* mulsi */
732 COSTS_N_INSNS (3), /* mulsi_const */
733 COSTS_N_INSNS (2), /* mulsi_const9 */
734 COSTS_N_INSNS (5), /* muldi */
735 COSTS_N_INSNS (17), /* divsi */
736 COSTS_N_INSNS (17), /* divdi */
737 COSTS_N_INSNS (3), /* fp */
738 COSTS_N_INSNS (3), /* dmul */
739 COSTS_N_INSNS (17), /* sdiv */
740 COSTS_N_INSNS (31), /* ddiv */
741 32, /* cache line size */
747 /* Instruction costs on PPC7450 processors. */
749 struct processor_costs ppc7450_cost = {
750 COSTS_N_INSNS (4), /* mulsi */
751 COSTS_N_INSNS (3), /* mulsi_const */
752 COSTS_N_INSNS (3), /* mulsi_const9 */
753 COSTS_N_INSNS (4), /* muldi */
754 COSTS_N_INSNS (23), /* divsi */
755 COSTS_N_INSNS (23), /* divdi */
756 COSTS_N_INSNS (5), /* fp */
757 COSTS_N_INSNS (5), /* dmul */
758 COSTS_N_INSNS (21), /* sdiv */
759 COSTS_N_INSNS (35), /* ddiv */
760 32, /* cache line size */
766 /* Instruction costs on PPC8540 processors. */
768 struct processor_costs ppc8540_cost = {
769 COSTS_N_INSNS (4), /* mulsi */
770 COSTS_N_INSNS (4), /* mulsi_const */
771 COSTS_N_INSNS (4), /* mulsi_const9 */
772 COSTS_N_INSNS (4), /* muldi */
773 COSTS_N_INSNS (19), /* divsi */
774 COSTS_N_INSNS (19), /* divdi */
775 COSTS_N_INSNS (4), /* fp */
776 COSTS_N_INSNS (4), /* dmul */
777 COSTS_N_INSNS (29), /* sdiv */
778 COSTS_N_INSNS (29), /* ddiv */
779 32, /* cache line size */
782 1, /* prefetch streams /*/
785 /* Instruction costs on E300C2 and E300C3 cores. */
787 struct processor_costs ppce300c2c3_cost = {
788 COSTS_N_INSNS (4), /* mulsi */
789 COSTS_N_INSNS (4), /* mulsi_const */
790 COSTS_N_INSNS (4), /* mulsi_const9 */
791 COSTS_N_INSNS (4), /* muldi */
792 COSTS_N_INSNS (19), /* divsi */
793 COSTS_N_INSNS (19), /* divdi */
794 COSTS_N_INSNS (3), /* fp */
795 COSTS_N_INSNS (4), /* dmul */
796 COSTS_N_INSNS (18), /* sdiv */
797 COSTS_N_INSNS (33), /* ddiv */
801 1, /* prefetch streams /*/
804 /* Instruction costs on PPCE500MC processors. */
806 struct processor_costs ppce500mc_cost = {
807 COSTS_N_INSNS (4), /* mulsi */
808 COSTS_N_INSNS (4), /* mulsi_const */
809 COSTS_N_INSNS (4), /* mulsi_const9 */
810 COSTS_N_INSNS (4), /* muldi */
811 COSTS_N_INSNS (14), /* divsi */
812 COSTS_N_INSNS (14), /* divdi */
813 COSTS_N_INSNS (8), /* fp */
814 COSTS_N_INSNS (10), /* dmul */
815 COSTS_N_INSNS (36), /* sdiv */
816 COSTS_N_INSNS (66), /* ddiv */
817 64, /* cache line size */
820 1, /* prefetch streams /*/
823 /* Instruction costs on PPCE500MC64 processors. */
825 struct processor_costs ppce500mc64_cost = {
826 COSTS_N_INSNS (4), /* mulsi */
827 COSTS_N_INSNS (4), /* mulsi_const */
828 COSTS_N_INSNS (4), /* mulsi_const9 */
829 COSTS_N_INSNS (4), /* muldi */
830 COSTS_N_INSNS (14), /* divsi */
831 COSTS_N_INSNS (14), /* divdi */
832 COSTS_N_INSNS (4), /* fp */
833 COSTS_N_INSNS (10), /* dmul */
834 COSTS_N_INSNS (36), /* sdiv */
835 COSTS_N_INSNS (66), /* ddiv */
836 64, /* cache line size */
839 1, /* prefetch streams /*/
842 /* Instruction costs on AppliedMicro Titan processors. */
844 struct processor_costs titan_cost = {
845 COSTS_N_INSNS (5), /* mulsi */
846 COSTS_N_INSNS (5), /* mulsi_const */
847 COSTS_N_INSNS (5), /* mulsi_const9 */
848 COSTS_N_INSNS (5), /* muldi */
849 COSTS_N_INSNS (18), /* divsi */
850 COSTS_N_INSNS (18), /* divdi */
851 COSTS_N_INSNS (10), /* fp */
852 COSTS_N_INSNS (10), /* dmul */
853 COSTS_N_INSNS (46), /* sdiv */
854 COSTS_N_INSNS (72), /* ddiv */
855 32, /* cache line size */
858 1, /* prefetch streams /*/
861 /* Instruction costs on POWER4 and POWER5 processors. */
863 struct processor_costs power4_cost = {
864 COSTS_N_INSNS (3), /* mulsi */
865 COSTS_N_INSNS (2), /* mulsi_const */
866 COSTS_N_INSNS (2), /* mulsi_const9 */
867 COSTS_N_INSNS (4), /* muldi */
868 COSTS_N_INSNS (18), /* divsi */
869 COSTS_N_INSNS (34), /* divdi */
870 COSTS_N_INSNS (3), /* fp */
871 COSTS_N_INSNS (3), /* dmul */
872 COSTS_N_INSNS (17), /* sdiv */
873 COSTS_N_INSNS (17), /* ddiv */
874 128, /* cache line size */
877 8, /* prefetch streams /*/
880 /* Instruction costs on POWER6 processors. */
882 struct processor_costs power6_cost = {
883 COSTS_N_INSNS (8), /* mulsi */
884 COSTS_N_INSNS (8), /* mulsi_const */
885 COSTS_N_INSNS (8), /* mulsi_const9 */
886 COSTS_N_INSNS (8), /* muldi */
887 COSTS_N_INSNS (22), /* divsi */
888 COSTS_N_INSNS (28), /* divdi */
889 COSTS_N_INSNS (3), /* fp */
890 COSTS_N_INSNS (3), /* dmul */
891 COSTS_N_INSNS (13), /* sdiv */
892 COSTS_N_INSNS (16), /* ddiv */
893 128, /* cache line size */
896 16, /* prefetch streams */
899 /* Instruction costs on POWER7 processors. */
901 struct processor_costs power7_cost = {
902 COSTS_N_INSNS (2), /* mulsi */
903 COSTS_N_INSNS (2), /* mulsi_const */
904 COSTS_N_INSNS (2), /* mulsi_const9 */
905 COSTS_N_INSNS (2), /* muldi */
906 COSTS_N_INSNS (18), /* divsi */
907 COSTS_N_INSNS (34), /* divdi */
908 COSTS_N_INSNS (3), /* fp */
909 COSTS_N_INSNS (3), /* dmul */
910 COSTS_N_INSNS (13), /* sdiv */
911 COSTS_N_INSNS (16), /* ddiv */
912 128, /* cache line size */
915 12, /* prefetch streams */
918 /* Instruction costs on POWER A2 processors. */
920 struct processor_costs ppca2_cost = {
921 COSTS_N_INSNS (16), /* mulsi */
922 COSTS_N_INSNS (16), /* mulsi_const */
923 COSTS_N_INSNS (16), /* mulsi_const9 */
924 COSTS_N_INSNS (16), /* muldi */
925 COSTS_N_INSNS (22), /* divsi */
926 COSTS_N_INSNS (28), /* divdi */
927 COSTS_N_INSNS (3), /* fp */
928 COSTS_N_INSNS (3), /* dmul */
929 COSTS_N_INSNS (59), /* sdiv */
930 COSTS_N_INSNS (72), /* ddiv */
934 16, /* prefetch streams */
938 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
939 #undef RS6000_BUILTIN
940 #undef RS6000_BUILTIN_EQUATE
941 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
942 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
944 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
946 #include "rs6000-builtin.def"
949 #undef RS6000_BUILTIN
950 #undef RS6000_BUILTIN_EQUATE
952 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
953 static tree (*rs6000_veclib_handler) (tree, tree, tree);
956 static bool rs6000_function_ok_for_sibcall (tree, tree);
957 static const char *rs6000_invalid_within_doloop (const_rtx);
958 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
959 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
960 static rtx rs6000_generate_compare (rtx, enum machine_mode);
961 static void rs6000_emit_stack_tie (void);
962 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
963 static bool spe_func_has_64bit_regs_p (void);
964 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
966 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
967 static unsigned rs6000_hash_constant (rtx);
968 static unsigned toc_hash_function (const void *);
969 static int toc_hash_eq (const void *, const void *);
970 static bool reg_offset_addressing_ok_p (enum machine_mode);
971 static bool virtual_stack_registers_memory_p (rtx);
972 static bool constant_pool_expr_p (rtx);
973 static bool legitimate_small_data_p (enum machine_mode, rtx);
974 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
975 static struct machine_function * rs6000_init_machine_status (void);
976 static bool rs6000_assemble_integer (rtx, unsigned int, int);
977 static bool no_global_regs_above (int, bool);
978 #ifdef HAVE_GAS_HIDDEN
979 static void rs6000_assemble_visibility (tree, int);
981 static int rs6000_ra_ever_killed (void);
982 static bool rs6000_attribute_takes_identifier_p (const_tree);
983 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
984 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
985 static bool rs6000_ms_bitfield_layout_p (const_tree);
986 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
987 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
988 static const char *rs6000_mangle_type (const_tree);
989 static void rs6000_set_default_type_attributes (tree);
990 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
991 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
992 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
993 enum machine_mode, bool, bool, bool);
994 static bool rs6000_reg_live_or_pic_offset_p (int);
995 static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
996 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
997 static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
998 static void rs6000_restore_saved_cr (rtx, int);
999 static bool rs6000_output_addr_const_extra (FILE *, rtx);
1000 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
1001 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
1002 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
1004 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
1005 static bool rs6000_return_in_memory (const_tree, const_tree);
1006 static rtx rs6000_function_value (const_tree, const_tree, bool);
1007 static void rs6000_file_start (void);
1009 static int rs6000_elf_reloc_rw_mask (void);
1010 static void rs6000_elf_asm_out_constructor (rtx, int);
1011 static void rs6000_elf_asm_out_destructor (rtx, int);
1012 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
1013 static void rs6000_elf_asm_init_sections (void);
1014 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
1015 unsigned HOST_WIDE_INT);
1016 static void rs6000_elf_encode_section_info (tree, rtx, int)
1019 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
1020 static void rs6000_alloc_sdmode_stack_slot (void);
1021 static void rs6000_instantiate_decls (void);
1023 static void rs6000_xcoff_asm_output_anchor (rtx);
1024 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
1025 static void rs6000_xcoff_asm_init_sections (void);
1026 static int rs6000_xcoff_reloc_rw_mask (void);
1027 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
1028 static section *rs6000_xcoff_select_section (tree, int,
1029 unsigned HOST_WIDE_INT);
1030 static void rs6000_xcoff_unique_section (tree, int);
1031 static section *rs6000_xcoff_select_rtx_section
1032 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
1033 static const char * rs6000_xcoff_strip_name_encoding (const char *);
1034 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
1035 static void rs6000_xcoff_file_start (void);
1036 static void rs6000_xcoff_file_end (void);
1038 static int rs6000_variable_issue (FILE *, int, rtx, int);
1039 static int rs6000_register_move_cost (enum machine_mode,
1040 reg_class_t, reg_class_t);
1041 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
1042 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
1043 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
1044 static int rs6000_debug_address_cost (rtx, bool);
1045 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
1046 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
1047 static void rs6000_sched_init (FILE *, int, int);
1048 static bool is_microcoded_insn (rtx);
1049 static bool is_nonpipeline_insn (rtx);
1050 static bool is_cracked_insn (rtx);
1051 static bool is_branch_slot_insn (rtx);
1052 static bool is_load_insn (rtx);
1053 static rtx get_store_dest (rtx pat);
1054 static bool is_store_insn (rtx);
1055 static bool set_to_load_agen (rtx,rtx);
1056 static bool adjacent_mem_locations (rtx,rtx);
1057 static int rs6000_adjust_priority (rtx, int);
1058 static int rs6000_issue_rate (void);
1059 static bool rs6000_is_costly_dependence (dep_t, int, int);
1060 static rtx get_next_active_insn (rtx, rtx);
1061 static bool insn_terminates_group_p (rtx , enum group_termination);
1062 static bool insn_must_be_first_in_group (rtx);
1063 static bool insn_must_be_last_in_group (rtx);
1064 static bool is_costly_group (rtx *, rtx);
1065 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
1066 static int redefine_groups (FILE *, int, rtx, rtx);
1067 static int pad_groups (FILE *, int, rtx, rtx);
1068 static void rs6000_sched_finish (FILE *, int);
1069 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
1070 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
1071 static int rs6000_use_sched_lookahead (void);
1072 static int rs6000_use_sched_lookahead_guard (rtx);
1073 static void * rs6000_alloc_sched_context (void);
1074 static void rs6000_init_sched_context (void *, bool);
1075 static void rs6000_set_sched_context (void *);
1076 static void rs6000_free_sched_context (void *);
1077 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
1078 static tree rs6000_builtin_mask_for_load (void);
1079 static tree rs6000_builtin_mul_widen_even (tree);
1080 static tree rs6000_builtin_mul_widen_odd (tree);
1081 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
1082 static tree rs6000_builtin_vec_perm (tree, tree *);
1083 static bool rs6000_builtin_support_vector_misalignment (enum
1087 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
1089 static unsigned int rs6000_units_per_simd_word (enum machine_mode);
1091 static void def_builtin (int, const char *, tree, int);
1092 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1093 static void rs6000_init_builtins (void);
1094 static tree rs6000_builtin_decl (unsigned, bool);
1096 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1097 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1098 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1099 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1100 static void altivec_init_builtins (void);
1101 static unsigned builtin_hash_function (const void *);
1102 static int builtin_hash_eq (const void *, const void *);
1103 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1104 enum machine_mode, enum machine_mode,
1105 enum rs6000_builtins, const char *name);
1106 static void rs6000_common_init_builtins (void);
1107 static void rs6000_init_libfuncs (void);
1109 static void paired_init_builtins (void);
1110 static rtx paired_expand_builtin (tree, rtx, bool *);
1111 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1112 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1113 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1115 static void enable_mask_for_builtins (struct builtin_description *, int,
1116 enum rs6000_builtins,
1117 enum rs6000_builtins);
1118 static void spe_init_builtins (void);
1119 static rtx spe_expand_builtin (tree, rtx, bool *);
1120 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1121 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1122 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1123 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1124 static rs6000_stack_t *rs6000_stack_info (void);
1125 static void debug_stack_info (rs6000_stack_t *);
1127 static rtx altivec_expand_builtin (tree, rtx, bool *);
1128 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1129 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1130 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1131 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1132 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1133 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1134 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1135 static rtx altivec_expand_vec_set_builtin (tree);
1136 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1137 static int get_element_number (tree, tree);
1138 static void rs6000_option_override (void);
1139 static void rs6000_option_optimization (int, int);
1140 static bool rs6000_handle_option (size_t, const char *, int);
1141 static void rs6000_parse_tls_size_option (void);
1142 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1143 static int first_altivec_reg_to_save (void);
1144 static unsigned int compute_vrsave_mask (void);
1145 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1146 static void is_altivec_return_reg (rtx, void *);
1147 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1148 int easy_vector_constant (rtx, enum machine_mode);
1149 static rtx rs6000_dwarf_register_span (rtx);
1150 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1151 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1152 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1153 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1154 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1155 static rtx rs6000_delegitimize_address (rtx);
1156 static rtx rs6000_tls_get_addr (void);
1157 static rtx rs6000_got_sym (void);
1158 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1159 static const char *rs6000_get_some_local_dynamic_name (void);
1160 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1161 static rtx rs6000_complex_function_value (enum machine_mode);
1162 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1163 enum machine_mode, const_tree);
1164 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1165 HOST_WIDE_INT, int);
1166 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1169 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1172 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1173 const_tree, HOST_WIDE_INT,
1175 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1176 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1177 static void rs6000_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
1179 static rtx rs6000_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
1181 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1182 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1183 enum machine_mode, tree,
1185 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1187 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1189 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1191 static void macho_branch_islands (void);
1192 static int no_previous_def (tree function_name);
1193 static tree get_prev_label (tree function_name);
1194 static void rs6000_darwin_file_start (void);
1197 static tree rs6000_build_builtin_va_list (void);
1198 static void rs6000_va_start (tree, rtx);
1199 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1200 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1201 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1202 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1203 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1204 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1206 static tree rs6000_stack_protect_fail (void);
1208 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1211 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1214 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1216 = rs6000_legitimize_reload_address;
1218 static bool rs6000_mode_dependent_address_p (const_rtx);
1219 static bool rs6000_mode_dependent_address (const_rtx);
1220 static bool rs6000_debug_mode_dependent_address (const_rtx);
1221 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1222 = rs6000_mode_dependent_address;
1224 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1225 enum machine_mode, rtx);
1226 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1229 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1230 enum machine_mode, rtx)
1231 = rs6000_secondary_reload_class;
1233 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1234 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1236 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1237 = rs6000_preferred_reload_class;
1239 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1242 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1246 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1248 = rs6000_secondary_memory_needed;
1250 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1253 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1257 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1260 = rs6000_cannot_change_mode_class;
1262 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1264 struct secondary_reload_info *);
1266 static const reg_class_t *rs6000_ira_cover_classes (void);
1268 const int INSN_NOT_AVAILABLE = -1;
1269 static enum machine_mode rs6000_eh_return_filter_mode (void);
1270 static bool rs6000_can_eliminate (const int, const int);
1271 static void rs6000_trampoline_init (rtx, tree, rtx);
1273 /* Hash table stuff for keeping track of TOC entries. */
1275 struct GTY(()) toc_hash_struct
1277 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1278 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1280 enum machine_mode key_mode;
1284 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1286 /* Hash table to keep track of the argument types for builtin functions. */
1288 struct GTY(()) builtin_hash_struct
1291 enum machine_mode mode[4]; /* return value + 3 arguments. */
1292 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1295 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1297 /* Default register names. */
1298 char rs6000_reg_names[][8] =
1300 "0", "1", "2", "3", "4", "5", "6", "7",
1301 "8", "9", "10", "11", "12", "13", "14", "15",
1302 "16", "17", "18", "19", "20", "21", "22", "23",
1303 "24", "25", "26", "27", "28", "29", "30", "31",
1304 "0", "1", "2", "3", "4", "5", "6", "7",
1305 "8", "9", "10", "11", "12", "13", "14", "15",
1306 "16", "17", "18", "19", "20", "21", "22", "23",
1307 "24", "25", "26", "27", "28", "29", "30", "31",
1308 "mq", "lr", "ctr","ap",
1309 "0", "1", "2", "3", "4", "5", "6", "7",
1311 /* AltiVec registers. */
1312 "0", "1", "2", "3", "4", "5", "6", "7",
1313 "8", "9", "10", "11", "12", "13", "14", "15",
1314 "16", "17", "18", "19", "20", "21", "22", "23",
1315 "24", "25", "26", "27", "28", "29", "30", "31",
1317 /* SPE registers. */
1318 "spe_acc", "spefscr",
1319 /* Soft frame pointer. */
1323 #ifdef TARGET_REGNAMES
1324 static const char alt_reg_names[][8] =
1326 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1327 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1328 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1329 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1330 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1331 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1332 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1333 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1334 "mq", "lr", "ctr", "ap",
1335 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1337 /* AltiVec registers. */
1338 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1339 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1340 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1341 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1343 /* SPE registers. */
1344 "spe_acc", "spefscr",
1345 /* Soft frame pointer. */
1350 /* Table of valid machine attributes. */
1352 static const struct attribute_spec rs6000_attribute_table[] =
1354 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1355 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1356 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1357 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1358 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1359 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1360 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1361 SUBTARGET_ATTRIBUTE_TABLE,
1363 { NULL, 0, 0, false, false, false, NULL }
1366 #ifndef MASK_STRICT_ALIGN
1367 #define MASK_STRICT_ALIGN 0
1369 #ifndef TARGET_PROFILE_KERNEL
1370 #define TARGET_PROFILE_KERNEL 0
1373 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1374 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1376 /* Initialize the GCC target structure. */
1377 #undef TARGET_ATTRIBUTE_TABLE
1378 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1379 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1380 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1381 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1382 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1384 #undef TARGET_ASM_ALIGNED_DI_OP
1385 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1387 /* Default unaligned ops are only provided for ELF. Find the ops needed
1388 for non-ELF systems. */
1389 #ifndef OBJECT_FORMAT_ELF
1391 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1393 #undef TARGET_ASM_UNALIGNED_HI_OP
1394 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1395 #undef TARGET_ASM_UNALIGNED_SI_OP
1396 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1397 #undef TARGET_ASM_UNALIGNED_DI_OP
1398 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1401 #undef TARGET_ASM_UNALIGNED_HI_OP
1402 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1403 #undef TARGET_ASM_UNALIGNED_SI_OP
1404 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1405 #undef TARGET_ASM_UNALIGNED_DI_OP
1406 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1407 #undef TARGET_ASM_ALIGNED_DI_OP
1408 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1412 /* This hook deals with fixups for relocatable code and DI-mode objects
1414 #undef TARGET_ASM_INTEGER
1415 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1417 #ifdef HAVE_GAS_HIDDEN
1418 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1419 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1422 #undef TARGET_HAVE_TLS
1423 #define TARGET_HAVE_TLS HAVE_AS_TLS
1425 #undef TARGET_CANNOT_FORCE_CONST_MEM
1426 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1428 #undef TARGET_DELEGITIMIZE_ADDRESS
1429 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1431 #undef TARGET_ASM_FUNCTION_PROLOGUE
1432 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1433 #undef TARGET_ASM_FUNCTION_EPILOGUE
1434 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1436 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1437 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1439 #undef TARGET_LEGITIMIZE_ADDRESS
1440 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1442 #undef TARGET_SCHED_VARIABLE_ISSUE
1443 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1445 #undef TARGET_SCHED_ISSUE_RATE
1446 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1447 #undef TARGET_SCHED_ADJUST_COST
1448 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1449 #undef TARGET_SCHED_ADJUST_PRIORITY
1450 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1451 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1452 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1453 #undef TARGET_SCHED_INIT
1454 #define TARGET_SCHED_INIT rs6000_sched_init
1455 #undef TARGET_SCHED_FINISH
1456 #define TARGET_SCHED_FINISH rs6000_sched_finish
1457 #undef TARGET_SCHED_REORDER
1458 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1459 #undef TARGET_SCHED_REORDER2
1460 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1462 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1463 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1465 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1466 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1468 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1469 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1470 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1471 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1472 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1473 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1474 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1475 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1477 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1478 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1479 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1480 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1481 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1482 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1483 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1484 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1485 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1486 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1487 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1488 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1489 rs6000_builtin_support_vector_misalignment
1490 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1491 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1492 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1493 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1494 rs6000_builtin_vectorization_cost
1495 #undef TARGET_VECTORIZE_UNITS_PER_SIMD_WORD
1496 #define TARGET_VECTORIZE_UNITS_PER_SIMD_WORD \
1497 rs6000_units_per_simd_word
1499 #undef TARGET_INIT_BUILTINS
1500 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1501 #undef TARGET_BUILTIN_DECL
1502 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1504 #undef TARGET_EXPAND_BUILTIN
1505 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1507 #undef TARGET_MANGLE_TYPE
1508 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1510 #undef TARGET_INIT_LIBFUNCS
1511 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1514 #undef TARGET_BINDS_LOCAL_P
1515 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1518 #undef TARGET_MS_BITFIELD_LAYOUT_P
1519 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1521 #undef TARGET_ASM_OUTPUT_MI_THUNK
1522 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1524 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1525 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1527 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1528 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1530 #undef TARGET_INVALID_WITHIN_DOLOOP
1531 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1533 #undef TARGET_REGISTER_MOVE_COST
1534 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1535 #undef TARGET_MEMORY_MOVE_COST
1536 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1537 #undef TARGET_RTX_COSTS
1538 #define TARGET_RTX_COSTS rs6000_rtx_costs
1539 #undef TARGET_ADDRESS_COST
1540 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1542 #undef TARGET_DWARF_REGISTER_SPAN
1543 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1545 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1546 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1548 /* On rs6000, function arguments are promoted, as are function return
1550 #undef TARGET_PROMOTE_FUNCTION_MODE
1551 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1553 #undef TARGET_RETURN_IN_MEMORY
1554 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1556 #undef TARGET_SETUP_INCOMING_VARARGS
1557 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1559 /* Always strict argument naming on rs6000. */
1560 #undef TARGET_STRICT_ARGUMENT_NAMING
1561 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1562 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1563 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1564 #undef TARGET_SPLIT_COMPLEX_ARG
1565 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1566 #undef TARGET_MUST_PASS_IN_STACK
1567 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1568 #undef TARGET_PASS_BY_REFERENCE
1569 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1570 #undef TARGET_ARG_PARTIAL_BYTES
1571 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1572 #undef TARGET_FUNCTION_ARG_ADVANCE
1573 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1574 #undef TARGET_FUNCTION_ARG
1575 #define TARGET_FUNCTION_ARG rs6000_function_arg
1577 #undef TARGET_BUILD_BUILTIN_VA_LIST
1578 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1580 #undef TARGET_EXPAND_BUILTIN_VA_START
1581 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1583 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1584 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1586 #undef TARGET_EH_RETURN_FILTER_MODE
1587 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1589 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1590 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1592 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1593 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1595 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1596 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1598 #undef TARGET_HANDLE_OPTION
1599 #define TARGET_HANDLE_OPTION rs6000_handle_option
1601 #undef TARGET_OPTION_OVERRIDE
1602 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1604 #undef TARGET_OPTION_OPTIMIZATION
1605 #define TARGET_OPTION_OPTIMIZATION rs6000_option_optimization
1607 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1608 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1609 rs6000_builtin_vectorized_function
1611 #undef TARGET_DEFAULT_TARGET_FLAGS
1612 #define TARGET_DEFAULT_TARGET_FLAGS \
1615 #undef TARGET_STACK_PROTECT_FAIL
1616 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1618 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1619 The PowerPC architecture requires only weak consistency among
1620 processors--that is, memory accesses between processors need not be
1621 sequentially consistent and memory accesses among processors can occur
1622 in any order. The ability to order memory accesses weakly provides
1623 opportunities for more efficient use of the system bus. Unless a
1624 dependency exists, the 604e allows read operations to precede store
1626 #undef TARGET_RELAXED_ORDERING
1627 #define TARGET_RELAXED_ORDERING true
1630 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1631 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1634 /* Use a 32-bit anchor range. This leads to sequences like:
1636 addis tmp,anchor,high
1639 where tmp itself acts as an anchor, and can be shared between
1640 accesses to the same 64k page. */
1641 #undef TARGET_MIN_ANCHOR_OFFSET
1642 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1643 #undef TARGET_MAX_ANCHOR_OFFSET
1644 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1645 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1646 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1648 #undef TARGET_BUILTIN_RECIPROCAL
1649 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1651 #undef TARGET_EXPAND_TO_RTL_HOOK
1652 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1654 #undef TARGET_INSTANTIATE_DECLS
1655 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1657 #undef TARGET_SECONDARY_RELOAD
1658 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1660 #undef TARGET_IRA_COVER_CLASSES
1661 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1663 #undef TARGET_LEGITIMATE_ADDRESS_P
1664 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1666 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1667 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1669 #undef TARGET_CAN_ELIMINATE
1670 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1672 #undef TARGET_TRAMPOLINE_INIT
1673 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1675 #undef TARGET_FUNCTION_VALUE
1676 #define TARGET_FUNCTION_VALUE rs6000_function_value
1678 struct gcc_target targetm = TARGET_INITIALIZER;
1680 /* Return number of consecutive hard regs needed starting at reg REGNO
1681 to hold something of mode MODE.
1682 This is ordinarily the length in words of a value of mode MODE
1683 but can be less for certain modes in special long registers.
1685 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1686 scalar instructions. The upper 32 bits are only available to the
1689 POWER and PowerPC GPRs hold 32 bits worth;
1690 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1693 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1695 unsigned HOST_WIDE_INT reg_size;
1697 if (FP_REGNO_P (regno))
1698 reg_size = (VECTOR_MEM_VSX_P (mode)
1699 ? UNITS_PER_VSX_WORD
1700 : UNITS_PER_FP_WORD);
1702 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1703 reg_size = UNITS_PER_SPE_WORD;
1705 else if (ALTIVEC_REGNO_P (regno))
1706 reg_size = UNITS_PER_ALTIVEC_WORD;
1708 /* The value returned for SCmode in the E500 double case is 2 for
1709 ABI compatibility; storing an SCmode value in a single register
1710 would require function_arg and rs6000_spe_function_arg to handle
1711 SCmode so as to pass the value correctly in a pair of
1713 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1714 && !DECIMAL_FLOAT_MODE_P (mode))
1715 reg_size = UNITS_PER_FP_WORD;
1718 reg_size = UNITS_PER_WORD;
1720 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1723 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1726 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1728 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1730 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1731 implementations. Don't allow an item to be split between a FP register
1732 and an Altivec register. */
1733 if (VECTOR_MEM_VSX_P (mode))
1735 if (FP_REGNO_P (regno))
1736 return FP_REGNO_P (last_regno);
1738 if (ALTIVEC_REGNO_P (regno))
1739 return ALTIVEC_REGNO_P (last_regno);
1742 /* The GPRs can hold any mode, but values bigger than one register
1743 cannot go past R31. */
1744 if (INT_REGNO_P (regno))
1745 return INT_REGNO_P (last_regno);
1747 /* The float registers (except for VSX vector modes) can only hold floating
1748 modes and DImode. This excludes the 32-bit decimal float mode for
1750 if (FP_REGNO_P (regno))
1752 if (SCALAR_FLOAT_MODE_P (mode)
1753 && (mode != TDmode || (regno % 2) == 0)
1754 && FP_REGNO_P (last_regno))
1757 if (GET_MODE_CLASS (mode) == MODE_INT
1758 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1761 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1762 && PAIRED_VECTOR_MODE (mode))
1768 /* The CR register can only hold CC modes. */
1769 if (CR_REGNO_P (regno))
1770 return GET_MODE_CLASS (mode) == MODE_CC;
1772 if (CA_REGNO_P (regno))
1773 return mode == BImode;
1775 /* AltiVec only in AldyVec registers. */
1776 if (ALTIVEC_REGNO_P (regno))
1777 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1779 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1780 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1783 /* We cannot put TImode anywhere except general register and it must be able
1784 to fit within the register set. In the future, allow TImode in the
1785 Altivec or VSX registers. */
1787 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1790 /* Print interesting facts about registers. */
1792 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1796 for (r = first_regno; r <= last_regno; ++r)
1798 const char *comma = "";
1801 if (first_regno == last_regno)
1802 fprintf (stderr, "%s:\t", reg_name);
1804 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1807 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1808 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1812 fprintf (stderr, ",\n\t");
1817 if (rs6000_hard_regno_nregs[m][r] > 1)
1818 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1819 rs6000_hard_regno_nregs[m][r]);
1821 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1826 if (call_used_regs[r])
1830 fprintf (stderr, ",\n\t");
1835 len += fprintf (stderr, "%s%s", comma, "call-used");
1843 fprintf (stderr, ",\n\t");
1848 len += fprintf (stderr, "%s%s", comma, "fixed");
1854 fprintf (stderr, ",\n\t");
1858 fprintf (stderr, "%sregno = %d\n", comma, r);
1862 /* Print various interesting information with -mdebug=reg. */
1864 rs6000_debug_reg_global (void)
1866 const char *nl = (const char *)0;
1868 char costly_num[20];
1870 const char *costly_str;
1871 const char *nop_str;
1873 /* Map enum rs6000_vector to string. */
1874 static const char *rs6000_debug_vector_unit[] = {
1883 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1884 LAST_VIRTUAL_REGISTER);
1885 rs6000_debug_reg_print (0, 31, "gr");
1886 rs6000_debug_reg_print (32, 63, "fp");
1887 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1890 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1891 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1892 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1893 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1894 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
1895 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1896 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1897 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1898 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1902 "d reg_class = %s\n"
1903 "f reg_class = %s\n"
1904 "v reg_class = %s\n"
1905 "wa reg_class = %s\n"
1906 "wd reg_class = %s\n"
1907 "wf reg_class = %s\n"
1908 "ws reg_class = %s\n\n",
1909 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1910 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1911 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1912 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1913 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1914 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1915 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1917 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1918 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1921 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1923 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1924 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1930 if (rs6000_recip_control)
1932 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
1934 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1935 if (rs6000_recip_bits[m])
1938 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1940 (RS6000_RECIP_AUTO_RE_P (m)
1942 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
1943 (RS6000_RECIP_AUTO_RSQRTE_P (m)
1945 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
1948 fputs ("\n", stderr);
1951 switch (rs6000_sched_costly_dep)
1953 case max_dep_latency:
1954 costly_str = "max_dep_latency";
1958 costly_str = "no_dep_costly";
1961 case all_deps_costly:
1962 costly_str = "all_deps_costly";
1965 case true_store_to_load_dep_costly:
1966 costly_str = "true_store_to_load_dep_costly";
1969 case store_to_load_dep_costly:
1970 costly_str = "store_to_load_dep_costly";
1974 costly_str = costly_num;
1975 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1979 switch (rs6000_sched_insert_nops)
1981 case sched_finish_regroup_exact:
1982 nop_str = "sched_finish_regroup_exact";
1985 case sched_finish_pad_groups:
1986 nop_str = "sched_finish_pad_groups";
1989 case sched_finish_none:
1990 nop_str = "sched_finish_none";
1995 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2000 "always_hint = %s\n"
2001 "align_branch_targets = %s\n"
2002 "sched_restricted_insns_priority = %d\n"
2003 "sched_costly_dep = %s\n"
2004 "sched_insert_nops = %s\n\n",
2005 rs6000_always_hint ? "true" : "false",
2006 rs6000_align_branch_targets ? "true" : "false",
2007 (int)rs6000_sched_restricted_insns_priority,
2008 costly_str, nop_str);
2011 /* Initialize the various global tables that are based on register size. */
2013 rs6000_init_hard_regno_mode_ok (void)
2019 /* Precalculate REGNO_REG_CLASS. */
2020 rs6000_regno_regclass[0] = GENERAL_REGS;
2021 for (r = 1; r < 32; ++r)
2022 rs6000_regno_regclass[r] = BASE_REGS;
2024 for (r = 32; r < 64; ++r)
2025 rs6000_regno_regclass[r] = FLOAT_REGS;
2027 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2028 rs6000_regno_regclass[r] = NO_REGS;
2030 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2031 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2033 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2034 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2035 rs6000_regno_regclass[r] = CR_REGS;
2037 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2038 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2039 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2040 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2041 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2042 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2043 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2044 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2045 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2046 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2048 /* Precalculate vector information, this must be set up before the
2049 rs6000_hard_regno_nregs_internal below. */
2050 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2052 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2053 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2054 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2057 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2058 rs6000_constraints[c] = NO_REGS;
2060 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2061 believes it can use native alignment or still uses 128-bit alignment. */
2062 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2073 /* V2DF mode, VSX only. */
2076 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2077 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2078 rs6000_vector_align[V2DFmode] = align64;
2081 /* V4SF mode, either VSX or Altivec. */
2084 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2085 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2086 rs6000_vector_align[V4SFmode] = align32;
2088 else if (TARGET_ALTIVEC)
2090 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2091 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2092 rs6000_vector_align[V4SFmode] = align32;
2095 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2099 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2100 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2101 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2102 rs6000_vector_align[V4SImode] = align32;
2103 rs6000_vector_align[V8HImode] = align32;
2104 rs6000_vector_align[V16QImode] = align32;
2108 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2109 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2110 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2114 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2115 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2116 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2120 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2121 Altivec doesn't have 64-bit support. */
2124 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2125 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2126 rs6000_vector_align[V2DImode] = align64;
2129 /* DFmode, see if we want to use the VSX unit. */
2130 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2132 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2133 rs6000_vector_mem[DFmode]
2134 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2135 rs6000_vector_align[DFmode] = align64;
2138 /* TODO add SPE and paired floating point vector support. */
2140 /* Register class constaints for the constraints that depend on compile
2142 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2143 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2145 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2146 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2150 /* At present, we just use VSX_REGS, but we have different constraints
2151 based on the use, in case we want to fine tune the default register
2152 class used. wa = any VSX register, wf = register class to use for
2153 V4SF, wd = register class to use for V2DF, and ws = register classs to
2154 use for DF scalars. */
2155 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2156 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2157 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2158 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2164 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2166 /* Set up the reload helper functions. */
2167 if (TARGET_VSX || TARGET_ALTIVEC)
2171 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2172 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2173 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2174 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2175 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2176 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2177 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2178 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2179 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2180 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2181 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2182 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2186 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2187 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2188 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2189 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2190 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2191 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2192 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2193 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2194 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2195 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2196 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2197 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2201 /* Precalculate HARD_REGNO_NREGS. */
2202 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2203 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2204 rs6000_hard_regno_nregs[m][r]
2205 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2207 /* Precalculate HARD_REGNO_MODE_OK. */
2208 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2209 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2210 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2211 rs6000_hard_regno_mode_ok_p[m][r] = true;
2213 /* Precalculate CLASS_MAX_NREGS sizes. */
2214 for (c = 0; c < LIM_REG_CLASSES; ++c)
2218 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2219 reg_size = UNITS_PER_VSX_WORD;
2221 else if (c == ALTIVEC_REGS)
2222 reg_size = UNITS_PER_ALTIVEC_WORD;
2224 else if (c == FLOAT_REGS)
2225 reg_size = UNITS_PER_FP_WORD;
2228 reg_size = UNITS_PER_WORD;
2230 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2231 rs6000_class_max_nregs[m][c]
2232 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2235 if (TARGET_E500_DOUBLE)
2236 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2238 /* Calculate which modes to automatically generate code to use a the
2239 reciprocal divide and square root instructions. In the future, possibly
2240 automatically generate the instructions even if the user did not specify
2241 -mrecip. The older machines double precision reciprocal sqrt estimate is
2242 not accurate enough. */
2243 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2245 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2247 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2248 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2249 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2250 if (VECTOR_UNIT_VSX_P (V2DFmode))
2251 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2253 if (TARGET_FRSQRTES)
2254 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2256 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2257 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2258 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2259 if (VECTOR_UNIT_VSX_P (V2DFmode))
2260 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2262 if (rs6000_recip_control)
2264 if (!TARGET_FUSED_MADD)
2265 warning (0, "-mrecip requires -mfused-madd");
2266 if (!flag_finite_math_only)
2267 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2268 if (flag_trapping_math)
2269 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2270 if (!flag_reciprocal_math)
2271 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2272 if (TARGET_FUSED_MADD && flag_finite_math_only && !flag_trapping_math
2273 && flag_reciprocal_math)
2275 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2276 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2277 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2279 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2280 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2281 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2283 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2284 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2285 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2287 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2288 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2289 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2291 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2292 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2293 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2295 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2296 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2297 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2299 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2300 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2301 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2303 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2304 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2305 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2309 if (TARGET_DEBUG_REG)
2310 rs6000_debug_reg_global ();
2312 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2314 "SImode variable mult cost = %d\n"
2315 "SImode constant mult cost = %d\n"
2316 "SImode short constant mult cost = %d\n"
2317 "DImode multipliciation cost = %d\n"
2318 "SImode division cost = %d\n"
2319 "DImode division cost = %d\n"
2320 "Simple fp operation cost = %d\n"
2321 "DFmode multiplication cost = %d\n"
2322 "SFmode division cost = %d\n"
2323 "DFmode division cost = %d\n"
2324 "cache line size = %d\n"
2325 "l1 cache size = %d\n"
2326 "l2 cache size = %d\n"
2327 "simultaneous prefetches = %d\n"
2330 rs6000_cost->mulsi_const,
2331 rs6000_cost->mulsi_const9,
2339 rs6000_cost->cache_line_size,
2340 rs6000_cost->l1_cache_size,
2341 rs6000_cost->l2_cache_size,
2342 rs6000_cost->simultaneous_prefetches);
2346 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2349 darwin_rs6000_override_options (void)
2351 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2353 rs6000_altivec_abi = 1;
2354 TARGET_ALTIVEC_VRSAVE = 1;
2355 if (DEFAULT_ABI == ABI_DARWIN)
2357 if (MACHO_DYNAMIC_NO_PIC_P)
2360 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2363 else if (flag_pic == 1)
2368 darwin_one_byte_bool = 1;
2370 if (TARGET_64BIT && ! TARGET_POWERPC64)
2372 target_flags |= MASK_POWERPC64;
2373 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2377 rs6000_default_long_calls = 1;
2378 target_flags |= MASK_SOFT_FLOAT;
2381 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2383 if (!flag_mkernel && !flag_apple_kext
2385 && ! (target_flags_explicit & MASK_ALTIVEC))
2386 target_flags |= MASK_ALTIVEC;
2388 /* Unless the user (not the configurer) has explicitly overridden
2389 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2390 G4 unless targetting the kernel. */
2393 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2394 && ! (target_flags_explicit & MASK_ALTIVEC)
2395 && ! rs6000_select[1].string)
2397 target_flags |= MASK_ALTIVEC;
2402 /* If not otherwise specified by a target, make 'long double' equivalent to
2405 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2406 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2409 /* Override command line options. Mostly we process the processor
2410 type and sometimes adjust other TARGET_ options. */
2413 rs6000_option_override_internal (const char *default_cpu)
2416 struct rs6000_cpu_select *ptr;
2419 /* Simplifications for entries below. */
2422 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2423 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2426 /* This table occasionally claims that a processor does not support
2427 a particular feature even though it does, but the feature is slower
2428 than the alternative. Thus, it shouldn't be relied on as a
2429 complete description of the processor's support.
2431 Please keep this list in order, and don't forget to update the
2432 documentation in invoke.texi when adding a new processor or
2436 const char *const name; /* Canonical processor name. */
2437 const enum processor_type processor; /* Processor type enum value. */
2438 const int target_enable; /* Target flags to enable. */
2439 } const processor_target_table[]
2440 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2441 {"403", PROCESSOR_PPC403,
2442 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2443 {"405", PROCESSOR_PPC405,
2444 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2445 {"405fp", PROCESSOR_PPC405,
2446 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2447 {"440", PROCESSOR_PPC440,
2448 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2449 {"440fp", PROCESSOR_PPC440,
2450 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2451 {"464", PROCESSOR_PPC440,
2452 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2453 {"464fp", PROCESSOR_PPC440,
2454 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2455 {"476", PROCESSOR_PPC476,
2456 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2457 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2458 {"476fp", PROCESSOR_PPC476,
2459 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2460 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2461 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2462 {"601", PROCESSOR_PPC601,
2463 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2464 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2465 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2466 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2467 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2468 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2469 {"620", PROCESSOR_PPC620,
2470 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2471 {"630", PROCESSOR_PPC630,
2472 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2473 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2474 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2475 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2476 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2477 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2478 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2479 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2480 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2482 /* 8548 has a dummy entry for now. */
2483 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2485 {"a2", PROCESSOR_PPCA2,
2486 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2487 | MASK_CMPB | MASK_NO_UPDATE },
2488 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2489 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2490 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2492 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2493 | MASK_PPC_GFXOPT | MASK_ISEL},
2494 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2495 {"970", PROCESSOR_POWER4,
2496 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2497 {"cell", PROCESSOR_CELL,
2498 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2499 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2500 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2501 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2502 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2503 {"G5", PROCESSOR_POWER4,
2504 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2505 {"titan", PROCESSOR_TITAN,
2506 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2507 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2508 {"power2", PROCESSOR_POWER,
2509 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2510 {"power3", PROCESSOR_PPC630,
2511 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2512 {"power4", PROCESSOR_POWER4,
2513 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2515 {"power5", PROCESSOR_POWER5,
2516 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2517 | MASK_MFCRF | MASK_POPCNTB},
2518 {"power5+", PROCESSOR_POWER5,
2519 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2520 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2521 {"power6", PROCESSOR_POWER6,
2522 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2523 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2524 | MASK_RECIP_PRECISION},
2525 {"power6x", PROCESSOR_POWER6,
2526 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2527 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2528 | MASK_MFPGPR | MASK_RECIP_PRECISION},
2529 {"power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
2530 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2531 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2532 | MASK_VSX | MASK_RECIP_PRECISION},
2533 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2534 {"powerpc64", PROCESSOR_POWERPC64,
2535 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2536 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2537 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2538 {"rios2", PROCESSOR_RIOS2,
2539 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2540 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2541 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2542 {"rs64", PROCESSOR_RS64A,
2543 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2546 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2548 /* Some OSs don't support saving the high part of 64-bit registers on
2549 context switch. Other OSs don't support saving Altivec registers.
2550 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2551 settings; if the user wants either, the user must explicitly specify
2552 them and we won't interfere with the user's specification. */
2555 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2556 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2557 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2558 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2559 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2560 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
2561 | MASK_RECIP_PRECISION)
2564 /* Masks for instructions set at various powerpc ISAs. */
2566 ISA_2_1_MASKS = MASK_MFCRF,
2567 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB | MASK_FPRND),
2569 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't
2570 add ALTIVEC, since in general it isn't a win on power6. In ISA 2.04,
2571 fsel, fre, fsqrt, etc. were no longer documented as optional. Group
2572 masks by server and embedded. */
2573 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
2574 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
2575 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
2577 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
2578 altivec is a win so enable it. */
2579 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
2580 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
2584 /* Numerous experiment shows that IRA based loop pressure
2585 calculation works better for RTL loop invariant motion on targets
2586 with enough (>= 32) registers. It is an expensive optimization.
2587 So it is on only for peak performance. */
2589 flag_ira_loop_pressure = 1;
2591 /* Set the pointer size. */
2594 rs6000_pmode = (int)DImode;
2595 rs6000_pointer_size = 64;
2599 rs6000_pmode = (int)SImode;
2600 rs6000_pointer_size = 32;
2603 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2604 #ifdef OS_MISSING_POWERPC64
2605 if (OS_MISSING_POWERPC64)
2606 set_masks &= ~MASK_POWERPC64;
2608 #ifdef OS_MISSING_ALTIVEC
2609 if (OS_MISSING_ALTIVEC)
2610 set_masks &= ~MASK_ALTIVEC;
2613 /* Don't override by the processor default if given explicitly. */
2614 set_masks &= ~target_flags_explicit;
2616 /* Identify the processor type. */
2617 rs6000_select[0].string = default_cpu;
2618 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2620 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2622 ptr = &rs6000_select[i];
2623 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2625 for (j = 0; j < ptt_size; j++)
2626 if (! strcmp (ptr->string, processor_target_table[j].name))
2628 if (ptr->set_tune_p)
2629 rs6000_cpu = processor_target_table[j].processor;
2631 if (ptr->set_arch_p)
2633 target_flags &= ~set_masks;
2634 target_flags |= (processor_target_table[j].target_enable
2641 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2645 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2646 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2649 error ("AltiVec not supported in this target");
2651 error ("Spe not supported in this target");
2654 /* Disable Cell microcode if we are optimizing for the Cell
2655 and not optimizing for size. */
2656 if (rs6000_gen_cell_microcode == -1)
2657 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2660 /* If we are optimizing big endian systems for space and it's OK to
2661 use instructions that would be microcoded on the Cell, use the
2662 load/store multiple and string instructions. */
2663 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2664 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2666 /* Don't allow -mmultiple or -mstring on little endian systems
2667 unless the cpu is a 750, because the hardware doesn't support the
2668 instructions used in little endian mode, and causes an alignment
2669 trap. The 750 does not cause an alignment trap (except when the
2670 target is unaligned). */
2672 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2674 if (TARGET_MULTIPLE)
2676 target_flags &= ~MASK_MULTIPLE;
2677 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2678 warning (0, "-mmultiple is not supported on little endian systems");
2683 target_flags &= ~MASK_STRING;
2684 if ((target_flags_explicit & MASK_STRING) != 0)
2685 warning (0, "-mstring is not supported on little endian systems");
2689 /* Add some warnings for VSX. */
2692 const char *msg = NULL;
2693 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2694 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2696 if (target_flags_explicit & MASK_VSX)
2697 msg = N_("-mvsx requires hardware floating point");
2699 target_flags &= ~ MASK_VSX;
2701 else if (TARGET_PAIRED_FLOAT)
2702 msg = N_("-mvsx and -mpaired are incompatible");
2703 /* The hardware will allow VSX and little endian, but until we make sure
2704 things like vector select, etc. work don't allow VSX on little endian
2705 systems at this point. */
2706 else if (!BYTES_BIG_ENDIAN)
2707 msg = N_("-mvsx used with little endian code");
2708 else if (TARGET_AVOID_XFORM > 0)
2709 msg = N_("-mvsx needs indexed addressing");
2710 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2712 if (target_flags_explicit & MASK_VSX)
2713 msg = N_("-mvsx and -mno-altivec are incompatible");
2715 msg = N_("-mno-altivec disables vsx");
2721 target_flags &= ~ MASK_VSX;
2722 target_flags_explicit |= MASK_VSX;
2726 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2727 unless the user explicitly used the -mno-<option> to disable the code. */
2729 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2730 else if (TARGET_POPCNTD)
2731 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2732 else if (TARGET_DFP)
2733 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2734 else if (TARGET_CMPB)
2735 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2736 else if (TARGET_POPCNTB || TARGET_FPRND)
2737 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2738 else if (TARGET_ALTIVEC)
2739 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2741 /* E500mc does "better" if we inline more aggressively. Respect the
2742 user's opinion, though. */
2743 if (rs6000_block_move_inline_limit == 0
2744 && (rs6000_cpu == PROCESSOR_PPCE500MC
2745 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2746 rs6000_block_move_inline_limit = 128;
2748 /* store_one_arg depends on expand_block_move to handle at least the
2749 size of reg_parm_stack_space. */
2750 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2751 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2753 /* Set debug flags */
2754 if (rs6000_debug_name)
2756 if (! strcmp (rs6000_debug_name, "all"))
2757 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2758 = rs6000_debug_addr = rs6000_debug_cost = 1;
2759 else if (! strcmp (rs6000_debug_name, "stack"))
2760 rs6000_debug_stack = 1;
2761 else if (! strcmp (rs6000_debug_name, "arg"))
2762 rs6000_debug_arg = 1;
2763 else if (! strcmp (rs6000_debug_name, "reg"))
2764 rs6000_debug_reg = 1;
2765 else if (! strcmp (rs6000_debug_name, "addr"))
2766 rs6000_debug_addr = 1;
2767 else if (! strcmp (rs6000_debug_name, "cost"))
2768 rs6000_debug_cost = 1;
2770 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2772 /* If the appropriate debug option is enabled, replace the target hooks
2773 with debug versions that call the real version and then prints
2774 debugging information. */
2775 if (TARGET_DEBUG_COST)
2777 targetm.rtx_costs = rs6000_debug_rtx_costs;
2778 targetm.address_cost = rs6000_debug_address_cost;
2779 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2782 if (TARGET_DEBUG_ADDR)
2784 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2785 targetm.legitimize_address = rs6000_debug_legitimize_address;
2786 rs6000_secondary_reload_class_ptr
2787 = rs6000_debug_secondary_reload_class;
2788 rs6000_secondary_memory_needed_ptr
2789 = rs6000_debug_secondary_memory_needed;
2790 rs6000_cannot_change_mode_class_ptr
2791 = rs6000_debug_cannot_change_mode_class;
2792 rs6000_preferred_reload_class_ptr
2793 = rs6000_debug_preferred_reload_class;
2794 rs6000_legitimize_reload_address_ptr
2795 = rs6000_debug_legitimize_reload_address;
2796 rs6000_mode_dependent_address_ptr
2797 = rs6000_debug_mode_dependent_address;
2801 if (rs6000_traceback_name)
2803 if (! strncmp (rs6000_traceback_name, "full", 4))
2804 rs6000_traceback = traceback_full;
2805 else if (! strncmp (rs6000_traceback_name, "part", 4))
2806 rs6000_traceback = traceback_part;
2807 else if (! strncmp (rs6000_traceback_name, "no", 2))
2808 rs6000_traceback = traceback_none;
2810 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2811 rs6000_traceback_name);
2814 if (rs6000_veclibabi_name)
2816 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2817 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2819 error ("unknown vectorization library ABI type (%s) for "
2820 "-mveclibabi= switch", rs6000_veclibabi_name);
2823 if (!rs6000_explicit_options.long_double)
2824 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2826 #ifndef POWERPC_LINUX
2827 if (!rs6000_explicit_options.ieee)
2828 rs6000_ieeequad = 1;
2831 /* Enable Altivec ABI for AIX -maltivec. */
2832 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2833 rs6000_altivec_abi = 1;
2835 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2836 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2837 be explicitly overridden in either case. */
2840 if (!rs6000_explicit_options.altivec_abi
2841 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2842 rs6000_altivec_abi = 1;
2844 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2845 if (!rs6000_explicit_options.vrsave)
2846 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2849 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2850 So far, the only darwin64 targets are also MACH-O. */
2852 && DEFAULT_ABI == ABI_DARWIN
2855 rs6000_darwin64_abi = 1;
2856 /* Default to natural alignment, for better performance. */
2857 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2860 /* Place FP constants in the constant pool instead of TOC
2861 if section anchors enabled. */
2862 if (flag_section_anchors)
2863 TARGET_NO_FP_IN_TOC = 1;
2865 /* Handle -mtls-size option. */
2866 rs6000_parse_tls_size_option ();
2868 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2869 SUBTARGET_OVERRIDE_OPTIONS;
2871 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2872 SUBSUBTARGET_OVERRIDE_OPTIONS;
2874 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2875 SUB3TARGET_OVERRIDE_OPTIONS;
2878 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2879 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2881 /* The e500 and e500mc do not have string instructions, and we set
2882 MASK_STRING above when optimizing for size. */
2883 if ((target_flags & MASK_STRING) != 0)
2884 target_flags = target_flags & ~MASK_STRING;
2886 else if (rs6000_select[1].string != NULL)
2888 /* For the powerpc-eabispe configuration, we set all these by
2889 default, so let's unset them if we manually set another
2890 CPU that is not the E500. */
2891 if (!rs6000_explicit_options.spe_abi)
2893 if (!rs6000_explicit_options.spe)
2895 if (!rs6000_explicit_options.float_gprs)
2896 rs6000_float_gprs = 0;
2897 if (!(target_flags_explicit & MASK_ISEL))
2898 target_flags &= ~MASK_ISEL;
2901 /* Detect invalid option combinations with E500. */
2904 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2905 && rs6000_cpu != PROCESSOR_POWER5
2906 && rs6000_cpu != PROCESSOR_POWER6
2907 && rs6000_cpu != PROCESSOR_POWER7
2908 && rs6000_cpu != PROCESSOR_PPCA2
2909 && rs6000_cpu != PROCESSOR_CELL);
2910 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2911 || rs6000_cpu == PROCESSOR_POWER5
2912 || rs6000_cpu == PROCESSOR_POWER7);
2913 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2914 || rs6000_cpu == PROCESSOR_POWER5
2915 || rs6000_cpu == PROCESSOR_POWER6
2916 || rs6000_cpu == PROCESSOR_POWER7
2917 || rs6000_cpu == PROCESSOR_PPCE500MC
2918 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2920 /* Allow debug switches to override the above settings. */
2921 if (TARGET_ALWAYS_HINT > 0)
2922 rs6000_always_hint = TARGET_ALWAYS_HINT;
2924 if (TARGET_SCHED_GROUPS > 0)
2925 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2927 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2928 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2930 rs6000_sched_restricted_insns_priority
2931 = (rs6000_sched_groups ? 1 : 0);
2933 /* Handle -msched-costly-dep option. */
2934 rs6000_sched_costly_dep
2935 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2937 if (rs6000_sched_costly_dep_str)
2939 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2940 rs6000_sched_costly_dep = no_dep_costly;
2941 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2942 rs6000_sched_costly_dep = all_deps_costly;
2943 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2944 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2945 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2946 rs6000_sched_costly_dep = store_to_load_dep_costly;
2948 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2949 atoi (rs6000_sched_costly_dep_str));
2952 /* Handle -minsert-sched-nops option. */
2953 rs6000_sched_insert_nops
2954 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2956 if (rs6000_sched_insert_nops_str)
2958 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2959 rs6000_sched_insert_nops = sched_finish_none;
2960 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2961 rs6000_sched_insert_nops = sched_finish_pad_groups;
2962 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2963 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2965 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2966 atoi (rs6000_sched_insert_nops_str));
2969 #ifdef TARGET_REGNAMES
2970 /* If the user desires alternate register names, copy in the
2971 alternate names now. */
2972 if (TARGET_REGNAMES)
2973 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2976 /* Set aix_struct_return last, after the ABI is determined.
2977 If -maix-struct-return or -msvr4-struct-return was explicitly
2978 used, don't override with the ABI default. */
2979 if (!rs6000_explicit_options.aix_struct_ret)
2980 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2983 /* IBM XL compiler defaults to unsigned bitfields. */
2984 if (TARGET_XL_COMPAT)
2985 flag_signed_bitfields = 0;
2988 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2989 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2992 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2994 /* We can only guarantee the availability of DI pseudo-ops when
2995 assembling for 64-bit targets. */
2998 targetm.asm_out.aligned_op.di = NULL;
2999 targetm.asm_out.unaligned_op.di = NULL;
3002 /* Set branch target alignment, if not optimizing for size. */
3005 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3006 aligned 8byte to avoid misprediction by the branch predictor. */
3007 if (rs6000_cpu == PROCESSOR_TITAN
3008 || rs6000_cpu == PROCESSOR_CELL)
3010 if (align_functions <= 0)
3011 align_functions = 8;
3012 if (align_jumps <= 0)
3014 if (align_loops <= 0)
3017 if (rs6000_align_branch_targets)
3019 if (align_functions <= 0)
3020 align_functions = 16;
3021 if (align_jumps <= 0)
3023 if (align_loops <= 0)
3026 if (align_jumps_max_skip <= 0)
3027 align_jumps_max_skip = 15;
3028 if (align_loops_max_skip <= 0)
3029 align_loops_max_skip = 15;
3032 /* Arrange to save and restore machine status around nested functions. */
3033 init_machine_status = rs6000_init_machine_status;
3035 /* We should always be splitting complex arguments, but we can't break
3036 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3037 if (DEFAULT_ABI != ABI_AIX)
3038 targetm.calls.split_complex_arg = NULL;
3040 /* Initialize rs6000_cost with the appropriate target costs. */
3042 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3046 case PROCESSOR_RIOS1:
3047 rs6000_cost = &rios1_cost;
3050 case PROCESSOR_RIOS2:
3051 rs6000_cost = &rios2_cost;
3054 case PROCESSOR_RS64A:
3055 rs6000_cost = &rs64a_cost;
3058 case PROCESSOR_MPCCORE:
3059 rs6000_cost = &mpccore_cost;
3062 case PROCESSOR_PPC403:
3063 rs6000_cost = &ppc403_cost;
3066 case PROCESSOR_PPC405:
3067 rs6000_cost = &ppc405_cost;
3070 case PROCESSOR_PPC440:
3071 rs6000_cost = &ppc440_cost;
3074 case PROCESSOR_PPC476:
3075 rs6000_cost = &ppc476_cost;
3078 case PROCESSOR_PPC601:
3079 rs6000_cost = &ppc601_cost;
3082 case PROCESSOR_PPC603:
3083 rs6000_cost = &ppc603_cost;
3086 case PROCESSOR_PPC604:
3087 rs6000_cost = &ppc604_cost;
3090 case PROCESSOR_PPC604e:
3091 rs6000_cost = &ppc604e_cost;
3094 case PROCESSOR_PPC620:
3095 rs6000_cost = &ppc620_cost;
3098 case PROCESSOR_PPC630:
3099 rs6000_cost = &ppc630_cost;
3102 case PROCESSOR_CELL:
3103 rs6000_cost = &ppccell_cost;
3106 case PROCESSOR_PPC750:
3107 case PROCESSOR_PPC7400:
3108 rs6000_cost = &ppc750_cost;
3111 case PROCESSOR_PPC7450:
3112 rs6000_cost = &ppc7450_cost;
3115 case PROCESSOR_PPC8540:
3116 rs6000_cost = &ppc8540_cost;
3119 case PROCESSOR_PPCE300C2:
3120 case PROCESSOR_PPCE300C3:
3121 rs6000_cost = &ppce300c2c3_cost;
3124 case PROCESSOR_PPCE500MC:
3125 rs6000_cost = &ppce500mc_cost;
3128 case PROCESSOR_PPCE500MC64:
3129 rs6000_cost = &ppce500mc64_cost;
3132 case PROCESSOR_TITAN:
3133 rs6000_cost = &titan_cost;
3136 case PROCESSOR_POWER4:
3137 case PROCESSOR_POWER5:
3138 rs6000_cost = &power4_cost;
3141 case PROCESSOR_POWER6:
3142 rs6000_cost = &power6_cost;
3145 case PROCESSOR_POWER7:
3146 rs6000_cost = &power7_cost;
3149 case PROCESSOR_PPCA2:
3150 rs6000_cost = &ppca2_cost;
3157 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
3158 set_param_value ("simultaneous-prefetches",
3159 rs6000_cost->simultaneous_prefetches);
3160 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
3161 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
3162 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
3163 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
3164 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
3165 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
3167 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
3168 can be optimized to ap = __builtin_next_arg (0). */
3169 if (DEFAULT_ABI != ABI_V4)
3170 targetm.expand_builtin_va_start = NULL;
3172 /* Set up single/double float flags.
3173 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3174 then set both flags. */
3175 if (TARGET_HARD_FLOAT && TARGET_FPRS
3176 && rs6000_single_float == 0 && rs6000_double_float == 0)
3177 rs6000_single_float = rs6000_double_float = 1;
3179 /* Reset single and double FP flags if target is E500. */
3182 rs6000_single_float = rs6000_double_float = 0;
3183 if (TARGET_E500_SINGLE)
3184 rs6000_single_float = 1;
3185 if (TARGET_E500_DOUBLE)
3186 rs6000_single_float = rs6000_double_float = 1;
3189 /* If not explicitly specified via option, decide whether to generate indexed
3190 load/store instructions. */
3191 if (TARGET_AVOID_XFORM == -1)
3192 /* Avoid indexed addressing when targeting Power6 in order to avoid
3193 the DERAT mispredict penalty. */
3194 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
3196 /* Set the -mrecip options. */
3197 if (rs6000_recip_name)
3199 char *p = ASTRDUP (rs6000_recip_name);
3201 unsigned int mask, i;
3204 while ((q = strtok (p, ",")) != NULL)
3215 if (!strcmp (q, "default"))
3216 mask = ((TARGET_RECIP_PRECISION)
3217 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3220 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3221 if (!strcmp (q, recip_options[i].string))
3223 mask = recip_options[i].mask;
3227 if (i == ARRAY_SIZE (recip_options))
3229 error ("Unknown option for -mrecip=%s", q);
3236 rs6000_recip_control &= ~mask;
3238 rs6000_recip_control |= mask;
3242 rs6000_init_hard_regno_mode_ok ();
3245 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3246 define the target cpu type. */
3249 rs6000_option_override (void)
3251 rs6000_option_override_internal (OPTION_TARGET_CPU_DEFAULT);
3254 /* Implement targetm.vectorize.builtin_mask_for_load. */
3256 rs6000_builtin_mask_for_load (void)
3258 if (TARGET_ALTIVEC || TARGET_VSX)
3259 return altivec_builtin_mask_for_load;
3264 /* Implement targetm.vectorize.builtin_conversion.
3265 Returns a decl of a function that implements conversion of an integer vector
3266 into a floating-point vector, or vice-versa. DEST_TYPE is the
3267 destination type and SRC_TYPE the source type of the conversion.
3268 Return NULL_TREE if it is not available. */
3270 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3272 enum tree_code code = (enum tree_code) tcode;
3276 case FIX_TRUNC_EXPR:
3277 switch (TYPE_MODE (dest_type))
3280 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3283 return TYPE_UNSIGNED (dest_type)
3284 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3285 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3288 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3291 return TYPE_UNSIGNED (dest_type)
3292 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3293 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3300 switch (TYPE_MODE (src_type))
3303 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3306 return TYPE_UNSIGNED (src_type)
3307 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3308 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3311 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3314 return TYPE_UNSIGNED (src_type)
3315 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3316 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3327 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3329 rs6000_builtin_mul_widen_even (tree type)
3331 if (!TARGET_ALTIVEC)
3334 switch (TYPE_MODE (type))
3337 return TYPE_UNSIGNED (type)
3338 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3339 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3342 return TYPE_UNSIGNED (type)
3343 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3344 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3350 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3352 rs6000_builtin_mul_widen_odd (tree type)
3354 if (!TARGET_ALTIVEC)
3357 switch (TYPE_MODE (type))
3360 return TYPE_UNSIGNED (type)
3361 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3362 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3365 return TYPE_UNSIGNED (type)
3366 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3367 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3374 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3375 after applying N number of iterations. This routine does not determine
3376 how may iterations are required to reach desired alignment. */
3379 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3386 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3389 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3399 /* Assuming that all other types are naturally aligned. CHECKME! */
3404 /* Return true if the vector misalignment factor is supported by the
3407 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3414 /* Return if movmisalign pattern is not supported for this mode. */
3415 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3418 if (misalignment == -1)
3420 /* Misalignment factor is unknown at compile time but we know
3421 it's word aligned. */
3422 if (rs6000_vector_alignment_reachable (type, is_packed))
3424 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3426 if (element_size == 64 || element_size == 32)
3433 /* VSX supports word-aligned vector. */
3434 if (misalignment % 4 == 0)
3440 /* Implement targetm.vectorize.builtin_vec_perm. */
3442 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3444 tree inner_type = TREE_TYPE (type);
3445 bool uns_p = TYPE_UNSIGNED (inner_type);
3448 *mask_element_type = unsigned_char_type_node;
3450 switch (TYPE_MODE (type))
3454 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3455 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3460 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3461 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3466 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3467 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3471 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3475 if (!TARGET_ALLOW_DF_PERMUTE)
3478 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3482 if (!TARGET_ALLOW_DF_PERMUTE)
3486 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3487 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3499 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3501 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3502 tree vectype, int misalign)
3506 switch (type_of_cost)
3516 case cond_branch_not_taken:
3520 case cond_branch_taken:
3523 case unaligned_load:
3524 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3526 elements = TYPE_VECTOR_SUBPARTS (vectype);
3528 /* Double word aligned. */
3536 /* Double word aligned. */
3540 /* Unknown misalignment. */
3553 /* Misaligned loads are not supported. */
3558 case unaligned_store:
3559 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3561 elements = TYPE_VECTOR_SUBPARTS (vectype);
3563 /* Double word aligned. */
3571 /* Double word aligned. */
3575 /* Unknown misalignment. */
3588 /* Misaligned stores are not supported. */
3598 /* Implement targetm.vectorize.units_per_simd_word. */
3601 rs6000_units_per_simd_word (enum machine_mode mode ATTRIBUTE_UNUSED)
3603 return (TARGET_VSX ? UNITS_PER_VSX_WORD
3604 : (TARGET_ALTIVEC ? UNITS_PER_ALTIVEC_WORD
3605 : (TARGET_SPE ? UNITS_PER_SPE_WORD
3606 : (TARGET_PAIRED_FLOAT ? UNITS_PER_PAIRED_WORD
3607 : UNITS_PER_WORD))));
3610 /* Handle generic options of the form -mfoo=yes/no.
3611 NAME is the option name.
3612 VALUE is the option value.
3613 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3614 whether the option value is 'yes' or 'no' respectively. */
3616 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3620 else if (!strcmp (value, "yes"))
3622 else if (!strcmp (value, "no"))
3625 error ("unknown -m%s= option specified: '%s'", name, value);
3628 /* Validate and record the size specified with the -mtls-size option. */
3631 rs6000_parse_tls_size_option (void)
3633 if (rs6000_tls_size_string == 0)
3635 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3636 rs6000_tls_size = 16;
3637 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3638 rs6000_tls_size = 32;
3639 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3640 rs6000_tls_size = 64;
3642 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3646 rs6000_option_optimization (int level ATTRIBUTE_UNUSED,
3647 int size ATTRIBUTE_UNUSED)
3649 if (DEFAULT_ABI == ABI_DARWIN)
3650 /* The Darwin libraries never set errno, so we might as well
3651 avoid calling them when that's the only reason we would. */
3652 flag_errno_math = 0;
3654 /* Double growth factor to counter reduced min jump length. */
3655 set_param_value ("max-grow-copy-bb-insns", 16);
3657 /* Enable section anchors by default.
3658 Skip section anchors for Objective C and Objective C++
3659 until front-ends fixed. */
3660 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3661 flag_section_anchors = 2;
3664 static enum fpu_type_t
3665 rs6000_parse_fpu_option (const char *option)
3667 if (!strcmp("none", option)) return FPU_NONE;
3668 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3669 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3670 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3671 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3672 error("unknown value %s for -mfpu", option);
3677 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3678 library with vectorized intrinsics. */
3681 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3684 const char *suffix = NULL;
3685 tree fntype, new_fndecl, bdecl = NULL_TREE;
3688 enum machine_mode el_mode, in_mode;
3691 /* Libmass is suitable for unsafe math only as it does not correctly support
3692 parts of IEEE with the required precision such as denormals. Only support
3693 it if we have VSX to use the simd d2 or f4 functions.
3694 XXX: Add variable length support. */
3695 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3698 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3699 n = TYPE_VECTOR_SUBPARTS (type_out);
3700 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3701 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3702 if (el_mode != in_mode
3706 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3708 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3711 case BUILT_IN_ATAN2:
3712 case BUILT_IN_HYPOT:
3718 case BUILT_IN_ACOSH:
3720 case BUILT_IN_ASINH:
3722 case BUILT_IN_ATANH:
3730 case BUILT_IN_EXPM1:
3731 case BUILT_IN_LGAMMA:
3732 case BUILT_IN_LOG10:
3733 case BUILT_IN_LOG1P:
3741 bdecl = implicit_built_in_decls[fn];
3742 suffix = "d2"; /* pow -> powd2 */
3743 if (el_mode != DFmode
3748 case BUILT_IN_ATAN2F:
3749 case BUILT_IN_HYPOTF:
3754 case BUILT_IN_ACOSF:
3755 case BUILT_IN_ACOSHF:
3756 case BUILT_IN_ASINF:
3757 case BUILT_IN_ASINHF:
3758 case BUILT_IN_ATANF:
3759 case BUILT_IN_ATANHF:
3760 case BUILT_IN_CBRTF:
3762 case BUILT_IN_COSHF:
3764 case BUILT_IN_ERFCF:
3765 case BUILT_IN_EXP2F:
3767 case BUILT_IN_EXPM1F:
3768 case BUILT_IN_LGAMMAF:
3769 case BUILT_IN_LOG10F:
3770 case BUILT_IN_LOG1PF:
3771 case BUILT_IN_LOG2F:
3774 case BUILT_IN_SINHF:
3775 case BUILT_IN_SQRTF:
3777 case BUILT_IN_TANHF:
3778 bdecl = implicit_built_in_decls[fn];
3779 suffix = "4"; /* powf -> powf4 */
3780 if (el_mode != SFmode
3792 gcc_assert (suffix != NULL);
3793 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3794 strcpy (name, bname + sizeof ("__builtin_") - 1);
3795 strcat (name, suffix);
3798 fntype = build_function_type_list (type_out, type_in, NULL);
3799 else if (n_args == 2)
3800 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3804 /* Build a function declaration for the vectorized function. */
3805 new_fndecl = build_decl (BUILTINS_LOCATION,
3806 FUNCTION_DECL, get_identifier (name), fntype);
3807 TREE_PUBLIC (new_fndecl) = 1;
3808 DECL_EXTERNAL (new_fndecl) = 1;
3809 DECL_IS_NOVOPS (new_fndecl) = 1;
3810 TREE_READONLY (new_fndecl) = 1;
3815 /* Returns a function decl for a vectorized version of the builtin function
3816 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3817 if it is not available. */
3820 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3823 enum machine_mode in_mode, out_mode;
3826 if (TREE_CODE (type_out) != VECTOR_TYPE
3827 || TREE_CODE (type_in) != VECTOR_TYPE
3828 || !TARGET_VECTORIZE_BUILTINS)
3831 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3832 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3833 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3834 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3836 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3838 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3841 case BUILT_IN_COPYSIGN:
3842 if (VECTOR_UNIT_VSX_P (V2DFmode)
3843 && out_mode == DFmode && out_n == 2
3844 && in_mode == DFmode && in_n == 2)
3845 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3847 case BUILT_IN_COPYSIGNF:
3848 if (out_mode != SFmode || out_n != 4
3849 || in_mode != SFmode || in_n != 4)
3851 if (VECTOR_UNIT_VSX_P (V4SFmode))
3852 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3853 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3854 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3857 if (VECTOR_UNIT_VSX_P (V2DFmode)
3858 && out_mode == DFmode && out_n == 2
3859 && in_mode == DFmode && in_n == 2)
3860 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3862 case BUILT_IN_SQRTF:
3863 if (VECTOR_UNIT_VSX_P (V4SFmode)
3864 && out_mode == SFmode && out_n == 4
3865 && in_mode == SFmode && in_n == 4)
3866 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3869 if (VECTOR_UNIT_VSX_P (V2DFmode)
3870 && out_mode == DFmode && out_n == 2
3871 && in_mode == DFmode && in_n == 2)
3872 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3874 case BUILT_IN_CEILF:
3875 if (out_mode != SFmode || out_n != 4
3876 || in_mode != SFmode || in_n != 4)
3878 if (VECTOR_UNIT_VSX_P (V4SFmode))
3879 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3880 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3881 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3883 case BUILT_IN_FLOOR:
3884 if (VECTOR_UNIT_VSX_P (V2DFmode)
3885 && out_mode == DFmode && out_n == 2
3886 && in_mode == DFmode && in_n == 2)
3887 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3889 case BUILT_IN_FLOORF:
3890 if (out_mode != SFmode || out_n != 4
3891 || in_mode != SFmode || in_n != 4)
3893 if (VECTOR_UNIT_VSX_P (V4SFmode))
3894 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3895 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3896 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3898 case BUILT_IN_TRUNC:
3899 if (VECTOR_UNIT_VSX_P (V2DFmode)
3900 && out_mode == DFmode && out_n == 2
3901 && in_mode == DFmode && in_n == 2)
3902 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3904 case BUILT_IN_TRUNCF:
3905 if (out_mode != SFmode || out_n != 4
3906 || in_mode != SFmode || in_n != 4)
3908 if (VECTOR_UNIT_VSX_P (V4SFmode))
3909 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3910 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3911 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3913 case BUILT_IN_NEARBYINT:
3914 if (VECTOR_UNIT_VSX_P (V2DFmode)
3915 && flag_unsafe_math_optimizations
3916 && out_mode == DFmode && out_n == 2
3917 && in_mode == DFmode && in_n == 2)
3918 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3920 case BUILT_IN_NEARBYINTF:
3921 if (VECTOR_UNIT_VSX_P (V4SFmode)
3922 && flag_unsafe_math_optimizations
3923 && out_mode == SFmode && out_n == 4
3924 && in_mode == SFmode && in_n == 4)
3925 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3928 if (VECTOR_UNIT_VSX_P (V2DFmode)
3929 && !flag_trapping_math
3930 && out_mode == DFmode && out_n == 2
3931 && in_mode == DFmode && in_n == 2)
3932 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3934 case BUILT_IN_RINTF:
3935 if (VECTOR_UNIT_VSX_P (V4SFmode)
3936 && !flag_trapping_math
3937 && out_mode == SFmode && out_n == 4
3938 && in_mode == SFmode && in_n == 4)
3939 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3946 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3948 enum rs6000_builtins fn
3949 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
3952 case RS6000_BUILTIN_RSQRTF:
3953 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3954 && out_mode == SFmode && out_n == 4
3955 && in_mode == SFmode && in_n == 4)
3956 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
3958 case RS6000_BUILTIN_RSQRT:
3959 if (VECTOR_UNIT_VSX_P (V2DFmode)
3960 && out_mode == DFmode && out_n == 2
3961 && in_mode == DFmode && in_n == 2)
3962 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
3964 case RS6000_BUILTIN_RECIPF:
3965 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3966 && out_mode == SFmode && out_n == 4
3967 && in_mode == SFmode && in_n == 4)
3968 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
3970 case RS6000_BUILTIN_RECIP:
3971 if (VECTOR_UNIT_VSX_P (V2DFmode)
3972 && out_mode == DFmode && out_n == 2
3973 && in_mode == DFmode && in_n == 2)
3974 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
3981 /* Generate calls to libmass if appropriate. */
3982 if (rs6000_veclib_handler)
3983 return rs6000_veclib_handler (fndecl, type_out, type_in);
3989 /* Implement TARGET_HANDLE_OPTION. */
3992 rs6000_handle_option (size_t code, const char *arg, int value)
3994 enum fpu_type_t fpu_type = FPU_NONE;
4000 target_flags &= ~(MASK_POWER | MASK_POWER2
4001 | MASK_MULTIPLE | MASK_STRING);
4002 target_flags_explicit |= (MASK_POWER | MASK_POWER2
4003 | MASK_MULTIPLE | MASK_STRING);
4005 case OPT_mno_powerpc:
4006 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
4007 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4008 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
4009 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4012 target_flags &= ~MASK_MINIMAL_TOC;
4013 TARGET_NO_FP_IN_TOC = 0;
4014 TARGET_NO_SUM_IN_TOC = 0;
4015 target_flags_explicit |= MASK_MINIMAL_TOC;
4016 #ifdef TARGET_USES_SYSV4_OPT
4017 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4018 just the same as -mminimal-toc. */
4019 target_flags |= MASK_MINIMAL_TOC;
4020 target_flags_explicit |= MASK_MINIMAL_TOC;
4024 #ifdef TARGET_USES_SYSV4_OPT
4026 /* Make -mtoc behave like -mminimal-toc. */
4027 target_flags |= MASK_MINIMAL_TOC;
4028 target_flags_explicit |= MASK_MINIMAL_TOC;
4032 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4034 if (strcmp (arg, "small") == 0)
4035 cmodel = CMODEL_SMALL;
4036 else if (strcmp (arg, "medium") == 0)
4037 cmodel = CMODEL_MEDIUM;
4038 else if (strcmp (arg, "large") == 0)
4039 cmodel = CMODEL_LARGE;
4042 error ("invalid option for -mcmodel: '%s'", arg);
4045 rs6000_explicit_options.cmodel = true;
4048 #ifdef TARGET_USES_AIX64_OPT
4053 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4054 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4055 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4058 #ifdef TARGET_USES_AIX64_OPT
4063 target_flags &= ~MASK_POWERPC64;
4064 target_flags_explicit |= MASK_POWERPC64;
4067 case OPT_minsert_sched_nops_:
4068 rs6000_sched_insert_nops_str = arg;
4071 case OPT_mminimal_toc:
4074 TARGET_NO_FP_IN_TOC = 0;
4075 TARGET_NO_SUM_IN_TOC = 0;
4082 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4083 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4090 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4091 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4095 case OPT_mpowerpc_gpopt:
4096 case OPT_mpowerpc_gfxopt:
4099 target_flags |= MASK_POWERPC;
4100 target_flags_explicit |= MASK_POWERPC;
4104 case OPT_maix_struct_return:
4105 case OPT_msvr4_struct_return:
4106 rs6000_explicit_options.aix_struct_ret = true;
4110 rs6000_explicit_options.vrsave = true;
4111 TARGET_ALTIVEC_VRSAVE = value;
4115 rs6000_explicit_options.vrsave = true;
4116 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
4120 target_flags_explicit |= MASK_ISEL;
4122 rs6000_parse_yes_no_option ("isel", arg, &isel);
4124 target_flags |= MASK_ISEL;
4126 target_flags &= ~MASK_ISEL;
4130 rs6000_explicit_options.spe = true;
4135 rs6000_explicit_options.spe = true;
4136 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
4140 rs6000_debug_name = arg;
4143 #ifdef TARGET_USES_SYSV4_OPT
4145 rs6000_abi_name = arg;
4149 rs6000_sdata_name = arg;
4152 case OPT_mtls_size_:
4153 rs6000_tls_size_string = arg;
4156 case OPT_mrelocatable:
4159 target_flags |= MASK_MINIMAL_TOC;
4160 target_flags_explicit |= MASK_MINIMAL_TOC;
4161 TARGET_NO_FP_IN_TOC = 1;
4165 case OPT_mrelocatable_lib:
4168 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4169 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4170 TARGET_NO_FP_IN_TOC = 1;
4174 target_flags &= ~MASK_RELOCATABLE;
4175 target_flags_explicit |= MASK_RELOCATABLE;
4181 if (!strcmp (arg, "altivec"))
4183 rs6000_explicit_options.altivec_abi = true;
4184 rs6000_altivec_abi = 1;
4186 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4189 else if (! strcmp (arg, "no-altivec"))
4191 rs6000_explicit_options.altivec_abi = true;
4192 rs6000_altivec_abi = 0;
4194 else if (! strcmp (arg, "spe"))
4196 rs6000_explicit_options.spe_abi = true;
4198 rs6000_altivec_abi = 0;
4199 if (!TARGET_SPE_ABI)
4200 error ("not configured for ABI: '%s'", arg);
4202 else if (! strcmp (arg, "no-spe"))
4204 rs6000_explicit_options.spe_abi = true;
4208 /* These are here for testing during development only, do not
4209 document in the manual please. */
4210 else if (! strcmp (arg, "d64"))
4212 rs6000_darwin64_abi = 1;
4213 warning (0, "Using darwin64 ABI");
4215 else if (! strcmp (arg, "d32"))
4217 rs6000_darwin64_abi = 0;
4218 warning (0, "Using old darwin ABI");
4221 else if (! strcmp (arg, "ibmlongdouble"))
4223 rs6000_explicit_options.ieee = true;
4224 rs6000_ieeequad = 0;
4225 warning (0, "Using IBM extended precision long double");
4227 else if (! strcmp (arg, "ieeelongdouble"))
4229 rs6000_explicit_options.ieee = true;
4230 rs6000_ieeequad = 1;
4231 warning (0, "Using IEEE extended precision long double");
4236 error ("unknown ABI specified: '%s'", arg);
4242 rs6000_select[1].string = arg;
4246 rs6000_select[2].string = arg;
4249 case OPT_mtraceback_:
4250 rs6000_traceback_name = arg;
4253 case OPT_mfloat_gprs_:
4254 rs6000_explicit_options.float_gprs = true;
4255 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4256 rs6000_float_gprs = 1;
4257 else if (! strcmp (arg, "double"))
4258 rs6000_float_gprs = 2;
4259 else if (! strcmp (arg, "no"))
4260 rs6000_float_gprs = 0;
4263 error ("invalid option for -mfloat-gprs: '%s'", arg);
4268 case OPT_mlong_double_:
4269 rs6000_explicit_options.long_double = true;
4270 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4271 if (value != 64 && value != 128)
4273 error ("Unknown switch -mlong-double-%s", arg);
4274 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4278 rs6000_long_double_type_size = value;
4281 case OPT_msched_costly_dep_:
4282 rs6000_sched_costly_dep_str = arg;
4286 rs6000_explicit_options.alignment = true;
4287 if (! strcmp (arg, "power"))
4289 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4290 some C library functions, so warn about it. The flag may be
4291 useful for performance studies from time to time though, so
4292 don't disable it entirely. */
4293 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4294 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4295 " it is incompatible with the installed C and C++ libraries");
4296 rs6000_alignment_flags = MASK_ALIGN_POWER;
4298 else if (! strcmp (arg, "natural"))
4299 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4302 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4307 case OPT_msingle_float:
4308 if (!TARGET_SINGLE_FPU)
4309 warning (0, "-msingle-float option equivalent to -mhard-float");
4310 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4311 rs6000_double_float = 0;
4312 target_flags &= ~MASK_SOFT_FLOAT;
4313 target_flags_explicit |= MASK_SOFT_FLOAT;
4316 case OPT_mdouble_float:
4317 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4318 rs6000_single_float = 1;
4319 target_flags &= ~MASK_SOFT_FLOAT;
4320 target_flags_explicit |= MASK_SOFT_FLOAT;
4323 case OPT_msimple_fpu:
4324 if (!TARGET_SINGLE_FPU)
4325 warning (0, "-msimple-fpu option ignored");
4328 case OPT_mhard_float:
4329 /* -mhard_float implies -msingle-float and -mdouble-float. */
4330 rs6000_single_float = rs6000_double_float = 1;
4333 case OPT_msoft_float:
4334 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4335 rs6000_single_float = rs6000_double_float = 0;
4339 fpu_type = rs6000_parse_fpu_option(arg);
4340 if (fpu_type != FPU_NONE)
4341 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4343 target_flags &= ~MASK_SOFT_FLOAT;
4344 target_flags_explicit |= MASK_SOFT_FLOAT;
4345 rs6000_xilinx_fpu = 1;
4346 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4347 rs6000_single_float = 1;
4348 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4349 rs6000_single_float = rs6000_double_float = 1;
4350 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4351 rs6000_simple_fpu = 1;
4355 /* -mfpu=none is equivalent to -msoft-float */
4356 target_flags |= MASK_SOFT_FLOAT;
4357 target_flags_explicit |= MASK_SOFT_FLOAT;
4358 rs6000_single_float = rs6000_double_float = 0;
4362 rs6000_recip_name = (value) ? "default" : "none";
4366 rs6000_recip_name = arg;
4372 /* Do anything needed at the start of the asm file. */
4375 rs6000_file_start (void)
4379 const char *start = buffer;
4380 struct rs6000_cpu_select *ptr;
4381 const char *default_cpu = TARGET_CPU_DEFAULT;
4382 FILE *file = asm_out_file;
4384 default_file_start ();
4386 #ifdef TARGET_BI_ARCH
4387 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4391 if (flag_verbose_asm)
4393 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4394 rs6000_select[0].string = default_cpu;
4396 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4398 ptr = &rs6000_select[i];
4399 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4401 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4406 if (PPC405_ERRATUM77)
4408 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4412 #ifdef USING_ELFOS_H
4413 switch (rs6000_sdata)
4415 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4416 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4417 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4418 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4421 if (rs6000_sdata && g_switch_value)
4423 fprintf (file, "%s -G %d", start,
4433 #ifdef HAVE_AS_GNU_ATTRIBUTE
4434 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
4436 fprintf (file, "\t.gnu_attribute 4, %d\n",
4437 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
4438 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
4440 fprintf (file, "\t.gnu_attribute 8, %d\n",
4441 (TARGET_ALTIVEC_ABI ? 2
4442 : TARGET_SPE_ABI ? 3
4444 fprintf (file, "\t.gnu_attribute 12, %d\n",
4445 aix_struct_return ? 2 : 1);
4450 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4452 switch_to_section (toc_section);
4453 switch_to_section (text_section);
4458 /* Return nonzero if this function is known to have a null epilogue. */
4461 direct_return (void)
4463 if (reload_completed)
4465 rs6000_stack_t *info = rs6000_stack_info ();
4467 if (info->first_gp_reg_save == 32
4468 && info->first_fp_reg_save == 64
4469 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4470 && ! info->lr_save_p
4471 && ! info->cr_save_p
4472 && info->vrsave_mask == 0
4480 /* Return the number of instructions it takes to form a constant in an
4481 integer register. */
4484 num_insns_constant_wide (HOST_WIDE_INT value)
4486 /* signed constant loadable with {cal|addi} */
4487 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4490 /* constant loadable with {cau|addis} */
4491 else if ((value & 0xffff) == 0
4492 && (value >> 31 == -1 || value >> 31 == 0))
4495 #if HOST_BITS_PER_WIDE_INT == 64
4496 else if (TARGET_POWERPC64)
4498 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4499 HOST_WIDE_INT high = value >> 31;
4501 if (high == 0 || high == -1)
4507 return num_insns_constant_wide (high) + 1;
4509 return num_insns_constant_wide (low) + 1;
4511 return (num_insns_constant_wide (high)
4512 + num_insns_constant_wide (low) + 1);
4521 num_insns_constant (rtx op, enum machine_mode mode)
4523 HOST_WIDE_INT low, high;
4525 switch (GET_CODE (op))
4528 #if HOST_BITS_PER_WIDE_INT == 64
4529 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4530 && mask64_operand (op, mode))
4534 return num_insns_constant_wide (INTVAL (op));
4537 if (mode == SFmode || mode == SDmode)
4542 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4543 if (DECIMAL_FLOAT_MODE_P (mode))
4544 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4546 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4547 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4550 if (mode == VOIDmode || mode == DImode)
4552 high = CONST_DOUBLE_HIGH (op);
4553 low = CONST_DOUBLE_LOW (op);
4560 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4561 if (DECIMAL_FLOAT_MODE_P (mode))
4562 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4564 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4565 high = l[WORDS_BIG_ENDIAN == 0];
4566 low = l[WORDS_BIG_ENDIAN != 0];
4570 return (num_insns_constant_wide (low)
4571 + num_insns_constant_wide (high));
4574 if ((high == 0 && low >= 0)
4575 || (high == -1 && low < 0))
4576 return num_insns_constant_wide (low);
4578 else if (mask64_operand (op, mode))
4582 return num_insns_constant_wide (high) + 1;
4585 return (num_insns_constant_wide (high)
4586 + num_insns_constant_wide (low) + 1);
4594 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4595 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4596 corresponding element of the vector, but for V4SFmode and V2SFmode,
4597 the corresponding "float" is interpreted as an SImode integer. */
4600 const_vector_elt_as_int (rtx op, unsigned int elt)
4602 rtx tmp = CONST_VECTOR_ELT (op, elt);
4603 if (GET_MODE (op) == V4SFmode
4604 || GET_MODE (op) == V2SFmode)
4605 tmp = gen_lowpart (SImode, tmp);
4606 return INTVAL (tmp);
4609 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4610 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4611 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4612 all items are set to the same value and contain COPIES replicas of the
4613 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4614 operand and the others are set to the value of the operand's msb. */
4617 vspltis_constant (rtx op, unsigned step, unsigned copies)
4619 enum machine_mode mode = GET_MODE (op);
4620 enum machine_mode inner = GET_MODE_INNER (mode);
4623 unsigned nunits = GET_MODE_NUNITS (mode);
4624 unsigned bitsize = GET_MODE_BITSIZE (inner);
4625 unsigned mask = GET_MODE_MASK (inner);
4627 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
4628 HOST_WIDE_INT splat_val = val;
4629 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
4631 /* Construct the value to be splatted, if possible. If not, return 0. */
4632 for (i = 2; i <= copies; i *= 2)
4634 HOST_WIDE_INT small_val;
4636 small_val = splat_val >> bitsize;
4638 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4640 splat_val = small_val;
4643 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4644 if (EASY_VECTOR_15 (splat_val))
4647 /* Also check if we can splat, and then add the result to itself. Do so if
4648 the value is positive, of if the splat instruction is using OP's mode;
4649 for splat_val < 0, the splat and the add should use the same mode. */
4650 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4651 && (splat_val >= 0 || (step == 1 && copies == 1)))
4654 /* Also check if are loading up the most significant bit which can be done by
4655 loading up -1 and shifting the value left by -1. */
4656 else if (EASY_VECTOR_MSB (splat_val, inner))
4662 /* Check if VAL is present in every STEP-th element, and the
4663 other elements are filled with its most significant bit. */
4664 for (i = 0; i < nunits - 1; ++i)
4666 HOST_WIDE_INT desired_val;
4667 if (((i + 1) & (step - 1)) == 0)
4670 desired_val = msb_val;
4672 if (desired_val != const_vector_elt_as_int (op, i))
4680 /* Return true if OP is of the given MODE and can be synthesized
4681 with a vspltisb, vspltish or vspltisw. */
4684 easy_altivec_constant (rtx op, enum machine_mode mode)
4686 unsigned step, copies;
4688 if (mode == VOIDmode)
4689 mode = GET_MODE (op);
4690 else if (mode != GET_MODE (op))
4693 /* Start with a vspltisw. */
4694 step = GET_MODE_NUNITS (mode) / 4;
4697 if (vspltis_constant (op, step, copies))
4700 /* Then try with a vspltish. */
4706 if (vspltis_constant (op, step, copies))
4709 /* And finally a vspltisb. */
4715 if (vspltis_constant (op, step, copies))
4721 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4722 result is OP. Abort if it is not possible. */
4725 gen_easy_altivec_constant (rtx op)
4727 enum machine_mode mode = GET_MODE (op);
4728 int nunits = GET_MODE_NUNITS (mode);
4729 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4730 unsigned step = nunits / 4;
4731 unsigned copies = 1;
4733 /* Start with a vspltisw. */
4734 if (vspltis_constant (op, step, copies))
4735 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4737 /* Then try with a vspltish. */
4743 if (vspltis_constant (op, step, copies))
4744 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4746 /* And finally a vspltisb. */
4752 if (vspltis_constant (op, step, copies))
4753 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4759 output_vec_const_move (rtx *operands)
4762 enum machine_mode mode;
4767 mode = GET_MODE (dest);
4769 if (TARGET_VSX && zero_constant (vec, mode))
4770 return "xxlxor %x0,%x0,%x0";
4775 if (zero_constant (vec, mode))
4776 return "vxor %0,%0,%0";
4778 splat_vec = gen_easy_altivec_constant (vec);
4779 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4780 operands[1] = XEXP (splat_vec, 0);
4781 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4784 switch (GET_MODE (splat_vec))
4787 return "vspltisw %0,%1";
4790 return "vspltish %0,%1";
4793 return "vspltisb %0,%1";
4800 gcc_assert (TARGET_SPE);
4802 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4803 pattern of V1DI, V4HI, and V2SF.
4805 FIXME: We should probably return # and add post reload
4806 splitters for these, but this way is so easy ;-). */
4807 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4808 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4809 operands[1] = CONST_VECTOR_ELT (vec, 0);
4810 operands[2] = CONST_VECTOR_ELT (vec, 1);
4812 return "li %0,%1\n\tevmergelo %0,%0,%0";
4814 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4817 /* Initialize TARGET of vector PAIRED to VALS. */
4820 paired_expand_vector_init (rtx target, rtx vals)
4822 enum machine_mode mode = GET_MODE (target);
4823 int n_elts = GET_MODE_NUNITS (mode);
4825 rtx x, new_rtx, tmp, constant_op, op1, op2;
4828 for (i = 0; i < n_elts; ++i)
4830 x = XVECEXP (vals, 0, i);
4831 if (!CONSTANT_P (x))
4836 /* Load from constant pool. */
4837 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4843 /* The vector is initialized only with non-constants. */
4844 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4845 XVECEXP (vals, 0, 1));
4847 emit_move_insn (target, new_rtx);
4851 /* One field is non-constant and the other one is a constant. Load the
4852 constant from the constant pool and use ps_merge instruction to
4853 construct the whole vector. */
4854 op1 = XVECEXP (vals, 0, 0);
4855 op2 = XVECEXP (vals, 0, 1);
4857 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4859 tmp = gen_reg_rtx (GET_MODE (constant_op));
4860 emit_move_insn (tmp, constant_op);
4862 if (CONSTANT_P (op1))
4863 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4865 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4867 emit_move_insn (target, new_rtx);
4871 paired_expand_vector_move (rtx operands[])
4873 rtx op0 = operands[0], op1 = operands[1];
4875 emit_move_insn (op0, op1);
4878 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4879 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4880 operands for the relation operation COND. This is a recursive
4884 paired_emit_vector_compare (enum rtx_code rcode,
4885 rtx dest, rtx op0, rtx op1,
4886 rtx cc_op0, rtx cc_op1)
4888 rtx tmp = gen_reg_rtx (V2SFmode);
4891 gcc_assert (TARGET_PAIRED_FLOAT);
4892 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4898 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4902 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4903 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4907 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4910 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4913 tmp1 = gen_reg_rtx (V2SFmode);
4914 max = gen_reg_rtx (V2SFmode);
4915 min = gen_reg_rtx (V2SFmode);
4916 gen_reg_rtx (V2SFmode);
4918 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4919 emit_insn (gen_selv2sf4
4920 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4921 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4922 emit_insn (gen_selv2sf4
4923 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4924 emit_insn (gen_subv2sf3 (tmp1, min, max));
4925 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4928 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4931 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4934 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4937 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4940 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4949 /* Emit vector conditional expression.
4950 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4951 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4954 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4955 rtx cond, rtx cc_op0, rtx cc_op1)
4957 enum rtx_code rcode = GET_CODE (cond);
4959 if (!TARGET_PAIRED_FLOAT)
4962 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4967 /* Initialize vector TARGET to VALS. */
4970 rs6000_expand_vector_init (rtx target, rtx vals)
4972 enum machine_mode mode = GET_MODE (target);
4973 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4974 int n_elts = GET_MODE_NUNITS (mode);
4975 int n_var = 0, one_var = -1;
4976 bool all_same = true, all_const_zero = true;
4980 for (i = 0; i < n_elts; ++i)
4982 x = XVECEXP (vals, 0, i);
4983 if (!CONSTANT_P (x))
4984 ++n_var, one_var = i;
4985 else if (x != CONST0_RTX (inner_mode))
4986 all_const_zero = false;
4988 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4994 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4995 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4996 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4998 /* Zero register. */
4999 emit_insn (gen_rtx_SET (VOIDmode, target,
5000 gen_rtx_XOR (mode, target, target)));
5003 else if (int_vector_p && easy_vector_constant (const_vec, mode))
5005 /* Splat immediate. */
5006 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
5011 /* Load from constant pool. */
5012 emit_move_insn (target, const_vec);
5017 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5018 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5022 rtx element = XVECEXP (vals, 0, 0);
5023 if (mode == V2DFmode)
5024 emit_insn (gen_vsx_splat_v2df (target, element));
5026 emit_insn (gen_vsx_splat_v2di (target, element));
5030 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
5031 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
5032 if (mode == V2DFmode)
5033 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5035 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5040 /* With single precision floating point on VSX, know that internally single
5041 precision is actually represented as a double, and either make 2 V2DF
5042 vectors, and convert these vectors to single precision, or do one
5043 conversion, and splat the result to the other elements. */
5044 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5048 rtx freg = gen_reg_rtx (V4SFmode);
5049 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5051 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5052 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5056 rtx dbl_even = gen_reg_rtx (V2DFmode);
5057 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5058 rtx flt_even = gen_reg_rtx (V4SFmode);
5059 rtx flt_odd = gen_reg_rtx (V4SFmode);
5061 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5062 copy_to_reg (XVECEXP (vals, 0, 0)),
5063 copy_to_reg (XVECEXP (vals, 0, 1))));
5064 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5065 copy_to_reg (XVECEXP (vals, 0, 2)),
5066 copy_to_reg (XVECEXP (vals, 0, 3))));
5067 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5068 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5069 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5074 /* Store value to stack temp. Load vector element. Splat. However, splat
5075 of 64-bit items is not supported on Altivec. */
5076 if (all_same && GET_MODE_SIZE (mode) <= 4)
5078 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5079 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5080 XVECEXP (vals, 0, 0));
5081 x = gen_rtx_UNSPEC (VOIDmode,
5082 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5083 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5085 gen_rtx_SET (VOIDmode,
5088 x = gen_rtx_VEC_SELECT (inner_mode, target,
5089 gen_rtx_PARALLEL (VOIDmode,
5090 gen_rtvec (1, const0_rtx)));
5091 emit_insn (gen_rtx_SET (VOIDmode, target,
5092 gen_rtx_VEC_DUPLICATE (mode, x)));
5096 /* One field is non-constant. Load constant then overwrite
5100 rtx copy = copy_rtx (vals);
5102 /* Load constant part of vector, substitute neighboring value for
5104 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5105 rs6000_expand_vector_init (target, copy);
5107 /* Insert variable. */
5108 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5112 /* Construct the vector in memory one field at a time
5113 and load the whole vector. */
5114 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5115 for (i = 0; i < n_elts; i++)
5116 emit_move_insn (adjust_address_nv (mem, inner_mode,
5117 i * GET_MODE_SIZE (inner_mode)),
5118 XVECEXP (vals, 0, i));
5119 emit_move_insn (target, mem);
5122 /* Set field ELT of TARGET to VAL. */
5125 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5127 enum machine_mode mode = GET_MODE (target);
5128 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5129 rtx reg = gen_reg_rtx (mode);
5131 int width = GET_MODE_SIZE (inner_mode);
5134 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5136 rtx (*set_func) (rtx, rtx, rtx, rtx)
5137 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5138 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5142 /* Load single variable value. */
5143 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5144 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5145 x = gen_rtx_UNSPEC (VOIDmode,
5146 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5147 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5149 gen_rtx_SET (VOIDmode,
5153 /* Linear sequence. */
5154 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5155 for (i = 0; i < 16; ++i)
5156 XVECEXP (mask, 0, i) = GEN_INT (i);
5158 /* Set permute mask to insert element into target. */
5159 for (i = 0; i < width; ++i)
5160 XVECEXP (mask, 0, elt*width + i)
5161 = GEN_INT (i + 0x10);
5162 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5163 x = gen_rtx_UNSPEC (mode,
5164 gen_rtvec (3, target, reg,
5165 force_reg (V16QImode, x)),
5167 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5170 /* Extract field ELT from VEC into TARGET. */
5173 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5175 enum machine_mode mode = GET_MODE (vec);
5176 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5179 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5181 rtx (*extract_func) (rtx, rtx, rtx)
5182 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5183 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5187 /* Allocate mode-sized buffer. */
5188 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5190 /* Add offset to field within buffer matching vector element. */
5191 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
5193 /* Store single field into mode-sized buffer. */
5194 x = gen_rtx_UNSPEC (VOIDmode,
5195 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
5196 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5198 gen_rtx_SET (VOIDmode,
5201 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5204 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5205 implement ANDing by the mask IN. */
5207 build_mask64_2_operands (rtx in, rtx *out)
5209 #if HOST_BITS_PER_WIDE_INT >= 64
5210 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5213 gcc_assert (GET_CODE (in) == CONST_INT);
5218 /* Assume c initially something like 0x00fff000000fffff. The idea
5219 is to rotate the word so that the middle ^^^^^^ group of zeros
5220 is at the MS end and can be cleared with an rldicl mask. We then
5221 rotate back and clear off the MS ^^ group of zeros with a
5223 c = ~c; /* c == 0xff000ffffff00000 */
5224 lsb = c & -c; /* lsb == 0x0000000000100000 */
5225 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5226 c = ~c; /* c == 0x00fff000000fffff */
5227 c &= -lsb; /* c == 0x00fff00000000000 */
5228 lsb = c & -c; /* lsb == 0x0000100000000000 */
5229 c = ~c; /* c == 0xff000fffffffffff */
5230 c &= -lsb; /* c == 0xff00000000000000 */
5232 while ((lsb >>= 1) != 0)
5233 shift++; /* shift == 44 on exit from loop */
5234 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5235 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5236 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5240 /* Assume c initially something like 0xff000f0000000000. The idea
5241 is to rotate the word so that the ^^^ middle group of zeros
5242 is at the LS end and can be cleared with an rldicr mask. We then
5243 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5245 lsb = c & -c; /* lsb == 0x0000010000000000 */
5246 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5247 c = ~c; /* c == 0x00fff0ffffffffff */
5248 c &= -lsb; /* c == 0x00fff00000000000 */
5249 lsb = c & -c; /* lsb == 0x0000100000000000 */
5250 c = ~c; /* c == 0xff000fffffffffff */
5251 c &= -lsb; /* c == 0xff00000000000000 */
5253 while ((lsb >>= 1) != 0)
5254 shift++; /* shift == 44 on exit from loop */
5255 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5256 m1 >>= shift; /* m1 == 0x0000000000000fff */
5257 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5260 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5261 masks will be all 1's. We are guaranteed more than one transition. */
5262 out[0] = GEN_INT (64 - shift);
5263 out[1] = GEN_INT (m1);
5264 out[2] = GEN_INT (shift);
5265 out[3] = GEN_INT (m2);
5273 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5276 invalid_e500_subreg (rtx op, enum machine_mode mode)
5278 if (TARGET_E500_DOUBLE)
5280 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5281 subreg:TI and reg:TF. Decimal float modes are like integer
5282 modes (only low part of each register used) for this
5284 if (GET_CODE (op) == SUBREG
5285 && (mode == SImode || mode == DImode || mode == TImode
5286 || mode == DDmode || mode == TDmode)
5287 && REG_P (SUBREG_REG (op))
5288 && (GET_MODE (SUBREG_REG (op)) == DFmode
5289 || GET_MODE (SUBREG_REG (op)) == TFmode))
5292 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5294 if (GET_CODE (op) == SUBREG
5295 && (mode == DFmode || mode == TFmode)
5296 && REG_P (SUBREG_REG (op))
5297 && (GET_MODE (SUBREG_REG (op)) == DImode
5298 || GET_MODE (SUBREG_REG (op)) == TImode
5299 || GET_MODE (SUBREG_REG (op)) == DDmode
5300 || GET_MODE (SUBREG_REG (op)) == TDmode))
5305 && GET_CODE (op) == SUBREG
5307 && REG_P (SUBREG_REG (op))
5308 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5314 /* AIX increases natural record alignment to doubleword if the first
5315 field is an FP double while the FP fields remain word aligned. */
5318 rs6000_special_round_type_align (tree type, unsigned int computed,
5319 unsigned int specified)
5321 unsigned int align = MAX (computed, specified);
5322 tree field = TYPE_FIELDS (type);
5324 /* Skip all non field decls */
5325 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5326 field = DECL_CHAIN (field);
5328 if (field != NULL && field != type)
5330 type = TREE_TYPE (field);
5331 while (TREE_CODE (type) == ARRAY_TYPE)
5332 type = TREE_TYPE (type);
5334 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5335 align = MAX (align, 64);
5341 /* Darwin increases record alignment to the natural alignment of
5345 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5346 unsigned int specified)
5348 unsigned int align = MAX (computed, specified);
5350 if (TYPE_PACKED (type))
5353 /* Find the first field, looking down into aggregates. */
5355 tree field = TYPE_FIELDS (type);
5356 /* Skip all non field decls */
5357 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5358 field = DECL_CHAIN (field);
5361 /* A packed field does not contribute any extra alignment. */
5362 if (DECL_PACKED (field))
5364 type = TREE_TYPE (field);
5365 while (TREE_CODE (type) == ARRAY_TYPE)
5366 type = TREE_TYPE (type);
5367 } while (AGGREGATE_TYPE_P (type));
5369 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5370 align = MAX (align, TYPE_ALIGN (type));
5375 /* Return 1 for an operand in small memory on V.4/eabi. */
5378 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5379 enum machine_mode mode ATTRIBUTE_UNUSED)
5384 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5387 if (DEFAULT_ABI != ABI_V4)
5390 /* Vector and float memory instructions have a limited offset on the
5391 SPE, so using a vector or float variable directly as an operand is
5394 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5397 if (GET_CODE (op) == SYMBOL_REF)
5400 else if (GET_CODE (op) != CONST
5401 || GET_CODE (XEXP (op, 0)) != PLUS
5402 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5403 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5408 rtx sum = XEXP (op, 0);
5409 HOST_WIDE_INT summand;
5411 /* We have to be careful here, because it is the referenced address
5412 that must be 32k from _SDA_BASE_, not just the symbol. */
5413 summand = INTVAL (XEXP (sum, 1));
5414 if (summand < 0 || summand > g_switch_value)
5417 sym_ref = XEXP (sum, 0);
5420 return SYMBOL_REF_SMALL_P (sym_ref);
5426 /* Return true if either operand is a general purpose register. */
5429 gpr_or_gpr_p (rtx op0, rtx op1)
5431 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5432 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5436 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5439 reg_offset_addressing_ok_p (enum machine_mode mode)
5449 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5450 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5458 /* Paired vector modes. Only reg+reg addressing is valid. */
5459 if (TARGET_PAIRED_FLOAT)
5471 virtual_stack_registers_memory_p (rtx op)
5475 if (GET_CODE (op) == REG)
5476 regnum = REGNO (op);
5478 else if (GET_CODE (op) == PLUS
5479 && GET_CODE (XEXP (op, 0)) == REG
5480 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5481 regnum = REGNO (XEXP (op, 0));
5486 return (regnum >= FIRST_VIRTUAL_REGISTER
5487 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5491 constant_pool_expr_p (rtx op)
5495 split_const (op, &base, &offset);
5496 return (GET_CODE (base) == SYMBOL_REF
5497 && CONSTANT_POOL_ADDRESS_P (base)
5498 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5501 static rtx tocrel_base, tocrel_offset;
5504 toc_relative_expr_p (rtx op)
5506 if (GET_CODE (op) != CONST)
5509 split_const (op, &tocrel_base, &tocrel_offset);
5510 return (GET_CODE (tocrel_base) == UNSPEC
5511 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5515 legitimate_constant_pool_address_p (const_rtx x, bool strict)
5518 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5519 && GET_CODE (XEXP (x, 0)) == REG
5520 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5521 || ((TARGET_MINIMAL_TOC
5522 || TARGET_CMODEL != CMODEL_SMALL)
5523 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5524 && toc_relative_expr_p (XEXP (x, 1)));
5528 legitimate_small_data_p (enum machine_mode mode, rtx x)
5530 return (DEFAULT_ABI == ABI_V4
5531 && !flag_pic && !TARGET_TOC
5532 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5533 && small_data_operand (x, mode));
5536 /* SPE offset addressing is limited to 5-bits worth of double words. */
5537 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5540 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5542 unsigned HOST_WIDE_INT offset, extra;
5544 if (GET_CODE (x) != PLUS)
5546 if (GET_CODE (XEXP (x, 0)) != REG)
5548 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5550 if (!reg_offset_addressing_ok_p (mode))
5551 return virtual_stack_registers_memory_p (x);
5552 if (legitimate_constant_pool_address_p (x, strict))
5554 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5557 offset = INTVAL (XEXP (x, 1));
5565 /* SPE vector modes. */
5566 return SPE_CONST_OFFSET_OK (offset);
5569 if (TARGET_E500_DOUBLE)
5570 return SPE_CONST_OFFSET_OK (offset);
5572 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5574 if (VECTOR_MEM_VSX_P (DFmode))
5579 /* On e500v2, we may have:
5581 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5583 Which gets addressed with evldd instructions. */
5584 if (TARGET_E500_DOUBLE)
5585 return SPE_CONST_OFFSET_OK (offset);
5587 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5589 else if (offset & 3)
5594 if (TARGET_E500_DOUBLE)
5595 return (SPE_CONST_OFFSET_OK (offset)
5596 && SPE_CONST_OFFSET_OK (offset + 8));
5600 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5602 else if (offset & 3)
5613 return (offset < 0x10000) && (offset + extra < 0x10000);
5617 legitimate_indexed_address_p (rtx x, int strict)
5621 if (GET_CODE (x) != PLUS)
5627 /* Recognize the rtl generated by reload which we know will later be
5628 replaced with proper base and index regs. */
5630 && reload_in_progress
5631 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5635 return (REG_P (op0) && REG_P (op1)
5636 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5637 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5638 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5639 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5643 avoiding_indexed_address_p (enum machine_mode mode)
5645 /* Avoid indexed addressing for modes that have non-indexed
5646 load/store instruction forms. */
5647 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5651 legitimate_indirect_address_p (rtx x, int strict)
5653 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5657 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5659 if (!TARGET_MACHO || !flag_pic
5660 || mode != SImode || GET_CODE (x) != MEM)
5664 if (GET_CODE (x) != LO_SUM)
5666 if (GET_CODE (XEXP (x, 0)) != REG)
5668 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5672 return CONSTANT_P (x);
5676 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5678 if (GET_CODE (x) != LO_SUM)
5680 if (GET_CODE (XEXP (x, 0)) != REG)
5682 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5684 /* Restrict addressing for DI because of our SUBREG hackery. */
5685 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5686 || mode == DDmode || mode == TDmode
5691 if (TARGET_ELF || TARGET_MACHO)
5693 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5697 if (GET_MODE_NUNITS (mode) != 1)
5699 if (GET_MODE_BITSIZE (mode) > 64
5700 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5701 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5702 && (mode == DFmode || mode == DDmode))))
5705 return CONSTANT_P (x);
5712 /* Try machine-dependent ways of modifying an illegitimate address
5713 to be legitimate. If we find one, return the new, valid address.
5714 This is used from only one place: `memory_address' in explow.c.
5716 OLDX is the address as it was before break_out_memory_refs was
5717 called. In some cases it is useful to look at this to decide what
5720 It is always safe for this function to do nothing. It exists to
5721 recognize opportunities to optimize the output.
5723 On RS/6000, first check for the sum of a register with a constant
5724 integer that is out of range. If so, generate code to add the
5725 constant with the low-order 16 bits masked to the register and force
5726 this result into another register (this can be done with `cau').
5727 Then generate an address of REG+(CONST&0xffff), allowing for the
5728 possibility of bit 16 being a one.
5730 Then check for the sum of a register and something not constant, try to
5731 load the other things into a register and return the sum. */
5734 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5735 enum machine_mode mode)
5737 unsigned int extra = 0;
5739 if (!reg_offset_addressing_ok_p (mode))
5741 if (virtual_stack_registers_memory_p (x))
5744 /* In theory we should not be seeing addresses of the form reg+0,
5745 but just in case it is generated, optimize it away. */
5746 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5747 return force_reg (Pmode, XEXP (x, 0));
5749 /* Make sure both operands are registers. */
5750 else if (GET_CODE (x) == PLUS)
5751 return gen_rtx_PLUS (Pmode,
5752 force_reg (Pmode, XEXP (x, 0)),
5753 force_reg (Pmode, XEXP (x, 1)));
5755 return force_reg (Pmode, x);
5757 if (GET_CODE (x) == SYMBOL_REF)
5759 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5761 return rs6000_legitimize_tls_address (x, model);
5771 if (!TARGET_POWERPC64)
5779 extra = TARGET_POWERPC64 ? 8 : 12;
5785 if (GET_CODE (x) == PLUS
5786 && GET_CODE (XEXP (x, 0)) == REG
5787 && GET_CODE (XEXP (x, 1)) == CONST_INT
5788 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5790 && !((TARGET_POWERPC64
5791 && (mode == DImode || mode == TImode)
5792 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5793 || SPE_VECTOR_MODE (mode)
5794 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5795 || mode == DImode || mode == DDmode
5796 || mode == TDmode))))
5798 HOST_WIDE_INT high_int, low_int;
5800 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5801 if (low_int >= 0x8000 - extra)
5803 high_int = INTVAL (XEXP (x, 1)) - low_int;
5804 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5805 GEN_INT (high_int)), 0);
5806 return plus_constant (sum, low_int);
5808 else if (GET_CODE (x) == PLUS
5809 && GET_CODE (XEXP (x, 0)) == REG
5810 && GET_CODE (XEXP (x, 1)) != CONST_INT
5811 && GET_MODE_NUNITS (mode) == 1
5812 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5814 || ((mode != DImode && mode != DFmode && mode != DDmode)
5815 || (TARGET_E500_DOUBLE && mode != DDmode)))
5816 && (TARGET_POWERPC64 || mode != DImode)
5817 && !avoiding_indexed_address_p (mode)
5822 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5823 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5825 else if (SPE_VECTOR_MODE (mode)
5826 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5827 || mode == DDmode || mode == TDmode
5828 || mode == DImode)))
5832 /* We accept [reg + reg] and [reg + OFFSET]. */
5834 if (GET_CODE (x) == PLUS)
5836 rtx op1 = XEXP (x, 0);
5837 rtx op2 = XEXP (x, 1);
5840 op1 = force_reg (Pmode, op1);
5842 if (GET_CODE (op2) != REG
5843 && (GET_CODE (op2) != CONST_INT
5844 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5845 || (GET_MODE_SIZE (mode) > 8
5846 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5847 op2 = force_reg (Pmode, op2);
5849 /* We can't always do [reg + reg] for these, because [reg +
5850 reg + offset] is not a legitimate addressing mode. */
5851 y = gen_rtx_PLUS (Pmode, op1, op2);
5853 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5854 return force_reg (Pmode, y);
5859 return force_reg (Pmode, x);
5865 && GET_CODE (x) != CONST_INT
5866 && GET_CODE (x) != CONST_DOUBLE
5868 && GET_MODE_NUNITS (mode) == 1
5869 && (GET_MODE_BITSIZE (mode) <= 32
5870 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5871 && (mode == DFmode || mode == DDmode))))
5873 rtx reg = gen_reg_rtx (Pmode);
5874 emit_insn (gen_elf_high (reg, x));
5875 return gen_rtx_LO_SUM (Pmode, reg, x);
5877 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5880 && ! MACHO_DYNAMIC_NO_PIC_P
5882 && GET_CODE (x) != CONST_INT
5883 && GET_CODE (x) != CONST_DOUBLE
5885 && GET_MODE_NUNITS (mode) == 1
5886 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5887 || (mode != DFmode && mode != DDmode))
5891 rtx reg = gen_reg_rtx (Pmode);
5892 emit_insn (gen_macho_high (reg, x));
5893 return gen_rtx_LO_SUM (Pmode, reg, x);
5896 && GET_CODE (x) == SYMBOL_REF
5897 && constant_pool_expr_p (x)
5898 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5900 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5901 return create_TOC_reference (x, reg);
5907 /* Debug version of rs6000_legitimize_address. */
5909 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5915 ret = rs6000_legitimize_address (x, oldx, mode);
5916 insns = get_insns ();
5922 "\nrs6000_legitimize_address: mode %s, old code %s, "
5923 "new code %s, modified\n",
5924 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5925 GET_RTX_NAME (GET_CODE (ret)));
5927 fprintf (stderr, "Original address:\n");
5930 fprintf (stderr, "oldx:\n");
5933 fprintf (stderr, "New address:\n");
5938 fprintf (stderr, "Insns added:\n");
5939 debug_rtx_list (insns, 20);
5945 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5946 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5957 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5958 We need to emit DTP-relative relocations. */
5961 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5966 fputs ("\t.long\t", file);
5969 fputs (DOUBLE_INT_ASM_OP, file);
5974 output_addr_const (file, x);
5975 fputs ("@dtprel+0x8000", file);
5978 /* In the name of slightly smaller debug output, and to cater to
5979 general assembler lossage, recognize various UNSPEC sequences
5980 and turn them back into a direct symbol reference. */
5983 rs6000_delegitimize_address (rtx orig_x)
5987 orig_x = delegitimize_mem_from_attrs (orig_x);
5992 if ((GET_CODE (x) == PLUS
5993 || GET_CODE (x) == LO_SUM)
5994 && GET_CODE (XEXP (x, 0)) == REG
5995 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5996 || TARGET_MINIMAL_TOC
5997 || TARGET_CMODEL != CMODEL_SMALL)
5998 && GET_CODE (XEXP (x, 1)) == CONST)
6000 y = XEXP (XEXP (x, 1), 0);
6001 if (GET_CODE (y) == UNSPEC
6002 && XINT (y, 1) == UNSPEC_TOCREL)
6004 y = XVECEXP (y, 0, 0);
6005 if (!MEM_P (orig_x))
6008 return replace_equiv_address_nv (orig_x, y);
6013 && GET_CODE (orig_x) == LO_SUM
6014 && GET_CODE (XEXP (x, 1)) == CONST)
6016 y = XEXP (XEXP (x, 1), 0);
6017 if (GET_CODE (y) == UNSPEC
6018 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
6019 return XVECEXP (y, 0, 0);
6025 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6027 static GTY(()) rtx rs6000_tls_symbol;
6029 rs6000_tls_get_addr (void)
6031 if (!rs6000_tls_symbol)
6032 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6034 return rs6000_tls_symbol;
6037 /* Construct the SYMBOL_REF for TLS GOT references. */
6039 static GTY(()) rtx rs6000_got_symbol;
6041 rs6000_got_sym (void)
6043 if (!rs6000_got_symbol)
6045 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6046 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6047 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6050 return rs6000_got_symbol;
6053 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6054 this (thread-local) address. */
6057 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6061 dest = gen_reg_rtx (Pmode);
6062 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6068 tlsreg = gen_rtx_REG (Pmode, 13);
6069 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6073 tlsreg = gen_rtx_REG (Pmode, 2);
6074 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6078 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6082 tmp = gen_reg_rtx (Pmode);
6085 tlsreg = gen_rtx_REG (Pmode, 13);
6086 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6090 tlsreg = gen_rtx_REG (Pmode, 2);
6091 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6095 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6097 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6102 rtx r3, got, tga, tmp1, tmp2, call_insn;
6104 /* We currently use relocations like @got@tlsgd for tls, which
6105 means the linker will handle allocation of tls entries, placing
6106 them in the .got section. So use a pointer to the .got section,
6107 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6108 or to secondary GOT sections used by 32-bit -fPIC. */
6110 got = gen_rtx_REG (Pmode, 2);
6114 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6117 rtx gsym = rs6000_got_sym ();
6118 got = gen_reg_rtx (Pmode);
6120 rs6000_emit_move (got, gsym, Pmode);
6125 tmp1 = gen_reg_rtx (Pmode);
6126 tmp2 = gen_reg_rtx (Pmode);
6127 mem = gen_const_mem (Pmode, tmp1);
6128 lab = gen_label_rtx ();
6129 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6130 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6131 emit_move_insn (tmp2, mem);
6132 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6133 set_unique_reg_note (last, REG_EQUAL, gsym);
6138 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6140 r3 = gen_rtx_REG (Pmode, 3);
6141 tga = rs6000_tls_get_addr ();
6142 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
6144 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6145 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6146 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6147 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6148 else if (DEFAULT_ABI == ABI_V4)
6149 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6152 call_insn = last_call_insn ();
6153 PATTERN (call_insn) = insn;
6154 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6155 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6156 pic_offset_table_rtx);
6158 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6160 r3 = gen_rtx_REG (Pmode, 3);
6161 tga = rs6000_tls_get_addr ();
6162 tmp1 = gen_reg_rtx (Pmode);
6163 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
6165 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6166 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6167 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6168 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6169 else if (DEFAULT_ABI == ABI_V4)
6170 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6173 call_insn = last_call_insn ();
6174 PATTERN (call_insn) = insn;
6175 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6176 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6177 pic_offset_table_rtx);
6179 if (rs6000_tls_size == 16)
6182 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6184 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6186 else if (rs6000_tls_size == 32)
6188 tmp2 = gen_reg_rtx (Pmode);
6190 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6192 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6195 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6197 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6201 tmp2 = gen_reg_rtx (Pmode);
6203 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6205 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6207 insn = gen_rtx_SET (Pmode, dest,
6208 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6214 /* IE, or 64-bit offset LE. */
6215 tmp2 = gen_reg_rtx (Pmode);
6217 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6219 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6222 insn = gen_tls_tls_64 (dest, tmp2, addr);
6224 insn = gen_tls_tls_32 (dest, tmp2, addr);
6232 /* Return 1 if X contains a thread-local symbol. */
6235 rs6000_tls_referenced_p (rtx x)
6237 if (! TARGET_HAVE_TLS)
6240 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6243 /* Return 1 if *X is a thread-local symbol. This is the same as
6244 rs6000_tls_symbol_ref except for the type of the unused argument. */
6247 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6249 return RS6000_SYMBOL_REF_TLS_P (*x);
6252 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6253 replace the input X, or the original X if no replacement is called for.
6254 The output parameter *WIN is 1 if the calling macro should goto WIN,
6257 For RS/6000, we wish to handle large displacements off a base
6258 register by splitting the addend across an addiu/addis and the mem insn.
6259 This cuts number of extra insns needed from 3 to 1.
6261 On Darwin, we use this to generate code for floating point constants.
6262 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6263 The Darwin code is inside #if TARGET_MACHO because only then are the
6264 machopic_* functions defined. */
6266 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6267 int opnum, int type,
6268 int ind_levels ATTRIBUTE_UNUSED, int *win)
6270 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6272 /* We must recognize output that we have already generated ourselves. */
6273 if (GET_CODE (x) == PLUS
6274 && GET_CODE (XEXP (x, 0)) == PLUS
6275 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6276 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6277 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6279 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6280 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6281 opnum, (enum reload_type)type);
6286 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6287 if (GET_CODE (x) == LO_SUM
6288 && GET_CODE (XEXP (x, 0)) == HIGH)
6290 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6291 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6292 opnum, (enum reload_type)type);
6298 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6299 && GET_CODE (x) == LO_SUM
6300 && GET_CODE (XEXP (x, 0)) == PLUS
6301 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6302 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6303 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6304 && machopic_operand_p (XEXP (x, 1)))
6306 /* Result of previous invocation of this function on Darwin
6307 floating point constant. */
6308 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6309 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6310 opnum, (enum reload_type)type);
6316 if (TARGET_CMODEL != CMODEL_SMALL
6317 && GET_CODE (x) == LO_SUM
6318 && GET_CODE (XEXP (x, 0)) == PLUS
6319 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6320 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6321 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6322 && GET_CODE (XEXP (x, 1)) == CONST
6323 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6324 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6325 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6327 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6328 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6329 opnum, (enum reload_type) type);
6334 /* Force ld/std non-word aligned offset into base register by wrapping
6336 if (GET_CODE (x) == PLUS
6337 && GET_CODE (XEXP (x, 0)) == REG
6338 && REGNO (XEXP (x, 0)) < 32
6339 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6340 && GET_CODE (XEXP (x, 1)) == CONST_INT
6342 && (INTVAL (XEXP (x, 1)) & 3) != 0
6343 && VECTOR_MEM_NONE_P (mode)
6344 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6345 && TARGET_POWERPC64)
6347 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6348 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6349 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6350 opnum, (enum reload_type) type);
6355 if (GET_CODE (x) == PLUS
6356 && GET_CODE (XEXP (x, 0)) == REG
6357 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6358 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6359 && GET_CODE (XEXP (x, 1)) == CONST_INT
6361 && !SPE_VECTOR_MODE (mode)
6362 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6363 || mode == DDmode || mode == TDmode
6365 && VECTOR_MEM_NONE_P (mode))
6367 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6368 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6370 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6372 /* Check for 32-bit overflow. */
6373 if (high + low != val)
6379 /* Reload the high part into a base reg; leave the low part
6380 in the mem directly. */
6382 x = gen_rtx_PLUS (GET_MODE (x),
6383 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6387 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6388 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6389 opnum, (enum reload_type)type);
6394 if (GET_CODE (x) == SYMBOL_REF
6396 && VECTOR_MEM_NONE_P (mode)
6397 && !SPE_VECTOR_MODE (mode)
6399 && DEFAULT_ABI == ABI_DARWIN
6400 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6402 && DEFAULT_ABI == ABI_V4
6405 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6406 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6410 && (mode != DImode || TARGET_POWERPC64)
6411 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6412 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6417 rtx offset = machopic_gen_offset (x);
6418 x = gen_rtx_LO_SUM (GET_MODE (x),
6419 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6420 gen_rtx_HIGH (Pmode, offset)), offset);
6424 x = gen_rtx_LO_SUM (GET_MODE (x),
6425 gen_rtx_HIGH (Pmode, x), x);
6427 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6428 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6429 opnum, (enum reload_type)type);
6434 /* Reload an offset address wrapped by an AND that represents the
6435 masking of the lower bits. Strip the outer AND and let reload
6436 convert the offset address into an indirect address. For VSX,
6437 force reload to create the address with an AND in a separate
6438 register, because we can't guarantee an altivec register will
6440 if (VECTOR_MEM_ALTIVEC_P (mode)
6441 && GET_CODE (x) == AND
6442 && GET_CODE (XEXP (x, 0)) == PLUS
6443 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6444 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6445 && GET_CODE (XEXP (x, 1)) == CONST_INT
6446 && INTVAL (XEXP (x, 1)) == -16)
6455 && GET_CODE (x) == SYMBOL_REF
6456 && constant_pool_expr_p (x)
6457 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6459 x = create_TOC_reference (x, NULL_RTX);
6460 if (TARGET_CMODEL != CMODEL_SMALL)
6461 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6462 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6463 opnum, (enum reload_type) type);
6471 /* Debug version of rs6000_legitimize_reload_address. */
6473 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6474 int opnum, int type,
6475 int ind_levels, int *win)
6477 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6480 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6481 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6482 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6486 fprintf (stderr, "Same address returned\n");
6488 fprintf (stderr, "NULL returned\n");
6491 fprintf (stderr, "New address:\n");
6498 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6499 that is a valid memory address for an instruction.
6500 The MODE argument is the machine mode for the MEM expression
6501 that wants to use this address.
6503 On the RS/6000, there are four valid address: a SYMBOL_REF that
6504 refers to a constant pool entry of an address (or the sum of it
6505 plus a constant), a short (16-bit signed) constant plus a register,
6506 the sum of two registers, or a register indirect, possibly with an
6507 auto-increment. For DFmode, DDmode and DImode with a constant plus
6508 register, we must ensure that both words are addressable or PowerPC64
6509 with offset word aligned.
6511 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6512 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6513 because adjacent memory cells are accessed by adding word-sized offsets
6514 during assembly output. */
6516 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6518 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6520 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6521 if (VECTOR_MEM_ALTIVEC_P (mode)
6522 && GET_CODE (x) == AND
6523 && GET_CODE (XEXP (x, 1)) == CONST_INT
6524 && INTVAL (XEXP (x, 1)) == -16)
6527 if (RS6000_SYMBOL_REF_TLS_P (x))
6529 if (legitimate_indirect_address_p (x, reg_ok_strict))
6531 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6532 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6533 && !SPE_VECTOR_MODE (mode)
6536 /* Restrict addressing for DI because of our SUBREG hackery. */
6537 && !(TARGET_E500_DOUBLE
6538 && (mode == DFmode || mode == DDmode || mode == DImode))
6540 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6542 if (virtual_stack_registers_memory_p (x))
6544 if (reg_offset_p && legitimate_small_data_p (mode, x))
6546 if (reg_offset_p && legitimate_constant_pool_address_p (x, reg_ok_strict))
6548 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6551 && GET_CODE (x) == PLUS
6552 && GET_CODE (XEXP (x, 0)) == REG
6553 && (XEXP (x, 0) == virtual_stack_vars_rtx
6554 || XEXP (x, 0) == arg_pointer_rtx)
6555 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6557 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6562 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6564 || (mode != DFmode && mode != DDmode)
6565 || (TARGET_E500_DOUBLE && mode != DDmode))
6566 && (TARGET_POWERPC64 || mode != DImode)
6567 && !avoiding_indexed_address_p (mode)
6568 && legitimate_indexed_address_p (x, reg_ok_strict))
6570 if (GET_CODE (x) == PRE_MODIFY
6574 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6576 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6577 && (TARGET_POWERPC64 || mode != DImode)
6578 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6579 && !SPE_VECTOR_MODE (mode)
6580 /* Restrict addressing for DI because of our SUBREG hackery. */
6581 && !(TARGET_E500_DOUBLE
6582 && (mode == DFmode || mode == DDmode || mode == DImode))
6584 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6585 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6586 || (!avoiding_indexed_address_p (mode)
6587 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6588 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6590 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6595 /* Debug version of rs6000_legitimate_address_p. */
6597 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6600 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6602 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6603 "strict = %d, code = %s\n",
6604 ret ? "true" : "false",
6605 GET_MODE_NAME (mode),
6607 GET_RTX_NAME (GET_CODE (x)));
6613 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6616 rs6000_mode_dependent_address_p (const_rtx addr)
6618 return rs6000_mode_dependent_address_ptr (addr);
6621 /* Go to LABEL if ADDR (a legitimate address expression)
6622 has an effect that depends on the machine mode it is used for.
6624 On the RS/6000 this is true of all integral offsets (since AltiVec
6625 and VSX modes don't allow them) or is a pre-increment or decrement.
6627 ??? Except that due to conceptual problems in offsettable_address_p
6628 we can't really report the problems of integral offsets. So leave
6629 this assuming that the adjustable offset must be valid for the
6630 sub-words of a TFmode operand, which is what we had before. */
6633 rs6000_mode_dependent_address (const_rtx addr)
6635 switch (GET_CODE (addr))
6638 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6639 is considered a legitimate address before reload, so there
6640 are no offset restrictions in that case. Note that this
6641 condition is safe in strict mode because any address involving
6642 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6643 been rejected as illegitimate. */
6644 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6645 && XEXP (addr, 0) != arg_pointer_rtx
6646 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6648 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6649 return val + 12 + 0x8000 >= 0x10000;
6654 /* Anything in the constant pool is sufficiently aligned that
6655 all bytes have the same high part address. */
6656 return !legitimate_constant_pool_address_p (addr, false);
6658 /* Auto-increment cases are now treated generically in recog.c. */
6660 return TARGET_UPDATE;
6662 /* AND is only allowed in Altivec loads. */
6673 /* Debug version of rs6000_mode_dependent_address. */
6675 rs6000_debug_mode_dependent_address (const_rtx addr)
6677 bool ret = rs6000_mode_dependent_address (addr);
6679 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6680 ret ? "true" : "false");
6686 /* Implement FIND_BASE_TERM. */
6689 rs6000_find_base_term (rtx op)
6693 split_const (op, &base, &offset);
6694 if (GET_CODE (base) == UNSPEC)
6695 switch (XINT (base, 1))
6698 case UNSPEC_MACHOPIC_OFFSET:
6699 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6700 for aliasing purposes. */
6701 return XVECEXP (base, 0, 0);
6707 /* More elaborate version of recog's offsettable_memref_p predicate
6708 that works around the ??? note of rs6000_mode_dependent_address.
6709 In particular it accepts
6711 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6713 in 32-bit mode, that the recog predicate rejects. */
6716 rs6000_offsettable_memref_p (rtx op)
6721 /* First mimic offsettable_memref_p. */
6722 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6725 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6726 the latter predicate knows nothing about the mode of the memory
6727 reference and, therefore, assumes that it is the largest supported
6728 mode (TFmode). As a consequence, legitimate offsettable memory
6729 references are rejected. rs6000_legitimate_offset_address_p contains
6730 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6731 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6734 /* Change register usage conditional on target flags. */
6736 rs6000_conditional_register_usage (void)
6740 /* Set MQ register fixed (already call_used) if not POWER
6741 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6746 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6748 fixed_regs[13] = call_used_regs[13]
6749 = call_really_used_regs[13] = 1;
6751 /* Conditionally disable FPRs. */
6752 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6753 for (i = 32; i < 64; i++)
6754 fixed_regs[i] = call_used_regs[i]
6755 = call_really_used_regs[i] = 1;
6757 /* The TOC register is not killed across calls in a way that is
6758 visible to the compiler. */
6759 if (DEFAULT_ABI == ABI_AIX)
6760 call_really_used_regs[2] = 0;
6762 if (DEFAULT_ABI == ABI_V4
6763 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6765 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6767 if (DEFAULT_ABI == ABI_V4
6768 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6770 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6771 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6772 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6774 if (DEFAULT_ABI == ABI_DARWIN
6775 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6776 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6777 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6778 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6780 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6781 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6782 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6786 global_regs[SPEFSCR_REGNO] = 1;
6787 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6788 registers in prologues and epilogues. We no longer use r14
6789 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6790 pool for link-compatibility with older versions of GCC. Once
6791 "old" code has died out, we can return r14 to the allocation
6794 = call_used_regs[14]
6795 = call_really_used_regs[14] = 1;
6798 if (!TARGET_ALTIVEC && !TARGET_VSX)
6800 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6801 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6802 call_really_used_regs[VRSAVE_REGNO] = 1;
6805 if (TARGET_ALTIVEC || TARGET_VSX)
6806 global_regs[VSCR_REGNO] = 1;
6808 if (TARGET_ALTIVEC_ABI)
6810 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6811 call_used_regs[i] = call_really_used_regs[i] = 1;
6813 /* AIX reserves VR20:31 in non-extended ABI mode. */
6815 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6816 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6820 /* Try to output insns to set TARGET equal to the constant C if it can
6821 be done in less than N insns. Do all computations in MODE.
6822 Returns the place where the output has been placed if it can be
6823 done and the insns have been emitted. If it would take more than N
6824 insns, zero is returned and no insns and emitted. */
6827 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6828 rtx source, int n ATTRIBUTE_UNUSED)
6830 rtx result, insn, set;
6831 HOST_WIDE_INT c0, c1;
6838 dest = gen_reg_rtx (mode);
6839 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6843 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6845 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6846 GEN_INT (INTVAL (source)
6847 & (~ (HOST_WIDE_INT) 0xffff))));
6848 emit_insn (gen_rtx_SET (VOIDmode, dest,
6849 gen_rtx_IOR (SImode, copy_rtx (result),
6850 GEN_INT (INTVAL (source) & 0xffff))));
6855 switch (GET_CODE (source))
6858 c0 = INTVAL (source);
6863 #if HOST_BITS_PER_WIDE_INT >= 64
6864 c0 = CONST_DOUBLE_LOW (source);
6867 c0 = CONST_DOUBLE_LOW (source);
6868 c1 = CONST_DOUBLE_HIGH (source);
6876 result = rs6000_emit_set_long_const (dest, c0, c1);
6883 insn = get_last_insn ();
6884 set = single_set (insn);
6885 if (! CONSTANT_P (SET_SRC (set)))
6886 set_unique_reg_note (insn, REG_EQUAL, source);
6891 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6892 fall back to a straight forward decomposition. We do this to avoid
6893 exponential run times encountered when looking for longer sequences
6894 with rs6000_emit_set_const. */
6896 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6898 if (!TARGET_POWERPC64)
6900 rtx operand1, operand2;
6902 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6904 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6906 emit_move_insn (operand1, GEN_INT (c1));
6907 emit_move_insn (operand2, GEN_INT (c2));
6911 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6914 ud2 = (c1 & 0xffff0000) >> 16;
6915 #if HOST_BITS_PER_WIDE_INT >= 64
6919 ud4 = (c2 & 0xffff0000) >> 16;
6921 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6922 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6925 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6927 emit_move_insn (dest, GEN_INT (ud1));
6930 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6931 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6934 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6937 emit_move_insn (dest, GEN_INT (ud2 << 16));
6939 emit_move_insn (copy_rtx (dest),
6940 gen_rtx_IOR (DImode, copy_rtx (dest),
6943 else if (ud3 == 0 && ud4 == 0)
6945 gcc_assert (ud2 & 0x8000);
6946 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6949 emit_move_insn (copy_rtx (dest),
6950 gen_rtx_IOR (DImode, copy_rtx (dest),
6952 emit_move_insn (copy_rtx (dest),
6953 gen_rtx_ZERO_EXTEND (DImode,
6954 gen_lowpart (SImode,
6957 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6958 || (ud4 == 0 && ! (ud3 & 0x8000)))
6961 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6964 emit_move_insn (dest, GEN_INT (ud3 << 16));
6967 emit_move_insn (copy_rtx (dest),
6968 gen_rtx_IOR (DImode, copy_rtx (dest),
6970 emit_move_insn (copy_rtx (dest),
6971 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6974 emit_move_insn (copy_rtx (dest),
6975 gen_rtx_IOR (DImode, copy_rtx (dest),
6981 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6984 emit_move_insn (dest, GEN_INT (ud4 << 16));
6987 emit_move_insn (copy_rtx (dest),
6988 gen_rtx_IOR (DImode, copy_rtx (dest),
6991 emit_move_insn (copy_rtx (dest),
6992 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6995 emit_move_insn (copy_rtx (dest),
6996 gen_rtx_IOR (DImode, copy_rtx (dest),
6997 GEN_INT (ud2 << 16)));
6999 emit_move_insn (copy_rtx (dest),
7000 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
7006 /* Helper for the following. Get rid of [r+r] memory refs
7007 in cases where it won't work (TImode, TFmode, TDmode). */
7010 rs6000_eliminate_indexed_memrefs (rtx operands[2])
7012 if (reload_in_progress)
7015 if (GET_CODE (operands[0]) == MEM
7016 && GET_CODE (XEXP (operands[0], 0)) != REG
7017 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), false))
7019 = replace_equiv_address (operands[0],
7020 copy_addr_to_reg (XEXP (operands[0], 0)));
7022 if (GET_CODE (operands[1]) == MEM
7023 && GET_CODE (XEXP (operands[1], 0)) != REG
7024 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), false))
7026 = replace_equiv_address (operands[1],
7027 copy_addr_to_reg (XEXP (operands[1], 0)));
7030 /* Return true if memory accesses to DECL are known to never straddle
7034 offsettable_ok_by_alignment (tree decl)
7036 unsigned HOST_WIDE_INT dsize, dalign;
7038 /* Presume any compiler generated symbol_ref is suitably aligned. */
7042 if (TREE_CODE (decl) != VAR_DECL
7043 && TREE_CODE (decl) != PARM_DECL
7044 && TREE_CODE (decl) != RESULT_DECL
7045 && TREE_CODE (decl) != FIELD_DECL)
7048 if (!DECL_SIZE_UNIT (decl))
7051 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
7054 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
7060 dalign = DECL_ALIGN_UNIT (decl);
7061 return dalign >= dsize;
7064 /* Emit a move from SOURCE to DEST in mode MODE. */
7066 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7070 operands[1] = source;
7072 if (TARGET_DEBUG_ADDR)
7075 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7076 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7077 GET_MODE_NAME (mode),
7080 can_create_pseudo_p ());
7082 fprintf (stderr, "source:\n");
7086 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7087 if (GET_CODE (operands[1]) == CONST_DOUBLE
7088 && ! FLOAT_MODE_P (mode)
7089 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7091 /* FIXME. This should never happen. */
7092 /* Since it seems that it does, do the safe thing and convert
7094 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7096 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7097 || FLOAT_MODE_P (mode)
7098 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7099 || CONST_DOUBLE_LOW (operands[1]) < 0)
7100 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7101 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7103 /* Check if GCC is setting up a block move that will end up using FP
7104 registers as temporaries. We must make sure this is acceptable. */
7105 if (GET_CODE (operands[0]) == MEM
7106 && GET_CODE (operands[1]) == MEM
7108 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7109 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7110 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7111 ? 32 : MEM_ALIGN (operands[0])))
7112 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7114 : MEM_ALIGN (operands[1]))))
7115 && ! MEM_VOLATILE_P (operands [0])
7116 && ! MEM_VOLATILE_P (operands [1]))
7118 emit_move_insn (adjust_address (operands[0], SImode, 0),
7119 adjust_address (operands[1], SImode, 0));
7120 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7121 adjust_address (copy_rtx (operands[1]), SImode, 4));
7125 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7126 && !gpc_reg_operand (operands[1], mode))
7127 operands[1] = force_reg (mode, operands[1]);
7129 if (mode == SFmode && ! TARGET_POWERPC
7130 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7131 && GET_CODE (operands[0]) == MEM)
7135 if (reload_in_progress || reload_completed)
7136 regnum = true_regnum (operands[1]);
7137 else if (GET_CODE (operands[1]) == REG)
7138 regnum = REGNO (operands[1]);
7142 /* If operands[1] is a register, on POWER it may have
7143 double-precision data in it, so truncate it to single
7145 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7148 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7149 : gen_reg_rtx (mode));
7150 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7151 operands[1] = newreg;
7155 /* Recognize the case where operand[1] is a reference to thread-local
7156 data and load its address to a register. */
7157 if (rs6000_tls_referenced_p (operands[1]))
7159 enum tls_model model;
7160 rtx tmp = operands[1];
7163 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7165 addend = XEXP (XEXP (tmp, 0), 1);
7166 tmp = XEXP (XEXP (tmp, 0), 0);
7169 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7170 model = SYMBOL_REF_TLS_MODEL (tmp);
7171 gcc_assert (model != 0);
7173 tmp = rs6000_legitimize_tls_address (tmp, model);
7176 tmp = gen_rtx_PLUS (mode, tmp, addend);
7177 tmp = force_operand (tmp, operands[0]);
7182 /* Handle the case where reload calls us with an invalid address. */
7183 if (reload_in_progress && mode == Pmode
7184 && (! general_operand (operands[1], mode)
7185 || ! nonimmediate_operand (operands[0], mode)))
7188 /* 128-bit constant floating-point values on Darwin should really be
7189 loaded as two parts. */
7190 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7191 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7193 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7194 know how to get a DFmode SUBREG of a TFmode. */
7195 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7196 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7197 simplify_gen_subreg (imode, operands[1], mode, 0),
7199 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7200 GET_MODE_SIZE (imode)),
7201 simplify_gen_subreg (imode, operands[1], mode,
7202 GET_MODE_SIZE (imode)),
7207 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7208 cfun->machine->sdmode_stack_slot =
7209 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7211 if (reload_in_progress
7213 && MEM_P (operands[0])
7214 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7215 && REG_P (operands[1]))
7217 if (FP_REGNO_P (REGNO (operands[1])))
7219 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7220 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7221 emit_insn (gen_movsd_store (mem, operands[1]));
7223 else if (INT_REGNO_P (REGNO (operands[1])))
7225 rtx mem = adjust_address_nv (operands[0], mode, 4);
7226 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7227 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7233 if (reload_in_progress
7235 && REG_P (operands[0])
7236 && MEM_P (operands[1])
7237 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7239 if (FP_REGNO_P (REGNO (operands[0])))
7241 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7242 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7243 emit_insn (gen_movsd_load (operands[0], mem));
7245 else if (INT_REGNO_P (REGNO (operands[0])))
7247 rtx mem = adjust_address_nv (operands[1], mode, 4);
7248 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7249 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7256 /* FIXME: In the long term, this switch statement should go away
7257 and be replaced by a sequence of tests based on things like
7263 if (CONSTANT_P (operands[1])
7264 && GET_CODE (operands[1]) != CONST_INT)
7265 operands[1] = force_const_mem (mode, operands[1]);
7270 rs6000_eliminate_indexed_memrefs (operands);
7277 if (CONSTANT_P (operands[1])
7278 && ! easy_fp_constant (operands[1], mode))
7279 operands[1] = force_const_mem (mode, operands[1]);
7292 if (CONSTANT_P (operands[1])
7293 && !easy_vector_constant (operands[1], mode))
7294 operands[1] = force_const_mem (mode, operands[1]);
7299 /* Use default pattern for address of ELF small data */
7302 && DEFAULT_ABI == ABI_V4
7303 && (GET_CODE (operands[1]) == SYMBOL_REF
7304 || GET_CODE (operands[1]) == CONST)
7305 && small_data_operand (operands[1], mode))
7307 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7311 if (DEFAULT_ABI == ABI_V4
7312 && mode == Pmode && mode == SImode
7313 && flag_pic == 1 && got_operand (operands[1], mode))
7315 emit_insn (gen_movsi_got (operands[0], operands[1]));
7319 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7323 && CONSTANT_P (operands[1])
7324 && GET_CODE (operands[1]) != HIGH
7325 && GET_CODE (operands[1]) != CONST_INT)
7327 rtx target = (!can_create_pseudo_p ()
7329 : gen_reg_rtx (mode));
7331 /* If this is a function address on -mcall-aixdesc,
7332 convert it to the address of the descriptor. */
7333 if (DEFAULT_ABI == ABI_AIX
7334 && GET_CODE (operands[1]) == SYMBOL_REF
7335 && XSTR (operands[1], 0)[0] == '.')
7337 const char *name = XSTR (operands[1], 0);
7339 while (*name == '.')
7341 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7342 CONSTANT_POOL_ADDRESS_P (new_ref)
7343 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7344 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7345 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7346 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7347 operands[1] = new_ref;
7350 if (DEFAULT_ABI == ABI_DARWIN)
7353 if (MACHO_DYNAMIC_NO_PIC_P)
7355 /* Take care of any required data indirection. */
7356 operands[1] = rs6000_machopic_legitimize_pic_address (
7357 operands[1], mode, operands[0]);
7358 if (operands[0] != operands[1])
7359 emit_insn (gen_rtx_SET (VOIDmode,
7360 operands[0], operands[1]));
7364 emit_insn (gen_macho_high (target, operands[1]));
7365 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7369 emit_insn (gen_elf_high (target, operands[1]));
7370 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7374 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7375 and we have put it in the TOC, we just need to make a TOC-relative
7378 && GET_CODE (operands[1]) == SYMBOL_REF
7379 && constant_pool_expr_p (operands[1])
7380 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7381 get_pool_mode (operands[1])))
7382 || (TARGET_CMODEL == CMODEL_MEDIUM
7383 && GET_CODE (operands[1]) == SYMBOL_REF
7384 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7385 && SYMBOL_REF_LOCAL_P (operands[1])
7386 && offsettable_ok_by_alignment (SYMBOL_REF_DECL (operands[1]))))
7389 if (TARGET_CMODEL != CMODEL_SMALL)
7391 if (can_create_pseudo_p ())
7392 reg = gen_reg_rtx (Pmode);
7396 operands[1] = create_TOC_reference (operands[1], reg);
7398 else if (mode == Pmode
7399 && CONSTANT_P (operands[1])
7400 && ((GET_CODE (operands[1]) != CONST_INT
7401 && ! easy_fp_constant (operands[1], mode))
7402 || (GET_CODE (operands[1]) == CONST_INT
7403 && (num_insns_constant (operands[1], mode)
7404 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7405 || (GET_CODE (operands[0]) == REG
7406 && FP_REGNO_P (REGNO (operands[0]))))
7407 && GET_CODE (operands[1]) != HIGH
7408 && ! legitimate_constant_pool_address_p (operands[1], false)
7409 && ! toc_relative_expr_p (operands[1])
7410 && (TARGET_CMODEL == CMODEL_SMALL
7411 || can_create_pseudo_p ()
7412 || (REG_P (operands[0])
7413 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7417 /* Darwin uses a special PIC legitimizer. */
7418 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7421 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7423 if (operands[0] != operands[1])
7424 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7429 /* If we are to limit the number of things we put in the TOC and
7430 this is a symbol plus a constant we can add in one insn,
7431 just put the symbol in the TOC and add the constant. Don't do
7432 this if reload is in progress. */
7433 if (GET_CODE (operands[1]) == CONST
7434 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7435 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7436 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7437 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7438 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7439 && ! side_effects_p (operands[0]))
7442 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7443 rtx other = XEXP (XEXP (operands[1], 0), 1);
7445 sym = force_reg (mode, sym);
7446 emit_insn (gen_add3_insn (operands[0], sym, other));
7450 operands[1] = force_const_mem (mode, operands[1]);
7453 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7454 && constant_pool_expr_p (XEXP (operands[1], 0))
7455 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7456 get_pool_constant (XEXP (operands[1], 0)),
7457 get_pool_mode (XEXP (operands[1], 0))))
7461 if (TARGET_CMODEL != CMODEL_SMALL)
7463 if (can_create_pseudo_p ())
7464 reg = gen_reg_rtx (Pmode);
7468 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7469 operands[1] = gen_const_mem (mode, tocref);
7470 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7476 rs6000_eliminate_indexed_memrefs (operands);
7480 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7482 gen_rtx_SET (VOIDmode,
7483 operands[0], operands[1]),
7484 gen_rtx_CLOBBER (VOIDmode,
7485 gen_rtx_SCRATCH (SImode)))));
7491 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7494 /* Above, we may have called force_const_mem which may have returned
7495 an invalid address. If we can, fix this up; otherwise, reload will
7496 have to deal with it. */
7497 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7498 operands[1] = validize_mem (operands[1]);
7501 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7504 /* Nonzero if we can use a floating-point register to pass this arg. */
7505 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7506 (SCALAR_FLOAT_MODE_P (MODE) \
7507 && (CUM)->fregno <= FP_ARG_MAX_REG \
7508 && TARGET_HARD_FLOAT && TARGET_FPRS)
7510 /* Nonzero if we can use an AltiVec register to pass this arg. */
7511 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7512 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7513 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7514 && TARGET_ALTIVEC_ABI \
7517 /* Return a nonzero value to say to return the function value in
7518 memory, just as large structures are always returned. TYPE will be
7519 the data type of the value, and FNTYPE will be the type of the
7520 function doing the returning, or @code{NULL} for libcalls.
7522 The AIX ABI for the RS/6000 specifies that all structures are
7523 returned in memory. The Darwin ABI does the same.
7525 For the Darwin 64 Bit ABI, a function result can be returned in
7526 registers or in memory, depending on the size of the return data
7527 type. If it is returned in registers, the value occupies the same
7528 registers as it would if it were the first and only function
7529 argument. Otherwise, the function places its result in memory at
7530 the location pointed to by GPR3.
7532 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7533 but a draft put them in memory, and GCC used to implement the draft
7534 instead of the final standard. Therefore, aix_struct_return
7535 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7536 compatibility can change DRAFT_V4_STRUCT_RET to override the
7537 default, and -m switches get the final word. See
7538 rs6000_option_override_internal for more details.
7540 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7541 long double support is enabled. These values are returned in memory.
7543 int_size_in_bytes returns -1 for variable size objects, which go in
7544 memory always. The cast to unsigned makes -1 > 8. */
7547 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7549 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7551 && rs6000_darwin64_abi
7552 && TREE_CODE (type) == RECORD_TYPE
7553 && int_size_in_bytes (type) > 0)
7555 CUMULATIVE_ARGS valcum;
7559 valcum.fregno = FP_ARG_MIN_REG;
7560 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7561 /* Do a trial code generation as if this were going to be passed
7562 as an argument; if any part goes in memory, we return NULL. */
7563 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7566 /* Otherwise fall through to more conventional ABI rules. */
7569 if (AGGREGATE_TYPE_P (type)
7570 && (aix_struct_return
7571 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7574 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7575 modes only exist for GCC vector types if -maltivec. */
7576 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7577 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7580 /* Return synthetic vectors in memory. */
7581 if (TREE_CODE (type) == VECTOR_TYPE
7582 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7584 static bool warned_for_return_big_vectors = false;
7585 if (!warned_for_return_big_vectors)
7587 warning (0, "GCC vector returned by reference: "
7588 "non-standard ABI extension with no compatibility guarantee");
7589 warned_for_return_big_vectors = true;
7594 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7600 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7601 for a call to a function whose data type is FNTYPE.
7602 For a library call, FNTYPE is 0.
7604 For incoming args we set the number of arguments in the prototype large
7605 so we never return a PARALLEL. */
7608 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7609 rtx libname ATTRIBUTE_UNUSED, int incoming,
7610 int libcall, int n_named_args)
7612 static CUMULATIVE_ARGS zero_cumulative;
7614 *cum = zero_cumulative;
7616 cum->fregno = FP_ARG_MIN_REG;
7617 cum->vregno = ALTIVEC_ARG_MIN_REG;
7618 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7619 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7620 ? CALL_LIBCALL : CALL_NORMAL);
7621 cum->sysv_gregno = GP_ARG_MIN_REG;
7622 cum->stdarg = stdarg_p (fntype);
7624 cum->nargs_prototype = 0;
7625 if (incoming || cum->prototype)
7626 cum->nargs_prototype = n_named_args;
7628 /* Check for a longcall attribute. */
7629 if ((!fntype && rs6000_default_long_calls)
7631 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7632 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7633 cum->call_cookie |= CALL_LONG;
7635 if (TARGET_DEBUG_ARG)
7637 fprintf (stderr, "\ninit_cumulative_args:");
7640 tree ret_type = TREE_TYPE (fntype);
7641 fprintf (stderr, " ret code = %s,",
7642 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7645 if (cum->call_cookie & CALL_LONG)
7646 fprintf (stderr, " longcall,");
7648 fprintf (stderr, " proto = %d, nargs = %d\n",
7649 cum->prototype, cum->nargs_prototype);
7654 && TARGET_ALTIVEC_ABI
7655 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7657 error ("cannot return value in vector register because"
7658 " altivec instructions are disabled, use -maltivec"
7663 /* Return true if TYPE must be passed on the stack and not in registers. */
7666 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7668 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7669 return must_pass_in_stack_var_size (mode, type);
7671 return must_pass_in_stack_var_size_or_pad (mode, type);
7674 /* If defined, a C expression which determines whether, and in which
7675 direction, to pad out an argument with extra space. The value
7676 should be of type `enum direction': either `upward' to pad above
7677 the argument, `downward' to pad below, or `none' to inhibit
7680 For the AIX ABI structs are always stored left shifted in their
7684 function_arg_padding (enum machine_mode mode, const_tree type)
7686 #ifndef AGGREGATE_PADDING_FIXED
7687 #define AGGREGATE_PADDING_FIXED 0
7689 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7690 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7693 if (!AGGREGATE_PADDING_FIXED)
7695 /* GCC used to pass structures of the same size as integer types as
7696 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7697 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7698 passed padded downward, except that -mstrict-align further
7699 muddied the water in that multi-component structures of 2 and 4
7700 bytes in size were passed padded upward.
7702 The following arranges for best compatibility with previous
7703 versions of gcc, but removes the -mstrict-align dependency. */
7704 if (BYTES_BIG_ENDIAN)
7706 HOST_WIDE_INT size = 0;
7708 if (mode == BLKmode)
7710 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7711 size = int_size_in_bytes (type);
7714 size = GET_MODE_SIZE (mode);
7716 if (size == 1 || size == 2 || size == 4)
7722 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7724 if (type != 0 && AGGREGATE_TYPE_P (type))
7728 /* Fall back to the default. */
7729 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7732 /* If defined, a C expression that gives the alignment boundary, in bits,
7733 of an argument with the specified mode and type. If it is not defined,
7734 PARM_BOUNDARY is used for all arguments.
7736 V.4 wants long longs and doubles to be double word aligned. Just
7737 testing the mode size is a boneheaded way to do this as it means
7738 that other types such as complex int are also double word aligned.
7739 However, we're stuck with this because changing the ABI might break
7740 existing library interfaces.
7742 Doubleword align SPE vectors.
7743 Quadword align Altivec vectors.
7744 Quadword align large synthetic vector types. */
7747 function_arg_boundary (enum machine_mode mode, const_tree type)
7749 if (DEFAULT_ABI == ABI_V4
7750 && (GET_MODE_SIZE (mode) == 8
7751 || (TARGET_HARD_FLOAT
7753 && (mode == TFmode || mode == TDmode))))
7755 else if (SPE_VECTOR_MODE (mode)
7756 || (type && TREE_CODE (type) == VECTOR_TYPE
7757 && int_size_in_bytes (type) >= 8
7758 && int_size_in_bytes (type) < 16))
7760 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
7761 || (type && TREE_CODE (type) == VECTOR_TYPE
7762 && int_size_in_bytes (type) >= 16))
7764 else if (TARGET_MACHO
7765 && rs6000_darwin64_abi
7767 && type && TYPE_ALIGN (type) > 64)
7770 return PARM_BOUNDARY;
7773 /* For a function parm of MODE and TYPE, return the starting word in
7774 the parameter area. NWORDS of the parameter area are already used. */
7777 rs6000_parm_start (enum machine_mode mode, const_tree type,
7778 unsigned int nwords)
7781 unsigned int parm_offset;
7783 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7784 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7785 return nwords + (-(parm_offset + nwords) & align);
7788 /* Compute the size (in words) of a function argument. */
7790 static unsigned long
7791 rs6000_arg_size (enum machine_mode mode, const_tree type)
7795 if (mode != BLKmode)
7796 size = GET_MODE_SIZE (mode);
7798 size = int_size_in_bytes (type);
7801 return (size + 3) >> 2;
7803 return (size + 7) >> 3;
7806 /* Use this to flush pending int fields. */
7809 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7810 HOST_WIDE_INT bitpos, int final)
7812 unsigned int startbit, endbit;
7813 int intregs, intoffset;
7814 enum machine_mode mode;
7816 /* Handle the situations where a float is taking up the first half
7817 of the GPR, and the other half is empty (typically due to
7818 alignment restrictions). We can detect this by a 8-byte-aligned
7819 int field, or by seeing that this is the final flush for this
7820 argument. Count the word and continue on. */
7821 if (cum->floats_in_gpr == 1
7822 && (cum->intoffset % 64 == 0
7823 || (cum->intoffset == -1 && final)))
7826 cum->floats_in_gpr = 0;
7829 if (cum->intoffset == -1)
7832 intoffset = cum->intoffset;
7833 cum->intoffset = -1;
7834 cum->floats_in_gpr = 0;
7836 if (intoffset % BITS_PER_WORD != 0)
7838 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7840 if (mode == BLKmode)
7842 /* We couldn't find an appropriate mode, which happens,
7843 e.g., in packed structs when there are 3 bytes to load.
7844 Back intoffset back to the beginning of the word in this
7846 intoffset = intoffset & -BITS_PER_WORD;
7850 startbit = intoffset & -BITS_PER_WORD;
7851 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7852 intregs = (endbit - startbit) / BITS_PER_WORD;
7853 cum->words += intregs;
7854 /* words should be unsigned. */
7855 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
7857 int pad = (endbit/BITS_PER_WORD) - cum->words;
7862 /* The darwin64 ABI calls for us to recurse down through structs,
7863 looking for elements passed in registers. Unfortunately, we have
7864 to track int register count here also because of misalignments
7865 in powerpc alignment mode. */
7868 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7870 HOST_WIDE_INT startbitpos)
7874 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7875 if (TREE_CODE (f) == FIELD_DECL)
7877 HOST_WIDE_INT bitpos = startbitpos;
7878 tree ftype = TREE_TYPE (f);
7879 enum machine_mode mode;
7880 if (ftype == error_mark_node)
7882 mode = TYPE_MODE (ftype);
7884 if (DECL_SIZE (f) != 0
7885 && host_integerp (bit_position (f), 1))
7886 bitpos += int_bit_position (f);
7888 /* ??? FIXME: else assume zero offset. */
7890 if (TREE_CODE (ftype) == RECORD_TYPE)
7891 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7892 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7894 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7895 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7896 /* Single-precision floats present a special problem for
7897 us, because they are smaller than an 8-byte GPR, and so
7898 the structure-packing rules combined with the standard
7899 varargs behavior mean that we want to pack float/float
7900 and float/int combinations into a single register's
7901 space. This is complicated by the arg advance flushing,
7902 which works on arbitrarily large groups of int-type
7906 if (cum->floats_in_gpr == 1)
7908 /* Two floats in a word; count the word and reset
7911 cum->floats_in_gpr = 0;
7913 else if (bitpos % 64 == 0)
7915 /* A float at the beginning of an 8-byte word;
7916 count it and put off adjusting cum->words until
7917 we see if a arg advance flush is going to do it
7919 cum->floats_in_gpr++;
7923 /* The float is at the end of a word, preceded
7924 by integer fields, so the arg advance flush
7925 just above has already set cum->words and
7926 everything is taken care of. */
7930 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7932 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7934 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7938 else if (cum->intoffset == -1)
7939 cum->intoffset = bitpos;
7943 /* Check for an item that needs to be considered specially under the darwin 64
7944 bit ABI. These are record types where the mode is BLK or the structure is
7947 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
7949 return rs6000_darwin64_abi
7950 && ((mode == BLKmode
7951 && TREE_CODE (type) == RECORD_TYPE
7952 && int_size_in_bytes (type) > 0)
7953 || (type && TREE_CODE (type) == RECORD_TYPE
7954 && int_size_in_bytes (type) == 8)) ? 1 : 0;
7957 /* Update the data in CUM to advance over an argument
7958 of mode MODE and data type TYPE.
7959 (TYPE is null for libcalls where that information may not be available.)
7961 Note that for args passed by reference, function_arg will be called
7962 with MODE and TYPE set to that of the pointer to the arg, not the arg
7966 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7967 const_tree type, bool named, int depth)
7970 /* Only tick off an argument if we're not recursing. */
7972 cum->nargs_prototype--;
7974 if (TARGET_ALTIVEC_ABI
7975 && (ALTIVEC_VECTOR_MODE (mode)
7976 || VSX_VECTOR_MODE (mode)
7977 || (type && TREE_CODE (type) == VECTOR_TYPE
7978 && int_size_in_bytes (type) == 16)))
7982 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7985 if (!TARGET_ALTIVEC)
7986 error ("cannot pass argument in vector register because"
7987 " altivec instructions are disabled, use -maltivec"
7990 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7991 even if it is going to be passed in a vector register.
7992 Darwin does the same for variable-argument functions. */
7993 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7994 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8004 /* Vector parameters must be 16-byte aligned. This places
8005 them at 2 mod 4 in terms of words in 32-bit mode, since
8006 the parameter save area starts at offset 24 from the
8007 stack. In 64-bit mode, they just have to start on an
8008 even word, since the parameter save area is 16-byte
8009 aligned. Space for GPRs is reserved even if the argument
8010 will be passed in memory. */
8012 align = (2 - cum->words) & 3;
8014 align = cum->words & 1;
8015 cum->words += align + rs6000_arg_size (mode, type);
8017 if (TARGET_DEBUG_ARG)
8019 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8021 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8022 cum->nargs_prototype, cum->prototype,
8023 GET_MODE_NAME (mode));
8027 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8029 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8032 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8034 int size = int_size_in_bytes (type);
8035 /* Variable sized types have size == -1 and are
8036 treated as if consisting entirely of ints.
8037 Pad to 16 byte boundary if needed. */
8038 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8039 && (cum->words % 2) != 0)
8041 /* For varargs, we can just go up by the size of the struct. */
8043 cum->words += (size + 7) / 8;
8046 /* It is tempting to say int register count just goes up by
8047 sizeof(type)/8, but this is wrong in a case such as
8048 { int; double; int; } [powerpc alignment]. We have to
8049 grovel through the fields for these too. */
8051 cum->floats_in_gpr = 0;
8052 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8053 rs6000_darwin64_record_arg_advance_flush (cum,
8054 size * BITS_PER_UNIT, 1);
8056 if (TARGET_DEBUG_ARG)
8058 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8059 cum->words, TYPE_ALIGN (type), size);
8061 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8062 cum->nargs_prototype, cum->prototype,
8063 GET_MODE_NAME (mode));
8066 else if (DEFAULT_ABI == ABI_V4)
8068 if (TARGET_HARD_FLOAT && TARGET_FPRS
8069 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8070 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8071 || (mode == TFmode && !TARGET_IEEEQUAD)
8072 || mode == SDmode || mode == DDmode || mode == TDmode))
8074 /* _Decimal128 must use an even/odd register pair. This assumes
8075 that the register number is odd when fregno is odd. */
8076 if (mode == TDmode && (cum->fregno % 2) == 1)
8079 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8080 <= FP_ARG_V4_MAX_REG)
8081 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8084 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8085 if (mode == DFmode || mode == TFmode
8086 || mode == DDmode || mode == TDmode)
8087 cum->words += cum->words & 1;
8088 cum->words += rs6000_arg_size (mode, type);
8093 int n_words = rs6000_arg_size (mode, type);
8094 int gregno = cum->sysv_gregno;
8096 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8097 (r7,r8) or (r9,r10). As does any other 2 word item such
8098 as complex int due to a historical mistake. */
8100 gregno += (1 - gregno) & 1;
8102 /* Multi-reg args are not split between registers and stack. */
8103 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8105 /* Long long and SPE vectors are aligned on the stack.
8106 So are other 2 word items such as complex int due to
8107 a historical mistake. */
8109 cum->words += cum->words & 1;
8110 cum->words += n_words;
8113 /* Note: continuing to accumulate gregno past when we've started
8114 spilling to the stack indicates the fact that we've started
8115 spilling to the stack to expand_builtin_saveregs. */
8116 cum->sysv_gregno = gregno + n_words;
8119 if (TARGET_DEBUG_ARG)
8121 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8122 cum->words, cum->fregno);
8123 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8124 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8125 fprintf (stderr, "mode = %4s, named = %d\n",
8126 GET_MODE_NAME (mode), named);
8131 int n_words = rs6000_arg_size (mode, type);
8132 int start_words = cum->words;
8133 int align_words = rs6000_parm_start (mode, type, start_words);
8135 cum->words = align_words + n_words;
8137 if (SCALAR_FLOAT_MODE_P (mode)
8138 && TARGET_HARD_FLOAT && TARGET_FPRS)
8140 /* _Decimal128 must be passed in an even/odd float register pair.
8141 This assumes that the register number is odd when fregno is
8143 if (mode == TDmode && (cum->fregno % 2) == 1)
8145 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8148 if (TARGET_DEBUG_ARG)
8150 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8151 cum->words, cum->fregno);
8152 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8153 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8154 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8155 named, align_words - start_words, depth);
8161 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8162 const_tree type, bool named)
8164 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8168 spe_build_register_parallel (enum machine_mode mode, int gregno)
8175 r1 = gen_rtx_REG (DImode, gregno);
8176 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8177 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8181 r1 = gen_rtx_REG (DImode, gregno);
8182 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8183 r3 = gen_rtx_REG (DImode, gregno + 2);
8184 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8185 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8188 r1 = gen_rtx_REG (DImode, gregno);
8189 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8190 r3 = gen_rtx_REG (DImode, gregno + 2);
8191 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8192 r5 = gen_rtx_REG (DImode, gregno + 4);
8193 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8194 r7 = gen_rtx_REG (DImode, gregno + 6);
8195 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8196 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8203 /* Determine where to put a SIMD argument on the SPE. */
8205 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8208 int gregno = cum->sysv_gregno;
8210 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8211 are passed and returned in a pair of GPRs for ABI compatibility. */
8212 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8213 || mode == DCmode || mode == TCmode))
8215 int n_words = rs6000_arg_size (mode, type);
8217 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8219 gregno += (1 - gregno) & 1;
8221 /* Multi-reg args are not split between registers and stack. */
8222 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8225 return spe_build_register_parallel (mode, gregno);
8229 int n_words = rs6000_arg_size (mode, type);
8231 /* SPE vectors are put in odd registers. */
8232 if (n_words == 2 && (gregno & 1) == 0)
8235 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8238 enum machine_mode m = SImode;
8240 r1 = gen_rtx_REG (m, gregno);
8241 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8242 r2 = gen_rtx_REG (m, gregno + 1);
8243 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8244 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8251 if (gregno <= GP_ARG_MAX_REG)
8252 return gen_rtx_REG (mode, gregno);
8258 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8259 structure between cum->intoffset and bitpos to integer registers. */
8262 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8263 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8265 enum machine_mode mode;
8267 unsigned int startbit, endbit;
8268 int this_regno, intregs, intoffset;
8271 if (cum->intoffset == -1)
8274 intoffset = cum->intoffset;
8275 cum->intoffset = -1;
8277 /* If this is the trailing part of a word, try to only load that
8278 much into the register. Otherwise load the whole register. Note
8279 that in the latter case we may pick up unwanted bits. It's not a
8280 problem at the moment but may wish to revisit. */
8282 if (intoffset % BITS_PER_WORD != 0)
8284 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8286 if (mode == BLKmode)
8288 /* We couldn't find an appropriate mode, which happens,
8289 e.g., in packed structs when there are 3 bytes to load.
8290 Back intoffset back to the beginning of the word in this
8292 intoffset = intoffset & -BITS_PER_WORD;
8299 startbit = intoffset & -BITS_PER_WORD;
8300 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8301 intregs = (endbit - startbit) / BITS_PER_WORD;
8302 this_regno = cum->words + intoffset / BITS_PER_WORD;
8304 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8307 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8311 intoffset /= BITS_PER_UNIT;
8314 regno = GP_ARG_MIN_REG + this_regno;
8315 reg = gen_rtx_REG (mode, regno);
8317 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8320 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8324 while (intregs > 0);
8327 /* Recursive workhorse for the following. */
8330 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8331 HOST_WIDE_INT startbitpos, rtx rvec[],
8336 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8337 if (TREE_CODE (f) == FIELD_DECL)
8339 HOST_WIDE_INT bitpos = startbitpos;
8340 tree ftype = TREE_TYPE (f);
8341 enum machine_mode mode;
8342 if (ftype == error_mark_node)
8344 mode = TYPE_MODE (ftype);
8346 if (DECL_SIZE (f) != 0
8347 && host_integerp (bit_position (f), 1))
8348 bitpos += int_bit_position (f);
8350 /* ??? FIXME: else assume zero offset. */
8352 if (TREE_CODE (ftype) == RECORD_TYPE)
8353 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8354 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8359 case SCmode: mode = SFmode; break;
8360 case DCmode: mode = DFmode; break;
8361 case TCmode: mode = TFmode; break;
8365 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8367 = gen_rtx_EXPR_LIST (VOIDmode,
8368 gen_rtx_REG (mode, cum->fregno++),
8369 GEN_INT (bitpos / BITS_PER_UNIT));
8370 if (mode == TFmode || mode == TDmode)
8373 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8375 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8377 = gen_rtx_EXPR_LIST (VOIDmode,
8378 gen_rtx_REG (mode, cum->vregno++),
8379 GEN_INT (bitpos / BITS_PER_UNIT));
8381 else if (cum->intoffset == -1)
8382 cum->intoffset = bitpos;
8386 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8387 the register(s) to be used for each field and subfield of a struct
8388 being passed by value, along with the offset of where the
8389 register's value may be found in the block. FP fields go in FP
8390 register, vector fields go in vector registers, and everything
8391 else goes in int registers, packed as in memory.
8393 This code is also used for function return values. RETVAL indicates
8394 whether this is the case.
8396 Much of this is taken from the SPARC V9 port, which has a similar
8397 calling convention. */
8400 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8401 bool named, bool retval)
8403 rtx rvec[FIRST_PSEUDO_REGISTER];
8404 int k = 1, kbase = 1;
8405 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8406 /* This is a copy; modifications are not visible to our caller. */
8407 CUMULATIVE_ARGS copy_cum = *orig_cum;
8408 CUMULATIVE_ARGS *cum = ©_cum;
8410 /* Pad to 16 byte boundary if needed. */
8411 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8412 && (cum->words % 2) != 0)
8419 /* Put entries into rvec[] for individual FP and vector fields, and
8420 for the chunks of memory that go in int regs. Note we start at
8421 element 1; 0 is reserved for an indication of using memory, and
8422 may or may not be filled in below. */
8423 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
8424 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8426 /* If any part of the struct went on the stack put all of it there.
8427 This hack is because the generic code for
8428 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8429 parts of the struct are not at the beginning. */
8433 return NULL_RTX; /* doesn't go in registers at all */
8435 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8437 if (k > 1 || cum->use_stack)
8438 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8443 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8446 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8451 rtx rvec[GP_ARG_NUM_REG + 1];
8453 if (align_words >= GP_ARG_NUM_REG)
8456 n_units = rs6000_arg_size (mode, type);
8458 /* Optimize the simple case where the arg fits in one gpr, except in
8459 the case of BLKmode due to assign_parms assuming that registers are
8460 BITS_PER_WORD wide. */
8462 || (n_units == 1 && mode != BLKmode))
8463 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8466 if (align_words + n_units > GP_ARG_NUM_REG)
8467 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8468 using a magic NULL_RTX component.
8469 This is not strictly correct. Only some of the arg belongs in
8470 memory, not all of it. However, the normal scheme using
8471 function_arg_partial_nregs can result in unusual subregs, eg.
8472 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8473 store the whole arg to memory is often more efficient than code
8474 to store pieces, and we know that space is available in the right
8475 place for the whole arg. */
8476 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8481 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8482 rtx off = GEN_INT (i++ * 4);
8483 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8485 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8487 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8490 /* Determine where to put an argument to a function.
8491 Value is zero to push the argument on the stack,
8492 or a hard register in which to store the argument.
8494 MODE is the argument's machine mode.
8495 TYPE is the data type of the argument (as a tree).
8496 This is null for libcalls where that information may
8498 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8499 the preceding args and about the function being called. It is
8500 not modified in this routine.
8501 NAMED is nonzero if this argument is a named parameter
8502 (otherwise it is an extra parameter matching an ellipsis).
8504 On RS/6000 the first eight words of non-FP are normally in registers
8505 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8506 Under V.4, the first 8 FP args are in registers.
8508 If this is floating-point and no prototype is specified, we use
8509 both an FP and integer register (or possibly FP reg and stack). Library
8510 functions (when CALL_LIBCALL is set) always have the proper types for args,
8511 so we can pass the FP value just in one register. emit_library_function
8512 doesn't support PARALLEL anyway.
8514 Note that for args passed by reference, function_arg will be called
8515 with MODE and TYPE set to that of the pointer to the arg, not the arg
8519 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8520 const_tree type, bool named)
8522 enum rs6000_abi abi = DEFAULT_ABI;
8524 /* Return a marker to indicate whether CR1 needs to set or clear the
8525 bit that V.4 uses to say fp args were passed in registers.
8526 Assume that we don't need the marker for software floating point,
8527 or compiler generated library calls. */
8528 if (mode == VOIDmode)
8531 && (cum->call_cookie & CALL_LIBCALL) == 0
8533 || (cum->nargs_prototype < 0
8534 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8536 /* For the SPE, we need to crxor CR6 always. */
8538 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8539 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8540 return GEN_INT (cum->call_cookie
8541 | ((cum->fregno == FP_ARG_MIN_REG)
8542 ? CALL_V4_SET_FP_ARGS
8543 : CALL_V4_CLEAR_FP_ARGS));
8546 return GEN_INT (cum->call_cookie);
8549 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8551 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
8552 if (rslt != NULL_RTX)
8554 /* Else fall through to usual handling. */
8557 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8558 if (TARGET_64BIT && ! cum->prototype)
8560 /* Vector parameters get passed in vector register
8561 and also in GPRs or memory, in absence of prototype. */
8564 align_words = (cum->words + 1) & ~1;
8566 if (align_words >= GP_ARG_NUM_REG)
8572 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8574 return gen_rtx_PARALLEL (mode,
8576 gen_rtx_EXPR_LIST (VOIDmode,
8578 gen_rtx_EXPR_LIST (VOIDmode,
8579 gen_rtx_REG (mode, cum->vregno),
8583 return gen_rtx_REG (mode, cum->vregno);
8584 else if (TARGET_ALTIVEC_ABI
8585 && (ALTIVEC_VECTOR_MODE (mode)
8586 || VSX_VECTOR_MODE (mode)
8587 || (type && TREE_CODE (type) == VECTOR_TYPE
8588 && int_size_in_bytes (type) == 16)))
8590 if (named || abi == ABI_V4)
8594 /* Vector parameters to varargs functions under AIX or Darwin
8595 get passed in memory and possibly also in GPRs. */
8596 int align, align_words, n_words;
8597 enum machine_mode part_mode;
8599 /* Vector parameters must be 16-byte aligned. This places them at
8600 2 mod 4 in terms of words in 32-bit mode, since the parameter
8601 save area starts at offset 24 from the stack. In 64-bit mode,
8602 they just have to start on an even word, since the parameter
8603 save area is 16-byte aligned. */
8605 align = (2 - cum->words) & 3;
8607 align = cum->words & 1;
8608 align_words = cum->words + align;
8610 /* Out of registers? Memory, then. */
8611 if (align_words >= GP_ARG_NUM_REG)
8614 if (TARGET_32BIT && TARGET_POWERPC64)
8615 return rs6000_mixed_function_arg (mode, type, align_words);
8617 /* The vector value goes in GPRs. Only the part of the
8618 value in GPRs is reported here. */
8620 n_words = rs6000_arg_size (mode, type);
8621 if (align_words + n_words > GP_ARG_NUM_REG)
8622 /* Fortunately, there are only two possibilities, the value
8623 is either wholly in GPRs or half in GPRs and half not. */
8626 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8629 else if (TARGET_SPE_ABI && TARGET_SPE
8630 && (SPE_VECTOR_MODE (mode)
8631 || (TARGET_E500_DOUBLE && (mode == DFmode
8634 || mode == TCmode))))
8635 return rs6000_spe_function_arg (cum, mode, type);
8637 else if (abi == ABI_V4)
8639 if (TARGET_HARD_FLOAT && TARGET_FPRS
8640 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8641 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8642 || (mode == TFmode && !TARGET_IEEEQUAD)
8643 || mode == SDmode || mode == DDmode || mode == TDmode))
8645 /* _Decimal128 must use an even/odd register pair. This assumes
8646 that the register number is odd when fregno is odd. */
8647 if (mode == TDmode && (cum->fregno % 2) == 1)
8650 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8651 <= FP_ARG_V4_MAX_REG)
8652 return gen_rtx_REG (mode, cum->fregno);
8658 int n_words = rs6000_arg_size (mode, type);
8659 int gregno = cum->sysv_gregno;
8661 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8662 (r7,r8) or (r9,r10). As does any other 2 word item such
8663 as complex int due to a historical mistake. */
8665 gregno += (1 - gregno) & 1;
8667 /* Multi-reg args are not split between registers and stack. */
8668 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8671 if (TARGET_32BIT && TARGET_POWERPC64)
8672 return rs6000_mixed_function_arg (mode, type,
8673 gregno - GP_ARG_MIN_REG);
8674 return gen_rtx_REG (mode, gregno);
8679 int align_words = rs6000_parm_start (mode, type, cum->words);
8681 /* _Decimal128 must be passed in an even/odd float register pair.
8682 This assumes that the register number is odd when fregno is odd. */
8683 if (mode == TDmode && (cum->fregno % 2) == 1)
8686 if (USE_FP_FOR_ARG_P (cum, mode, type))
8688 rtx rvec[GP_ARG_NUM_REG + 1];
8692 enum machine_mode fmode = mode;
8693 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8695 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8697 /* Currently, we only ever need one reg here because complex
8698 doubles are split. */
8699 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8700 && (fmode == TFmode || fmode == TDmode));
8702 /* Long double or _Decimal128 split over regs and memory. */
8703 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8706 /* Do we also need to pass this arg in the parameter save
8709 && (cum->nargs_prototype <= 0
8710 || (DEFAULT_ABI == ABI_AIX
8712 && align_words >= GP_ARG_NUM_REG)));
8714 if (!needs_psave && mode == fmode)
8715 return gen_rtx_REG (fmode, cum->fregno);
8720 /* Describe the part that goes in gprs or the stack.
8721 This piece must come first, before the fprs. */
8722 if (align_words < GP_ARG_NUM_REG)
8724 unsigned long n_words = rs6000_arg_size (mode, type);
8726 if (align_words + n_words > GP_ARG_NUM_REG
8727 || (TARGET_32BIT && TARGET_POWERPC64))
8729 /* If this is partially on the stack, then we only
8730 include the portion actually in registers here. */
8731 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8734 if (align_words + n_words > GP_ARG_NUM_REG)
8735 /* Not all of the arg fits in gprs. Say that it
8736 goes in memory too, using a magic NULL_RTX
8737 component. Also see comment in
8738 rs6000_mixed_function_arg for why the normal
8739 function_arg_partial_nregs scheme doesn't work
8741 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8745 r = gen_rtx_REG (rmode,
8746 GP_ARG_MIN_REG + align_words);
8747 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8748 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8750 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8754 /* The whole arg fits in gprs. */
8755 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8756 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8760 /* It's entirely in memory. */
8761 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8764 /* Describe where this piece goes in the fprs. */
8765 r = gen_rtx_REG (fmode, cum->fregno);
8766 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8768 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8770 else if (align_words < GP_ARG_NUM_REG)
8772 if (TARGET_32BIT && TARGET_POWERPC64)
8773 return rs6000_mixed_function_arg (mode, type, align_words);
8775 if (mode == BLKmode)
8778 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8785 /* For an arg passed partly in registers and partly in memory, this is
8786 the number of bytes passed in registers. For args passed entirely in
8787 registers or entirely in memory, zero. When an arg is described by a
8788 PARALLEL, perhaps using more than one register type, this function
8789 returns the number of bytes used by the first element of the PARALLEL. */
8792 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8793 tree type, bool named)
8798 if (DEFAULT_ABI == ABI_V4)
8801 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8802 && cum->nargs_prototype >= 0)
8805 /* In this complicated case we just disable the partial_nregs code. */
8806 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8809 align_words = rs6000_parm_start (mode, type, cum->words);
8811 if (USE_FP_FOR_ARG_P (cum, mode, type))
8813 /* If we are passing this arg in the fixed parameter save area
8814 (gprs or memory) as well as fprs, then this function should
8815 return the number of partial bytes passed in the parameter
8816 save area rather than partial bytes passed in fprs. */
8818 && (cum->nargs_prototype <= 0
8819 || (DEFAULT_ABI == ABI_AIX
8821 && align_words >= GP_ARG_NUM_REG)))
8823 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8824 > FP_ARG_MAX_REG + 1)
8825 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8826 else if (cum->nargs_prototype >= 0)
8830 if (align_words < GP_ARG_NUM_REG
8831 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8832 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8834 if (ret != 0 && TARGET_DEBUG_ARG)
8835 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8840 /* A C expression that indicates when an argument must be passed by
8841 reference. If nonzero for an argument, a copy of that argument is
8842 made in memory and a pointer to the argument is passed instead of
8843 the argument itself. The pointer is passed in whatever way is
8844 appropriate for passing a pointer to that type.
8846 Under V.4, aggregates and long double are passed by reference.
8848 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8849 reference unless the AltiVec vector extension ABI is in force.
8851 As an extension to all ABIs, variable sized types are passed by
8855 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
8856 enum machine_mode mode, const_tree type,
8857 bool named ATTRIBUTE_UNUSED)
8859 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8861 if (TARGET_DEBUG_ARG)
8862 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8869 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8871 if (TARGET_DEBUG_ARG)
8872 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8876 if (int_size_in_bytes (type) < 0)
8878 if (TARGET_DEBUG_ARG)
8879 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8883 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8884 modes only exist for GCC vector types if -maltivec. */
8885 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8887 if (TARGET_DEBUG_ARG)
8888 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8892 /* Pass synthetic vectors in memory. */
8893 if (TREE_CODE (type) == VECTOR_TYPE
8894 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8896 static bool warned_for_pass_big_vectors = false;
8897 if (TARGET_DEBUG_ARG)
8898 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8899 if (!warned_for_pass_big_vectors)
8901 warning (0, "GCC vector passed by reference: "
8902 "non-standard ABI extension with no compatibility guarantee");
8903 warned_for_pass_big_vectors = true;
8912 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8915 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8920 for (i = 0; i < nregs; i++)
8922 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8923 if (reload_completed)
8925 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8928 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8929 i * GET_MODE_SIZE (reg_mode));
8932 tem = replace_equiv_address (tem, XEXP (tem, 0));
8936 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8940 /* Perform any needed actions needed for a function that is receiving a
8941 variable number of arguments.
8945 MODE and TYPE are the mode and type of the current parameter.
8947 PRETEND_SIZE is a variable that should be set to the amount of stack
8948 that must be pushed by the prolog to pretend that our caller pushed
8951 Normally, this macro will push all remaining incoming registers on the
8952 stack and set PRETEND_SIZE to the length of the registers pushed. */
8955 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8956 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8959 CUMULATIVE_ARGS next_cum;
8960 int reg_size = TARGET_32BIT ? 4 : 8;
8961 rtx save_area = NULL_RTX, mem;
8962 int first_reg_offset;
8965 /* Skip the last named argument. */
8967 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
8969 if (DEFAULT_ABI == ABI_V4)
8971 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8975 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8976 HOST_WIDE_INT offset = 0;
8978 /* Try to optimize the size of the varargs save area.
8979 The ABI requires that ap.reg_save_area is doubleword
8980 aligned, but we don't need to allocate space for all
8981 the bytes, only those to which we actually will save
8983 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8984 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8985 if (TARGET_HARD_FLOAT && TARGET_FPRS
8986 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8987 && cfun->va_list_fpr_size)
8990 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8991 * UNITS_PER_FP_WORD;
8992 if (cfun->va_list_fpr_size
8993 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8994 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8996 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8997 * UNITS_PER_FP_WORD;
9001 offset = -((first_reg_offset * reg_size) & ~7);
9002 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9004 gpr_reg_num = cfun->va_list_gpr_size;
9005 if (reg_size == 4 && (first_reg_offset & 1))
9008 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9011 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9013 - (int) (GP_ARG_NUM_REG * reg_size);
9015 if (gpr_size + fpr_size)
9018 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9019 gcc_assert (GET_CODE (reg_save_area) == MEM);
9020 reg_save_area = XEXP (reg_save_area, 0);
9021 if (GET_CODE (reg_save_area) == PLUS)
9023 gcc_assert (XEXP (reg_save_area, 0)
9024 == virtual_stack_vars_rtx);
9025 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9026 offset += INTVAL (XEXP (reg_save_area, 1));
9029 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9032 cfun->machine->varargs_save_offset = offset;
9033 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9038 first_reg_offset = next_cum.words;
9039 save_area = virtual_incoming_args_rtx;
9041 if (targetm.calls.must_pass_in_stack (mode, type))
9042 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9045 set = get_varargs_alias_set ();
9046 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9047 && cfun->va_list_gpr_size)
9049 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9051 if (va_list_gpr_counter_field)
9053 /* V4 va_list_gpr_size counts number of registers needed. */
9054 if (nregs > cfun->va_list_gpr_size)
9055 nregs = cfun->va_list_gpr_size;
9059 /* char * va_list instead counts number of bytes needed. */
9060 if (nregs > cfun->va_list_gpr_size / reg_size)
9061 nregs = cfun->va_list_gpr_size / reg_size;
9064 mem = gen_rtx_MEM (BLKmode,
9065 plus_constant (save_area,
9066 first_reg_offset * reg_size));
9067 MEM_NOTRAP_P (mem) = 1;
9068 set_mem_alias_set (mem, set);
9069 set_mem_align (mem, BITS_PER_WORD);
9071 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9075 /* Save FP registers if needed. */
9076 if (DEFAULT_ABI == ABI_V4
9077 && TARGET_HARD_FLOAT && TARGET_FPRS
9079 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9080 && cfun->va_list_fpr_size)
9082 int fregno = next_cum.fregno, nregs;
9083 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9084 rtx lab = gen_label_rtx ();
9085 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9086 * UNITS_PER_FP_WORD);
9089 (gen_rtx_SET (VOIDmode,
9091 gen_rtx_IF_THEN_ELSE (VOIDmode,
9092 gen_rtx_NE (VOIDmode, cr1,
9094 gen_rtx_LABEL_REF (VOIDmode, lab),
9098 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9099 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9101 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9103 plus_constant (save_area, off));
9104 MEM_NOTRAP_P (mem) = 1;
9105 set_mem_alias_set (mem, set);
9106 set_mem_align (mem, GET_MODE_ALIGNMENT (
9107 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9108 ? DFmode : SFmode));
9109 emit_move_insn (mem, gen_rtx_REG (
9110 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9111 ? DFmode : SFmode, fregno));
9118 /* Create the va_list data type. */
9121 rs6000_build_builtin_va_list (void)
9123 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9125 /* For AIX, prefer 'char *' because that's what the system
9126 header files like. */
9127 if (DEFAULT_ABI != ABI_V4)
9128 return build_pointer_type (char_type_node);
9130 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9131 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9132 get_identifier ("__va_list_tag"), record);
9134 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9135 unsigned_char_type_node);
9136 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9137 unsigned_char_type_node);
9138 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9140 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9141 get_identifier ("reserved"), short_unsigned_type_node);
9142 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9143 get_identifier ("overflow_arg_area"),
9145 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9146 get_identifier ("reg_save_area"),
9149 va_list_gpr_counter_field = f_gpr;
9150 va_list_fpr_counter_field = f_fpr;
9152 DECL_FIELD_CONTEXT (f_gpr) = record;
9153 DECL_FIELD_CONTEXT (f_fpr) = record;
9154 DECL_FIELD_CONTEXT (f_res) = record;
9155 DECL_FIELD_CONTEXT (f_ovf) = record;
9156 DECL_FIELD_CONTEXT (f_sav) = record;
9158 TREE_CHAIN (record) = type_decl;
9159 TYPE_NAME (record) = type_decl;
9160 TYPE_FIELDS (record) = f_gpr;
9161 DECL_CHAIN (f_gpr) = f_fpr;
9162 DECL_CHAIN (f_fpr) = f_res;
9163 DECL_CHAIN (f_res) = f_ovf;
9164 DECL_CHAIN (f_ovf) = f_sav;
9166 layout_type (record);
9168 /* The correct type is an array type of one element. */
9169 return build_array_type (record, build_index_type (size_zero_node));
9172 /* Implement va_start. */
9175 rs6000_va_start (tree valist, rtx nextarg)
9177 HOST_WIDE_INT words, n_gpr, n_fpr;
9178 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9179 tree gpr, fpr, ovf, sav, t;
9181 /* Only SVR4 needs something special. */
9182 if (DEFAULT_ABI != ABI_V4)
9184 std_expand_builtin_va_start (valist, nextarg);
9188 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9189 f_fpr = DECL_CHAIN (f_gpr);
9190 f_res = DECL_CHAIN (f_fpr);
9191 f_ovf = DECL_CHAIN (f_res);
9192 f_sav = DECL_CHAIN (f_ovf);
9194 valist = build_va_arg_indirect_ref (valist);
9195 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9196 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9198 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9200 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9203 /* Count number of gp and fp argument registers used. */
9204 words = crtl->args.info.words;
9205 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9207 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9210 if (TARGET_DEBUG_ARG)
9211 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9212 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9213 words, n_gpr, n_fpr);
9215 if (cfun->va_list_gpr_size)
9217 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9218 build_int_cst (NULL_TREE, n_gpr));
9219 TREE_SIDE_EFFECTS (t) = 1;
9220 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9223 if (cfun->va_list_fpr_size)
9225 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9226 build_int_cst (NULL_TREE, n_fpr));
9227 TREE_SIDE_EFFECTS (t) = 1;
9228 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9231 /* Find the overflow area. */
9232 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9234 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9235 size_int (words * UNITS_PER_WORD));
9236 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9237 TREE_SIDE_EFFECTS (t) = 1;
9238 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9240 /* If there were no va_arg invocations, don't set up the register
9242 if (!cfun->va_list_gpr_size
9243 && !cfun->va_list_fpr_size
9244 && n_gpr < GP_ARG_NUM_REG
9245 && n_fpr < FP_ARG_V4_MAX_REG)
9248 /* Find the register save area. */
9249 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9250 if (cfun->machine->varargs_save_offset)
9251 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9252 size_int (cfun->machine->varargs_save_offset));
9253 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9254 TREE_SIDE_EFFECTS (t) = 1;
9255 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9258 /* Implement va_arg. */
9261 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9264 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9265 tree gpr, fpr, ovf, sav, reg, t, u;
9266 int size, rsize, n_reg, sav_ofs, sav_scale;
9267 tree lab_false, lab_over, addr;
9269 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9273 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9275 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9276 return build_va_arg_indirect_ref (t);
9279 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9280 earlier version of gcc, with the property that it always applied alignment
9281 adjustments to the va-args (even for zero-sized types). The cheapest way
9282 to deal with this is to replicate the effect of the part of
9283 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9285 We don't need to check for pass-by-reference because of the test above.
9286 We can return a simplifed answer, since we know there's no offset to add. */
9289 && rs6000_darwin64_abi
9290 && integer_zerop (TYPE_SIZE (type)))
9292 unsigned HOST_WIDE_INT align, boundary;
9293 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9294 align = PARM_BOUNDARY / BITS_PER_UNIT;
9295 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
9296 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9297 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9298 boundary /= BITS_PER_UNIT;
9299 if (boundary > align)
9302 /* This updates arg ptr by the amount that would be necessary
9303 to align the zero-sized (but not zero-alignment) item. */
9304 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9305 fold_build2 (POINTER_PLUS_EXPR,
9307 valist_tmp, size_int (boundary - 1)));
9308 gimplify_and_add (t, pre_p);
9310 t = fold_convert (sizetype, valist_tmp);
9311 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9312 fold_convert (TREE_TYPE (valist),
9313 fold_build2 (BIT_AND_EXPR, sizetype, t,
9314 size_int (-boundary))));
9315 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9316 gimplify_and_add (t, pre_p);
9318 /* Since it is zero-sized there's no increment for the item itself. */
9319 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9320 return build_va_arg_indirect_ref (valist_tmp);
9323 if (DEFAULT_ABI != ABI_V4)
9325 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9327 tree elem_type = TREE_TYPE (type);
9328 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9329 int elem_size = GET_MODE_SIZE (elem_mode);
9331 if (elem_size < UNITS_PER_WORD)
9333 tree real_part, imag_part;
9334 gimple_seq post = NULL;
9336 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9338 /* Copy the value into a temporary, lest the formal temporary
9339 be reused out from under us. */
9340 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9341 gimple_seq_add_seq (pre_p, post);
9343 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9346 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9350 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9353 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9354 f_fpr = DECL_CHAIN (f_gpr);
9355 f_res = DECL_CHAIN (f_fpr);
9356 f_ovf = DECL_CHAIN (f_res);
9357 f_sav = DECL_CHAIN (f_ovf);
9359 valist = build_va_arg_indirect_ref (valist);
9360 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9361 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9363 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9365 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9368 size = int_size_in_bytes (type);
9369 rsize = (size + 3) / 4;
9372 if (TARGET_HARD_FLOAT && TARGET_FPRS
9373 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9374 || (TARGET_DOUBLE_FLOAT
9375 && (TYPE_MODE (type) == DFmode
9376 || TYPE_MODE (type) == TFmode
9377 || TYPE_MODE (type) == SDmode
9378 || TYPE_MODE (type) == DDmode
9379 || TYPE_MODE (type) == TDmode))))
9381 /* FP args go in FP registers, if present. */
9383 n_reg = (size + 7) / 8;
9384 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9385 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9386 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9391 /* Otherwise into GP registers. */
9400 /* Pull the value out of the saved registers.... */
9403 addr = create_tmp_var (ptr_type_node, "addr");
9405 /* AltiVec vectors never go in registers when -mabi=altivec. */
9406 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9410 lab_false = create_artificial_label (input_location);
9411 lab_over = create_artificial_label (input_location);
9413 /* Long long and SPE vectors are aligned in the registers.
9414 As are any other 2 gpr item such as complex int due to a
9415 historical mistake. */
9417 if (n_reg == 2 && reg == gpr)
9420 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9421 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9422 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9423 unshare_expr (reg), u);
9425 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9426 reg number is 0 for f1, so we want to make it odd. */
9427 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9429 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9430 build_int_cst (TREE_TYPE (reg), 1));
9431 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9434 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9435 t = build2 (GE_EXPR, boolean_type_node, u, t);
9436 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9437 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9438 gimplify_and_add (t, pre_p);
9442 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9444 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9445 build_int_cst (TREE_TYPE (reg), n_reg));
9446 u = fold_convert (sizetype, u);
9447 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9448 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9450 /* _Decimal32 varargs are located in the second word of the 64-bit
9451 FP register for 32-bit binaries. */
9452 if (!TARGET_POWERPC64
9453 && TARGET_HARD_FLOAT && TARGET_FPRS
9454 && TYPE_MODE (type) == SDmode)
9455 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9457 gimplify_assign (addr, t, pre_p);
9459 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9461 stmt = gimple_build_label (lab_false);
9462 gimple_seq_add_stmt (pre_p, stmt);
9464 if ((n_reg == 2 && !regalign) || n_reg > 2)
9466 /* Ensure that we don't find any more args in regs.
9467 Alignment has taken care of for special cases. */
9468 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9472 /* ... otherwise out of the overflow area. */
9474 /* Care for on-stack alignment if needed. */
9478 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9479 t = fold_convert (sizetype, t);
9480 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9482 t = fold_convert (TREE_TYPE (ovf), t);
9484 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9486 gimplify_assign (unshare_expr (addr), t, pre_p);
9488 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9489 gimplify_assign (unshare_expr (ovf), t, pre_p);
9493 stmt = gimple_build_label (lab_over);
9494 gimple_seq_add_stmt (pre_p, stmt);
9497 if (STRICT_ALIGNMENT
9498 && (TYPE_ALIGN (type)
9499 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9501 /* The value (of type complex double, for example) may not be
9502 aligned in memory in the saved registers, so copy via a
9503 temporary. (This is the same code as used for SPARC.) */
9504 tree tmp = create_tmp_var (type, "va_arg_tmp");
9505 tree dest_addr = build_fold_addr_expr (tmp);
9507 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9508 3, dest_addr, addr, size_int (rsize * 4));
9510 gimplify_and_add (copy, pre_p);
9514 addr = fold_convert (ptrtype, addr);
9515 return build_va_arg_indirect_ref (addr);
9521 def_builtin (int mask, const char *name, tree type, int code)
9523 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9526 if (rs6000_builtin_decls[code])
9527 fatal_error ("internal error: builtin function to %s already processed.",
9530 rs6000_builtin_decls[code] = t =
9531 add_builtin_function (name, type, code, BUILT_IN_MD,
9534 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9535 switch (builtin_classify[code])
9540 /* assume builtin can do anything. */
9541 case RS6000_BTC_MISC:
9544 /* const function, function only depends on the inputs. */
9545 case RS6000_BTC_CONST:
9546 TREE_READONLY (t) = 1;
9547 TREE_NOTHROW (t) = 1;
9550 /* pure function, function can read global memory. */
9551 case RS6000_BTC_PURE:
9552 DECL_PURE_P (t) = 1;
9553 TREE_NOTHROW (t) = 1;
9556 /* Function is a math function. If rounding mode is on, then treat
9557 the function as not reading global memory, but it can have
9558 arbitrary side effects. If it is off, then assume the function is
9559 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9560 attribute in builtin-attribute.def that is used for the math
9562 case RS6000_BTC_FP_PURE:
9563 TREE_NOTHROW (t) = 1;
9564 if (flag_rounding_math)
9566 DECL_PURE_P (t) = 1;
9567 DECL_IS_NOVOPS (t) = 1;
9570 TREE_READONLY (t) = 1;
9576 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9578 static const struct builtin_description bdesc_3arg[] =
9580 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9581 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9582 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9583 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9584 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9585 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9586 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9587 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9588 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9589 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9590 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9591 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9592 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9593 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9594 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9595 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9596 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9597 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9598 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9599 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9600 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9601 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9602 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9603 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9604 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9605 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9606 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9607 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9608 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9609 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9610 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9611 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9612 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9613 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9614 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9616 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9617 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9618 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9619 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9620 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9621 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9622 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9623 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9624 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9625 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9626 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9627 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9628 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9629 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9630 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9632 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9633 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9634 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9635 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9637 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9638 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9639 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9640 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9642 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9643 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9645 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9646 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9647 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9648 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9649 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9650 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9651 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9652 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9653 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9654 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9656 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9657 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9658 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9659 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9660 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9661 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9662 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9663 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9664 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9665 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9667 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9668 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9669 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9670 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9671 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9672 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9673 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9674 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9675 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9677 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9678 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9679 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9680 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9681 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9682 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9683 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9685 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9686 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9687 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9688 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9689 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9690 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9691 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9692 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9693 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9696 /* DST operations: void foo (void *, const int, const char). */
9698 static const struct builtin_description bdesc_dst[] =
9700 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9701 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9702 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9703 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9705 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9706 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9707 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9708 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9711 /* Simple binary operations: VECc = foo (VECa, VECb). */
9713 static struct builtin_description bdesc_2arg[] =
9715 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9716 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9717 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9718 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9719 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9720 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9721 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9722 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9723 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9724 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9725 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9726 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9727 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9728 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9729 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9730 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9731 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9732 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9733 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9734 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9735 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9736 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9737 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9738 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9739 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9740 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9741 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9742 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9743 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9744 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9745 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9746 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9747 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9748 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9749 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9750 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9751 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9752 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9753 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9754 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9755 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9756 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9757 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9758 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9759 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9760 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9761 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9762 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9763 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9764 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9765 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9766 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9767 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9768 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9769 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9770 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9771 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9772 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9773 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9774 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9775 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9776 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9777 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9778 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9779 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9780 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9781 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9782 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9783 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9784 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9785 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9786 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9787 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9788 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9789 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9790 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9791 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9792 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9793 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9794 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9795 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9796 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9797 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9798 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9799 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9800 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9801 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9802 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9803 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9804 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9805 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9806 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9807 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9808 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9809 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9810 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9811 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9812 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9813 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9814 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9815 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9816 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9817 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9818 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9819 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9820 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9821 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9822 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9823 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9824 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9825 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9826 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9827 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9828 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9829 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9830 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9831 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9833 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9834 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9835 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9836 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9837 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9838 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9839 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9840 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9841 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9842 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9843 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9844 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9846 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9847 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9848 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9849 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9850 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9851 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9852 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9853 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9854 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9855 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9856 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9857 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9859 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9860 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9861 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9862 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9863 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9864 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9866 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9867 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9868 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9869 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9870 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9871 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9872 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9873 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9874 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9875 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9876 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9877 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9879 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9880 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9881 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9882 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9883 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9884 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9885 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9886 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9887 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9888 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9889 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9890 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9891 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9892 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9893 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9894 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9895 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9896 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9897 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9898 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9899 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9900 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9901 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9902 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9903 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9904 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9905 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9906 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9907 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9908 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9909 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9910 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9911 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9912 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9913 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9914 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9915 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9916 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9917 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9918 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9919 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9920 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9921 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9922 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9923 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9924 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9925 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9926 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9927 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9928 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9929 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9930 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9931 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9932 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9933 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9934 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9935 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9936 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9937 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9938 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9939 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9940 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9941 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9942 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9943 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9944 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9945 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9946 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9947 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9948 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9949 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9950 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9951 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9952 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9953 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9954 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9955 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9956 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9957 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9958 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9959 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9960 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9961 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9962 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9963 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9964 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9965 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9966 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9967 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
9968 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9969 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9970 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9971 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9972 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9973 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9974 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9975 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9978 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9979 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9980 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9981 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9982 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9983 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9984 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9985 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9987 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9988 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9989 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9990 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9996 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9997 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9998 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9999 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10000 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10007 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10009 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10010 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10012 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10013 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10014 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10015 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10016 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10017 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10018 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10019 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10020 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10021 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10023 /* Place holder, leave as first spe builtin. */
10024 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10025 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10026 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10027 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10028 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10029 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10030 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10031 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10032 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10033 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10034 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10035 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10036 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10037 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10038 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10039 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10040 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10041 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10042 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10043 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10044 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10045 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10046 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10047 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10048 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10049 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10050 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10051 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10052 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10053 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10054 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10055 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10056 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10057 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10058 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10059 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10060 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10061 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10062 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10063 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10064 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10065 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10066 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10067 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10068 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10069 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10070 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10071 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10072 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10073 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10074 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10075 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10076 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10077 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10078 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10079 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10080 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10081 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10082 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10083 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10084 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10085 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10086 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10087 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10088 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10089 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10090 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10091 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10092 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10093 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10094 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10095 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10096 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10097 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10098 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10099 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10100 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10101 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10102 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10103 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10104 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10105 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10106 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10107 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10108 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10109 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10110 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10111 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10112 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10113 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10114 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10115 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10116 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10117 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10118 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10119 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10120 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10121 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10122 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10123 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10124 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10125 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10126 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10127 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10128 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10129 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10130 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10131 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10132 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10134 /* SPE binary operations expecting a 5-bit unsigned literal. */
10135 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10137 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10138 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10139 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10140 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10141 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10142 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10143 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10144 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10145 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10146 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10147 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10148 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10149 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10150 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10151 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10152 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10153 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10154 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10155 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10156 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10157 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10158 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10159 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10160 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10161 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10162 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10164 /* Place-holder. Leave as last binary SPE builtin. */
10165 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10168 /* AltiVec predicates. */
10170 struct builtin_description_predicates
10172 const unsigned int mask;
10173 const enum insn_code icode;
10174 const char *const name;
10175 const enum rs6000_builtins code;
10178 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10180 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10181 ALTIVEC_BUILTIN_VCMPBFP_P },
10182 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10183 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10184 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10185 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10186 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10187 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10188 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10189 ALTIVEC_BUILTIN_VCMPEQUW_P },
10190 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10191 ALTIVEC_BUILTIN_VCMPGTSW_P },
10192 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10193 ALTIVEC_BUILTIN_VCMPGTUW_P },
10194 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10195 ALTIVEC_BUILTIN_VCMPEQUH_P },
10196 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10197 ALTIVEC_BUILTIN_VCMPGTSH_P },
10198 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10199 ALTIVEC_BUILTIN_VCMPGTUH_P },
10200 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10201 ALTIVEC_BUILTIN_VCMPEQUB_P },
10202 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10203 ALTIVEC_BUILTIN_VCMPGTSB_P },
10204 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10205 ALTIVEC_BUILTIN_VCMPGTUB_P },
10207 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10208 VSX_BUILTIN_XVCMPEQSP_P },
10209 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10210 VSX_BUILTIN_XVCMPGESP_P },
10211 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10212 VSX_BUILTIN_XVCMPGTSP_P },
10213 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10214 VSX_BUILTIN_XVCMPEQDP_P },
10215 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10216 VSX_BUILTIN_XVCMPGEDP_P },
10217 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10218 VSX_BUILTIN_XVCMPGTDP_P },
10220 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10221 ALTIVEC_BUILTIN_VCMPEQ_P },
10222 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10223 ALTIVEC_BUILTIN_VCMPGT_P },
10224 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10225 ALTIVEC_BUILTIN_VCMPGE_P }
10228 /* SPE predicates. */
10229 static struct builtin_description bdesc_spe_predicates[] =
10231 /* Place-holder. Leave as first. */
10232 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10233 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10234 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10235 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10236 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10237 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10238 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10239 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10240 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10241 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10242 /* Place-holder. Leave as last. */
10243 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10246 /* SPE evsel predicates. */
10247 static struct builtin_description bdesc_spe_evsel[] =
10249 /* Place-holder. Leave as first. */
10250 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10251 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10252 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10253 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10254 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10255 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10256 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10257 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10258 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10259 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10260 /* Place-holder. Leave as last. */
10261 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10264 /* PAIRED predicates. */
10265 static const struct builtin_description bdesc_paired_preds[] =
10267 /* Place-holder. Leave as first. */
10268 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10269 /* Place-holder. Leave as last. */
10270 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10273 /* ABS* operations. */
10275 static const struct builtin_description bdesc_abs[] =
10277 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10278 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10279 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10280 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10281 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10282 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10283 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10284 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10285 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10286 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10287 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10290 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10293 static struct builtin_description bdesc_1arg[] =
10295 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10296 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10297 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10298 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10299 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10300 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10301 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10302 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10303 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10304 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10305 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10306 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10307 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10308 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10309 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10310 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10311 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10312 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10314 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10315 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10316 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10317 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10318 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10319 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10320 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10322 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10323 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10324 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10325 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10326 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10327 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10328 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10330 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10331 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10332 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10333 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10334 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10335 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10337 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10338 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10339 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10340 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10341 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10342 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10344 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10345 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10346 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10347 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10349 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10350 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10351 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10352 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10353 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10354 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10355 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10356 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10357 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10359 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10360 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10361 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10362 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10363 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10364 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10365 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10366 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10367 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10369 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10370 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10371 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10372 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10373 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10375 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10376 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10377 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10378 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10379 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10380 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10381 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10382 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10383 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10384 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10385 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10386 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10387 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10388 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10389 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10390 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10391 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10392 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10393 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10394 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10396 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10397 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10398 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10400 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10401 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10402 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10403 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10405 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10406 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10407 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10408 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10409 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10410 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10411 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10412 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10413 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10414 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10415 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10416 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10417 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10418 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10419 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10420 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10421 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10422 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10423 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10424 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10425 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10426 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10427 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10428 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10429 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10430 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10431 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10432 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10433 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10434 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10436 /* Place-holder. Leave as last unary SPE builtin. */
10437 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10439 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10440 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10441 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10442 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10443 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10447 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10450 tree arg0 = CALL_EXPR_ARG (exp, 0);
10451 rtx op0 = expand_normal (arg0);
10452 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10453 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10455 if (icode == CODE_FOR_nothing)
10456 /* Builtin not supported on this processor. */
10459 /* If we got invalid arguments bail out before generating bad rtl. */
10460 if (arg0 == error_mark_node)
10463 if (icode == CODE_FOR_altivec_vspltisb
10464 || icode == CODE_FOR_altivec_vspltish
10465 || icode == CODE_FOR_altivec_vspltisw
10466 || icode == CODE_FOR_spe_evsplatfi
10467 || icode == CODE_FOR_spe_evsplati)
10469 /* Only allow 5-bit *signed* literals. */
10470 if (GET_CODE (op0) != CONST_INT
10471 || INTVAL (op0) > 15
10472 || INTVAL (op0) < -16)
10474 error ("argument 1 must be a 5-bit signed literal");
10480 || GET_MODE (target) != tmode
10481 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10482 target = gen_reg_rtx (tmode);
10484 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10485 op0 = copy_to_mode_reg (mode0, op0);
10487 pat = GEN_FCN (icode) (target, op0);
10496 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10498 rtx pat, scratch1, scratch2;
10499 tree arg0 = CALL_EXPR_ARG (exp, 0);
10500 rtx op0 = expand_normal (arg0);
10501 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10502 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10504 /* If we have invalid arguments, bail out before generating bad rtl. */
10505 if (arg0 == error_mark_node)
10509 || GET_MODE (target) != tmode
10510 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10511 target = gen_reg_rtx (tmode);
10513 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10514 op0 = copy_to_mode_reg (mode0, op0);
10516 scratch1 = gen_reg_rtx (mode0);
10517 scratch2 = gen_reg_rtx (mode0);
10519 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10528 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10531 tree arg0 = CALL_EXPR_ARG (exp, 0);
10532 tree arg1 = CALL_EXPR_ARG (exp, 1);
10533 rtx op0 = expand_normal (arg0);
10534 rtx op1 = expand_normal (arg1);
10535 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10536 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10537 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10539 if (icode == CODE_FOR_nothing)
10540 /* Builtin not supported on this processor. */
10543 /* If we got invalid arguments bail out before generating bad rtl. */
10544 if (arg0 == error_mark_node || arg1 == error_mark_node)
10547 if (icode == CODE_FOR_altivec_vcfux
10548 || icode == CODE_FOR_altivec_vcfsx
10549 || icode == CODE_FOR_altivec_vctsxs
10550 || icode == CODE_FOR_altivec_vctuxs
10551 || icode == CODE_FOR_altivec_vspltb
10552 || icode == CODE_FOR_altivec_vsplth
10553 || icode == CODE_FOR_altivec_vspltw
10554 || icode == CODE_FOR_spe_evaddiw
10555 || icode == CODE_FOR_spe_evldd
10556 || icode == CODE_FOR_spe_evldh
10557 || icode == CODE_FOR_spe_evldw
10558 || icode == CODE_FOR_spe_evlhhesplat
10559 || icode == CODE_FOR_spe_evlhhossplat
10560 || icode == CODE_FOR_spe_evlhhousplat
10561 || icode == CODE_FOR_spe_evlwhe
10562 || icode == CODE_FOR_spe_evlwhos
10563 || icode == CODE_FOR_spe_evlwhou
10564 || icode == CODE_FOR_spe_evlwhsplat
10565 || icode == CODE_FOR_spe_evlwwsplat
10566 || icode == CODE_FOR_spe_evrlwi
10567 || icode == CODE_FOR_spe_evslwi
10568 || icode == CODE_FOR_spe_evsrwis
10569 || icode == CODE_FOR_spe_evsubifw
10570 || icode == CODE_FOR_spe_evsrwiu)
10572 /* Only allow 5-bit unsigned literals. */
10574 if (TREE_CODE (arg1) != INTEGER_CST
10575 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10577 error ("argument 2 must be a 5-bit unsigned literal");
10583 || GET_MODE (target) != tmode
10584 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10585 target = gen_reg_rtx (tmode);
10587 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10588 op0 = copy_to_mode_reg (mode0, op0);
10589 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10590 op1 = copy_to_mode_reg (mode1, op1);
10592 pat = GEN_FCN (icode) (target, op0, op1);
10601 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10604 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10605 tree arg0 = CALL_EXPR_ARG (exp, 1);
10606 tree arg1 = CALL_EXPR_ARG (exp, 2);
10607 rtx op0 = expand_normal (arg0);
10608 rtx op1 = expand_normal (arg1);
10609 enum machine_mode tmode = SImode;
10610 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10611 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10614 if (TREE_CODE (cr6_form) != INTEGER_CST)
10616 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10620 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10622 gcc_assert (mode0 == mode1);
10624 /* If we have invalid arguments, bail out before generating bad rtl. */
10625 if (arg0 == error_mark_node || arg1 == error_mark_node)
10629 || GET_MODE (target) != tmode
10630 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10631 target = gen_reg_rtx (tmode);
10633 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10634 op0 = copy_to_mode_reg (mode0, op0);
10635 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10636 op1 = copy_to_mode_reg (mode1, op1);
10638 scratch = gen_reg_rtx (mode0);
10640 pat = GEN_FCN (icode) (scratch, op0, op1);
10645 /* The vec_any* and vec_all* predicates use the same opcodes for two
10646 different operations, but the bits in CR6 will be different
10647 depending on what information we want. So we have to play tricks
10648 with CR6 to get the right bits out.
10650 If you think this is disgusting, look at the specs for the
10651 AltiVec predicates. */
10653 switch (cr6_form_int)
10656 emit_insn (gen_cr6_test_for_zero (target));
10659 emit_insn (gen_cr6_test_for_zero_reverse (target));
10662 emit_insn (gen_cr6_test_for_lt (target));
10665 emit_insn (gen_cr6_test_for_lt_reverse (target));
10668 error ("argument 1 of __builtin_altivec_predicate is out of range");
10676 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10679 tree arg0 = CALL_EXPR_ARG (exp, 0);
10680 tree arg1 = CALL_EXPR_ARG (exp, 1);
10681 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10682 enum machine_mode mode0 = Pmode;
10683 enum machine_mode mode1 = Pmode;
10684 rtx op0 = expand_normal (arg0);
10685 rtx op1 = expand_normal (arg1);
10687 if (icode == CODE_FOR_nothing)
10688 /* Builtin not supported on this processor. */
10691 /* If we got invalid arguments bail out before generating bad rtl. */
10692 if (arg0 == error_mark_node || arg1 == error_mark_node)
10696 || GET_MODE (target) != tmode
10697 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10698 target = gen_reg_rtx (tmode);
10700 op1 = copy_to_mode_reg (mode1, op1);
10702 if (op0 == const0_rtx)
10704 addr = gen_rtx_MEM (tmode, op1);
10708 op0 = copy_to_mode_reg (mode0, op0);
10709 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10712 pat = GEN_FCN (icode) (target, addr);
10722 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10725 tree arg0 = CALL_EXPR_ARG (exp, 0);
10726 tree arg1 = CALL_EXPR_ARG (exp, 1);
10727 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10728 enum machine_mode mode0 = Pmode;
10729 enum machine_mode mode1 = Pmode;
10730 rtx op0 = expand_normal (arg0);
10731 rtx op1 = expand_normal (arg1);
10733 if (icode == CODE_FOR_nothing)
10734 /* Builtin not supported on this processor. */
10737 /* If we got invalid arguments bail out before generating bad rtl. */
10738 if (arg0 == error_mark_node || arg1 == error_mark_node)
10742 || GET_MODE (target) != tmode
10743 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10744 target = gen_reg_rtx (tmode);
10746 op1 = copy_to_mode_reg (mode1, op1);
10748 if (op0 == const0_rtx)
10750 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10754 op0 = copy_to_mode_reg (mode0, op0);
10755 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10758 pat = GEN_FCN (icode) (target, addr);
10768 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10770 tree arg0 = CALL_EXPR_ARG (exp, 0);
10771 tree arg1 = CALL_EXPR_ARG (exp, 1);
10772 tree arg2 = CALL_EXPR_ARG (exp, 2);
10773 rtx op0 = expand_normal (arg0);
10774 rtx op1 = expand_normal (arg1);
10775 rtx op2 = expand_normal (arg2);
10777 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10778 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10779 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10781 /* Invalid arguments. Bail before doing anything stoopid! */
10782 if (arg0 == error_mark_node
10783 || arg1 == error_mark_node
10784 || arg2 == error_mark_node)
10787 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10788 op0 = copy_to_mode_reg (mode2, op0);
10789 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10790 op1 = copy_to_mode_reg (mode0, op1);
10791 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10792 op2 = copy_to_mode_reg (mode1, op2);
10794 pat = GEN_FCN (icode) (op1, op2, op0);
10801 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10803 tree arg0 = CALL_EXPR_ARG (exp, 0);
10804 tree arg1 = CALL_EXPR_ARG (exp, 1);
10805 tree arg2 = CALL_EXPR_ARG (exp, 2);
10806 rtx op0 = expand_normal (arg0);
10807 rtx op1 = expand_normal (arg1);
10808 rtx op2 = expand_normal (arg2);
10810 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10811 enum machine_mode mode1 = Pmode;
10812 enum machine_mode mode2 = Pmode;
10814 /* Invalid arguments. Bail before doing anything stoopid! */
10815 if (arg0 == error_mark_node
10816 || arg1 == error_mark_node
10817 || arg2 == error_mark_node)
10820 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10821 op0 = copy_to_mode_reg (tmode, op0);
10823 op2 = copy_to_mode_reg (mode2, op2);
10825 if (op1 == const0_rtx)
10827 addr = gen_rtx_MEM (tmode, op2);
10831 op1 = copy_to_mode_reg (mode1, op1);
10832 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10835 pat = GEN_FCN (icode) (addr, op0);
10842 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10844 tree arg0 = CALL_EXPR_ARG (exp, 0);
10845 tree arg1 = CALL_EXPR_ARG (exp, 1);
10846 tree arg2 = CALL_EXPR_ARG (exp, 2);
10847 rtx op0 = expand_normal (arg0);
10848 rtx op1 = expand_normal (arg1);
10849 rtx op2 = expand_normal (arg2);
10851 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10852 enum machine_mode mode1 = Pmode;
10853 enum machine_mode mode2 = Pmode;
10855 /* Invalid arguments. Bail before doing anything stoopid! */
10856 if (arg0 == error_mark_node
10857 || arg1 == error_mark_node
10858 || arg2 == error_mark_node)
10861 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10862 op0 = copy_to_mode_reg (tmode, op0);
10864 op2 = copy_to_mode_reg (mode2, op2);
10866 if (op1 == const0_rtx)
10868 addr = gen_rtx_MEM (tmode, op2);
10872 op1 = copy_to_mode_reg (mode1, op1);
10873 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10876 pat = GEN_FCN (icode) (addr, op0);
10883 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10886 tree arg0 = CALL_EXPR_ARG (exp, 0);
10887 tree arg1 = CALL_EXPR_ARG (exp, 1);
10888 tree arg2 = CALL_EXPR_ARG (exp, 2);
10889 rtx op0 = expand_normal (arg0);
10890 rtx op1 = expand_normal (arg1);
10891 rtx op2 = expand_normal (arg2);
10892 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10893 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10894 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10895 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10897 if (icode == CODE_FOR_nothing)
10898 /* Builtin not supported on this processor. */
10901 /* If we got invalid arguments bail out before generating bad rtl. */
10902 if (arg0 == error_mark_node
10903 || arg1 == error_mark_node
10904 || arg2 == error_mark_node)
10907 /* Check and prepare argument depending on the instruction code.
10909 Note that a switch statement instead of the sequence of tests
10910 would be incorrect as many of the CODE_FOR values could be
10911 CODE_FOR_nothing and that would yield multiple alternatives
10912 with identical values. We'd never reach here at runtime in
10914 if (icode == CODE_FOR_altivec_vsldoi_v4sf
10915 || icode == CODE_FOR_altivec_vsldoi_v4si
10916 || icode == CODE_FOR_altivec_vsldoi_v8hi
10917 || icode == CODE_FOR_altivec_vsldoi_v16qi)
10919 /* Only allow 4-bit unsigned literals. */
10921 if (TREE_CODE (arg2) != INTEGER_CST
10922 || TREE_INT_CST_LOW (arg2) & ~0xf)
10924 error ("argument 3 must be a 4-bit unsigned literal");
10928 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
10929 || icode == CODE_FOR_vsx_xxpermdi_v2di
10930 || icode == CODE_FOR_vsx_xxsldwi_v16qi
10931 || icode == CODE_FOR_vsx_xxsldwi_v8hi
10932 || icode == CODE_FOR_vsx_xxsldwi_v4si
10933 || icode == CODE_FOR_vsx_xxsldwi_v4sf
10934 || icode == CODE_FOR_vsx_xxsldwi_v2di
10935 || icode == CODE_FOR_vsx_xxsldwi_v2df)
10937 /* Only allow 2-bit unsigned literals. */
10939 if (TREE_CODE (arg2) != INTEGER_CST
10940 || TREE_INT_CST_LOW (arg2) & ~0x3)
10942 error ("argument 3 must be a 2-bit unsigned literal");
10946 else if (icode == CODE_FOR_vsx_set_v2df
10947 || icode == CODE_FOR_vsx_set_v2di)
10949 /* Only allow 1-bit unsigned literals. */
10951 if (TREE_CODE (arg2) != INTEGER_CST
10952 || TREE_INT_CST_LOW (arg2) & ~0x1)
10954 error ("argument 3 must be a 1-bit unsigned literal");
10960 || GET_MODE (target) != tmode
10961 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10962 target = gen_reg_rtx (tmode);
10964 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10965 op0 = copy_to_mode_reg (mode0, op0);
10966 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10967 op1 = copy_to_mode_reg (mode1, op1);
10968 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10969 op2 = copy_to_mode_reg (mode2, op2);
10971 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10972 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10974 pat = GEN_FCN (icode) (target, op0, op1, op2);
10982 /* Expand the lvx builtins. */
10984 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10986 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10987 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10989 enum machine_mode tmode, mode0;
10991 enum insn_code icode;
10995 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10996 icode = CODE_FOR_vector_load_v16qi;
10998 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10999 icode = CODE_FOR_vector_load_v8hi;
11001 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11002 icode = CODE_FOR_vector_load_v4si;
11004 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11005 icode = CODE_FOR_vector_load_v4sf;
11008 *expandedp = false;
11014 arg0 = CALL_EXPR_ARG (exp, 0);
11015 op0 = expand_normal (arg0);
11016 tmode = insn_data[icode].operand[0].mode;
11017 mode0 = insn_data[icode].operand[1].mode;
11020 || GET_MODE (target) != tmode
11021 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11022 target = gen_reg_rtx (tmode);
11024 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11025 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11027 pat = GEN_FCN (icode) (target, op0);
11034 /* Expand the stvx builtins. */
11036 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11039 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11040 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11042 enum machine_mode mode0, mode1;
11044 enum insn_code icode;
11048 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11049 icode = CODE_FOR_vector_store_v16qi;
11051 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11052 icode = CODE_FOR_vector_store_v8hi;
11054 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11055 icode = CODE_FOR_vector_store_v4si;
11057 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11058 icode = CODE_FOR_vector_store_v4sf;
11061 *expandedp = false;
11065 arg0 = CALL_EXPR_ARG (exp, 0);
11066 arg1 = CALL_EXPR_ARG (exp, 1);
11067 op0 = expand_normal (arg0);
11068 op1 = expand_normal (arg1);
11069 mode0 = insn_data[icode].operand[0].mode;
11070 mode1 = insn_data[icode].operand[1].mode;
11072 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11073 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11074 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11075 op1 = copy_to_mode_reg (mode1, op1);
11077 pat = GEN_FCN (icode) (op0, op1);
11085 /* Expand the dst builtins. */
11087 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11090 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11091 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11092 tree arg0, arg1, arg2;
11093 enum machine_mode mode0, mode1;
11094 rtx pat, op0, op1, op2;
11095 const struct builtin_description *d;
11098 *expandedp = false;
11100 /* Handle DST variants. */
11102 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11103 if (d->code == fcode)
11105 arg0 = CALL_EXPR_ARG (exp, 0);
11106 arg1 = CALL_EXPR_ARG (exp, 1);
11107 arg2 = CALL_EXPR_ARG (exp, 2);
11108 op0 = expand_normal (arg0);
11109 op1 = expand_normal (arg1);
11110 op2 = expand_normal (arg2);
11111 mode0 = insn_data[d->icode].operand[0].mode;
11112 mode1 = insn_data[d->icode].operand[1].mode;
11114 /* Invalid arguments, bail out before generating bad rtl. */
11115 if (arg0 == error_mark_node
11116 || arg1 == error_mark_node
11117 || arg2 == error_mark_node)
11122 if (TREE_CODE (arg2) != INTEGER_CST
11123 || TREE_INT_CST_LOW (arg2) & ~0x3)
11125 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11129 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11130 op0 = copy_to_mode_reg (Pmode, op0);
11131 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11132 op1 = copy_to_mode_reg (mode1, op1);
11134 pat = GEN_FCN (d->icode) (op0, op1, op2);
11144 /* Expand vec_init builtin. */
11146 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11148 enum machine_mode tmode = TYPE_MODE (type);
11149 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11150 int i, n_elt = GET_MODE_NUNITS (tmode);
11151 rtvec v = rtvec_alloc (n_elt);
11153 gcc_assert (VECTOR_MODE_P (tmode));
11154 gcc_assert (n_elt == call_expr_nargs (exp));
11156 for (i = 0; i < n_elt; ++i)
11158 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11159 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11162 if (!target || !register_operand (target, tmode))
11163 target = gen_reg_rtx (tmode);
11165 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11169 /* Return the integer constant in ARG. Constrain it to be in the range
11170 of the subparts of VEC_TYPE; issue an error if not. */
11173 get_element_number (tree vec_type, tree arg)
11175 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11177 if (!host_integerp (arg, 1)
11178 || (elt = tree_low_cst (arg, 1), elt > max))
11180 error ("selector must be an integer constant in the range 0..%wi", max);
11187 /* Expand vec_set builtin. */
11189 altivec_expand_vec_set_builtin (tree exp)
11191 enum machine_mode tmode, mode1;
11192 tree arg0, arg1, arg2;
11196 arg0 = CALL_EXPR_ARG (exp, 0);
11197 arg1 = CALL_EXPR_ARG (exp, 1);
11198 arg2 = CALL_EXPR_ARG (exp, 2);
11200 tmode = TYPE_MODE (TREE_TYPE (arg0));
11201 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11202 gcc_assert (VECTOR_MODE_P (tmode));
11204 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11205 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11206 elt = get_element_number (TREE_TYPE (arg0), arg2);
11208 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11209 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11211 op0 = force_reg (tmode, op0);
11212 op1 = force_reg (mode1, op1);
11214 rs6000_expand_vector_set (op0, op1, elt);
11219 /* Expand vec_ext builtin. */
11221 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11223 enum machine_mode tmode, mode0;
11228 arg0 = CALL_EXPR_ARG (exp, 0);
11229 arg1 = CALL_EXPR_ARG (exp, 1);
11231 op0 = expand_normal (arg0);
11232 elt = get_element_number (TREE_TYPE (arg0), arg1);
11234 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11235 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11236 gcc_assert (VECTOR_MODE_P (mode0));
11238 op0 = force_reg (mode0, op0);
11240 if (optimize || !target || !register_operand (target, tmode))
11241 target = gen_reg_rtx (tmode);
11243 rs6000_expand_vector_extract (target, op0, elt);
11248 /* Expand the builtin in EXP and store the result in TARGET. Store
11249 true in *EXPANDEDP if we found a builtin to expand. */
11251 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11253 const struct builtin_description *d;
11254 const struct builtin_description_predicates *dp;
11256 enum insn_code icode;
11257 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11260 enum machine_mode tmode, mode0;
11261 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11263 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11264 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11265 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11266 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11269 error ("unresolved overload for Altivec builtin %qF", fndecl);
11273 target = altivec_expand_ld_builtin (exp, target, expandedp);
11277 target = altivec_expand_st_builtin (exp, target, expandedp);
11281 target = altivec_expand_dst_builtin (exp, target, expandedp);
11289 case ALTIVEC_BUILTIN_STVX:
11290 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
11291 case ALTIVEC_BUILTIN_STVEBX:
11292 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11293 case ALTIVEC_BUILTIN_STVEHX:
11294 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11295 case ALTIVEC_BUILTIN_STVEWX:
11296 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11297 case ALTIVEC_BUILTIN_STVXL:
11298 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11300 case ALTIVEC_BUILTIN_STVLX:
11301 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11302 case ALTIVEC_BUILTIN_STVLXL:
11303 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11304 case ALTIVEC_BUILTIN_STVRX:
11305 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11306 case ALTIVEC_BUILTIN_STVRXL:
11307 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11309 case ALTIVEC_BUILTIN_MFVSCR:
11310 icode = CODE_FOR_altivec_mfvscr;
11311 tmode = insn_data[icode].operand[0].mode;
11314 || GET_MODE (target) != tmode
11315 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11316 target = gen_reg_rtx (tmode);
11318 pat = GEN_FCN (icode) (target);
11324 case ALTIVEC_BUILTIN_MTVSCR:
11325 icode = CODE_FOR_altivec_mtvscr;
11326 arg0 = CALL_EXPR_ARG (exp, 0);
11327 op0 = expand_normal (arg0);
11328 mode0 = insn_data[icode].operand[0].mode;
11330 /* If we got invalid arguments bail out before generating bad rtl. */
11331 if (arg0 == error_mark_node)
11334 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11335 op0 = copy_to_mode_reg (mode0, op0);
11337 pat = GEN_FCN (icode) (op0);
11342 case ALTIVEC_BUILTIN_DSSALL:
11343 emit_insn (gen_altivec_dssall ());
11346 case ALTIVEC_BUILTIN_DSS:
11347 icode = CODE_FOR_altivec_dss;
11348 arg0 = CALL_EXPR_ARG (exp, 0);
11350 op0 = expand_normal (arg0);
11351 mode0 = insn_data[icode].operand[0].mode;
11353 /* If we got invalid arguments bail out before generating bad rtl. */
11354 if (arg0 == error_mark_node)
11357 if (TREE_CODE (arg0) != INTEGER_CST
11358 || TREE_INT_CST_LOW (arg0) & ~0x3)
11360 error ("argument to dss must be a 2-bit unsigned literal");
11364 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11365 op0 = copy_to_mode_reg (mode0, op0);
11367 emit_insn (gen_altivec_dss (op0));
11370 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11371 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11372 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11373 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11374 case VSX_BUILTIN_VEC_INIT_V2DF:
11375 case VSX_BUILTIN_VEC_INIT_V2DI:
11376 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11378 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11379 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11380 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11381 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11382 case VSX_BUILTIN_VEC_SET_V2DF:
11383 case VSX_BUILTIN_VEC_SET_V2DI:
11384 return altivec_expand_vec_set_builtin (exp);
11386 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11387 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11388 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11389 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11390 case VSX_BUILTIN_VEC_EXT_V2DF:
11391 case VSX_BUILTIN_VEC_EXT_V2DI:
11392 return altivec_expand_vec_ext_builtin (exp, target);
11396 /* Fall through. */
11399 /* Expand abs* operations. */
11401 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11402 if (d->code == fcode)
11403 return altivec_expand_abs_builtin (d->icode, exp, target);
11405 /* Expand the AltiVec predicates. */
11406 dp = bdesc_altivec_preds;
11407 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11408 if (dp->code == fcode)
11409 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11411 /* LV* are funky. We initialized them differently. */
11414 case ALTIVEC_BUILTIN_LVSL:
11415 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11416 exp, target, false);
11417 case ALTIVEC_BUILTIN_LVSR:
11418 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11419 exp, target, false);
11420 case ALTIVEC_BUILTIN_LVEBX:
11421 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11422 exp, target, false);
11423 case ALTIVEC_BUILTIN_LVEHX:
11424 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11425 exp, target, false);
11426 case ALTIVEC_BUILTIN_LVEWX:
11427 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11428 exp, target, false);
11429 case ALTIVEC_BUILTIN_LVXL:
11430 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11431 exp, target, false);
11432 case ALTIVEC_BUILTIN_LVX:
11433 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
11434 exp, target, false);
11435 case ALTIVEC_BUILTIN_LVLX:
11436 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11437 exp, target, true);
11438 case ALTIVEC_BUILTIN_LVLXL:
11439 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11440 exp, target, true);
11441 case ALTIVEC_BUILTIN_LVRX:
11442 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11443 exp, target, true);
11444 case ALTIVEC_BUILTIN_LVRXL:
11445 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11446 exp, target, true);
11449 /* Fall through. */
11452 *expandedp = false;
11456 /* Expand the builtin in EXP and store the result in TARGET. Store
11457 true in *EXPANDEDP if we found a builtin to expand. */
11459 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11461 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11462 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11463 const struct builtin_description *d;
11470 case PAIRED_BUILTIN_STX:
11471 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11472 case PAIRED_BUILTIN_LX:
11473 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11476 /* Fall through. */
11479 /* Expand the paired predicates. */
11480 d = bdesc_paired_preds;
11481 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11482 if (d->code == fcode)
11483 return paired_expand_predicate_builtin (d->icode, exp, target);
11485 *expandedp = false;
11489 /* Binops that need to be initialized manually, but can be expanded
11490 automagically by rs6000_expand_binop_builtin. */
11491 static struct builtin_description bdesc_2arg_spe[] =
11493 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11494 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11495 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11496 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11497 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11498 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11499 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11500 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11501 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11502 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11503 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11504 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11505 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11506 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11507 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11508 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11509 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11510 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11511 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11512 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11513 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11514 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11517 /* Expand the builtin in EXP and store the result in TARGET. Store
11518 true in *EXPANDEDP if we found a builtin to expand.
11520 This expands the SPE builtins that are not simple unary and binary
11523 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11525 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11527 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11528 enum insn_code icode;
11529 enum machine_mode tmode, mode0;
11531 struct builtin_description *d;
11536 /* Syntax check for a 5-bit unsigned immediate. */
11539 case SPE_BUILTIN_EVSTDD:
11540 case SPE_BUILTIN_EVSTDH:
11541 case SPE_BUILTIN_EVSTDW:
11542 case SPE_BUILTIN_EVSTWHE:
11543 case SPE_BUILTIN_EVSTWHO:
11544 case SPE_BUILTIN_EVSTWWE:
11545 case SPE_BUILTIN_EVSTWWO:
11546 arg1 = CALL_EXPR_ARG (exp, 2);
11547 if (TREE_CODE (arg1) != INTEGER_CST
11548 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11550 error ("argument 2 must be a 5-bit unsigned literal");
11558 /* The evsplat*i instructions are not quite generic. */
11561 case SPE_BUILTIN_EVSPLATFI:
11562 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11564 case SPE_BUILTIN_EVSPLATI:
11565 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11571 d = (struct builtin_description *) bdesc_2arg_spe;
11572 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11573 if (d->code == fcode)
11574 return rs6000_expand_binop_builtin (d->icode, exp, target);
11576 d = (struct builtin_description *) bdesc_spe_predicates;
11577 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11578 if (d->code == fcode)
11579 return spe_expand_predicate_builtin (d->icode, exp, target);
11581 d = (struct builtin_description *) bdesc_spe_evsel;
11582 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11583 if (d->code == fcode)
11584 return spe_expand_evsel_builtin (d->icode, exp, target);
11588 case SPE_BUILTIN_EVSTDDX:
11589 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11590 case SPE_BUILTIN_EVSTDHX:
11591 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11592 case SPE_BUILTIN_EVSTDWX:
11593 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11594 case SPE_BUILTIN_EVSTWHEX:
11595 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11596 case SPE_BUILTIN_EVSTWHOX:
11597 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11598 case SPE_BUILTIN_EVSTWWEX:
11599 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11600 case SPE_BUILTIN_EVSTWWOX:
11601 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11602 case SPE_BUILTIN_EVSTDD:
11603 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11604 case SPE_BUILTIN_EVSTDH:
11605 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11606 case SPE_BUILTIN_EVSTDW:
11607 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11608 case SPE_BUILTIN_EVSTWHE:
11609 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11610 case SPE_BUILTIN_EVSTWHO:
11611 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11612 case SPE_BUILTIN_EVSTWWE:
11613 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11614 case SPE_BUILTIN_EVSTWWO:
11615 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11616 case SPE_BUILTIN_MFSPEFSCR:
11617 icode = CODE_FOR_spe_mfspefscr;
11618 tmode = insn_data[icode].operand[0].mode;
11621 || GET_MODE (target) != tmode
11622 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11623 target = gen_reg_rtx (tmode);
11625 pat = GEN_FCN (icode) (target);
11630 case SPE_BUILTIN_MTSPEFSCR:
11631 icode = CODE_FOR_spe_mtspefscr;
11632 arg0 = CALL_EXPR_ARG (exp, 0);
11633 op0 = expand_normal (arg0);
11634 mode0 = insn_data[icode].operand[0].mode;
11636 if (arg0 == error_mark_node)
11639 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11640 op0 = copy_to_mode_reg (mode0, op0);
11642 pat = GEN_FCN (icode) (op0);
11650 *expandedp = false;
11655 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11657 rtx pat, scratch, tmp;
11658 tree form = CALL_EXPR_ARG (exp, 0);
11659 tree arg0 = CALL_EXPR_ARG (exp, 1);
11660 tree arg1 = CALL_EXPR_ARG (exp, 2);
11661 rtx op0 = expand_normal (arg0);
11662 rtx op1 = expand_normal (arg1);
11663 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11664 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11666 enum rtx_code code;
11668 if (TREE_CODE (form) != INTEGER_CST)
11670 error ("argument 1 of __builtin_paired_predicate must be a constant");
11674 form_int = TREE_INT_CST_LOW (form);
11676 gcc_assert (mode0 == mode1);
11678 if (arg0 == error_mark_node || arg1 == error_mark_node)
11682 || GET_MODE (target) != SImode
11683 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11684 target = gen_reg_rtx (SImode);
11685 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11686 op0 = copy_to_mode_reg (mode0, op0);
11687 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11688 op1 = copy_to_mode_reg (mode1, op1);
11690 scratch = gen_reg_rtx (CCFPmode);
11692 pat = GEN_FCN (icode) (scratch, op0, op1);
11714 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11717 error ("argument 1 of __builtin_paired_predicate is out of range");
11721 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11722 emit_move_insn (target, tmp);
11727 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11729 rtx pat, scratch, tmp;
11730 tree form = CALL_EXPR_ARG (exp, 0);
11731 tree arg0 = CALL_EXPR_ARG (exp, 1);
11732 tree arg1 = CALL_EXPR_ARG (exp, 2);
11733 rtx op0 = expand_normal (arg0);
11734 rtx op1 = expand_normal (arg1);
11735 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11736 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11738 enum rtx_code code;
11740 if (TREE_CODE (form) != INTEGER_CST)
11742 error ("argument 1 of __builtin_spe_predicate must be a constant");
11746 form_int = TREE_INT_CST_LOW (form);
11748 gcc_assert (mode0 == mode1);
11750 if (arg0 == error_mark_node || arg1 == error_mark_node)
11754 || GET_MODE (target) != SImode
11755 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11756 target = gen_reg_rtx (SImode);
11758 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11759 op0 = copy_to_mode_reg (mode0, op0);
11760 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11761 op1 = copy_to_mode_reg (mode1, op1);
11763 scratch = gen_reg_rtx (CCmode);
11765 pat = GEN_FCN (icode) (scratch, op0, op1);
11770 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11771 _lower_. We use one compare, but look in different bits of the
11772 CR for each variant.
11774 There are 2 elements in each SPE simd type (upper/lower). The CR
11775 bits are set as follows:
11777 BIT0 | BIT 1 | BIT 2 | BIT 3
11778 U | L | (U | L) | (U & L)
11780 So, for an "all" relationship, BIT 3 would be set.
11781 For an "any" relationship, BIT 2 would be set. Etc.
11783 Following traditional nomenclature, these bits map to:
11785 BIT0 | BIT 1 | BIT 2 | BIT 3
11788 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11793 /* All variant. OV bit. */
11795 /* We need to get to the OV bit, which is the ORDERED bit. We
11796 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11797 that's ugly and will make validate_condition_mode die.
11798 So let's just use another pattern. */
11799 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11801 /* Any variant. EQ bit. */
11805 /* Upper variant. LT bit. */
11809 /* Lower variant. GT bit. */
11814 error ("argument 1 of __builtin_spe_predicate is out of range");
11818 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11819 emit_move_insn (target, tmp);
11824 /* The evsel builtins look like this:
11826 e = __builtin_spe_evsel_OP (a, b, c, d);
11828 and work like this:
11830 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11831 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11835 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11838 tree arg0 = CALL_EXPR_ARG (exp, 0);
11839 tree arg1 = CALL_EXPR_ARG (exp, 1);
11840 tree arg2 = CALL_EXPR_ARG (exp, 2);
11841 tree arg3 = CALL_EXPR_ARG (exp, 3);
11842 rtx op0 = expand_normal (arg0);
11843 rtx op1 = expand_normal (arg1);
11844 rtx op2 = expand_normal (arg2);
11845 rtx op3 = expand_normal (arg3);
11846 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11847 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11849 gcc_assert (mode0 == mode1);
11851 if (arg0 == error_mark_node || arg1 == error_mark_node
11852 || arg2 == error_mark_node || arg3 == error_mark_node)
11856 || GET_MODE (target) != mode0
11857 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11858 target = gen_reg_rtx (mode0);
11860 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11861 op0 = copy_to_mode_reg (mode0, op0);
11862 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11863 op1 = copy_to_mode_reg (mode0, op1);
11864 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11865 op2 = copy_to_mode_reg (mode0, op2);
11866 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11867 op3 = copy_to_mode_reg (mode0, op3);
11869 /* Generate the compare. */
11870 scratch = gen_reg_rtx (CCmode);
11871 pat = GEN_FCN (icode) (scratch, op0, op1);
11876 if (mode0 == V2SImode)
11877 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11879 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11884 /* Expand an expression EXP that calls a built-in function,
11885 with result going to TARGET if that's convenient
11886 (and in mode MODE if that's convenient).
11887 SUBTARGET may be used as the target for computing one of EXP's operands.
11888 IGNORE is nonzero if the value is to be ignored. */
11891 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11892 enum machine_mode mode ATTRIBUTE_UNUSED,
11893 int ignore ATTRIBUTE_UNUSED)
11895 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11896 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11897 const struct builtin_description *d;
11904 case RS6000_BUILTIN_RECIP:
11905 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11907 case RS6000_BUILTIN_RECIPF:
11908 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11910 case RS6000_BUILTIN_RSQRTF:
11911 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11913 case RS6000_BUILTIN_RSQRT:
11914 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11916 case RS6000_BUILTIN_BSWAP_HI:
11917 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11919 case POWER7_BUILTIN_BPERMD:
11920 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11921 ? CODE_FOR_bpermd_di
11922 : CODE_FOR_bpermd_si), exp, target);
11924 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11925 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11927 int icode = (int) CODE_FOR_altivec_lvsr;
11928 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11929 enum machine_mode mode = insn_data[icode].operand[1].mode;
11933 gcc_assert (TARGET_ALTIVEC);
11935 arg = CALL_EXPR_ARG (exp, 0);
11936 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
11937 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11938 addr = memory_address (mode, op);
11939 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11943 /* For the load case need to negate the address. */
11944 op = gen_reg_rtx (GET_MODE (addr));
11945 emit_insn (gen_rtx_SET (VOIDmode, op,
11946 gen_rtx_NEG (GET_MODE (addr), addr)));
11948 op = gen_rtx_MEM (mode, op);
11951 || GET_MODE (target) != tmode
11952 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11953 target = gen_reg_rtx (tmode);
11955 /*pat = gen_altivec_lvsr (target, op);*/
11956 pat = GEN_FCN (icode) (target, op);
11964 case ALTIVEC_BUILTIN_VCFUX:
11965 case ALTIVEC_BUILTIN_VCFSX:
11966 case ALTIVEC_BUILTIN_VCTUXS:
11967 case ALTIVEC_BUILTIN_VCTSXS:
11968 /* FIXME: There's got to be a nicer way to handle this case than
11969 constructing a new CALL_EXPR. */
11970 if (call_expr_nargs (exp) == 1)
11972 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11973 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11981 if (TARGET_ALTIVEC)
11983 ret = altivec_expand_builtin (exp, target, &success);
11990 ret = spe_expand_builtin (exp, target, &success);
11995 if (TARGET_PAIRED_FLOAT)
11997 ret = paired_expand_builtin (exp, target, &success);
12003 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12005 /* Handle simple unary operations. */
12006 d = (struct builtin_description *) bdesc_1arg;
12007 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12008 if (d->code == fcode)
12009 return rs6000_expand_unop_builtin (d->icode, exp, target);
12011 /* Handle simple binary operations. */
12012 d = (struct builtin_description *) bdesc_2arg;
12013 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12014 if (d->code == fcode)
12015 return rs6000_expand_binop_builtin (d->icode, exp, target);
12017 /* Handle simple ternary operations. */
12019 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12020 if (d->code == fcode)
12021 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12023 gcc_unreachable ();
12027 rs6000_init_builtins (void)
12032 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12033 V2SF_type_node = build_vector_type (float_type_node, 2);
12034 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12035 V2DF_type_node = build_vector_type (double_type_node, 2);
12036 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12037 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12038 V4SF_type_node = build_vector_type (float_type_node, 4);
12039 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12040 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12042 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12043 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12044 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12045 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12047 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12048 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12049 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12050 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12052 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12053 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12054 'vector unsigned short'. */
12056 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12057 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12058 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12059 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12060 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12062 long_integer_type_internal_node = long_integer_type_node;
12063 long_unsigned_type_internal_node = long_unsigned_type_node;
12064 intQI_type_internal_node = intQI_type_node;
12065 uintQI_type_internal_node = unsigned_intQI_type_node;
12066 intHI_type_internal_node = intHI_type_node;
12067 uintHI_type_internal_node = unsigned_intHI_type_node;
12068 intSI_type_internal_node = intSI_type_node;
12069 uintSI_type_internal_node = unsigned_intSI_type_node;
12070 intDI_type_internal_node = intDI_type_node;
12071 uintDI_type_internal_node = unsigned_intDI_type_node;
12072 float_type_internal_node = float_type_node;
12073 double_type_internal_node = float_type_node;
12074 void_type_internal_node = void_type_node;
12076 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12078 builtin_mode_to_type[QImode][0] = integer_type_node;
12079 builtin_mode_to_type[HImode][0] = integer_type_node;
12080 builtin_mode_to_type[SImode][0] = intSI_type_node;
12081 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12082 builtin_mode_to_type[DImode][0] = intDI_type_node;
12083 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12084 builtin_mode_to_type[SFmode][0] = float_type_node;
12085 builtin_mode_to_type[DFmode][0] = double_type_node;
12086 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12087 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12088 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12089 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12090 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12091 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12092 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12093 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12094 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12095 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12096 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12097 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12098 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12100 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12101 get_identifier ("__bool char"),
12102 bool_char_type_node);
12103 TYPE_NAME (bool_char_type_node) = tdecl;
12104 (*lang_hooks.decls.pushdecl) (tdecl);
12105 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12106 get_identifier ("__bool short"),
12107 bool_short_type_node);
12108 TYPE_NAME (bool_short_type_node) = tdecl;
12109 (*lang_hooks.decls.pushdecl) (tdecl);
12110 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12111 get_identifier ("__bool int"),
12112 bool_int_type_node);
12113 TYPE_NAME (bool_int_type_node) = tdecl;
12114 (*lang_hooks.decls.pushdecl) (tdecl);
12115 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12117 TYPE_NAME (pixel_type_node) = tdecl;
12118 (*lang_hooks.decls.pushdecl) (tdecl);
12120 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12121 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12122 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12123 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12124 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12126 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12127 get_identifier ("__vector unsigned char"),
12128 unsigned_V16QI_type_node);
12129 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12130 (*lang_hooks.decls.pushdecl) (tdecl);
12131 tdecl = build_decl (BUILTINS_LOCATION,
12132 TYPE_DECL, get_identifier ("__vector signed char"),
12134 TYPE_NAME (V16QI_type_node) = tdecl;
12135 (*lang_hooks.decls.pushdecl) (tdecl);
12136 tdecl = build_decl (BUILTINS_LOCATION,
12137 TYPE_DECL, get_identifier ("__vector __bool char"),
12138 bool_V16QI_type_node);
12139 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12140 (*lang_hooks.decls.pushdecl) (tdecl);
12142 tdecl = build_decl (BUILTINS_LOCATION,
12143 TYPE_DECL, get_identifier ("__vector unsigned short"),
12144 unsigned_V8HI_type_node);
12145 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12146 (*lang_hooks.decls.pushdecl) (tdecl);
12147 tdecl = build_decl (BUILTINS_LOCATION,
12148 TYPE_DECL, get_identifier ("__vector signed short"),
12150 TYPE_NAME (V8HI_type_node) = tdecl;
12151 (*lang_hooks.decls.pushdecl) (tdecl);
12152 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12153 get_identifier ("__vector __bool short"),
12154 bool_V8HI_type_node);
12155 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12156 (*lang_hooks.decls.pushdecl) (tdecl);
12158 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12159 get_identifier ("__vector unsigned int"),
12160 unsigned_V4SI_type_node);
12161 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12162 (*lang_hooks.decls.pushdecl) (tdecl);
12163 tdecl = build_decl (BUILTINS_LOCATION,
12164 TYPE_DECL, get_identifier ("__vector signed int"),
12166 TYPE_NAME (V4SI_type_node) = tdecl;
12167 (*lang_hooks.decls.pushdecl) (tdecl);
12168 tdecl = build_decl (BUILTINS_LOCATION,
12169 TYPE_DECL, get_identifier ("__vector __bool int"),
12170 bool_V4SI_type_node);
12171 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12172 (*lang_hooks.decls.pushdecl) (tdecl);
12174 tdecl = build_decl (BUILTINS_LOCATION,
12175 TYPE_DECL, get_identifier ("__vector float"),
12177 TYPE_NAME (V4SF_type_node) = tdecl;
12178 (*lang_hooks.decls.pushdecl) (tdecl);
12179 tdecl = build_decl (BUILTINS_LOCATION,
12180 TYPE_DECL, get_identifier ("__vector __pixel"),
12181 pixel_V8HI_type_node);
12182 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12183 (*lang_hooks.decls.pushdecl) (tdecl);
12187 tdecl = build_decl (BUILTINS_LOCATION,
12188 TYPE_DECL, get_identifier ("__vector double"),
12190 TYPE_NAME (V2DF_type_node) = tdecl;
12191 (*lang_hooks.decls.pushdecl) (tdecl);
12193 tdecl = build_decl (BUILTINS_LOCATION,
12194 TYPE_DECL, get_identifier ("__vector long"),
12196 TYPE_NAME (V2DI_type_node) = tdecl;
12197 (*lang_hooks.decls.pushdecl) (tdecl);
12199 tdecl = build_decl (BUILTINS_LOCATION,
12200 TYPE_DECL, get_identifier ("__vector unsigned long"),
12201 unsigned_V2DI_type_node);
12202 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12203 (*lang_hooks.decls.pushdecl) (tdecl);
12205 tdecl = build_decl (BUILTINS_LOCATION,
12206 TYPE_DECL, get_identifier ("__vector __bool long"),
12207 bool_V2DI_type_node);
12208 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12209 (*lang_hooks.decls.pushdecl) (tdecl);
12212 if (TARGET_PAIRED_FLOAT)
12213 paired_init_builtins ();
12215 spe_init_builtins ();
12216 if (TARGET_ALTIVEC)
12217 altivec_init_builtins ();
12218 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12219 rs6000_common_init_builtins ();
12222 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12223 RS6000_BUILTIN_RECIP,
12224 "__builtin_recipdiv");
12225 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12226 RS6000_BUILTIN_RECIP);
12230 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12231 RS6000_BUILTIN_RECIPF,
12232 "__builtin_recipdivf");
12233 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12234 RS6000_BUILTIN_RECIPF);
12236 if (TARGET_FRSQRTE)
12238 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12239 RS6000_BUILTIN_RSQRT,
12240 "__builtin_rsqrt");
12241 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12242 RS6000_BUILTIN_RSQRT);
12244 if (TARGET_FRSQRTES)
12246 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12247 RS6000_BUILTIN_RSQRTF,
12248 "__builtin_rsqrtf");
12249 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12250 RS6000_BUILTIN_RSQRTF);
12252 if (TARGET_POPCNTD)
12254 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12255 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12256 POWER7_BUILTIN_BPERMD,
12257 "__builtin_bpermd");
12258 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12259 POWER7_BUILTIN_BPERMD);
12261 if (TARGET_POWERPC)
12263 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12264 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12265 unsigned_intHI_type_node,
12267 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12268 RS6000_BUILTIN_BSWAP_HI);
12272 /* AIX libm provides clog as __clog. */
12273 if (built_in_decls [BUILT_IN_CLOG])
12274 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12277 #ifdef SUBTARGET_INIT_BUILTINS
12278 SUBTARGET_INIT_BUILTINS;
12282 /* Returns the rs6000 builtin decl for CODE. */
12285 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12287 if (code >= RS6000_BUILTIN_COUNT)
12288 return error_mark_node;
12290 return rs6000_builtin_decls[code];
12293 /* Search through a set of builtins and enable the mask bits.
12294 DESC is an array of builtins.
12295 SIZE is the total number of builtins.
12296 START is the builtin enum at which to start.
12297 END is the builtin enum at which to end. */
12299 enable_mask_for_builtins (struct builtin_description *desc, int size,
12300 enum rs6000_builtins start,
12301 enum rs6000_builtins end)
12305 for (i = 0; i < size; ++i)
12306 if (desc[i].code == start)
12312 for (; i < size; ++i)
12314 /* Flip all the bits on. */
12315 desc[i].mask = target_flags;
12316 if (desc[i].code == end)
12322 spe_init_builtins (void)
12324 tree endlink = void_list_node;
12325 tree puint_type_node = build_pointer_type (unsigned_type_node);
12326 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12327 struct builtin_description *d;
12330 tree v2si_ftype_4_v2si
12331 = build_function_type
12332 (opaque_V2SI_type_node,
12333 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12334 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12335 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12336 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12339 tree v2sf_ftype_4_v2sf
12340 = build_function_type
12341 (opaque_V2SF_type_node,
12342 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12343 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12344 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12345 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12348 tree int_ftype_int_v2si_v2si
12349 = build_function_type
12350 (integer_type_node,
12351 tree_cons (NULL_TREE, integer_type_node,
12352 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12353 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12356 tree int_ftype_int_v2sf_v2sf
12357 = build_function_type
12358 (integer_type_node,
12359 tree_cons (NULL_TREE, integer_type_node,
12360 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12361 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12364 tree void_ftype_v2si_puint_int
12365 = build_function_type (void_type_node,
12366 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12367 tree_cons (NULL_TREE, puint_type_node,
12368 tree_cons (NULL_TREE,
12372 tree void_ftype_v2si_puint_char
12373 = build_function_type (void_type_node,
12374 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12375 tree_cons (NULL_TREE, puint_type_node,
12376 tree_cons (NULL_TREE,
12380 tree void_ftype_v2si_pv2si_int
12381 = build_function_type (void_type_node,
12382 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12383 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12384 tree_cons (NULL_TREE,
12388 tree void_ftype_v2si_pv2si_char
12389 = build_function_type (void_type_node,
12390 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12391 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12392 tree_cons (NULL_TREE,
12396 tree void_ftype_int
12397 = build_function_type (void_type_node,
12398 tree_cons (NULL_TREE, integer_type_node, endlink));
12400 tree int_ftype_void
12401 = build_function_type (integer_type_node, endlink);
12403 tree v2si_ftype_pv2si_int
12404 = build_function_type (opaque_V2SI_type_node,
12405 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12406 tree_cons (NULL_TREE, integer_type_node,
12409 tree v2si_ftype_puint_int
12410 = build_function_type (opaque_V2SI_type_node,
12411 tree_cons (NULL_TREE, puint_type_node,
12412 tree_cons (NULL_TREE, integer_type_node,
12415 tree v2si_ftype_pushort_int
12416 = build_function_type (opaque_V2SI_type_node,
12417 tree_cons (NULL_TREE, pushort_type_node,
12418 tree_cons (NULL_TREE, integer_type_node,
12421 tree v2si_ftype_signed_char
12422 = build_function_type (opaque_V2SI_type_node,
12423 tree_cons (NULL_TREE, signed_char_type_node,
12426 /* The initialization of the simple binary and unary builtins is
12427 done in rs6000_common_init_builtins, but we have to enable the
12428 mask bits here manually because we have run out of `target_flags'
12429 bits. We really need to redesign this mask business. */
12431 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12432 ARRAY_SIZE (bdesc_2arg),
12433 SPE_BUILTIN_EVADDW,
12434 SPE_BUILTIN_EVXOR);
12435 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12436 ARRAY_SIZE (bdesc_1arg),
12438 SPE_BUILTIN_EVSUBFUSIAAW);
12439 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12440 ARRAY_SIZE (bdesc_spe_predicates),
12441 SPE_BUILTIN_EVCMPEQ,
12442 SPE_BUILTIN_EVFSTSTLT);
12443 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12444 ARRAY_SIZE (bdesc_spe_evsel),
12445 SPE_BUILTIN_EVSEL_CMPGTS,
12446 SPE_BUILTIN_EVSEL_FSTSTEQ);
12448 (*lang_hooks.decls.pushdecl)
12449 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12450 get_identifier ("__ev64_opaque__"),
12451 opaque_V2SI_type_node));
12453 /* Initialize irregular SPE builtins. */
12455 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12456 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12457 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12458 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12459 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12460 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12461 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12462 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12463 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12464 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12465 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12466 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12467 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12468 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12469 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12470 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12471 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12472 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12475 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12476 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12477 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12478 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12479 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12480 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12481 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12482 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12483 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12484 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12485 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12486 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12487 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12488 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12489 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12490 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12491 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12492 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12493 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12494 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12495 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12496 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12499 d = (struct builtin_description *) bdesc_spe_predicates;
12500 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12504 switch (insn_data[d->icode].operand[1].mode)
12507 type = int_ftype_int_v2si_v2si;
12510 type = int_ftype_int_v2sf_v2sf;
12513 gcc_unreachable ();
12516 def_builtin (d->mask, d->name, type, d->code);
12519 /* Evsel predicates. */
12520 d = (struct builtin_description *) bdesc_spe_evsel;
12521 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12525 switch (insn_data[d->icode].operand[1].mode)
12528 type = v2si_ftype_4_v2si;
12531 type = v2sf_ftype_4_v2sf;
12534 gcc_unreachable ();
12537 def_builtin (d->mask, d->name, type, d->code);
12542 paired_init_builtins (void)
12544 const struct builtin_description *d;
12546 tree endlink = void_list_node;
12548 tree int_ftype_int_v2sf_v2sf
12549 = build_function_type
12550 (integer_type_node,
12551 tree_cons (NULL_TREE, integer_type_node,
12552 tree_cons (NULL_TREE, V2SF_type_node,
12553 tree_cons (NULL_TREE, V2SF_type_node,
12555 tree pcfloat_type_node =
12556 build_pointer_type (build_qualified_type
12557 (float_type_node, TYPE_QUAL_CONST));
12559 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12560 long_integer_type_node,
12563 tree void_ftype_v2sf_long_pcfloat =
12564 build_function_type_list (void_type_node,
12566 long_integer_type_node,
12571 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12572 PAIRED_BUILTIN_LX);
12575 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12576 PAIRED_BUILTIN_STX);
12579 d = bdesc_paired_preds;
12580 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12584 switch (insn_data[d->icode].operand[1].mode)
12587 type = int_ftype_int_v2sf_v2sf;
12590 gcc_unreachable ();
12593 def_builtin (d->mask, d->name, type, d->code);
12598 altivec_init_builtins (void)
12600 const struct builtin_description *d;
12601 const struct builtin_description_predicates *dp;
12605 tree pfloat_type_node = build_pointer_type (float_type_node);
12606 tree pint_type_node = build_pointer_type (integer_type_node);
12607 tree pshort_type_node = build_pointer_type (short_integer_type_node);
12608 tree pchar_type_node = build_pointer_type (char_type_node);
12610 tree pvoid_type_node = build_pointer_type (void_type_node);
12612 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
12613 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
12614 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
12615 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
12617 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
12619 tree int_ftype_opaque
12620 = build_function_type_list (integer_type_node,
12621 opaque_V4SI_type_node, NULL_TREE);
12622 tree opaque_ftype_opaque
12623 = build_function_type (integer_type_node,
12625 tree opaque_ftype_opaque_int
12626 = build_function_type_list (opaque_V4SI_type_node,
12627 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12628 tree opaque_ftype_opaque_opaque_int
12629 = build_function_type_list (opaque_V4SI_type_node,
12630 opaque_V4SI_type_node, opaque_V4SI_type_node,
12631 integer_type_node, NULL_TREE);
12632 tree int_ftype_int_opaque_opaque
12633 = build_function_type_list (integer_type_node,
12634 integer_type_node, opaque_V4SI_type_node,
12635 opaque_V4SI_type_node, NULL_TREE);
12636 tree int_ftype_int_v4si_v4si
12637 = build_function_type_list (integer_type_node,
12638 integer_type_node, V4SI_type_node,
12639 V4SI_type_node, NULL_TREE);
12640 tree v4sf_ftype_pcfloat
12641 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
12642 tree void_ftype_pfloat_v4sf
12643 = build_function_type_list (void_type_node,
12644 pfloat_type_node, V4SF_type_node, NULL_TREE);
12645 tree v4si_ftype_pcint
12646 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
12647 tree void_ftype_pint_v4si
12648 = build_function_type_list (void_type_node,
12649 pint_type_node, V4SI_type_node, NULL_TREE);
12650 tree v8hi_ftype_pcshort
12651 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
12652 tree void_ftype_pshort_v8hi
12653 = build_function_type_list (void_type_node,
12654 pshort_type_node, V8HI_type_node, NULL_TREE);
12655 tree v16qi_ftype_pcchar
12656 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
12657 tree void_ftype_pchar_v16qi
12658 = build_function_type_list (void_type_node,
12659 pchar_type_node, V16QI_type_node, NULL_TREE);
12660 tree void_ftype_v4si
12661 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12662 tree v8hi_ftype_void
12663 = build_function_type (V8HI_type_node, void_list_node);
12664 tree void_ftype_void
12665 = build_function_type (void_type_node, void_list_node);
12666 tree void_ftype_int
12667 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12669 tree opaque_ftype_long_pcvoid
12670 = build_function_type_list (opaque_V4SI_type_node,
12671 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12672 tree v16qi_ftype_long_pcvoid
12673 = build_function_type_list (V16QI_type_node,
12674 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12675 tree v8hi_ftype_long_pcvoid
12676 = build_function_type_list (V8HI_type_node,
12677 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12678 tree v4si_ftype_long_pcvoid
12679 = build_function_type_list (V4SI_type_node,
12680 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12682 tree void_ftype_opaque_long_pvoid
12683 = build_function_type_list (void_type_node,
12684 opaque_V4SI_type_node, long_integer_type_node,
12685 pvoid_type_node, NULL_TREE);
12686 tree void_ftype_v4si_long_pvoid
12687 = build_function_type_list (void_type_node,
12688 V4SI_type_node, long_integer_type_node,
12689 pvoid_type_node, NULL_TREE);
12690 tree void_ftype_v16qi_long_pvoid
12691 = build_function_type_list (void_type_node,
12692 V16QI_type_node, long_integer_type_node,
12693 pvoid_type_node, NULL_TREE);
12694 tree void_ftype_v8hi_long_pvoid
12695 = build_function_type_list (void_type_node,
12696 V8HI_type_node, long_integer_type_node,
12697 pvoid_type_node, NULL_TREE);
12698 tree int_ftype_int_v8hi_v8hi
12699 = build_function_type_list (integer_type_node,
12700 integer_type_node, V8HI_type_node,
12701 V8HI_type_node, NULL_TREE);
12702 tree int_ftype_int_v16qi_v16qi
12703 = build_function_type_list (integer_type_node,
12704 integer_type_node, V16QI_type_node,
12705 V16QI_type_node, NULL_TREE);
12706 tree int_ftype_int_v4sf_v4sf
12707 = build_function_type_list (integer_type_node,
12708 integer_type_node, V4SF_type_node,
12709 V4SF_type_node, NULL_TREE);
12710 tree int_ftype_int_v2df_v2df
12711 = build_function_type_list (integer_type_node,
12712 integer_type_node, V2DF_type_node,
12713 V2DF_type_node, NULL_TREE);
12714 tree v4si_ftype_v4si
12715 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12716 tree v8hi_ftype_v8hi
12717 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12718 tree v16qi_ftype_v16qi
12719 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12720 tree v4sf_ftype_v4sf
12721 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12722 tree v2df_ftype_v2df
12723 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12724 tree void_ftype_pcvoid_int_int
12725 = build_function_type_list (void_type_node,
12726 pcvoid_type_node, integer_type_node,
12727 integer_type_node, NULL_TREE);
12729 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
12730 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
12731 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
12732 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
12733 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
12734 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
12735 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
12736 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
12737 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
12738 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
12739 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
12740 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
12741 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
12742 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
12743 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
12744 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
12745 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12746 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12747 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12748 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12749 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12750 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12751 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12752 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12753 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12754 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12755 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12756 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12757 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12758 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12759 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12760 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12761 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12762 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12763 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12764 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12765 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12766 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12767 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12768 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12769 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12770 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12771 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12772 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12773 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12774 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12776 if (rs6000_cpu == PROCESSOR_CELL)
12778 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12779 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12780 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12781 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12783 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12784 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12785 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12786 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12788 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12789 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12790 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12791 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12793 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12794 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12795 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12796 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12798 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12799 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12800 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12802 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12803 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12804 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12805 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12806 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12807 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12808 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12809 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12810 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12811 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12812 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12813 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12815 /* Add the DST variants. */
12817 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12818 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12820 /* Initialize the predicates. */
12821 dp = bdesc_altivec_preds;
12822 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12824 enum machine_mode mode1;
12826 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12827 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12828 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12829 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12834 mode1 = insn_data[dp->icode].operand[1].mode;
12839 type = int_ftype_int_opaque_opaque;
12842 type = int_ftype_int_v4si_v4si;
12845 type = int_ftype_int_v8hi_v8hi;
12848 type = int_ftype_int_v16qi_v16qi;
12851 type = int_ftype_int_v4sf_v4sf;
12854 type = int_ftype_int_v2df_v2df;
12857 gcc_unreachable ();
12860 def_builtin (dp->mask, dp->name, type, dp->code);
12863 /* Initialize the abs* operators. */
12865 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12867 enum machine_mode mode0;
12870 mode0 = insn_data[d->icode].operand[0].mode;
12875 type = v4si_ftype_v4si;
12878 type = v8hi_ftype_v8hi;
12881 type = v16qi_ftype_v16qi;
12884 type = v4sf_ftype_v4sf;
12887 type = v2df_ftype_v2df;
12890 gcc_unreachable ();
12893 def_builtin (d->mask, d->name, type, d->code);
12896 if (TARGET_ALTIVEC)
12900 /* Initialize target builtin that implements
12901 targetm.vectorize.builtin_mask_for_load. */
12903 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12904 v16qi_ftype_long_pcvoid,
12905 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12906 BUILT_IN_MD, NULL, NULL_TREE);
12907 TREE_READONLY (decl) = 1;
12908 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12909 altivec_builtin_mask_for_load = decl;
12912 /* Access to the vec_init patterns. */
12913 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12914 integer_type_node, integer_type_node,
12915 integer_type_node, NULL_TREE);
12916 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12917 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12919 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12920 short_integer_type_node,
12921 short_integer_type_node,
12922 short_integer_type_node,
12923 short_integer_type_node,
12924 short_integer_type_node,
12925 short_integer_type_node,
12926 short_integer_type_node, NULL_TREE);
12927 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12928 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12930 ftype = build_function_type_list (V16QI_type_node, char_type_node,
12931 char_type_node, char_type_node,
12932 char_type_node, char_type_node,
12933 char_type_node, char_type_node,
12934 char_type_node, char_type_node,
12935 char_type_node, char_type_node,
12936 char_type_node, char_type_node,
12937 char_type_node, char_type_node,
12938 char_type_node, NULL_TREE);
12939 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
12940 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
12942 ftype = build_function_type_list (V4SF_type_node, float_type_node,
12943 float_type_node, float_type_node,
12944 float_type_node, NULL_TREE);
12945 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
12946 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12950 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12951 double_type_node, NULL_TREE);
12952 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12953 VSX_BUILTIN_VEC_INIT_V2DF);
12955 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12956 intDI_type_node, NULL_TREE);
12957 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12958 VSX_BUILTIN_VEC_INIT_V2DI);
12961 /* Access to the vec_set patterns. */
12962 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12964 integer_type_node, NULL_TREE);
12965 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12966 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12968 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12970 integer_type_node, NULL_TREE);
12971 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12972 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12974 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12976 integer_type_node, NULL_TREE);
12977 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12978 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12980 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12982 integer_type_node, NULL_TREE);
12983 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12984 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12988 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12990 integer_type_node, NULL_TREE);
12991 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12992 VSX_BUILTIN_VEC_SET_V2DF);
12994 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12996 integer_type_node, NULL_TREE);
12997 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12998 VSX_BUILTIN_VEC_SET_V2DI);
13001 /* Access to the vec_extract patterns. */
13002 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13003 integer_type_node, NULL_TREE);
13004 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13005 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13007 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13008 integer_type_node, NULL_TREE);
13009 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13010 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13012 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13013 integer_type_node, NULL_TREE);
13014 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13015 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13017 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13018 integer_type_node, NULL_TREE);
13019 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13020 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13024 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13025 integer_type_node, NULL_TREE);
13026 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13027 VSX_BUILTIN_VEC_EXT_V2DF);
13029 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13030 integer_type_node, NULL_TREE);
13031 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13032 VSX_BUILTIN_VEC_EXT_V2DI);
13036 /* Hash function for builtin functions with up to 3 arguments and a return
13039 builtin_hash_function (const void *hash_entry)
13043 const struct builtin_hash_struct *bh =
13044 (const struct builtin_hash_struct *) hash_entry;
13046 for (i = 0; i < 4; i++)
13048 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13049 ret = (ret * 2) + bh->uns_p[i];
13055 /* Compare builtin hash entries H1 and H2 for equivalence. */
13057 builtin_hash_eq (const void *h1, const void *h2)
13059 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13060 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13062 return ((p1->mode[0] == p2->mode[0])
13063 && (p1->mode[1] == p2->mode[1])
13064 && (p1->mode[2] == p2->mode[2])
13065 && (p1->mode[3] == p2->mode[3])
13066 && (p1->uns_p[0] == p2->uns_p[0])
13067 && (p1->uns_p[1] == p2->uns_p[1])
13068 && (p1->uns_p[2] == p2->uns_p[2])
13069 && (p1->uns_p[3] == p2->uns_p[3]));
13072 /* Map types for builtin functions with an explicit return type and up to 3
13073 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13074 of the argument. */
13076 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13077 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13078 enum rs6000_builtins builtin, const char *name)
13080 struct builtin_hash_struct h;
13081 struct builtin_hash_struct *h2;
13085 tree ret_type = NULL_TREE;
13086 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13089 /* Create builtin_hash_table. */
13090 if (builtin_hash_table == NULL)
13091 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13092 builtin_hash_eq, NULL);
13094 h.type = NULL_TREE;
13095 h.mode[0] = mode_ret;
13096 h.mode[1] = mode_arg0;
13097 h.mode[2] = mode_arg1;
13098 h.mode[3] = mode_arg2;
13104 /* If the builtin is a type that produces unsigned results or takes unsigned
13105 arguments, and it is returned as a decl for the vectorizer (such as
13106 widening multiplies, permute), make sure the arguments and return value
13107 are type correct. */
13110 /* unsigned 2 argument functions. */
13111 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13112 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13113 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13114 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13120 /* unsigned 3 argument functions. */
13121 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13122 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13123 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13124 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13125 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13126 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13127 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13128 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13129 case VSX_BUILTIN_VPERM_16QI_UNS:
13130 case VSX_BUILTIN_VPERM_8HI_UNS:
13131 case VSX_BUILTIN_VPERM_4SI_UNS:
13132 case VSX_BUILTIN_VPERM_2DI_UNS:
13133 case VSX_BUILTIN_XXSEL_16QI_UNS:
13134 case VSX_BUILTIN_XXSEL_8HI_UNS:
13135 case VSX_BUILTIN_XXSEL_4SI_UNS:
13136 case VSX_BUILTIN_XXSEL_2DI_UNS:
13143 /* signed permute functions with unsigned char mask. */
13144 case ALTIVEC_BUILTIN_VPERM_16QI:
13145 case ALTIVEC_BUILTIN_VPERM_8HI:
13146 case ALTIVEC_BUILTIN_VPERM_4SI:
13147 case ALTIVEC_BUILTIN_VPERM_4SF:
13148 case ALTIVEC_BUILTIN_VPERM_2DI:
13149 case ALTIVEC_BUILTIN_VPERM_2DF:
13150 case VSX_BUILTIN_VPERM_16QI:
13151 case VSX_BUILTIN_VPERM_8HI:
13152 case VSX_BUILTIN_VPERM_4SI:
13153 case VSX_BUILTIN_VPERM_4SF:
13154 case VSX_BUILTIN_VPERM_2DI:
13155 case VSX_BUILTIN_VPERM_2DF:
13159 /* unsigned args, signed return. */
13160 case VSX_BUILTIN_XVCVUXDDP_UNS:
13161 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13165 /* signed args, unsigned return. */
13166 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13167 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13175 /* Figure out how many args are present. */
13176 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13180 fatal_error ("internal error: builtin function %s had no type", name);
13182 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13183 if (!ret_type && h.uns_p[0])
13184 ret_type = builtin_mode_to_type[h.mode[0]][0];
13187 fatal_error ("internal error: builtin function %s had an unexpected "
13188 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13190 for (i = 0; i < num_args; i++)
13192 int m = (int) h.mode[i+1];
13193 int uns_p = h.uns_p[i+1];
13195 arg_type[i] = builtin_mode_to_type[m][uns_p];
13196 if (!arg_type[i] && uns_p)
13197 arg_type[i] = builtin_mode_to_type[m][0];
13200 fatal_error ("internal error: builtin function %s, argument %d "
13201 "had unexpected argument type %s", name, i,
13202 GET_MODE_NAME (m));
13205 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13206 if (*found == NULL)
13208 h2 = ggc_alloc_builtin_hash_struct ();
13210 *found = (void *)h2;
13211 args = void_list_node;
13213 for (i = num_args - 1; i >= 0; i--)
13214 args = tree_cons (NULL_TREE, arg_type[i], args);
13216 h2->type = build_function_type (ret_type, args);
13219 return ((struct builtin_hash_struct *)(*found))->type;
13223 rs6000_common_init_builtins (void)
13225 const struct builtin_description *d;
13228 tree opaque_ftype_opaque = NULL_TREE;
13229 tree opaque_ftype_opaque_opaque = NULL_TREE;
13230 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13231 tree v2si_ftype_qi = NULL_TREE;
13232 tree v2si_ftype_v2si_qi = NULL_TREE;
13233 tree v2si_ftype_int_qi = NULL_TREE;
13235 if (!TARGET_PAIRED_FLOAT)
13237 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13238 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13241 /* Add the ternary operators. */
13243 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13246 int mask = d->mask;
13248 if ((mask != 0 && (mask & target_flags) == 0)
13249 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13252 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13253 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13254 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13255 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13257 if (! (type = opaque_ftype_opaque_opaque_opaque))
13258 type = opaque_ftype_opaque_opaque_opaque
13259 = build_function_type_list (opaque_V4SI_type_node,
13260 opaque_V4SI_type_node,
13261 opaque_V4SI_type_node,
13262 opaque_V4SI_type_node,
13267 enum insn_code icode = d->icode;
13268 if (d->name == 0 || icode == CODE_FOR_nothing)
13271 type = builtin_function_type (insn_data[icode].operand[0].mode,
13272 insn_data[icode].operand[1].mode,
13273 insn_data[icode].operand[2].mode,
13274 insn_data[icode].operand[3].mode,
13278 def_builtin (d->mask, d->name, type, d->code);
13281 /* Add the binary operators. */
13283 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13285 enum machine_mode mode0, mode1, mode2;
13287 int mask = d->mask;
13289 if ((mask != 0 && (mask & target_flags) == 0)
13290 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13293 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13294 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13295 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13296 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13298 if (! (type = opaque_ftype_opaque_opaque))
13299 type = opaque_ftype_opaque_opaque
13300 = build_function_type_list (opaque_V4SI_type_node,
13301 opaque_V4SI_type_node,
13302 opaque_V4SI_type_node,
13307 enum insn_code icode = d->icode;
13308 if (d->name == 0 || icode == CODE_FOR_nothing)
13311 mode0 = insn_data[icode].operand[0].mode;
13312 mode1 = insn_data[icode].operand[1].mode;
13313 mode2 = insn_data[icode].operand[2].mode;
13315 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13317 if (! (type = v2si_ftype_v2si_qi))
13318 type = v2si_ftype_v2si_qi
13319 = build_function_type_list (opaque_V2SI_type_node,
13320 opaque_V2SI_type_node,
13325 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13326 && mode2 == QImode)
13328 if (! (type = v2si_ftype_int_qi))
13329 type = v2si_ftype_int_qi
13330 = build_function_type_list (opaque_V2SI_type_node,
13337 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13341 def_builtin (d->mask, d->name, type, d->code);
13344 /* Add the simple unary operators. */
13345 d = (struct builtin_description *) bdesc_1arg;
13346 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13348 enum machine_mode mode0, mode1;
13350 int mask = d->mask;
13352 if ((mask != 0 && (mask & target_flags) == 0)
13353 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13356 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13357 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13358 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13359 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13361 if (! (type = opaque_ftype_opaque))
13362 type = opaque_ftype_opaque
13363 = build_function_type_list (opaque_V4SI_type_node,
13364 opaque_V4SI_type_node,
13369 enum insn_code icode = d->icode;
13370 if (d->name == 0 || icode == CODE_FOR_nothing)
13373 mode0 = insn_data[icode].operand[0].mode;
13374 mode1 = insn_data[icode].operand[1].mode;
13376 if (mode0 == V2SImode && mode1 == QImode)
13378 if (! (type = v2si_ftype_qi))
13379 type = v2si_ftype_qi
13380 = build_function_type_list (opaque_V2SI_type_node,
13386 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13390 def_builtin (d->mask, d->name, type, d->code);
13395 rs6000_init_libfuncs (void)
13397 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13398 && !TARGET_POWER2 && !TARGET_POWERPC)
13400 /* AIX library routines for float->int conversion. */
13401 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13402 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13403 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13404 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13407 if (!TARGET_IEEEQUAD)
13408 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13409 if (!TARGET_XL_COMPAT)
13411 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13412 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13413 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13414 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13416 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13418 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13419 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13420 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13421 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13422 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13423 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13424 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13426 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13427 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13428 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13429 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13430 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13431 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13432 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13433 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13436 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13437 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13441 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13442 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13443 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13444 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13448 /* 32-bit SVR4 quad floating point routines. */
13450 set_optab_libfunc (add_optab, TFmode, "_q_add");
13451 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13452 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13453 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13454 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13455 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13456 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13458 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13459 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13460 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13461 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13462 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13463 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13465 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13466 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13467 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13468 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13469 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13470 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13471 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13472 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13477 /* Expand a block clear operation, and return 1 if successful. Return 0
13478 if we should let the compiler generate normal code.
13480 operands[0] is the destination
13481 operands[1] is the length
13482 operands[3] is the alignment */
13485 expand_block_clear (rtx operands[])
13487 rtx orig_dest = operands[0];
13488 rtx bytes_rtx = operands[1];
13489 rtx align_rtx = operands[3];
13490 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13491 HOST_WIDE_INT align;
13492 HOST_WIDE_INT bytes;
13497 /* If this is not a fixed size move, just call memcpy */
13501 /* This must be a fixed size alignment */
13502 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13503 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13505 /* Anything to clear? */
13506 bytes = INTVAL (bytes_rtx);
13510 /* Use the builtin memset after a point, to avoid huge code bloat.
13511 When optimize_size, avoid any significant code bloat; calling
13512 memset is about 4 instructions, so allow for one instruction to
13513 load zero and three to do clearing. */
13514 if (TARGET_ALTIVEC && align >= 128)
13516 else if (TARGET_POWERPC64 && align >= 32)
13518 else if (TARGET_SPE && align >= 64)
13523 if (optimize_size && bytes > 3 * clear_step)
13525 if (! optimize_size && bytes > 8 * clear_step)
13528 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13530 enum machine_mode mode = BLKmode;
13533 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13538 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13543 else if (bytes >= 8 && TARGET_POWERPC64
13544 /* 64-bit loads and stores require word-aligned
13546 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13551 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13552 { /* move 4 bytes */
13556 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13557 { /* move 2 bytes */
13561 else /* move 1 byte at a time */
13567 dest = adjust_address (orig_dest, mode, offset);
13569 emit_move_insn (dest, CONST0_RTX (mode));
13576 /* Expand a block move operation, and return 1 if successful. Return 0
13577 if we should let the compiler generate normal code.
13579 operands[0] is the destination
13580 operands[1] is the source
13581 operands[2] is the length
13582 operands[3] is the alignment */
13584 #define MAX_MOVE_REG 4
13587 expand_block_move (rtx operands[])
13589 rtx orig_dest = operands[0];
13590 rtx orig_src = operands[1];
13591 rtx bytes_rtx = operands[2];
13592 rtx align_rtx = operands[3];
13593 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13598 rtx stores[MAX_MOVE_REG];
13601 /* If this is not a fixed size move, just call memcpy */
13605 /* This must be a fixed size alignment */
13606 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13607 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13609 /* Anything to move? */
13610 bytes = INTVAL (bytes_rtx);
13614 if (bytes > rs6000_block_move_inline_limit)
13617 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13620 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13621 rtx (*mov) (rtx, rtx);
13623 enum machine_mode mode = BLKmode;
13626 /* Altivec first, since it will be faster than a string move
13627 when it applies, and usually not significantly larger. */
13628 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13632 gen_func.mov = gen_movv4si;
13634 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13638 gen_func.mov = gen_movv2si;
13640 else if (TARGET_STRING
13641 && bytes > 24 /* move up to 32 bytes at a time */
13647 && ! fixed_regs[10]
13648 && ! fixed_regs[11]
13649 && ! fixed_regs[12])
13651 move_bytes = (bytes > 32) ? 32 : bytes;
13652 gen_func.movmemsi = gen_movmemsi_8reg;
13654 else if (TARGET_STRING
13655 && bytes > 16 /* move up to 24 bytes at a time */
13661 && ! fixed_regs[10])
13663 move_bytes = (bytes > 24) ? 24 : bytes;
13664 gen_func.movmemsi = gen_movmemsi_6reg;
13666 else if (TARGET_STRING
13667 && bytes > 8 /* move up to 16 bytes at a time */
13671 && ! fixed_regs[8])
13673 move_bytes = (bytes > 16) ? 16 : bytes;
13674 gen_func.movmemsi = gen_movmemsi_4reg;
13676 else if (bytes >= 8 && TARGET_POWERPC64
13677 /* 64-bit loads and stores require word-aligned
13679 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13683 gen_func.mov = gen_movdi;
13685 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13686 { /* move up to 8 bytes at a time */
13687 move_bytes = (bytes > 8) ? 8 : bytes;
13688 gen_func.movmemsi = gen_movmemsi_2reg;
13690 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13691 { /* move 4 bytes */
13694 gen_func.mov = gen_movsi;
13696 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13697 { /* move 2 bytes */
13700 gen_func.mov = gen_movhi;
13702 else if (TARGET_STRING && bytes > 1)
13703 { /* move up to 4 bytes at a time */
13704 move_bytes = (bytes > 4) ? 4 : bytes;
13705 gen_func.movmemsi = gen_movmemsi_1reg;
13707 else /* move 1 byte at a time */
13711 gen_func.mov = gen_movqi;
13714 src = adjust_address (orig_src, mode, offset);
13715 dest = adjust_address (orig_dest, mode, offset);
13717 if (mode != BLKmode)
13719 rtx tmp_reg = gen_reg_rtx (mode);
13721 emit_insn ((*gen_func.mov) (tmp_reg, src));
13722 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13725 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13728 for (i = 0; i < num_reg; i++)
13729 emit_insn (stores[i]);
13733 if (mode == BLKmode)
13735 /* Move the address into scratch registers. The movmemsi
13736 patterns require zero offset. */
13737 if (!REG_P (XEXP (src, 0)))
13739 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13740 src = replace_equiv_address (src, src_reg);
13742 set_mem_size (src, GEN_INT (move_bytes));
13744 if (!REG_P (XEXP (dest, 0)))
13746 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13747 dest = replace_equiv_address (dest, dest_reg);
13749 set_mem_size (dest, GEN_INT (move_bytes));
13751 emit_insn ((*gen_func.movmemsi) (dest, src,
13752 GEN_INT (move_bytes & 31),
13761 /* Return a string to perform a load_multiple operation.
13762 operands[0] is the vector.
13763 operands[1] is the source address.
13764 operands[2] is the first destination register. */
13767 rs6000_output_load_multiple (rtx operands[3])
13769 /* We have to handle the case where the pseudo used to contain the address
13770 is assigned to one of the output registers. */
13772 int words = XVECLEN (operands[0], 0);
13775 if (XVECLEN (operands[0], 0) == 1)
13776 return "{l|lwz} %2,0(%1)";
13778 for (i = 0; i < words; i++)
13779 if (refers_to_regno_p (REGNO (operands[2]) + i,
13780 REGNO (operands[2]) + i + 1, operands[1], 0))
13784 xop[0] = GEN_INT (4 * (words-1));
13785 xop[1] = operands[1];
13786 xop[2] = operands[2];
13787 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13792 xop[0] = GEN_INT (4 * (words-1));
13793 xop[1] = operands[1];
13794 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13795 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);
13800 for (j = 0; j < words; j++)
13803 xop[0] = GEN_INT (j * 4);
13804 xop[1] = operands[1];
13805 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13806 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13808 xop[0] = GEN_INT (i * 4);
13809 xop[1] = operands[1];
13810 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13815 return "{lsi|lswi} %2,%1,%N0";
13819 /* A validation routine: say whether CODE, a condition code, and MODE
13820 match. The other alternatives either don't make sense or should
13821 never be generated. */
13824 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13826 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13827 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13828 && GET_MODE_CLASS (mode) == MODE_CC);
13830 /* These don't make sense. */
13831 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13832 || mode != CCUNSmode);
13834 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13835 || mode == CCUNSmode);
13837 gcc_assert (mode == CCFPmode
13838 || (code != ORDERED && code != UNORDERED
13839 && code != UNEQ && code != LTGT
13840 && code != UNGT && code != UNLT
13841 && code != UNGE && code != UNLE));
13843 /* These should never be generated except for
13844 flag_finite_math_only. */
13845 gcc_assert (mode != CCFPmode
13846 || flag_finite_math_only
13847 || (code != LE && code != GE
13848 && code != UNEQ && code != LTGT
13849 && code != UNGT && code != UNLT));
13851 /* These are invalid; the information is not there. */
13852 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13856 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13857 mask required to convert the result of a rotate insn into a shift
13858 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13861 includes_lshift_p (rtx shiftop, rtx andop)
13863 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13865 shift_mask <<= INTVAL (shiftop);
13867 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13870 /* Similar, but for right shift. */
13873 includes_rshift_p (rtx shiftop, rtx andop)
13875 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13877 shift_mask >>= INTVAL (shiftop);
13879 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13882 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13883 to perform a left shift. It must have exactly SHIFTOP least
13884 significant 0's, then one or more 1's, then zero or more 0's. */
13887 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13889 if (GET_CODE (andop) == CONST_INT)
13891 HOST_WIDE_INT c, lsb, shift_mask;
13893 c = INTVAL (andop);
13894 if (c == 0 || c == ~0)
13898 shift_mask <<= INTVAL (shiftop);
13900 /* Find the least significant one bit. */
13903 /* It must coincide with the LSB of the shift mask. */
13904 if (-lsb != shift_mask)
13907 /* Invert to look for the next transition (if any). */
13910 /* Remove the low group of ones (originally low group of zeros). */
13913 /* Again find the lsb, and check we have all 1's above. */
13917 else if (GET_CODE (andop) == CONST_DOUBLE
13918 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13920 HOST_WIDE_INT low, high, lsb;
13921 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13923 low = CONST_DOUBLE_LOW (andop);
13924 if (HOST_BITS_PER_WIDE_INT < 64)
13925 high = CONST_DOUBLE_HIGH (andop);
13927 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13928 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13931 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13933 shift_mask_high = ~0;
13934 if (INTVAL (shiftop) > 32)
13935 shift_mask_high <<= INTVAL (shiftop) - 32;
13937 lsb = high & -high;
13939 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13945 lsb = high & -high;
13946 return high == -lsb;
13949 shift_mask_low = ~0;
13950 shift_mask_low <<= INTVAL (shiftop);
13954 if (-lsb != shift_mask_low)
13957 if (HOST_BITS_PER_WIDE_INT < 64)
13962 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13964 lsb = high & -high;
13965 return high == -lsb;
13969 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13975 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13976 to perform a left shift. It must have SHIFTOP or more least
13977 significant 0's, with the remainder of the word 1's. */
13980 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13982 if (GET_CODE (andop) == CONST_INT)
13984 HOST_WIDE_INT c, lsb, shift_mask;
13987 shift_mask <<= INTVAL (shiftop);
13988 c = INTVAL (andop);
13990 /* Find the least significant one bit. */
13993 /* It must be covered by the shift mask.
13994 This test also rejects c == 0. */
13995 if ((lsb & shift_mask) == 0)
13998 /* Check we have all 1's above the transition, and reject all 1's. */
13999 return c == -lsb && lsb != 1;
14001 else if (GET_CODE (andop) == CONST_DOUBLE
14002 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14004 HOST_WIDE_INT low, lsb, shift_mask_low;
14006 low = CONST_DOUBLE_LOW (andop);
14008 if (HOST_BITS_PER_WIDE_INT < 64)
14010 HOST_WIDE_INT high, shift_mask_high;
14012 high = CONST_DOUBLE_HIGH (andop);
14016 shift_mask_high = ~0;
14017 if (INTVAL (shiftop) > 32)
14018 shift_mask_high <<= INTVAL (shiftop) - 32;
14020 lsb = high & -high;
14022 if ((lsb & shift_mask_high) == 0)
14025 return high == -lsb;
14031 shift_mask_low = ~0;
14032 shift_mask_low <<= INTVAL (shiftop);
14036 if ((lsb & shift_mask_low) == 0)
14039 return low == -lsb && lsb != 1;
14045 /* Return 1 if operands will generate a valid arguments to rlwimi
14046 instruction for insert with right shift in 64-bit mode. The mask may
14047 not start on the first bit or stop on the last bit because wrap-around
14048 effects of instruction do not correspond to semantics of RTL insn. */
14051 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14053 if (INTVAL (startop) > 32
14054 && INTVAL (startop) < 64
14055 && INTVAL (sizeop) > 1
14056 && INTVAL (sizeop) + INTVAL (startop) < 64
14057 && INTVAL (shiftop) > 0
14058 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14059 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14065 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14066 for lfq and stfq insns iff the registers are hard registers. */
14069 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14071 /* We might have been passed a SUBREG. */
14072 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14075 /* We might have been passed non floating point registers. */
14076 if (!FP_REGNO_P (REGNO (reg1))
14077 || !FP_REGNO_P (REGNO (reg2)))
14080 return (REGNO (reg1) == REGNO (reg2) - 1);
14083 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14084 addr1 and addr2 must be in consecutive memory locations
14085 (addr2 == addr1 + 8). */
14088 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14091 unsigned int reg1, reg2;
14092 int offset1, offset2;
14094 /* The mems cannot be volatile. */
14095 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14098 addr1 = XEXP (mem1, 0);
14099 addr2 = XEXP (mem2, 0);
14101 /* Extract an offset (if used) from the first addr. */
14102 if (GET_CODE (addr1) == PLUS)
14104 /* If not a REG, return zero. */
14105 if (GET_CODE (XEXP (addr1, 0)) != REG)
14109 reg1 = REGNO (XEXP (addr1, 0));
14110 /* The offset must be constant! */
14111 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14113 offset1 = INTVAL (XEXP (addr1, 1));
14116 else if (GET_CODE (addr1) != REG)
14120 reg1 = REGNO (addr1);
14121 /* This was a simple (mem (reg)) expression. Offset is 0. */
14125 /* And now for the second addr. */
14126 if (GET_CODE (addr2) == PLUS)
14128 /* If not a REG, return zero. */
14129 if (GET_CODE (XEXP (addr2, 0)) != REG)
14133 reg2 = REGNO (XEXP (addr2, 0));
14134 /* The offset must be constant. */
14135 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14137 offset2 = INTVAL (XEXP (addr2, 1));
14140 else if (GET_CODE (addr2) != REG)
14144 reg2 = REGNO (addr2);
14145 /* This was a simple (mem (reg)) expression. Offset is 0. */
14149 /* Both of these must have the same base register. */
14153 /* The offset for the second addr must be 8 more than the first addr. */
14154 if (offset2 != offset1 + 8)
14157 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14164 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14166 static bool eliminated = false;
14169 if (mode != SDmode)
14170 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14173 rtx mem = cfun->machine->sdmode_stack_slot;
14174 gcc_assert (mem != NULL_RTX);
14178 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14179 cfun->machine->sdmode_stack_slot = mem;
14185 if (TARGET_DEBUG_ADDR)
14187 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14188 GET_MODE_NAME (mode));
14190 fprintf (stderr, "\tNULL_RTX\n");
14199 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14201 /* Don't walk into types. */
14202 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14204 *walk_subtrees = 0;
14208 switch (TREE_CODE (*tp))
14217 case VIEW_CONVERT_EXPR:
14218 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14228 enum reload_reg_type {
14230 VECTOR_REGISTER_TYPE,
14231 OTHER_REGISTER_TYPE
14234 static enum reload_reg_type
14235 rs6000_reload_register_type (enum reg_class rclass)
14241 return GPR_REGISTER_TYPE;
14246 return VECTOR_REGISTER_TYPE;
14249 return OTHER_REGISTER_TYPE;
14253 /* Inform reload about cases where moving X with a mode MODE to a register in
14254 RCLASS requires an extra scratch or immediate register. Return the class
14255 needed for the immediate register.
14257 For VSX and Altivec, we may need a register to convert sp+offset into
14261 rs6000_secondary_reload (bool in_p,
14263 reg_class_t rclass_i,
14264 enum machine_mode mode,
14265 secondary_reload_info *sri)
14267 enum reg_class rclass = (enum reg_class) rclass_i;
14268 reg_class_t ret = ALL_REGS;
14269 enum insn_code icode;
14270 bool default_p = false;
14272 sri->icode = CODE_FOR_nothing;
14274 /* Convert vector loads and stores into gprs to use an additional base
14276 icode = rs6000_vector_reload[mode][in_p != false];
14277 if (icode != CODE_FOR_nothing)
14280 sri->icode = CODE_FOR_nothing;
14281 sri->extra_cost = 0;
14283 if (GET_CODE (x) == MEM)
14285 rtx addr = XEXP (x, 0);
14287 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14288 an extra register in that case, but it would need an extra
14289 register if the addressing is reg+reg or (reg+reg)&(-16). */
14290 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14292 if (!legitimate_indirect_address_p (addr, false)
14293 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14295 sri->icode = icode;
14296 /* account for splitting the loads, and converting the
14297 address from reg+reg to reg. */
14298 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14299 + ((GET_CODE (addr) == AND) ? 1 : 0));
14302 /* Loads to and stores from vector registers can only do reg+reg
14303 addressing. Altivec registers can also do (reg+reg)&(-16). */
14304 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14305 || rclass == FLOAT_REGS || rclass == NO_REGS)
14307 if (!VECTOR_MEM_ALTIVEC_P (mode)
14308 && GET_CODE (addr) == AND
14309 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14310 && INTVAL (XEXP (addr, 1)) == -16
14311 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14312 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14314 sri->icode = icode;
14315 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14318 else if (!legitimate_indirect_address_p (addr, false)
14319 && (rclass == NO_REGS
14320 || !legitimate_indexed_address_p (addr, false)))
14322 sri->icode = icode;
14323 sri->extra_cost = 1;
14326 icode = CODE_FOR_nothing;
14328 /* Any other loads, including to pseudo registers which haven't been
14329 assigned to a register yet, default to require a scratch
14333 sri->icode = icode;
14334 sri->extra_cost = 2;
14337 else if (REG_P (x))
14339 int regno = true_regnum (x);
14341 icode = CODE_FOR_nothing;
14342 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14346 enum reg_class xclass = REGNO_REG_CLASS (regno);
14347 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14348 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14350 /* If memory is needed, use default_secondary_reload to create the
14352 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14365 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14367 gcc_assert (ret != ALL_REGS);
14369 if (TARGET_DEBUG_ADDR)
14372 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14374 reg_class_names[ret],
14375 in_p ? "true" : "false",
14376 reg_class_names[rclass],
14377 GET_MODE_NAME (mode));
14380 fprintf (stderr, ", default secondary reload");
14382 if (sri->icode != CODE_FOR_nothing)
14383 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14384 insn_data[sri->icode].name, sri->extra_cost);
14386 fprintf (stderr, "\n");
14394 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14395 to SP+reg addressing. */
14398 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14400 int regno = true_regnum (reg);
14401 enum machine_mode mode = GET_MODE (reg);
14402 enum reg_class rclass;
14404 rtx and_op2 = NULL_RTX;
14407 rtx scratch_or_premodify = scratch;
14411 if (TARGET_DEBUG_ADDR)
14413 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14414 store_p ? "store" : "load");
14415 fprintf (stderr, "reg:\n");
14417 fprintf (stderr, "mem:\n");
14419 fprintf (stderr, "scratch:\n");
14420 debug_rtx (scratch);
14423 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14424 gcc_assert (GET_CODE (mem) == MEM);
14425 rclass = REGNO_REG_CLASS (regno);
14426 addr = XEXP (mem, 0);
14430 /* GPRs can handle reg + small constant, all other addresses need to use
14431 the scratch register. */
14434 if (GET_CODE (addr) == AND)
14436 and_op2 = XEXP (addr, 1);
14437 addr = XEXP (addr, 0);
14440 if (GET_CODE (addr) == PRE_MODIFY)
14442 scratch_or_premodify = XEXP (addr, 0);
14443 gcc_assert (REG_P (scratch_or_premodify));
14444 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14445 addr = XEXP (addr, 1);
14448 if (GET_CODE (addr) == PLUS
14449 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14450 || and_op2 != NULL_RTX))
14452 addr_op1 = XEXP (addr, 0);
14453 addr_op2 = XEXP (addr, 1);
14454 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14456 if (!REG_P (addr_op2)
14457 && (GET_CODE (addr_op2) != CONST_INT
14458 || !satisfies_constraint_I (addr_op2)))
14460 if (TARGET_DEBUG_ADDR)
14463 "\nMove plus addr to register %s, mode = %s: ",
14464 rs6000_reg_names[REGNO (scratch)],
14465 GET_MODE_NAME (mode));
14466 debug_rtx (addr_op2);
14468 rs6000_emit_move (scratch, addr_op2, Pmode);
14469 addr_op2 = scratch;
14472 emit_insn (gen_rtx_SET (VOIDmode,
14473 scratch_or_premodify,
14474 gen_rtx_PLUS (Pmode,
14478 addr = scratch_or_premodify;
14479 scratch_or_premodify = scratch;
14481 else if (!legitimate_indirect_address_p (addr, false)
14482 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14484 if (TARGET_DEBUG_ADDR)
14486 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14487 rs6000_reg_names[REGNO (scratch_or_premodify)],
14488 GET_MODE_NAME (mode));
14491 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14492 addr = scratch_or_premodify;
14493 scratch_or_premodify = scratch;
14497 /* Float/Altivec registers can only handle reg+reg addressing. Move
14498 other addresses into a scratch register. */
14503 /* With float regs, we need to handle the AND ourselves, since we can't
14504 use the Altivec instruction with an implicit AND -16. Allow scalar
14505 loads to float registers to use reg+offset even if VSX. */
14506 if (GET_CODE (addr) == AND
14507 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14508 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14509 || INTVAL (XEXP (addr, 1)) != -16
14510 || !VECTOR_MEM_ALTIVEC_P (mode)))
14512 and_op2 = XEXP (addr, 1);
14513 addr = XEXP (addr, 0);
14516 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14517 as the address later. */
14518 if (GET_CODE (addr) == PRE_MODIFY
14519 && (!VECTOR_MEM_VSX_P (mode)
14520 || and_op2 != NULL_RTX
14521 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14523 scratch_or_premodify = XEXP (addr, 0);
14524 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14526 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14527 addr = XEXP (addr, 1);
14530 if (legitimate_indirect_address_p (addr, false) /* reg */
14531 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14532 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14533 || (GET_CODE (addr) == AND /* Altivec memory */
14534 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14535 && INTVAL (XEXP (addr, 1)) == -16
14536 && VECTOR_MEM_ALTIVEC_P (mode))
14537 || (rclass == FLOAT_REGS /* legacy float mem */
14538 && GET_MODE_SIZE (mode) == 8
14539 && and_op2 == NULL_RTX
14540 && scratch_or_premodify == scratch
14541 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14544 else if (GET_CODE (addr) == PLUS)
14546 addr_op1 = XEXP (addr, 0);
14547 addr_op2 = XEXP (addr, 1);
14548 gcc_assert (REG_P (addr_op1));
14550 if (TARGET_DEBUG_ADDR)
14552 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14553 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14554 debug_rtx (addr_op2);
14556 rs6000_emit_move (scratch, addr_op2, Pmode);
14557 emit_insn (gen_rtx_SET (VOIDmode,
14558 scratch_or_premodify,
14559 gen_rtx_PLUS (Pmode,
14562 addr = scratch_or_premodify;
14563 scratch_or_premodify = scratch;
14566 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14567 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14569 if (TARGET_DEBUG_ADDR)
14571 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14572 rs6000_reg_names[REGNO (scratch_or_premodify)],
14573 GET_MODE_NAME (mode));
14577 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14578 addr = scratch_or_premodify;
14579 scratch_or_premodify = scratch;
14583 gcc_unreachable ();
14588 gcc_unreachable ();
14591 /* If the original address involved a pre-modify that we couldn't use the VSX
14592 memory instruction with update, and we haven't taken care of already,
14593 store the address in the pre-modify register and use that as the
14595 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14597 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14598 addr = scratch_or_premodify;
14601 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14602 memory instruction, recreate the AND now, including the clobber which is
14603 generated by the general ANDSI3/ANDDI3 patterns for the
14604 andi. instruction. */
14605 if (and_op2 != NULL_RTX)
14607 if (! legitimate_indirect_address_p (addr, false))
14609 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14613 if (TARGET_DEBUG_ADDR)
14615 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14616 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14617 debug_rtx (and_op2);
14620 and_rtx = gen_rtx_SET (VOIDmode,
14622 gen_rtx_AND (Pmode,
14626 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14627 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14628 gen_rtvec (2, and_rtx, cc_clobber)));
14632 /* Adjust the address if it changed. */
14633 if (addr != XEXP (mem, 0))
14635 mem = change_address (mem, mode, addr);
14636 if (TARGET_DEBUG_ADDR)
14637 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14640 /* Now create the move. */
14642 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14644 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14649 /* Target hook to return the cover classes for Integrated Register Allocator.
14650 Cover classes is a set of non-intersected register classes covering all hard
14651 registers used for register allocation purpose. Any move between two
14652 registers of a cover class should be cheaper than load or store of the
14653 registers. The value is array of register classes with LIM_REG_CLASSES used
14656 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14657 account for the Altivec and Floating registers being subsets of the VSX
14658 register set under VSX, but distinct register sets on pre-VSX machines. */
14660 static const reg_class_t *
14661 rs6000_ira_cover_classes (void)
14663 static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
14664 static const reg_class_t cover_vsx[] = IRA_COVER_CLASSES_VSX;
14666 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
14669 /* Allocate a 64-bit stack slot to be used for copying SDmode
14670 values through if this function has any SDmode references. */
14673 rs6000_alloc_sdmode_stack_slot (void)
14677 gimple_stmt_iterator gsi;
14679 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14682 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14684 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14687 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14688 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14694 /* Check for any SDmode parameters of the function. */
14695 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14697 if (TREE_TYPE (t) == error_mark_node)
14700 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14701 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14703 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14704 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14712 rs6000_instantiate_decls (void)
14714 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14715 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14718 /* Given an rtx X being reloaded into a reg required to be
14719 in class CLASS, return the class of reg to actually use.
14720 In general this is just CLASS; but on some machines
14721 in some cases it is preferable to use a more restrictive class.
14723 On the RS/6000, we have to return NO_REGS when we want to reload a
14724 floating-point CONST_DOUBLE to force it to be copied to memory.
14726 We also don't want to reload integer values into floating-point
14727 registers if we can at all help it. In fact, this can
14728 cause reload to die, if it tries to generate a reload of CTR
14729 into a FP register and discovers it doesn't have the memory location
14732 ??? Would it be a good idea to have reload do the converse, that is
14733 try to reload floating modes into FP registers if possible?
14736 static enum reg_class
14737 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14739 enum machine_mode mode = GET_MODE (x);
14741 if (VECTOR_UNIT_VSX_P (mode)
14742 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14745 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14746 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14747 && easy_vector_constant (x, mode))
14748 return ALTIVEC_REGS;
14750 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14753 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14754 return GENERAL_REGS;
14756 /* For VSX, prefer the traditional registers for 64-bit values because we can
14757 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14758 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14759 prefer Altivec loads.. */
14760 if (rclass == VSX_REGS)
14762 if (GET_MODE_SIZE (mode) <= 8)
14765 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14766 return ALTIVEC_REGS;
14774 /* Debug version of rs6000_preferred_reload_class. */
14775 static enum reg_class
14776 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14778 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14781 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14783 reg_class_names[ret], reg_class_names[rclass],
14784 GET_MODE_NAME (GET_MODE (x)));
14790 /* If we are copying between FP or AltiVec registers and anything else, we need
14791 a memory location. The exception is when we are targeting ppc64 and the
14792 move to/from fpr to gpr instructions are available. Also, under VSX, you
14793 can copy vector registers from the FP register set to the Altivec register
14794 set and vice versa. */
14797 rs6000_secondary_memory_needed (enum reg_class class1,
14798 enum reg_class class2,
14799 enum machine_mode mode)
14801 if (class1 == class2)
14804 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14805 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14806 between these classes. But we need memory for other things that can go in
14807 FLOAT_REGS like SFmode. */
14809 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14810 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14811 || class1 == FLOAT_REGS))
14812 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14813 && class2 != FLOAT_REGS);
14815 if (class1 == VSX_REGS || class2 == VSX_REGS)
14818 if (class1 == FLOAT_REGS
14819 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14820 || ((mode != DFmode)
14821 && (mode != DDmode)
14822 && (mode != DImode))))
14825 if (class2 == FLOAT_REGS
14826 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14827 || ((mode != DFmode)
14828 && (mode != DDmode)
14829 && (mode != DImode))))
14832 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14838 /* Debug version of rs6000_secondary_memory_needed. */
14840 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14841 enum reg_class class2,
14842 enum machine_mode mode)
14844 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14847 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14848 "class2 = %s, mode = %s\n",
14849 ret ? "true" : "false", reg_class_names[class1],
14850 reg_class_names[class2], GET_MODE_NAME (mode));
14855 /* Return the register class of a scratch register needed to copy IN into
14856 or out of a register in RCLASS in MODE. If it can be done directly,
14857 NO_REGS is returned. */
14859 static enum reg_class
14860 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14865 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14867 && MACHOPIC_INDIRECT
14871 /* We cannot copy a symbolic operand directly into anything
14872 other than BASE_REGS for TARGET_ELF. So indicate that a
14873 register from BASE_REGS is needed as an intermediate
14876 On Darwin, pic addresses require a load from memory, which
14877 needs a base register. */
14878 if (rclass != BASE_REGS
14879 && (GET_CODE (in) == SYMBOL_REF
14880 || GET_CODE (in) == HIGH
14881 || GET_CODE (in) == LABEL_REF
14882 || GET_CODE (in) == CONST))
14886 if (GET_CODE (in) == REG)
14888 regno = REGNO (in);
14889 if (regno >= FIRST_PSEUDO_REGISTER)
14891 regno = true_regnum (in);
14892 if (regno >= FIRST_PSEUDO_REGISTER)
14896 else if (GET_CODE (in) == SUBREG)
14898 regno = true_regnum (in);
14899 if (regno >= FIRST_PSEUDO_REGISTER)
14905 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14907 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14908 || (regno >= 0 && INT_REGNO_P (regno)))
14911 /* Constants, memory, and FP registers can go into FP registers. */
14912 if ((regno == -1 || FP_REGNO_P (regno))
14913 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14914 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14916 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14919 && (regno == -1 || VSX_REGNO_P (regno))
14920 && VSX_REG_CLASS_P (rclass))
14923 /* Memory, and AltiVec registers can go into AltiVec registers. */
14924 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14925 && rclass == ALTIVEC_REGS)
14928 /* We can copy among the CR registers. */
14929 if ((rclass == CR_REGS || rclass == CR0_REGS)
14930 && regno >= 0 && CR_REGNO_P (regno))
14933 /* Otherwise, we need GENERAL_REGS. */
14934 return GENERAL_REGS;
14937 /* Debug version of rs6000_secondary_reload_class. */
14938 static enum reg_class
14939 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14940 enum machine_mode mode, rtx in)
14942 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14944 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14945 "mode = %s, input rtx:\n",
14946 reg_class_names[ret], reg_class_names[rclass],
14947 GET_MODE_NAME (mode));
14953 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14956 rs6000_cannot_change_mode_class (enum machine_mode from,
14957 enum machine_mode to,
14958 enum reg_class rclass)
14960 unsigned from_size = GET_MODE_SIZE (from);
14961 unsigned to_size = GET_MODE_SIZE (to);
14963 if (from_size != to_size)
14965 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14966 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14967 && reg_classes_intersect_p (xclass, rclass));
14970 if (TARGET_E500_DOUBLE
14971 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14972 || (((to) == TFmode) + ((from) == TFmode)) == 1
14973 || (((to) == DDmode) + ((from) == DDmode)) == 1
14974 || (((to) == TDmode) + ((from) == TDmode)) == 1
14975 || (((to) == DImode) + ((from) == DImode)) == 1))
14978 /* Since the VSX register set includes traditional floating point registers
14979 and altivec registers, just check for the size being different instead of
14980 trying to check whether the modes are vector modes. Otherwise it won't
14981 allow say DF and DI to change classes. */
14982 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14983 return (from_size != 8 && from_size != 16);
14985 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14986 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14989 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14990 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14996 /* Debug version of rs6000_cannot_change_mode_class. */
14998 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14999 enum machine_mode to,
15000 enum reg_class rclass)
15002 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15005 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15006 "to = %s, rclass = %s\n",
15007 ret ? "true" : "false",
15008 GET_MODE_NAME (from), GET_MODE_NAME (to),
15009 reg_class_names[rclass]);
15014 /* Given a comparison operation, return the bit number in CCR to test. We
15015 know this is a valid comparison.
15017 SCC_P is 1 if this is for an scc. That means that %D will have been
15018 used instead of %C, so the bits will be in different places.
15020 Return -1 if OP isn't a valid comparison for some reason. */
15023 ccr_bit (rtx op, int scc_p)
15025 enum rtx_code code = GET_CODE (op);
15026 enum machine_mode cc_mode;
15031 if (!COMPARISON_P (op))
15034 reg = XEXP (op, 0);
15036 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15038 cc_mode = GET_MODE (reg);
15039 cc_regnum = REGNO (reg);
15040 base_bit = 4 * (cc_regnum - CR0_REGNO);
15042 validate_condition_mode (code, cc_mode);
15044 /* When generating a sCOND operation, only positive conditions are
15047 || code == EQ || code == GT || code == LT || code == UNORDERED
15048 || code == GTU || code == LTU);
15053 return scc_p ? base_bit + 3 : base_bit + 2;
15055 return base_bit + 2;
15056 case GT: case GTU: case UNLE:
15057 return base_bit + 1;
15058 case LT: case LTU: case UNGE:
15060 case ORDERED: case UNORDERED:
15061 return base_bit + 3;
15064 /* If scc, we will have done a cror to put the bit in the
15065 unordered position. So test that bit. For integer, this is ! LT
15066 unless this is an scc insn. */
15067 return scc_p ? base_bit + 3 : base_bit;
15070 return scc_p ? base_bit + 3 : base_bit + 1;
15073 gcc_unreachable ();
15077 /* Return the GOT register. */
15080 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15082 /* The second flow pass currently (June 1999) can't update
15083 regs_ever_live without disturbing other parts of the compiler, so
15084 update it here to make the prolog/epilogue code happy. */
15085 if (!can_create_pseudo_p ()
15086 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15087 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15089 crtl->uses_pic_offset_table = 1;
15091 return pic_offset_table_rtx;
15094 /* Function to init struct machine_function.
15095 This will be called, via a pointer variable,
15096 from push_function_context. */
15098 static struct machine_function *
15099 rs6000_init_machine_status (void)
15101 return ggc_alloc_cleared_machine_function ();
15104 /* These macros test for integers and extract the low-order bits. */
15106 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15107 && GET_MODE (X) == VOIDmode)
15109 #define INT_LOWPART(X) \
15110 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15113 extract_MB (rtx op)
15116 unsigned long val = INT_LOWPART (op);
15118 /* If the high bit is zero, the value is the first 1 bit we find
15120 if ((val & 0x80000000) == 0)
15122 gcc_assert (val & 0xffffffff);
15125 while (((val <<= 1) & 0x80000000) == 0)
15130 /* If the high bit is set and the low bit is not, or the mask is all
15131 1's, the value is zero. */
15132 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15135 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15138 while (((val >>= 1) & 1) != 0)
15145 extract_ME (rtx op)
15148 unsigned long val = INT_LOWPART (op);
15150 /* If the low bit is zero, the value is the first 1 bit we find from
15152 if ((val & 1) == 0)
15154 gcc_assert (val & 0xffffffff);
15157 while (((val >>= 1) & 1) == 0)
15163 /* If the low bit is set and the high bit is not, or the mask is all
15164 1's, the value is 31. */
15165 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15168 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15171 while (((val <<= 1) & 0x80000000) != 0)
15177 /* Locate some local-dynamic symbol still in use by this function
15178 so that we can print its name in some tls_ld pattern. */
15180 static const char *
15181 rs6000_get_some_local_dynamic_name (void)
15185 if (cfun->machine->some_ld_name)
15186 return cfun->machine->some_ld_name;
15188 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15190 && for_each_rtx (&PATTERN (insn),
15191 rs6000_get_some_local_dynamic_name_1, 0))
15192 return cfun->machine->some_ld_name;
15194 gcc_unreachable ();
15197 /* Helper function for rs6000_get_some_local_dynamic_name. */
15200 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15204 if (GET_CODE (x) == SYMBOL_REF)
15206 const char *str = XSTR (x, 0);
15207 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15209 cfun->machine->some_ld_name = str;
15217 /* Write out a function code label. */
15220 rs6000_output_function_entry (FILE *file, const char *fname)
15222 if (fname[0] != '.')
15224 switch (DEFAULT_ABI)
15227 gcc_unreachable ();
15233 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15242 RS6000_OUTPUT_BASENAME (file, fname);
15245 /* Print an operand. Recognize special options, documented below. */
15248 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15249 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15251 #define SMALL_DATA_RELOC "sda21"
15252 #define SMALL_DATA_REG 0
15256 print_operand (FILE *file, rtx x, int code)
15260 unsigned HOST_WIDE_INT uval;
15265 /* Write out an instruction after the call which may be replaced
15266 with glue code by the loader. This depends on the AIX version. */
15267 asm_fprintf (file, RS6000_CALL_GLUE);
15270 /* %a is output_address. */
15273 /* If X is a constant integer whose low-order 5 bits are zero,
15274 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15275 in the AIX assembler where "sri" with a zero shift count
15276 writes a trash instruction. */
15277 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15284 /* If constant, low-order 16 bits of constant, unsigned.
15285 Otherwise, write normally. */
15287 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15289 print_operand (file, x, 0);
15293 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15294 for 64-bit mask direction. */
15295 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15298 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15302 /* X is a CR register. Print the number of the GT bit of the CR. */
15303 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15304 output_operand_lossage ("invalid %%c value");
15306 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15310 /* Like 'J' but get to the GT bit only. */
15311 gcc_assert (GET_CODE (x) == REG);
15313 /* Bit 1 is GT bit. */
15314 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15316 /* Add one for shift count in rlinm for scc. */
15317 fprintf (file, "%d", i + 1);
15321 /* X is a CR register. Print the number of the EQ bit of the CR */
15322 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15323 output_operand_lossage ("invalid %%E value");
15325 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15329 /* X is a CR register. Print the shift count needed to move it
15330 to the high-order four bits. */
15331 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15332 output_operand_lossage ("invalid %%f value");
15334 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15338 /* Similar, but print the count for the rotate in the opposite
15340 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15341 output_operand_lossage ("invalid %%F value");
15343 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15347 /* X is a constant integer. If it is negative, print "m",
15348 otherwise print "z". This is to make an aze or ame insn. */
15349 if (GET_CODE (x) != CONST_INT)
15350 output_operand_lossage ("invalid %%G value");
15351 else if (INTVAL (x) >= 0)
15358 /* If constant, output low-order five bits. Otherwise, write
15361 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15363 print_operand (file, x, 0);
15367 /* If constant, output low-order six bits. Otherwise, write
15370 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15372 print_operand (file, x, 0);
15376 /* Print `i' if this is a constant, else nothing. */
15382 /* Write the bit number in CCR for jump. */
15383 i = ccr_bit (x, 0);
15385 output_operand_lossage ("invalid %%j code");
15387 fprintf (file, "%d", i);
15391 /* Similar, but add one for shift count in rlinm for scc and pass
15392 scc flag to `ccr_bit'. */
15393 i = ccr_bit (x, 1);
15395 output_operand_lossage ("invalid %%J code");
15397 /* If we want bit 31, write a shift count of zero, not 32. */
15398 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15402 /* X must be a constant. Write the 1's complement of the
15405 output_operand_lossage ("invalid %%k value");
15407 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15411 /* X must be a symbolic constant on ELF. Write an
15412 expression suitable for an 'addi' that adds in the low 16
15413 bits of the MEM. */
15414 if (GET_CODE (x) == CONST)
15416 if (GET_CODE (XEXP (x, 0)) != PLUS
15417 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15418 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15419 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15420 output_operand_lossage ("invalid %%K value");
15422 print_operand_address (file, x);
15423 fputs ("@l", file);
15426 /* %l is output_asm_label. */
15429 /* Write second word of DImode or DFmode reference. Works on register
15430 or non-indexed memory only. */
15431 if (GET_CODE (x) == REG)
15432 fputs (reg_names[REGNO (x) + 1], file);
15433 else if (GET_CODE (x) == MEM)
15435 /* Handle possible auto-increment. Since it is pre-increment and
15436 we have already done it, we can just use an offset of word. */
15437 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15438 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15439 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15441 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15442 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15445 output_address (XEXP (adjust_address_nv (x, SImode,
15449 if (small_data_operand (x, GET_MODE (x)))
15450 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15451 reg_names[SMALL_DATA_REG]);
15456 /* MB value for a mask operand. */
15457 if (! mask_operand (x, SImode))
15458 output_operand_lossage ("invalid %%m value");
15460 fprintf (file, "%d", extract_MB (x));
15464 /* ME value for a mask operand. */
15465 if (! mask_operand (x, SImode))
15466 output_operand_lossage ("invalid %%M value");
15468 fprintf (file, "%d", extract_ME (x));
15471 /* %n outputs the negative of its operand. */
15474 /* Write the number of elements in the vector times 4. */
15475 if (GET_CODE (x) != PARALLEL)
15476 output_operand_lossage ("invalid %%N value");
15478 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15482 /* Similar, but subtract 1 first. */
15483 if (GET_CODE (x) != PARALLEL)
15484 output_operand_lossage ("invalid %%O value");
15486 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15490 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15492 || INT_LOWPART (x) < 0
15493 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15494 output_operand_lossage ("invalid %%p value");
15496 fprintf (file, "%d", i);
15500 /* The operand must be an indirect memory reference. The result
15501 is the register name. */
15502 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15503 || REGNO (XEXP (x, 0)) >= 32)
15504 output_operand_lossage ("invalid %%P value");
15506 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15510 /* This outputs the logical code corresponding to a boolean
15511 expression. The expression may have one or both operands
15512 negated (if one, only the first one). For condition register
15513 logical operations, it will also treat the negated
15514 CR codes as NOTs, but not handle NOTs of them. */
15516 const char *const *t = 0;
15518 enum rtx_code code = GET_CODE (x);
15519 static const char * const tbl[3][3] = {
15520 { "and", "andc", "nor" },
15521 { "or", "orc", "nand" },
15522 { "xor", "eqv", "xor" } };
15526 else if (code == IOR)
15528 else if (code == XOR)
15531 output_operand_lossage ("invalid %%q value");
15533 if (GET_CODE (XEXP (x, 0)) != NOT)
15537 if (GET_CODE (XEXP (x, 1)) == NOT)
15555 /* X is a CR register. Print the mask for `mtcrf'. */
15556 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15557 output_operand_lossage ("invalid %%R value");
15559 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15563 /* Low 5 bits of 32 - value */
15565 output_operand_lossage ("invalid %%s value");
15567 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15571 /* PowerPC64 mask position. All 0's is excluded.
15572 CONST_INT 32-bit mask is considered sign-extended so any
15573 transition must occur within the CONST_INT, not on the boundary. */
15574 if (! mask64_operand (x, DImode))
15575 output_operand_lossage ("invalid %%S value");
15577 uval = INT_LOWPART (x);
15579 if (uval & 1) /* Clear Left */
15581 #if HOST_BITS_PER_WIDE_INT > 64
15582 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15586 else /* Clear Right */
15589 #if HOST_BITS_PER_WIDE_INT > 64
15590 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15596 gcc_assert (i >= 0);
15597 fprintf (file, "%d", i);
15601 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15602 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15604 /* Bit 3 is OV bit. */
15605 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15607 /* If we want bit 31, write a shift count of zero, not 32. */
15608 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15612 /* Print the symbolic name of a branch target register. */
15613 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15614 && REGNO (x) != CTR_REGNO))
15615 output_operand_lossage ("invalid %%T value");
15616 else if (REGNO (x) == LR_REGNO)
15617 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15619 fputs ("ctr", file);
15623 /* High-order 16 bits of constant for use in unsigned operand. */
15625 output_operand_lossage ("invalid %%u value");
15627 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15628 (INT_LOWPART (x) >> 16) & 0xffff);
15632 /* High-order 16 bits of constant for use in signed operand. */
15634 output_operand_lossage ("invalid %%v value");
15636 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15637 (INT_LOWPART (x) >> 16) & 0xffff);
15641 /* Print `u' if this has an auto-increment or auto-decrement. */
15642 if (GET_CODE (x) == MEM
15643 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15644 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15645 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15650 /* Print the trap code for this operand. */
15651 switch (GET_CODE (x))
15654 fputs ("eq", file); /* 4 */
15657 fputs ("ne", file); /* 24 */
15660 fputs ("lt", file); /* 16 */
15663 fputs ("le", file); /* 20 */
15666 fputs ("gt", file); /* 8 */
15669 fputs ("ge", file); /* 12 */
15672 fputs ("llt", file); /* 2 */
15675 fputs ("lle", file); /* 6 */
15678 fputs ("lgt", file); /* 1 */
15681 fputs ("lge", file); /* 5 */
15684 gcc_unreachable ();
15689 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15692 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15693 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15695 print_operand (file, x, 0);
15699 /* MB value for a PowerPC64 rldic operand. */
15700 val = (GET_CODE (x) == CONST_INT
15701 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15706 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15707 if ((val <<= 1) < 0)
15710 #if HOST_BITS_PER_WIDE_INT == 32
15711 if (GET_CODE (x) == CONST_INT && i >= 0)
15712 i += 32; /* zero-extend high-part was all 0's */
15713 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15715 val = CONST_DOUBLE_LOW (x);
15721 for ( ; i < 64; i++)
15722 if ((val <<= 1) < 0)
15727 fprintf (file, "%d", i + 1);
15731 /* X is a FPR or Altivec register used in a VSX context. */
15732 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15733 output_operand_lossage ("invalid %%x value");
15736 int reg = REGNO (x);
15737 int vsx_reg = (FP_REGNO_P (reg)
15739 : reg - FIRST_ALTIVEC_REGNO + 32);
15741 #ifdef TARGET_REGNAMES
15742 if (TARGET_REGNAMES)
15743 fprintf (file, "%%vs%d", vsx_reg);
15746 fprintf (file, "%d", vsx_reg);
15751 if (GET_CODE (x) == MEM
15752 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15753 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15754 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15759 /* Like 'L', for third word of TImode */
15760 if (GET_CODE (x) == REG)
15761 fputs (reg_names[REGNO (x) + 2], file);
15762 else if (GET_CODE (x) == MEM)
15764 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15765 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15766 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15767 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15768 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15770 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15771 if (small_data_operand (x, GET_MODE (x)))
15772 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15773 reg_names[SMALL_DATA_REG]);
15778 /* X is a SYMBOL_REF. Write out the name preceded by a
15779 period and without any trailing data in brackets. Used for function
15780 names. If we are configured for System V (or the embedded ABI) on
15781 the PowerPC, do not emit the period, since those systems do not use
15782 TOCs and the like. */
15783 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15785 /* Mark the decl as referenced so that cgraph will output the
15787 if (SYMBOL_REF_DECL (x))
15788 mark_decl_referenced (SYMBOL_REF_DECL (x));
15790 /* For macho, check to see if we need a stub. */
15793 const char *name = XSTR (x, 0);
15795 if (darwin_emit_branch_islands
15796 && MACHOPIC_INDIRECT
15797 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15798 name = machopic_indirection_name (x, /*stub_p=*/true);
15800 assemble_name (file, name);
15802 else if (!DOT_SYMBOLS)
15803 assemble_name (file, XSTR (x, 0));
15805 rs6000_output_function_entry (file, XSTR (x, 0));
15809 /* Like 'L', for last word of TImode. */
15810 if (GET_CODE (x) == REG)
15811 fputs (reg_names[REGNO (x) + 3], file);
15812 else if (GET_CODE (x) == MEM)
15814 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15815 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15816 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15817 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15818 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15820 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15821 if (small_data_operand (x, GET_MODE (x)))
15822 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15823 reg_names[SMALL_DATA_REG]);
15827 /* Print AltiVec or SPE memory operand. */
15832 gcc_assert (GET_CODE (x) == MEM);
15836 /* Ugly hack because %y is overloaded. */
15837 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15838 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15839 || GET_MODE (x) == TFmode
15840 || GET_MODE (x) == TImode))
15842 /* Handle [reg]. */
15843 if (GET_CODE (tmp) == REG)
15845 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15848 /* Handle [reg+UIMM]. */
15849 else if (GET_CODE (tmp) == PLUS &&
15850 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15854 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15856 x = INTVAL (XEXP (tmp, 1));
15857 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15861 /* Fall through. Must be [reg+reg]. */
15863 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15864 && GET_CODE (tmp) == AND
15865 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15866 && INTVAL (XEXP (tmp, 1)) == -16)
15867 tmp = XEXP (tmp, 0);
15868 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15869 && GET_CODE (tmp) == PRE_MODIFY)
15870 tmp = XEXP (tmp, 1);
15871 if (GET_CODE (tmp) == REG)
15872 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15875 if (!GET_CODE (tmp) == PLUS
15876 || !REG_P (XEXP (tmp, 0))
15877 || !REG_P (XEXP (tmp, 1)))
15879 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15883 if (REGNO (XEXP (tmp, 0)) == 0)
15884 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15885 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15887 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15888 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15894 if (GET_CODE (x) == REG)
15895 fprintf (file, "%s", reg_names[REGNO (x)]);
15896 else if (GET_CODE (x) == MEM)
15898 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15899 know the width from the mode. */
15900 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15901 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15902 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15903 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15904 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15905 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15906 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15907 output_address (XEXP (XEXP (x, 0), 1));
15909 output_address (XEXP (x, 0));
15912 output_addr_const (file, x);
15916 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15920 output_operand_lossage ("invalid %%xn code");
15924 /* Print the address of an operand. */
15927 print_operand_address (FILE *file, rtx x)
15929 if (GET_CODE (x) == REG)
15930 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15931 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15932 || GET_CODE (x) == LABEL_REF)
15934 output_addr_const (file, x);
15935 if (small_data_operand (x, GET_MODE (x)))
15936 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15937 reg_names[SMALL_DATA_REG]);
15939 gcc_assert (!TARGET_TOC);
15941 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15943 gcc_assert (REG_P (XEXP (x, 0)));
15944 if (REGNO (XEXP (x, 0)) == 0)
15945 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15946 reg_names[ REGNO (XEXP (x, 0)) ]);
15948 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15949 reg_names[ REGNO (XEXP (x, 1)) ]);
15951 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15952 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15953 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15955 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15956 && CONSTANT_P (XEXP (x, 1)))
15958 fprintf (file, "lo16(");
15959 output_addr_const (file, XEXP (x, 1));
15960 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15963 else if (legitimate_constant_pool_address_p (x, true))
15965 /* This hack along with a corresponding hack in
15966 rs6000_output_addr_const_extra arranges to output addends
15967 where the assembler expects to find them. eg.
15969 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
15970 without this hack would be output as "x@toc+8@l(9)". We
15971 want "x+8@toc@l(9)". */
15972 output_addr_const (file, tocrel_base);
15973 if (GET_CODE (x) == LO_SUM)
15974 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15976 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15979 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15980 && CONSTANT_P (XEXP (x, 1)))
15982 output_addr_const (file, XEXP (x, 1));
15983 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15987 gcc_unreachable ();
15990 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
15993 rs6000_output_addr_const_extra (FILE *file, rtx x)
15995 if (GET_CODE (x) == UNSPEC)
15996 switch (XINT (x, 1))
15998 case UNSPEC_TOCREL:
15999 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16000 output_addr_const (file, XVECEXP (x, 0, 0));
16001 if (x == tocrel_base && tocrel_offset != const0_rtx)
16003 if (INTVAL (tocrel_offset) >= 0)
16004 fprintf (file, "+");
16005 output_addr_const (file, tocrel_offset);
16007 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16010 assemble_name (file, toc_label_name);
16012 else if (TARGET_ELF)
16013 fputs ("@toc", file);
16017 case UNSPEC_MACHOPIC_OFFSET:
16018 output_addr_const (file, XVECEXP (x, 0, 0));
16020 machopic_output_function_base_name (file);
16027 /* Target hook for assembling integer objects. The PowerPC version has
16028 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16029 is defined. It also needs to handle DI-mode objects on 64-bit
16033 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16035 #ifdef RELOCATABLE_NEEDS_FIXUP
16036 /* Special handling for SI values. */
16037 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16039 static int recurse = 0;
16041 /* For -mrelocatable, we mark all addresses that need to be fixed up
16042 in the .fixup section. */
16043 if (TARGET_RELOCATABLE
16044 && in_section != toc_section
16045 && in_section != text_section
16046 && !unlikely_text_section_p (in_section)
16048 && GET_CODE (x) != CONST_INT
16049 && GET_CODE (x) != CONST_DOUBLE
16055 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16057 ASM_OUTPUT_LABEL (asm_out_file, buf);
16058 fprintf (asm_out_file, "\t.long\t(");
16059 output_addr_const (asm_out_file, x);
16060 fprintf (asm_out_file, ")@fixup\n");
16061 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16062 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16063 fprintf (asm_out_file, "\t.long\t");
16064 assemble_name (asm_out_file, buf);
16065 fprintf (asm_out_file, "\n\t.previous\n");
16069 /* Remove initial .'s to turn a -mcall-aixdesc function
16070 address into the address of the descriptor, not the function
16072 else if (GET_CODE (x) == SYMBOL_REF
16073 && XSTR (x, 0)[0] == '.'
16074 && DEFAULT_ABI == ABI_AIX)
16076 const char *name = XSTR (x, 0);
16077 while (*name == '.')
16080 fprintf (asm_out_file, "\t.long\t%s\n", name);
16084 #endif /* RELOCATABLE_NEEDS_FIXUP */
16085 return default_assemble_integer (x, size, aligned_p);
16088 #ifdef HAVE_GAS_HIDDEN
16089 /* Emit an assembler directive to set symbol visibility for DECL to
16090 VISIBILITY_TYPE. */
16093 rs6000_assemble_visibility (tree decl, int vis)
16095 /* Functions need to have their entry point symbol visibility set as
16096 well as their descriptor symbol visibility. */
16097 if (DEFAULT_ABI == ABI_AIX
16099 && TREE_CODE (decl) == FUNCTION_DECL)
16101 static const char * const visibility_types[] = {
16102 NULL, "internal", "hidden", "protected"
16105 const char *name, *type;
16107 name = ((* targetm.strip_name_encoding)
16108 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16109 type = visibility_types[vis];
16111 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16112 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16115 default_assemble_visibility (decl, vis);
16120 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16122 /* Reversal of FP compares takes care -- an ordered compare
16123 becomes an unordered compare and vice versa. */
16124 if (mode == CCFPmode
16125 && (!flag_finite_math_only
16126 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16127 || code == UNEQ || code == LTGT))
16128 return reverse_condition_maybe_unordered (code);
16130 return reverse_condition (code);
16133 /* Generate a compare for CODE. Return a brand-new rtx that
16134 represents the result of the compare. */
16137 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16139 enum machine_mode comp_mode;
16140 rtx compare_result;
16141 enum rtx_code code = GET_CODE (cmp);
16142 rtx op0 = XEXP (cmp, 0);
16143 rtx op1 = XEXP (cmp, 1);
16145 if (FLOAT_MODE_P (mode))
16146 comp_mode = CCFPmode;
16147 else if (code == GTU || code == LTU
16148 || code == GEU || code == LEU)
16149 comp_mode = CCUNSmode;
16150 else if ((code == EQ || code == NE)
16151 && GET_CODE (op0) == SUBREG
16152 && GET_CODE (op1) == SUBREG
16153 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16154 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16155 /* These are unsigned values, perhaps there will be a later
16156 ordering compare that can be shared with this one.
16157 Unfortunately we cannot detect the signedness of the operands
16158 for non-subregs. */
16159 comp_mode = CCUNSmode;
16161 comp_mode = CCmode;
16163 /* First, the compare. */
16164 compare_result = gen_reg_rtx (comp_mode);
16166 /* E500 FP compare instructions on the GPRs. Yuck! */
16167 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16168 && FLOAT_MODE_P (mode))
16170 rtx cmp, or_result, compare_result2;
16171 enum machine_mode op_mode = GET_MODE (op0);
16173 if (op_mode == VOIDmode)
16174 op_mode = GET_MODE (op1);
16176 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16177 This explains the following mess. */
16181 case EQ: case UNEQ: case NE: case LTGT:
16185 cmp = (flag_finite_math_only && !flag_trapping_math)
16186 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16187 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16191 cmp = (flag_finite_math_only && !flag_trapping_math)
16192 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16193 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16197 cmp = (flag_finite_math_only && !flag_trapping_math)
16198 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16199 : gen_cmptfeq_gpr (compare_result, op0, op1);
16203 gcc_unreachable ();
16207 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16211 cmp = (flag_finite_math_only && !flag_trapping_math)
16212 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16213 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16217 cmp = (flag_finite_math_only && !flag_trapping_math)
16218 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16219 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16223 cmp = (flag_finite_math_only && !flag_trapping_math)
16224 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16225 : gen_cmptfgt_gpr (compare_result, op0, op1);
16229 gcc_unreachable ();
16233 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16237 cmp = (flag_finite_math_only && !flag_trapping_math)
16238 ? gen_tstsflt_gpr (compare_result, op0, op1)
16239 : gen_cmpsflt_gpr (compare_result, op0, op1);
16243 cmp = (flag_finite_math_only && !flag_trapping_math)
16244 ? gen_tstdflt_gpr (compare_result, op0, op1)
16245 : gen_cmpdflt_gpr (compare_result, op0, op1);
16249 cmp = (flag_finite_math_only && !flag_trapping_math)
16250 ? gen_tsttflt_gpr (compare_result, op0, op1)
16251 : gen_cmptflt_gpr (compare_result, op0, op1);
16255 gcc_unreachable ();
16259 gcc_unreachable ();
16262 /* Synthesize LE and GE from LT/GT || EQ. */
16263 if (code == LE || code == GE || code == LEU || code == GEU)
16269 case LE: code = LT; break;
16270 case GE: code = GT; break;
16271 case LEU: code = LT; break;
16272 case GEU: code = GT; break;
16273 default: gcc_unreachable ();
16276 compare_result2 = gen_reg_rtx (CCFPmode);
16282 cmp = (flag_finite_math_only && !flag_trapping_math)
16283 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16284 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16288 cmp = (flag_finite_math_only && !flag_trapping_math)
16289 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16290 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16294 cmp = (flag_finite_math_only && !flag_trapping_math)
16295 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16296 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16300 gcc_unreachable ();
16304 /* OR them together. */
16305 or_result = gen_reg_rtx (CCFPmode);
16306 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16308 compare_result = or_result;
16313 if (code == NE || code == LTGT)
16323 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16324 CLOBBERs to match cmptf_internal2 pattern. */
16325 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16326 && GET_MODE (op0) == TFmode
16327 && !TARGET_IEEEQUAD
16328 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16329 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16331 gen_rtx_SET (VOIDmode,
16333 gen_rtx_COMPARE (comp_mode, op0, op1)),
16334 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16335 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16336 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16337 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16338 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16339 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16340 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16341 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16342 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16343 else if (GET_CODE (op1) == UNSPEC
16344 && XINT (op1, 1) == UNSPEC_SP_TEST)
16346 rtx op1b = XVECEXP (op1, 0, 0);
16347 comp_mode = CCEQmode;
16348 compare_result = gen_reg_rtx (CCEQmode);
16350 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16352 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16355 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16356 gen_rtx_COMPARE (comp_mode, op0, op1)));
16359 /* Some kinds of FP comparisons need an OR operation;
16360 under flag_finite_math_only we don't bother. */
16361 if (FLOAT_MODE_P (mode)
16362 && !flag_finite_math_only
16363 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16364 && (code == LE || code == GE
16365 || code == UNEQ || code == LTGT
16366 || code == UNGT || code == UNLT))
16368 enum rtx_code or1, or2;
16369 rtx or1_rtx, or2_rtx, compare2_rtx;
16370 rtx or_result = gen_reg_rtx (CCEQmode);
16374 case LE: or1 = LT; or2 = EQ; break;
16375 case GE: or1 = GT; or2 = EQ; break;
16376 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16377 case LTGT: or1 = LT; or2 = GT; break;
16378 case UNGT: or1 = UNORDERED; or2 = GT; break;
16379 case UNLT: or1 = UNORDERED; or2 = LT; break;
16380 default: gcc_unreachable ();
16382 validate_condition_mode (or1, comp_mode);
16383 validate_condition_mode (or2, comp_mode);
16384 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16385 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16386 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16387 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16389 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16391 compare_result = or_result;
16395 validate_condition_mode (code, GET_MODE (compare_result));
16397 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16401 /* Emit the RTL for an sISEL pattern. */
16404 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16406 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16410 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16413 enum machine_mode op_mode;
16414 enum rtx_code cond_code;
16415 rtx result = operands[0];
16417 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16419 rs6000_emit_sISEL (mode, operands);
16423 condition_rtx = rs6000_generate_compare (operands[1], mode);
16424 cond_code = GET_CODE (condition_rtx);
16426 if (FLOAT_MODE_P (mode)
16427 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16431 PUT_MODE (condition_rtx, SImode);
16432 t = XEXP (condition_rtx, 0);
16434 gcc_assert (cond_code == NE || cond_code == EQ);
16436 if (cond_code == NE)
16437 emit_insn (gen_e500_flip_gt_bit (t, t));
16439 emit_insn (gen_move_from_CR_gt_bit (result, t));
16443 if (cond_code == NE
16444 || cond_code == GE || cond_code == LE
16445 || cond_code == GEU || cond_code == LEU
16446 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16448 rtx not_result = gen_reg_rtx (CCEQmode);
16449 rtx not_op, rev_cond_rtx;
16450 enum machine_mode cc_mode;
16452 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16454 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16455 SImode, XEXP (condition_rtx, 0), const0_rtx);
16456 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16457 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16458 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16461 op_mode = GET_MODE (XEXP (operands[1], 0));
16462 if (op_mode == VOIDmode)
16463 op_mode = GET_MODE (XEXP (operands[1], 1));
16465 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16467 PUT_MODE (condition_rtx, DImode);
16468 convert_move (result, condition_rtx, 0);
16472 PUT_MODE (condition_rtx, SImode);
16473 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16477 /* Emit a branch of kind CODE to location LOC. */
16480 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16482 rtx condition_rtx, loc_ref;
16484 condition_rtx = rs6000_generate_compare (operands[0], mode);
16485 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16486 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16487 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16488 loc_ref, pc_rtx)));
16491 /* Return the string to output a conditional branch to LABEL, which is
16492 the operand number of the label, or -1 if the branch is really a
16493 conditional return.
16495 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16496 condition code register and its mode specifies what kind of
16497 comparison we made.
16499 REVERSED is nonzero if we should reverse the sense of the comparison.
16501 INSN is the insn. */
16504 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16506 static char string[64];
16507 enum rtx_code code = GET_CODE (op);
16508 rtx cc_reg = XEXP (op, 0);
16509 enum machine_mode mode = GET_MODE (cc_reg);
16510 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16511 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16512 int really_reversed = reversed ^ need_longbranch;
16518 validate_condition_mode (code, mode);
16520 /* Work out which way this really branches. We could use
16521 reverse_condition_maybe_unordered here always but this
16522 makes the resulting assembler clearer. */
16523 if (really_reversed)
16525 /* Reversal of FP compares takes care -- an ordered compare
16526 becomes an unordered compare and vice versa. */
16527 if (mode == CCFPmode)
16528 code = reverse_condition_maybe_unordered (code);
16530 code = reverse_condition (code);
16533 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16535 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16540 /* Opposite of GT. */
16549 gcc_unreachable ();
16555 /* Not all of these are actually distinct opcodes, but
16556 we distinguish them for clarity of the resulting assembler. */
16557 case NE: case LTGT:
16558 ccode = "ne"; break;
16559 case EQ: case UNEQ:
16560 ccode = "eq"; break;
16562 ccode = "ge"; break;
16563 case GT: case GTU: case UNGT:
16564 ccode = "gt"; break;
16566 ccode = "le"; break;
16567 case LT: case LTU: case UNLT:
16568 ccode = "lt"; break;
16569 case UNORDERED: ccode = "un"; break;
16570 case ORDERED: ccode = "nu"; break;
16571 case UNGE: ccode = "nl"; break;
16572 case UNLE: ccode = "ng"; break;
16574 gcc_unreachable ();
16577 /* Maybe we have a guess as to how likely the branch is.
16578 The old mnemonics don't have a way to specify this information. */
16580 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16581 if (note != NULL_RTX)
16583 /* PROB is the difference from 50%. */
16584 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16586 /* Only hint for highly probable/improbable branches on newer
16587 cpus as static prediction overrides processor dynamic
16588 prediction. For older cpus we may as well always hint, but
16589 assume not taken for branches that are very close to 50% as a
16590 mispredicted taken branch is more expensive than a
16591 mispredicted not-taken branch. */
16592 if (rs6000_always_hint
16593 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16594 && br_prob_note_reliable_p (note)))
16596 if (abs (prob) > REG_BR_PROB_BASE / 20
16597 && ((prob > 0) ^ need_longbranch))
16605 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16607 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16609 /* We need to escape any '%' characters in the reg_names string.
16610 Assume they'd only be the first character.... */
16611 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16613 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16617 /* If the branch distance was too far, we may have to use an
16618 unconditional branch to go the distance. */
16619 if (need_longbranch)
16620 s += sprintf (s, ",$+8\n\tb %s", label);
16622 s += sprintf (s, ",%s", label);
16628 /* Return the string to flip the GT bit on a CR. */
16630 output_e500_flip_gt_bit (rtx dst, rtx src)
16632 static char string[64];
16635 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16636 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16639 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16640 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16642 sprintf (string, "crnot %d,%d", a, b);
16646 /* Return insn for VSX or Altivec comparisons. */
16649 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16652 enum machine_mode mode = GET_MODE (op0);
16660 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16666 mask = gen_reg_rtx (mode);
16667 emit_insn (gen_rtx_SET (VOIDmode,
16669 gen_rtx_fmt_ee (code, mode, op0, op1)));
16676 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16677 DMODE is expected destination mode. This is a recursive function. */
16680 rs6000_emit_vector_compare (enum rtx_code rcode,
16682 enum machine_mode dmode)
16685 bool swap_operands = false;
16686 bool try_again = false;
16688 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16689 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16691 /* See if the comparison works as is. */
16692 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16700 swap_operands = true;
16705 swap_operands = true;
16713 /* Invert condition and try again.
16714 e.g., A != B becomes ~(A==B). */
16716 enum rtx_code rev_code;
16717 enum insn_code nor_code;
16720 rev_code = reverse_condition_maybe_unordered (rcode);
16721 if (rev_code == UNKNOWN)
16724 nor_code = optab_handler (one_cmpl_optab, dmode);
16725 if (nor_code == CODE_FOR_nothing)
16728 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16732 mask = gen_reg_rtx (dmode);
16733 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16741 /* Try GT/GTU/LT/LTU OR EQ */
16744 enum insn_code ior_code;
16745 enum rtx_code new_code;
16766 gcc_unreachable ();
16769 ior_code = optab_handler (ior_optab, dmode);
16770 if (ior_code == CODE_FOR_nothing)
16773 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16777 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16781 mask = gen_reg_rtx (dmode);
16782 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16800 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16805 /* You only get two chances. */
16809 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16810 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16811 operands for the relation operation COND. */
16814 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16815 rtx cond, rtx cc_op0, rtx cc_op1)
16817 enum machine_mode dest_mode = GET_MODE (dest);
16818 enum rtx_code rcode = GET_CODE (cond);
16819 enum machine_mode cc_mode = CCmode;
16823 bool invert_move = false;
16825 if (VECTOR_UNIT_NONE_P (dest_mode))
16830 /* Swap operands if we can, and fall back to doing the operation as
16831 specified, and doing a NOR to invert the test. */
16837 /* Invert condition and try again.
16838 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16839 invert_move = true;
16840 rcode = reverse_condition_maybe_unordered (rcode);
16841 if (rcode == UNKNOWN)
16845 /* Mark unsigned tests with CCUNSmode. */
16850 cc_mode = CCUNSmode;
16857 /* Get the vector mask for the given relational operations. */
16858 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16866 op_true = op_false;
16870 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
16871 emit_insn (gen_rtx_SET (VOIDmode,
16873 gen_rtx_IF_THEN_ELSE (dest_mode,
16880 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16881 operands of the last comparison is nonzero/true, FALSE_COND if it
16882 is zero/false. Return 0 if the hardware has no such operation. */
16885 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16887 enum rtx_code code = GET_CODE (op);
16888 rtx op0 = XEXP (op, 0);
16889 rtx op1 = XEXP (op, 1);
16890 REAL_VALUE_TYPE c1;
16891 enum machine_mode compare_mode = GET_MODE (op0);
16892 enum machine_mode result_mode = GET_MODE (dest);
16894 bool is_against_zero;
16896 /* These modes should always match. */
16897 if (GET_MODE (op1) != compare_mode
16898 /* In the isel case however, we can use a compare immediate, so
16899 op1 may be a small constant. */
16900 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16902 if (GET_MODE (true_cond) != result_mode)
16904 if (GET_MODE (false_cond) != result_mode)
16907 /* First, work out if the hardware can do this at all, or
16908 if it's too slow.... */
16909 if (!FLOAT_MODE_P (compare_mode))
16912 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16915 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16916 && SCALAR_FLOAT_MODE_P (compare_mode))
16919 is_against_zero = op1 == CONST0_RTX (compare_mode);
16921 /* A floating-point subtract might overflow, underflow, or produce
16922 an inexact result, thus changing the floating-point flags, so it
16923 can't be generated if we care about that. It's safe if one side
16924 of the construct is zero, since then no subtract will be
16926 if (SCALAR_FLOAT_MODE_P (compare_mode)
16927 && flag_trapping_math && ! is_against_zero)
16930 /* Eliminate half of the comparisons by switching operands, this
16931 makes the remaining code simpler. */
16932 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16933 || code == LTGT || code == LT || code == UNLE)
16935 code = reverse_condition_maybe_unordered (code);
16937 true_cond = false_cond;
16941 /* UNEQ and LTGT take four instructions for a comparison with zero,
16942 it'll probably be faster to use a branch here too. */
16943 if (code == UNEQ && HONOR_NANS (compare_mode))
16946 if (GET_CODE (op1) == CONST_DOUBLE)
16947 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16949 /* We're going to try to implement comparisons by performing
16950 a subtract, then comparing against zero. Unfortunately,
16951 Inf - Inf is NaN which is not zero, and so if we don't
16952 know that the operand is finite and the comparison
16953 would treat EQ different to UNORDERED, we can't do it. */
16954 if (HONOR_INFINITIES (compare_mode)
16955 && code != GT && code != UNGE
16956 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16957 /* Constructs of the form (a OP b ? a : b) are safe. */
16958 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16959 || (! rtx_equal_p (op0, true_cond)
16960 && ! rtx_equal_p (op1, true_cond))))
16963 /* At this point we know we can use fsel. */
16965 /* Reduce the comparison to a comparison against zero. */
16966 if (! is_against_zero)
16968 temp = gen_reg_rtx (compare_mode);
16969 emit_insn (gen_rtx_SET (VOIDmode, temp,
16970 gen_rtx_MINUS (compare_mode, op0, op1)));
16972 op1 = CONST0_RTX (compare_mode);
16975 /* If we don't care about NaNs we can reduce some of the comparisons
16976 down to faster ones. */
16977 if (! HONOR_NANS (compare_mode))
16983 true_cond = false_cond;
16996 /* Now, reduce everything down to a GE. */
17003 temp = gen_reg_rtx (compare_mode);
17004 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17009 temp = gen_reg_rtx (compare_mode);
17010 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17015 temp = gen_reg_rtx (compare_mode);
17016 emit_insn (gen_rtx_SET (VOIDmode, temp,
17017 gen_rtx_NEG (compare_mode,
17018 gen_rtx_ABS (compare_mode, op0))));
17023 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17024 temp = gen_reg_rtx (result_mode);
17025 emit_insn (gen_rtx_SET (VOIDmode, temp,
17026 gen_rtx_IF_THEN_ELSE (result_mode,
17027 gen_rtx_GE (VOIDmode,
17029 true_cond, false_cond)));
17030 false_cond = true_cond;
17033 temp = gen_reg_rtx (compare_mode);
17034 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17039 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17040 temp = gen_reg_rtx (result_mode);
17041 emit_insn (gen_rtx_SET (VOIDmode, temp,
17042 gen_rtx_IF_THEN_ELSE (result_mode,
17043 gen_rtx_GE (VOIDmode,
17045 true_cond, false_cond)));
17046 true_cond = false_cond;
17049 temp = gen_reg_rtx (compare_mode);
17050 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17055 gcc_unreachable ();
17058 emit_insn (gen_rtx_SET (VOIDmode, dest,
17059 gen_rtx_IF_THEN_ELSE (result_mode,
17060 gen_rtx_GE (VOIDmode,
17062 true_cond, false_cond)));
17066 /* Same as above, but for ints (isel). */
17069 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17071 rtx condition_rtx, cr;
17072 enum machine_mode mode = GET_MODE (dest);
17073 enum rtx_code cond_code;
17074 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17077 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17080 /* We still have to do the compare, because isel doesn't do a
17081 compare, it just looks at the CRx bits set by a previous compare
17083 condition_rtx = rs6000_generate_compare (op, mode);
17084 cond_code = GET_CODE (condition_rtx);
17085 cr = XEXP (condition_rtx, 0);
17086 signedp = GET_MODE (cr) == CCmode;
17088 isel_func = (mode == SImode
17089 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17090 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17094 case LT: case GT: case LTU: case GTU: case EQ:
17095 /* isel handles these directly. */
17099 /* We need to swap the sense of the comparison. */
17102 true_cond = false_cond;
17104 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17109 false_cond = force_reg (mode, false_cond);
17110 if (true_cond != const0_rtx)
17111 true_cond = force_reg (mode, true_cond);
17113 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17119 output_isel (rtx *operands)
17121 enum rtx_code code;
17123 code = GET_CODE (operands[1]);
17125 gcc_assert (!(code == GE || code == GEU || code == LE || code == LEU || code == NE));
17127 return "isel %0,%2,%3,%j1";
17131 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17133 enum machine_mode mode = GET_MODE (op0);
17137 /* VSX/altivec have direct min/max insns. */
17138 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
17140 emit_insn (gen_rtx_SET (VOIDmode,
17142 gen_rtx_fmt_ee (code, mode, op0, op1)));
17146 if (code == SMAX || code == SMIN)
17151 if (code == SMAX || code == UMAX)
17152 target = emit_conditional_move (dest, c, op0, op1, mode,
17153 op0, op1, mode, 0);
17155 target = emit_conditional_move (dest, c, op0, op1, mode,
17156 op1, op0, mode, 0);
17157 gcc_assert (target);
17158 if (target != dest)
17159 emit_move_insn (dest, target);
17162 /* Emit instructions to perform a load-reserved/store-conditional operation.
17163 The operation performed is an atomic
17164 (set M (CODE:MODE M OP))
17165 If not NULL, BEFORE is atomically set to M before the operation, and
17166 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17167 If SYNC_P then a memory barrier is emitted before the operation.
17168 Either OP or M may be wrapped in a NOT operation. */
17171 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17172 rtx m, rtx op, rtx before_param, rtx after_param,
17175 enum machine_mode used_mode;
17176 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17179 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17180 rtx shift = NULL_RTX;
17183 emit_insn (gen_lwsync ());
17187 /* If this is smaller than SImode, we'll have to use SImode with
17189 if (mode == QImode || mode == HImode)
17193 if (MEM_ALIGN (used_m) >= 32)
17196 if (BYTES_BIG_ENDIAN)
17197 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17199 shift = GEN_INT (ishift);
17200 used_m = change_address (used_m, SImode, 0);
17204 rtx addrSI, aligned_addr;
17205 int shift_mask = mode == QImode ? 0x18 : 0x10;
17207 addrSI = gen_lowpart_common (SImode,
17208 force_reg (Pmode, XEXP (used_m, 0)));
17209 addrSI = force_reg (SImode, addrSI);
17210 shift = gen_reg_rtx (SImode);
17212 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17213 GEN_INT (shift_mask)));
17214 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17216 aligned_addr = expand_binop (Pmode, and_optab,
17218 GEN_INT (-4), NULL_RTX,
17219 1, OPTAB_LIB_WIDEN);
17220 used_m = change_address (used_m, SImode, aligned_addr);
17221 set_mem_align (used_m, 32);
17223 /* It's safe to keep the old alias set of USED_M, because
17224 the operation is atomic and only affects the original
17228 if (GET_CODE (op) == NOT)
17230 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17231 oldop = gen_rtx_NOT (SImode, oldop);
17234 oldop = lowpart_subreg (SImode, op, mode);
17240 newop = expand_binop (SImode, and_optab,
17241 oldop, GEN_INT (imask), NULL_RTX,
17242 1, OPTAB_LIB_WIDEN);
17243 emit_insn (gen_ashlsi3 (newop, newop, shift));
17246 case NOT: /* NAND */
17247 newop = expand_binop (SImode, ior_optab,
17248 oldop, GEN_INT (~imask), NULL_RTX,
17249 1, OPTAB_LIB_WIDEN);
17250 emit_insn (gen_rotlsi3 (newop, newop, shift));
17254 newop = expand_binop (SImode, ior_optab,
17255 oldop, GEN_INT (~imask), NULL_RTX,
17256 1, OPTAB_LIB_WIDEN);
17257 emit_insn (gen_rotlsi3 (newop, newop, shift));
17265 newop = expand_binop (SImode, and_optab,
17266 oldop, GEN_INT (imask), NULL_RTX,
17267 1, OPTAB_LIB_WIDEN);
17268 emit_insn (gen_ashlsi3 (newop, newop, shift));
17270 mask = gen_reg_rtx (SImode);
17271 emit_move_insn (mask, GEN_INT (imask));
17272 emit_insn (gen_ashlsi3 (mask, mask, shift));
17275 newop = gen_rtx_PLUS (SImode, m, newop);
17277 newop = gen_rtx_MINUS (SImode, m, newop);
17278 newop = gen_rtx_AND (SImode, newop, mask);
17279 newop = gen_rtx_IOR (SImode, newop,
17280 gen_rtx_AND (SImode,
17281 gen_rtx_NOT (SImode, mask),
17287 gcc_unreachable ();
17291 used_mode = SImode;
17292 before = gen_reg_rtx (used_mode);
17293 after = gen_reg_rtx (used_mode);
17298 before = before_param;
17299 after = after_param;
17301 if (before == NULL_RTX)
17302 before = gen_reg_rtx (used_mode);
17303 if (after == NULL_RTX)
17304 after = gen_reg_rtx (used_mode);
17307 if ((code == PLUS || code == MINUS)
17308 && used_mode != mode)
17309 the_op = op; /* Computed above. */
17310 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17311 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17312 else if (code == NOT)
17313 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17314 gen_rtx_NOT (used_mode, m),
17315 gen_rtx_NOT (used_mode, op));
17317 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17319 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17320 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17321 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17322 gen_rtx_UNSPEC (used_mode,
17323 gen_rtvec (1, the_op),
17325 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17327 if ((code == PLUS || code == MINUS) && used_mode != mode)
17328 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17329 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17331 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17332 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17334 /* Shift and mask the return values properly. */
17335 if (used_mode != mode && before_param)
17337 emit_insn (gen_lshrsi3 (before, before, shift));
17338 convert_move (before_param, before, 1);
17341 if (used_mode != mode && after_param)
17343 emit_insn (gen_lshrsi3 (after, after, shift));
17344 convert_move (after_param, after, 1);
17347 /* The previous sequence will end with a branch that's dependent on
17348 the conditional store, so placing an isync will ensure that no
17349 other instructions (especially, no load or store instructions)
17350 can start before the atomic operation completes. */
17352 emit_insn (gen_isync ());
17355 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17356 COND is true. Mark the jump as unlikely to be taken. */
17359 emit_unlikely_jump (rtx cond, rtx label)
17361 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17364 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17365 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17366 add_reg_note (x, REG_BR_PROB, very_unlikely);
17369 /* A subroutine of the atomic operation splitters. Emit a load-locked
17370 instruction in MODE. */
17373 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17375 rtx (*fn) (rtx, rtx) = NULL;
17376 if (mode == SImode)
17377 fn = gen_load_locked_si;
17378 else if (mode == DImode)
17379 fn = gen_load_locked_di;
17380 emit_insn (fn (reg, mem));
17383 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17384 instruction in MODE. */
17387 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17389 rtx (*fn) (rtx, rtx, rtx) = NULL;
17390 if (mode == SImode)
17391 fn = gen_store_conditional_si;
17392 else if (mode == DImode)
17393 fn = gen_store_conditional_di;
17395 /* Emit sync before stwcx. to address PPC405 Erratum. */
17396 if (PPC405_ERRATUM77)
17397 emit_insn (gen_memory_barrier ());
17399 emit_insn (fn (res, mem, val));
17402 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17403 to perform. MEM is the memory on which to operate. VAL is the second
17404 operand of the binary operator. BEFORE and AFTER are optional locations to
17405 return the value of MEM either before of after the operation. SCRATCH is
17406 a scratch register. */
17409 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17410 rtx before, rtx after, rtx scratch)
17412 enum machine_mode mode = GET_MODE (mem);
17413 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17415 emit_insn (gen_lwsync ());
17417 label = gen_label_rtx ();
17418 emit_label (label);
17419 label = gen_rtx_LABEL_REF (VOIDmode, label);
17421 if (before == NULL_RTX)
17423 emit_load_locked (mode, before, mem);
17426 x = gen_rtx_IOR (mode,
17427 gen_rtx_NOT (mode, before),
17428 gen_rtx_NOT (mode, val));
17429 else if (code == AND)
17430 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17432 x = gen_rtx_fmt_ee (code, mode, before, val);
17434 if (after != NULL_RTX)
17435 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17436 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17438 emit_store_conditional (mode, cond, mem, scratch);
17440 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17441 emit_unlikely_jump (x, label);
17443 emit_insn (gen_isync ());
17446 /* Expand an atomic compare and swap operation. MEM is the memory on which
17447 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17448 value to be stored. SCRATCH is a scratch GPR. */
17451 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17454 enum machine_mode mode = GET_MODE (mem);
17455 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17457 emit_insn (gen_lwsync ());
17459 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17460 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17461 emit_label (XEXP (label1, 0));
17463 emit_load_locked (mode, retval, mem);
17465 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17466 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17468 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17469 emit_unlikely_jump (x, label2);
17471 emit_move_insn (scratch, newval);
17472 emit_store_conditional (mode, cond, mem, scratch);
17474 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17475 emit_unlikely_jump (x, label1);
17477 emit_insn (gen_isync ());
17478 emit_label (XEXP (label2, 0));
17481 /* Expand an atomic test and set operation. MEM is the memory on which
17482 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17485 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17487 enum machine_mode mode = GET_MODE (mem);
17488 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17490 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17491 emit_label (XEXP (label, 0));
17493 emit_load_locked (mode, retval, mem);
17494 emit_move_insn (scratch, val);
17495 emit_store_conditional (mode, cond, mem, scratch);
17497 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17498 emit_unlikely_jump (x, label);
17500 emit_insn (gen_isync ());
17504 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17506 enum machine_mode mode = GET_MODE (mem);
17507 rtx addrSI, align, wdst, shift, mask;
17508 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17509 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17511 /* Shift amount for subword relative to aligned word. */
17512 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17513 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17514 shift = gen_reg_rtx (SImode);
17515 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17516 GEN_INT (shift_mask)));
17517 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17519 /* Shift and mask old value into position within word. */
17520 oldval = convert_modes (SImode, mode, oldval, 1);
17521 oldval = expand_binop (SImode, and_optab,
17522 oldval, GEN_INT (imask), NULL_RTX,
17523 1, OPTAB_LIB_WIDEN);
17524 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17526 /* Shift and mask new value into position within word. */
17527 newval = convert_modes (SImode, mode, newval, 1);
17528 newval = expand_binop (SImode, and_optab,
17529 newval, GEN_INT (imask), NULL_RTX,
17530 1, OPTAB_LIB_WIDEN);
17531 emit_insn (gen_ashlsi3 (newval, newval, shift));
17533 /* Mask for insertion. */
17534 mask = gen_reg_rtx (SImode);
17535 emit_move_insn (mask, GEN_INT (imask));
17536 emit_insn (gen_ashlsi3 (mask, mask, shift));
17538 /* Address of aligned word containing subword. */
17539 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17540 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17541 mem = change_address (mem, SImode, align);
17542 set_mem_align (mem, 32);
17543 MEM_VOLATILE_P (mem) = 1;
17545 wdst = gen_reg_rtx (SImode);
17546 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17547 oldval, newval, mem));
17549 /* Shift the result back. */
17550 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17552 emit_move_insn (dst, gen_lowpart (mode, wdst));
17556 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17557 rtx oldval, rtx newval, rtx mem,
17560 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17562 emit_insn (gen_lwsync ());
17563 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17564 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17565 emit_label (XEXP (label1, 0));
17567 emit_load_locked (SImode, scratch, mem);
17569 /* Mask subword within loaded value for comparison with oldval.
17570 Use UNSPEC_AND to avoid clobber.*/
17571 emit_insn (gen_rtx_SET (SImode, dest,
17572 gen_rtx_UNSPEC (SImode,
17573 gen_rtvec (2, scratch, mask),
17576 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17577 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17579 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17580 emit_unlikely_jump (x, label2);
17582 /* Clear subword within loaded value for insertion of new value. */
17583 emit_insn (gen_rtx_SET (SImode, scratch,
17584 gen_rtx_AND (SImode,
17585 gen_rtx_NOT (SImode, mask), scratch)));
17586 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17587 emit_store_conditional (SImode, cond, mem, scratch);
17589 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17590 emit_unlikely_jump (x, label1);
17592 emit_insn (gen_isync ());
17593 emit_label (XEXP (label2, 0));
17597 /* Emit instructions to move SRC to DST. Called by splitters for
17598 multi-register moves. It will emit at most one instruction for
17599 each register that is accessed; that is, it won't emit li/lis pairs
17600 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17604 rs6000_split_multireg_move (rtx dst, rtx src)
17606 /* The register number of the first register being moved. */
17608 /* The mode that is to be moved. */
17609 enum machine_mode mode;
17610 /* The mode that the move is being done in, and its size. */
17611 enum machine_mode reg_mode;
17613 /* The number of registers that will be moved. */
17616 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17617 mode = GET_MODE (dst);
17618 nregs = hard_regno_nregs[reg][mode];
17619 if (FP_REGNO_P (reg))
17620 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17621 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17622 else if (ALTIVEC_REGNO_P (reg))
17623 reg_mode = V16QImode;
17624 else if (TARGET_E500_DOUBLE && mode == TFmode)
17627 reg_mode = word_mode;
17628 reg_mode_size = GET_MODE_SIZE (reg_mode);
17630 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17632 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17634 /* Move register range backwards, if we might have destructive
17637 for (i = nregs - 1; i >= 0; i--)
17638 emit_insn (gen_rtx_SET (VOIDmode,
17639 simplify_gen_subreg (reg_mode, dst, mode,
17640 i * reg_mode_size),
17641 simplify_gen_subreg (reg_mode, src, mode,
17642 i * reg_mode_size)));
17648 bool used_update = false;
17649 rtx restore_basereg = NULL_RTX;
17651 if (MEM_P (src) && INT_REGNO_P (reg))
17655 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17656 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17659 breg = XEXP (XEXP (src, 0), 0);
17660 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17661 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17662 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17663 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17664 src = replace_equiv_address (src, breg);
17666 else if (! rs6000_offsettable_memref_p (src))
17668 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17670 rtx basereg = XEXP (XEXP (src, 0), 0);
17673 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17674 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17675 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17676 used_update = true;
17679 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17680 XEXP (XEXP (src, 0), 1)));
17681 src = replace_equiv_address (src, basereg);
17685 rtx basereg = gen_rtx_REG (Pmode, reg);
17686 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17687 src = replace_equiv_address (src, basereg);
17691 breg = XEXP (src, 0);
17692 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17693 breg = XEXP (breg, 0);
17695 /* If the base register we are using to address memory is
17696 also a destination reg, then change that register last. */
17698 && REGNO (breg) >= REGNO (dst)
17699 && REGNO (breg) < REGNO (dst) + nregs)
17700 j = REGNO (breg) - REGNO (dst);
17702 else if (MEM_P (dst) && INT_REGNO_P (reg))
17706 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17707 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17710 breg = XEXP (XEXP (dst, 0), 0);
17711 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17712 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17713 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17715 /* We have to update the breg before doing the store.
17716 Use store with update, if available. */
17720 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17721 emit_insn (TARGET_32BIT
17722 ? (TARGET_POWERPC64
17723 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17724 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17725 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17726 used_update = true;
17729 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17730 dst = replace_equiv_address (dst, breg);
17732 else if (!rs6000_offsettable_memref_p (dst)
17733 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17735 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17737 rtx basereg = XEXP (XEXP (dst, 0), 0);
17740 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17741 emit_insn (gen_rtx_SET (VOIDmode,
17742 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17743 used_update = true;
17746 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17747 XEXP (XEXP (dst, 0), 1)));
17748 dst = replace_equiv_address (dst, basereg);
17752 rtx basereg = XEXP (XEXP (dst, 0), 0);
17753 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17754 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17756 && REG_P (offsetreg)
17757 && REGNO (basereg) != REGNO (offsetreg));
17758 if (REGNO (basereg) == 0)
17760 rtx tmp = offsetreg;
17761 offsetreg = basereg;
17764 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17765 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17766 dst = replace_equiv_address (dst, basereg);
17769 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17770 gcc_assert (rs6000_offsettable_memref_p (dst));
17773 for (i = 0; i < nregs; i++)
17775 /* Calculate index to next subword. */
17780 /* If compiler already emitted move of first word by
17781 store with update, no need to do anything. */
17782 if (j == 0 && used_update)
17785 emit_insn (gen_rtx_SET (VOIDmode,
17786 simplify_gen_subreg (reg_mode, dst, mode,
17787 j * reg_mode_size),
17788 simplify_gen_subreg (reg_mode, src, mode,
17789 j * reg_mode_size)));
17791 if (restore_basereg != NULL_RTX)
17792 emit_insn (restore_basereg);
17797 /* This page contains routines that are used to determine what the
17798 function prologue and epilogue code will do and write them out. */
17800 /* Return the first fixed-point register that is required to be
17801 saved. 32 if none. */
17804 first_reg_to_save (void)
17808 /* Find lowest numbered live register. */
17809 for (first_reg = 13; first_reg <= 31; first_reg++)
17810 if (df_regs_ever_live_p (first_reg)
17811 && (! call_used_regs[first_reg]
17812 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17813 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17814 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17815 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17820 && crtl->uses_pic_offset_table
17821 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17822 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17828 /* Similar, for FP regs. */
17831 first_fp_reg_to_save (void)
17835 /* Find lowest numbered live register. */
17836 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17837 if (df_regs_ever_live_p (first_reg))
17843 /* Similar, for AltiVec regs. */
17846 first_altivec_reg_to_save (void)
17850 /* Stack frame remains as is unless we are in AltiVec ABI. */
17851 if (! TARGET_ALTIVEC_ABI)
17852 return LAST_ALTIVEC_REGNO + 1;
17854 /* On Darwin, the unwind routines are compiled without
17855 TARGET_ALTIVEC, and use save_world to save/restore the
17856 altivec registers when necessary. */
17857 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17858 && ! TARGET_ALTIVEC)
17859 return FIRST_ALTIVEC_REGNO + 20;
17861 /* Find lowest numbered live register. */
17862 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17863 if (df_regs_ever_live_p (i))
17869 /* Return a 32-bit mask of the AltiVec registers we need to set in
17870 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17871 the 32-bit word is 0. */
17873 static unsigned int
17874 compute_vrsave_mask (void)
17876 unsigned int i, mask = 0;
17878 /* On Darwin, the unwind routines are compiled without
17879 TARGET_ALTIVEC, and use save_world to save/restore the
17880 call-saved altivec registers when necessary. */
17881 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17882 && ! TARGET_ALTIVEC)
17885 /* First, find out if we use _any_ altivec registers. */
17886 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17887 if (df_regs_ever_live_p (i))
17888 mask |= ALTIVEC_REG_BIT (i);
17893 /* Next, remove the argument registers from the set. These must
17894 be in the VRSAVE mask set by the caller, so we don't need to add
17895 them in again. More importantly, the mask we compute here is
17896 used to generate CLOBBERs in the set_vrsave insn, and we do not
17897 wish the argument registers to die. */
17898 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17899 mask &= ~ALTIVEC_REG_BIT (i);
17901 /* Similarly, remove the return value from the set. */
17904 diddle_return_value (is_altivec_return_reg, &yes);
17906 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17912 /* For a very restricted set of circumstances, we can cut down the
17913 size of prologues/epilogues by calling our own save/restore-the-world
17917 compute_save_world_info (rs6000_stack_t *info_ptr)
17919 info_ptr->world_save_p = 1;
17920 info_ptr->world_save_p
17921 = (WORLD_SAVE_P (info_ptr)
17922 && DEFAULT_ABI == ABI_DARWIN
17923 && ! (cfun->calls_setjmp && flag_exceptions)
17924 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17925 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17926 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17927 && info_ptr->cr_save_p);
17929 /* This will not work in conjunction with sibcalls. Make sure there
17930 are none. (This check is expensive, but seldom executed.) */
17931 if (WORLD_SAVE_P (info_ptr))
17934 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17935 if ( GET_CODE (insn) == CALL_INSN
17936 && SIBLING_CALL_P (insn))
17938 info_ptr->world_save_p = 0;
17943 if (WORLD_SAVE_P (info_ptr))
17945 /* Even if we're not touching VRsave, make sure there's room on the
17946 stack for it, if it looks like we're calling SAVE_WORLD, which
17947 will attempt to save it. */
17948 info_ptr->vrsave_size = 4;
17950 /* If we are going to save the world, we need to save the link register too. */
17951 info_ptr->lr_save_p = 1;
17953 /* "Save" the VRsave register too if we're saving the world. */
17954 if (info_ptr->vrsave_mask == 0)
17955 info_ptr->vrsave_mask = compute_vrsave_mask ();
17957 /* Because the Darwin register save/restore routines only handle
17958 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17960 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17961 && (info_ptr->first_altivec_reg_save
17962 >= FIRST_SAVED_ALTIVEC_REGNO));
17969 is_altivec_return_reg (rtx reg, void *xyes)
17971 bool *yes = (bool *) xyes;
17972 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17977 /* Calculate the stack information for the current function. This is
17978 complicated by having two separate calling sequences, the AIX calling
17979 sequence and the V.4 calling sequence.
17981 AIX (and Darwin/Mac OS X) stack frames look like:
17983 SP----> +---------------------------------------+
17984 | back chain to caller | 0 0
17985 +---------------------------------------+
17986 | saved CR | 4 8 (8-11)
17987 +---------------------------------------+
17989 +---------------------------------------+
17990 | reserved for compilers | 12 24
17991 +---------------------------------------+
17992 | reserved for binders | 16 32
17993 +---------------------------------------+
17994 | saved TOC pointer | 20 40
17995 +---------------------------------------+
17996 | Parameter save area (P) | 24 48
17997 +---------------------------------------+
17998 | Alloca space (A) | 24+P etc.
17999 +---------------------------------------+
18000 | Local variable space (L) | 24+P+A
18001 +---------------------------------------+
18002 | Float/int conversion temporary (X) | 24+P+A+L
18003 +---------------------------------------+
18004 | Save area for AltiVec registers (W) | 24+P+A+L+X
18005 +---------------------------------------+
18006 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18007 +---------------------------------------+
18008 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18009 +---------------------------------------+
18010 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18011 +---------------------------------------+
18012 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18013 +---------------------------------------+
18014 old SP->| back chain to caller's caller |
18015 +---------------------------------------+
18017 The required alignment for AIX configurations is two words (i.e., 8
18021 V.4 stack frames look like:
18023 SP----> +---------------------------------------+
18024 | back chain to caller | 0
18025 +---------------------------------------+
18026 | caller's saved LR | 4
18027 +---------------------------------------+
18028 | Parameter save area (P) | 8
18029 +---------------------------------------+
18030 | Alloca space (A) | 8+P
18031 +---------------------------------------+
18032 | Varargs save area (V) | 8+P+A
18033 +---------------------------------------+
18034 | Local variable space (L) | 8+P+A+V
18035 +---------------------------------------+
18036 | Float/int conversion temporary (X) | 8+P+A+V+L
18037 +---------------------------------------+
18038 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18039 +---------------------------------------+
18040 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18041 +---------------------------------------+
18042 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18043 +---------------------------------------+
18044 | SPE: area for 64-bit GP registers |
18045 +---------------------------------------+
18046 | SPE alignment padding |
18047 +---------------------------------------+
18048 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18049 +---------------------------------------+
18050 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18051 +---------------------------------------+
18052 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18053 +---------------------------------------+
18054 old SP->| back chain to caller's caller |
18055 +---------------------------------------+
18057 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18058 given. (But note below and in sysv4.h that we require only 8 and
18059 may round up the size of our stack frame anyways. The historical
18060 reason is early versions of powerpc-linux which didn't properly
18061 align the stack at program startup. A happy side-effect is that
18062 -mno-eabi libraries can be used with -meabi programs.)
18064 The EABI configuration defaults to the V.4 layout. However,
18065 the stack alignment requirements may differ. If -mno-eabi is not
18066 given, the required stack alignment is 8 bytes; if -mno-eabi is
18067 given, the required alignment is 16 bytes. (But see V.4 comment
18070 #ifndef ABI_STACK_BOUNDARY
18071 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18074 static rs6000_stack_t *
18075 rs6000_stack_info (void)
18077 static rs6000_stack_t info;
18078 rs6000_stack_t *info_ptr = &info;
18079 int reg_size = TARGET_32BIT ? 4 : 8;
18083 HOST_WIDE_INT non_fixed_size;
18085 memset (&info, 0, sizeof (info));
18089 /* Cache value so we don't rescan instruction chain over and over. */
18090 if (cfun->machine->insn_chain_scanned_p == 0)
18091 cfun->machine->insn_chain_scanned_p
18092 = spe_func_has_64bit_regs_p () + 1;
18093 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18096 /* Select which calling sequence. */
18097 info_ptr->abi = DEFAULT_ABI;
18099 /* Calculate which registers need to be saved & save area size. */
18100 info_ptr->first_gp_reg_save = first_reg_to_save ();
18101 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18102 even if it currently looks like we won't. Reload may need it to
18103 get at a constant; if so, it will have already created a constant
18104 pool entry for it. */
18105 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18106 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18107 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18108 && crtl->uses_const_pool
18109 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18110 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18112 first_gp = info_ptr->first_gp_reg_save;
18114 info_ptr->gp_size = reg_size * (32 - first_gp);
18116 /* For the SPE, we have an additional upper 32-bits on each GPR.
18117 Ideally we should save the entire 64-bits only when the upper
18118 half is used in SIMD instructions. Since we only record
18119 registers live (not the size they are used in), this proves
18120 difficult because we'd have to traverse the instruction chain at
18121 the right time, taking reload into account. This is a real pain,
18122 so we opt to save the GPRs in 64-bits always if but one register
18123 gets used in 64-bits. Otherwise, all the registers in the frame
18124 get saved in 32-bits.
18126 So... since when we save all GPRs (except the SP) in 64-bits, the
18127 traditional GP save area will be empty. */
18128 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18129 info_ptr->gp_size = 0;
18131 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18132 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18134 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18135 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18136 - info_ptr->first_altivec_reg_save);
18138 /* Does this function call anything? */
18139 info_ptr->calls_p = (! current_function_is_leaf
18140 || cfun->machine->ra_needs_full_frame);
18142 /* Determine if we need to save the link register. */
18143 if ((DEFAULT_ABI == ABI_AIX
18145 && !TARGET_PROFILE_KERNEL)
18146 #ifdef TARGET_RELOCATABLE
18147 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18149 || (info_ptr->first_fp_reg_save != 64
18150 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
18151 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18152 || info_ptr->calls_p
18153 || rs6000_ra_ever_killed ())
18155 info_ptr->lr_save_p = 1;
18156 df_set_regs_ever_live (LR_REGNO, true);
18159 /* Determine if we need to save the condition code registers. */
18160 if (df_regs_ever_live_p (CR2_REGNO)
18161 || df_regs_ever_live_p (CR3_REGNO)
18162 || df_regs_ever_live_p (CR4_REGNO))
18164 info_ptr->cr_save_p = 1;
18165 if (DEFAULT_ABI == ABI_V4)
18166 info_ptr->cr_size = reg_size;
18169 /* If the current function calls __builtin_eh_return, then we need
18170 to allocate stack space for registers that will hold data for
18171 the exception handler. */
18172 if (crtl->calls_eh_return)
18175 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18178 /* SPE saves EH registers in 64-bits. */
18179 ehrd_size = i * (TARGET_SPE_ABI
18180 && info_ptr->spe_64bit_regs_used != 0
18181 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18186 /* Determine various sizes. */
18187 info_ptr->reg_size = reg_size;
18188 info_ptr->fixed_size = RS6000_SAVE_AREA;
18189 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18190 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18191 TARGET_ALTIVEC ? 16 : 8);
18192 if (FRAME_GROWS_DOWNWARD)
18193 info_ptr->vars_size
18194 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18195 + info_ptr->parm_size,
18196 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18197 - (info_ptr->fixed_size + info_ptr->vars_size
18198 + info_ptr->parm_size);
18200 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18201 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18203 info_ptr->spe_gp_size = 0;
18205 if (TARGET_ALTIVEC_ABI)
18206 info_ptr->vrsave_mask = compute_vrsave_mask ();
18208 info_ptr->vrsave_mask = 0;
18210 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18211 info_ptr->vrsave_size = 4;
18213 info_ptr->vrsave_size = 0;
18215 compute_save_world_info (info_ptr);
18217 /* Calculate the offsets. */
18218 switch (DEFAULT_ABI)
18222 gcc_unreachable ();
18226 info_ptr->fp_save_offset = - info_ptr->fp_size;
18227 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18229 if (TARGET_ALTIVEC_ABI)
18231 info_ptr->vrsave_save_offset
18232 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18234 /* Align stack so vector save area is on a quadword boundary.
18235 The padding goes above the vectors. */
18236 if (info_ptr->altivec_size != 0)
18237 info_ptr->altivec_padding_size
18238 = info_ptr->vrsave_save_offset & 0xF;
18240 info_ptr->altivec_padding_size = 0;
18242 info_ptr->altivec_save_offset
18243 = info_ptr->vrsave_save_offset
18244 - info_ptr->altivec_padding_size
18245 - info_ptr->altivec_size;
18246 gcc_assert (info_ptr->altivec_size == 0
18247 || info_ptr->altivec_save_offset % 16 == 0);
18249 /* Adjust for AltiVec case. */
18250 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18253 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18254 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18255 info_ptr->lr_save_offset = 2*reg_size;
18259 info_ptr->fp_save_offset = - info_ptr->fp_size;
18260 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18261 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18263 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18265 /* Align stack so SPE GPR save area is aligned on a
18266 double-word boundary. */
18267 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18268 info_ptr->spe_padding_size
18269 = 8 - (-info_ptr->cr_save_offset % 8);
18271 info_ptr->spe_padding_size = 0;
18273 info_ptr->spe_gp_save_offset
18274 = info_ptr->cr_save_offset
18275 - info_ptr->spe_padding_size
18276 - info_ptr->spe_gp_size;
18278 /* Adjust for SPE case. */
18279 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18281 else if (TARGET_ALTIVEC_ABI)
18283 info_ptr->vrsave_save_offset
18284 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18286 /* Align stack so vector save area is on a quadword boundary. */
18287 if (info_ptr->altivec_size != 0)
18288 info_ptr->altivec_padding_size
18289 = 16 - (-info_ptr->vrsave_save_offset % 16);
18291 info_ptr->altivec_padding_size = 0;
18293 info_ptr->altivec_save_offset
18294 = info_ptr->vrsave_save_offset
18295 - info_ptr->altivec_padding_size
18296 - info_ptr->altivec_size;
18298 /* Adjust for AltiVec case. */
18299 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18302 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18303 info_ptr->ehrd_offset -= ehrd_size;
18304 info_ptr->lr_save_offset = reg_size;
18308 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18309 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18310 + info_ptr->gp_size
18311 + info_ptr->altivec_size
18312 + info_ptr->altivec_padding_size
18313 + info_ptr->spe_gp_size
18314 + info_ptr->spe_padding_size
18316 + info_ptr->cr_size
18317 + info_ptr->vrsave_size,
18320 non_fixed_size = (info_ptr->vars_size
18321 + info_ptr->parm_size
18322 + info_ptr->save_size);
18324 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18325 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18327 /* Determine if we need to allocate any stack frame:
18329 For AIX we need to push the stack if a frame pointer is needed
18330 (because the stack might be dynamically adjusted), if we are
18331 debugging, if we make calls, or if the sum of fp_save, gp_save,
18332 and local variables are more than the space needed to save all
18333 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18334 + 18*8 = 288 (GPR13 reserved).
18336 For V.4 we don't have the stack cushion that AIX uses, but assume
18337 that the debugger can handle stackless frames. */
18339 if (info_ptr->calls_p)
18340 info_ptr->push_p = 1;
18342 else if (DEFAULT_ABI == ABI_V4)
18343 info_ptr->push_p = non_fixed_size != 0;
18345 else if (frame_pointer_needed)
18346 info_ptr->push_p = 1;
18348 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18349 info_ptr->push_p = 1;
18352 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18354 /* Zero offsets if we're not saving those registers. */
18355 if (info_ptr->fp_size == 0)
18356 info_ptr->fp_save_offset = 0;
18358 if (info_ptr->gp_size == 0)
18359 info_ptr->gp_save_offset = 0;
18361 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18362 info_ptr->altivec_save_offset = 0;
18364 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18365 info_ptr->vrsave_save_offset = 0;
18367 if (! TARGET_SPE_ABI
18368 || info_ptr->spe_64bit_regs_used == 0
18369 || info_ptr->spe_gp_size == 0)
18370 info_ptr->spe_gp_save_offset = 0;
18372 if (! info_ptr->lr_save_p)
18373 info_ptr->lr_save_offset = 0;
18375 if (! info_ptr->cr_save_p)
18376 info_ptr->cr_save_offset = 0;
18381 /* Return true if the current function uses any GPRs in 64-bit SIMD
18385 spe_func_has_64bit_regs_p (void)
18389 /* Functions that save and restore all the call-saved registers will
18390 need to save/restore the registers in 64-bits. */
18391 if (crtl->calls_eh_return
18392 || cfun->calls_setjmp
18393 || crtl->has_nonlocal_goto)
18396 insns = get_insns ();
18398 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18404 /* FIXME: This should be implemented with attributes...
18406 (set_attr "spe64" "true")....then,
18407 if (get_spe64(insn)) return true;
18409 It's the only reliable way to do the stuff below. */
18411 i = PATTERN (insn);
18412 if (GET_CODE (i) == SET)
18414 enum machine_mode mode = GET_MODE (SET_SRC (i));
18416 if (SPE_VECTOR_MODE (mode))
18418 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18428 debug_stack_info (rs6000_stack_t *info)
18430 const char *abi_string;
18433 info = rs6000_stack_info ();
18435 fprintf (stderr, "\nStack information for function %s:\n",
18436 ((current_function_decl && DECL_NAME (current_function_decl))
18437 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18442 default: abi_string = "Unknown"; break;
18443 case ABI_NONE: abi_string = "NONE"; break;
18444 case ABI_AIX: abi_string = "AIX"; break;
18445 case ABI_DARWIN: abi_string = "Darwin"; break;
18446 case ABI_V4: abi_string = "V.4"; break;
18449 fprintf (stderr, "\tABI = %5s\n", abi_string);
18451 if (TARGET_ALTIVEC_ABI)
18452 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18454 if (TARGET_SPE_ABI)
18455 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18457 if (info->first_gp_reg_save != 32)
18458 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18460 if (info->first_fp_reg_save != 64)
18461 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18463 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18464 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18465 info->first_altivec_reg_save);
18467 if (info->lr_save_p)
18468 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18470 if (info->cr_save_p)
18471 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18473 if (info->vrsave_mask)
18474 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18477 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18480 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18482 if (info->gp_save_offset)
18483 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18485 if (info->fp_save_offset)
18486 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18488 if (info->altivec_save_offset)
18489 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18490 info->altivec_save_offset);
18492 if (info->spe_gp_save_offset)
18493 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18494 info->spe_gp_save_offset);
18496 if (info->vrsave_save_offset)
18497 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18498 info->vrsave_save_offset);
18500 if (info->lr_save_offset)
18501 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18503 if (info->cr_save_offset)
18504 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18506 if (info->varargs_save_offset)
18507 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18509 if (info->total_size)
18510 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18513 if (info->vars_size)
18514 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18517 if (info->parm_size)
18518 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18520 if (info->fixed_size)
18521 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18524 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18526 if (info->spe_gp_size)
18527 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18530 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18532 if (info->altivec_size)
18533 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18535 if (info->vrsave_size)
18536 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18538 if (info->altivec_padding_size)
18539 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18540 info->altivec_padding_size);
18542 if (info->spe_padding_size)
18543 fprintf (stderr, "\tspe_padding_size = %5d\n",
18544 info->spe_padding_size);
18547 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18549 if (info->save_size)
18550 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18552 if (info->reg_size != 4)
18553 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18555 fprintf (stderr, "\n");
18559 rs6000_return_addr (int count, rtx frame)
18561 /* Currently we don't optimize very well between prolog and body
18562 code and for PIC code the code can be actually quite bad, so
18563 don't try to be too clever here. */
18564 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18566 cfun->machine->ra_needs_full_frame = 1;
18573 plus_constant (copy_to_reg
18574 (gen_rtx_MEM (Pmode,
18575 memory_address (Pmode, frame))),
18576 RETURN_ADDRESS_OFFSET)));
18579 cfun->machine->ra_need_lr = 1;
18580 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18583 /* Say whether a function is a candidate for sibcall handling or not.
18584 We do not allow indirect calls to be optimized into sibling calls.
18585 Also, we can't do it if there are any vector parameters; there's
18586 nowhere to put the VRsave code so it works; note that functions with
18587 vector parameters are required to have a prototype, so the argument
18588 type info must be available here. (The tail recursion case can work
18589 with vector parameters, but there's no way to distinguish here.) */
18591 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
18596 if (TARGET_ALTIVEC_VRSAVE)
18598 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
18599 type; type = TREE_CHAIN (type))
18601 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
18605 if (DEFAULT_ABI == ABI_DARWIN
18606 || ((*targetm.binds_local_p) (decl)
18607 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
18609 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
18611 if (!lookup_attribute ("longcall", attr_list)
18612 || lookup_attribute ("shortcall", attr_list))
18619 /* NULL if INSN insn is valid within a low-overhead loop.
18620 Otherwise return why doloop cannot be applied.
18621 PowerPC uses the COUNT register for branch on table instructions. */
18623 static const char *
18624 rs6000_invalid_within_doloop (const_rtx insn)
18627 return "Function call in the loop.";
18630 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18631 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18632 return "Computed branch in the loop.";
18638 rs6000_ra_ever_killed (void)
18644 if (cfun->is_thunk)
18647 if (cfun->machine->lr_save_state)
18648 return cfun->machine->lr_save_state - 1;
18650 /* regs_ever_live has LR marked as used if any sibcalls are present,
18651 but this should not force saving and restoring in the
18652 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18653 clobbers LR, so that is inappropriate. */
18655 /* Also, the prologue can generate a store into LR that
18656 doesn't really count, like this:
18659 bcl to set PIC register
18663 When we're called from the epilogue, we need to avoid counting
18664 this as a store. */
18666 push_topmost_sequence ();
18667 top = get_insns ();
18668 pop_topmost_sequence ();
18669 reg = gen_rtx_REG (Pmode, LR_REGNO);
18671 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18677 if (!SIBLING_CALL_P (insn))
18680 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18682 else if (set_of (reg, insn) != NULL_RTX
18683 && !prologue_epilogue_contains (insn))
18690 /* Emit instructions needed to load the TOC register.
18691 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18692 a constant pool; or for SVR4 -fpic. */
18695 rs6000_emit_load_toc_table (int fromprolog)
18698 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18700 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18703 rtx lab, tmp1, tmp2, got;
18705 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18706 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18708 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18710 got = rs6000_got_sym ();
18711 tmp1 = tmp2 = dest;
18714 tmp1 = gen_reg_rtx (Pmode);
18715 tmp2 = gen_reg_rtx (Pmode);
18717 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18718 emit_move_insn (tmp1,
18719 gen_rtx_REG (Pmode, LR_REGNO));
18720 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18721 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18723 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18725 emit_insn (gen_load_toc_v4_pic_si ());
18726 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18728 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18731 rtx temp0 = (fromprolog
18732 ? gen_rtx_REG (Pmode, 0)
18733 : gen_reg_rtx (Pmode));
18739 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18740 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18742 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18743 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18745 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18746 emit_move_insn (dest,
18747 gen_rtx_REG (Pmode, LR_REGNO));
18748 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18754 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18755 lab = gen_label_rtx ();
18756 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18757 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18758 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18760 emit_insn (gen_addsi3 (dest, temp0, dest));
18762 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18764 /* This is for AIX code running in non-PIC ELF32. */
18767 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18768 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18770 emit_insn (gen_elf_high (dest, realsym));
18771 emit_insn (gen_elf_low (dest, dest, realsym));
18775 gcc_assert (DEFAULT_ABI == ABI_AIX);
18778 emit_insn (gen_load_toc_aix_si (dest));
18780 emit_insn (gen_load_toc_aix_di (dest));
18784 /* Emit instructions to restore the link register after determining where
18785 its value has been stored. */
18788 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18790 rs6000_stack_t *info = rs6000_stack_info ();
18793 operands[0] = source;
18794 operands[1] = scratch;
18796 if (info->lr_save_p)
18798 rtx frame_rtx = stack_pointer_rtx;
18799 HOST_WIDE_INT sp_offset = 0;
18802 if (frame_pointer_needed
18803 || cfun->calls_alloca
18804 || info->total_size > 32767)
18806 tmp = gen_frame_mem (Pmode, frame_rtx);
18807 emit_move_insn (operands[1], tmp);
18808 frame_rtx = operands[1];
18810 else if (info->push_p)
18811 sp_offset = info->total_size;
18813 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18814 tmp = gen_frame_mem (Pmode, tmp);
18815 emit_move_insn (tmp, operands[0]);
18818 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
18820 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18821 state of lr_save_p so any change from here on would be a bug. In
18822 particular, stop rs6000_ra_ever_killed from considering the SET
18823 of lr we may have added just above. */
18824 cfun->machine->lr_save_state = info->lr_save_p + 1;
18827 static GTY(()) alias_set_type set = -1;
18830 get_TOC_alias_set (void)
18833 set = new_alias_set ();
18837 /* This returns nonzero if the current function uses the TOC. This is
18838 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
18839 is generated by the ABI_V4 load_toc_* patterns. */
18846 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
18849 rtx pat = PATTERN (insn);
18852 if (GET_CODE (pat) == PARALLEL)
18853 for (i = 0; i < XVECLEN (pat, 0); i++)
18855 rtx sub = XVECEXP (pat, 0, i);
18856 if (GET_CODE (sub) == USE)
18858 sub = XEXP (sub, 0);
18859 if (GET_CODE (sub) == UNSPEC
18860 && XINT (sub, 1) == UNSPEC_TOC)
18870 create_TOC_reference (rtx symbol, rtx largetoc_reg)
18872 rtx tocrel, tocreg;
18874 if (TARGET_DEBUG_ADDR)
18876 if (GET_CODE (symbol) == SYMBOL_REF)
18877 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
18881 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
18882 GET_RTX_NAME (GET_CODE (symbol)));
18883 debug_rtx (symbol);
18887 if (!can_create_pseudo_p ())
18888 df_set_regs_ever_live (TOC_REGISTER, true);
18890 tocrel = gen_rtx_CONST (Pmode,
18891 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
18893 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
18894 if (TARGET_CMODEL != CMODEL_SMALL)
18896 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
18897 if (largetoc_reg != NULL)
18899 emit_move_insn (largetoc_reg, hi);
18902 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
18905 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
18908 /* Issue assembly directives that create a reference to the given DWARF
18909 FRAME_TABLE_LABEL from the current function section. */
18911 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
18913 fprintf (asm_out_file, "\t.ref %s\n",
18914 TARGET_STRIP_NAME_ENCODING (frame_table_label));
18917 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18918 and the change to the stack pointer. */
18921 rs6000_emit_stack_tie (void)
18923 rtx mem = gen_frame_mem (BLKmode,
18924 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
18926 emit_insn (gen_stack_tie (mem));
18929 /* Emit the correct code for allocating stack space, as insns.
18930 If COPY_REG, make sure a copy of the old frame is left there.
18931 The generated code may use hard register 0 as a temporary. */
18934 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
18937 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18938 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
18939 rtx todec = gen_int_mode (-size, Pmode);
18942 if (INTVAL (todec) != -size)
18944 warning (0, "stack frame too large");
18945 emit_insn (gen_trap ());
18949 if (crtl->limit_stack)
18951 if (REG_P (stack_limit_rtx)
18952 && REGNO (stack_limit_rtx) > 1
18953 && REGNO (stack_limit_rtx) <= 31)
18955 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
18956 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18959 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
18961 && DEFAULT_ABI == ABI_V4)
18963 rtx toload = gen_rtx_CONST (VOIDmode,
18964 gen_rtx_PLUS (Pmode,
18968 emit_insn (gen_elf_high (tmp_reg, toload));
18969 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
18970 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18974 warning (0, "stack limit expression is not supported");
18978 emit_move_insn (copy_reg, stack_reg);
18982 /* Need a note here so that try_split doesn't get confused. */
18983 if (get_last_insn () == NULL_RTX)
18984 emit_note (NOTE_INSN_DELETED);
18985 insn = emit_move_insn (tmp_reg, todec);
18986 try_split (PATTERN (insn), insn, 0);
18990 insn = emit_insn (TARGET_32BIT
18991 ? gen_movsi_update_stack (stack_reg, stack_reg,
18993 : gen_movdi_di_update_stack (stack_reg, stack_reg,
18994 todec, stack_reg));
18995 /* Since we didn't use gen_frame_mem to generate the MEM, grab
18996 it now and set the alias set/attributes. The above gen_*_update
18997 calls will generate a PARALLEL with the MEM set being the first
18999 par = PATTERN (insn);
19000 gcc_assert (GET_CODE (par) == PARALLEL);
19001 set = XVECEXP (par, 0, 0);
19002 gcc_assert (GET_CODE (set) == SET);
19003 mem = SET_DEST (set);
19004 gcc_assert (MEM_P (mem));
19005 MEM_NOTRAP_P (mem) = 1;
19006 set_mem_alias_set (mem, get_frame_alias_set ());
19008 RTX_FRAME_RELATED_P (insn) = 1;
19009 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19010 gen_rtx_SET (VOIDmode, stack_reg,
19011 gen_rtx_PLUS (Pmode, stack_reg,
19012 GEN_INT (-size))));
19015 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19017 #if PROBE_INTERVAL > 32768
19018 #error Cannot use indexed addressing mode for stack probing
19021 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19022 inclusive. These are offsets from the current stack pointer. */
19025 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19027 /* See if we have a constant small number of probes to generate. If so,
19028 that's the easy case. */
19029 if (first + size <= 32768)
19033 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19034 it exceeds SIZE. If only one probe is needed, this will not
19035 generate any code. Then probe at FIRST + SIZE. */
19036 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19037 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19039 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19042 /* Otherwise, do the same as above, but in a loop. Note that we must be
19043 extra careful with variables wrapping around because we might be at
19044 the very top (or the very bottom) of the address space and we have
19045 to be able to handle this case properly; in particular, we use an
19046 equality test for the loop condition. */
19049 HOST_WIDE_INT rounded_size;
19050 rtx r12 = gen_rtx_REG (Pmode, 12);
19051 rtx r0 = gen_rtx_REG (Pmode, 0);
19053 /* Sanity check for the addressing mode we're going to use. */
19054 gcc_assert (first <= 32768);
19056 /* Step 1: round SIZE to the previous multiple of the interval. */
19058 rounded_size = size & -PROBE_INTERVAL;
19061 /* Step 2: compute initial and final value of the loop counter. */
19063 /* TEST_ADDR = SP + FIRST. */
19064 emit_insn (gen_rtx_SET (VOIDmode, r12,
19065 plus_constant (stack_pointer_rtx, -first)));
19067 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19068 if (rounded_size > 32768)
19070 emit_move_insn (r0, GEN_INT (-rounded_size));
19071 emit_insn (gen_rtx_SET (VOIDmode, r0,
19072 gen_rtx_PLUS (Pmode, r12, r0)));
19075 emit_insn (gen_rtx_SET (VOIDmode, r0,
19076 plus_constant (r12, -rounded_size)));
19079 /* Step 3: the loop
19081 while (TEST_ADDR != LAST_ADDR)
19083 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19087 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19088 until it is equal to ROUNDED_SIZE. */
19091 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19093 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19096 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19097 that SIZE is equal to ROUNDED_SIZE. */
19099 if (size != rounded_size)
19100 emit_stack_probe (plus_constant (r12, rounded_size - size));
19104 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19105 absolute addresses. */
19108 output_probe_stack_range (rtx reg1, rtx reg2)
19110 static int labelno = 0;
19111 char loop_lab[32], end_lab[32];
19114 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19115 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19117 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19119 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19123 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19125 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19127 fputs ("\tbeq 0,", asm_out_file);
19128 assemble_name_raw (asm_out_file, end_lab);
19129 fputc ('\n', asm_out_file);
19131 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19132 xops[1] = GEN_INT (-PROBE_INTERVAL);
19133 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19135 /* Probe at TEST_ADDR and branch. */
19136 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19137 fprintf (asm_out_file, "\tb ");
19138 assemble_name_raw (asm_out_file, loop_lab);
19139 fputc ('\n', asm_out_file);
19141 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19146 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19147 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19148 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19149 deduce these equivalences by itself so it wasn't necessary to hold
19150 its hand so much. */
19153 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19154 rtx reg2, rtx rreg)
19158 /* copy_rtx will not make unique copies of registers, so we need to
19159 ensure we don't have unwanted sharing here. */
19161 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19164 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19166 real = copy_rtx (PATTERN (insn));
19168 if (reg2 != NULL_RTX)
19169 real = replace_rtx (real, reg2, rreg);
19171 real = replace_rtx (real, reg,
19172 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19173 STACK_POINTER_REGNUM),
19176 /* We expect that 'real' is either a SET or a PARALLEL containing
19177 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19178 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19180 if (GET_CODE (real) == SET)
19184 temp = simplify_rtx (SET_SRC (set));
19186 SET_SRC (set) = temp;
19187 temp = simplify_rtx (SET_DEST (set));
19189 SET_DEST (set) = temp;
19190 if (GET_CODE (SET_DEST (set)) == MEM)
19192 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19194 XEXP (SET_DEST (set), 0) = temp;
19201 gcc_assert (GET_CODE (real) == PARALLEL);
19202 for (i = 0; i < XVECLEN (real, 0); i++)
19203 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19205 rtx set = XVECEXP (real, 0, i);
19207 temp = simplify_rtx (SET_SRC (set));
19209 SET_SRC (set) = temp;
19210 temp = simplify_rtx (SET_DEST (set));
19212 SET_DEST (set) = temp;
19213 if (GET_CODE (SET_DEST (set)) == MEM)
19215 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19217 XEXP (SET_DEST (set), 0) = temp;
19219 RTX_FRAME_RELATED_P (set) = 1;
19223 RTX_FRAME_RELATED_P (insn) = 1;
19224 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19227 /* Returns an insn that has a vrsave set operation with the
19228 appropriate CLOBBERs. */
19231 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19234 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19235 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19238 = gen_rtx_SET (VOIDmode,
19240 gen_rtx_UNSPEC_VOLATILE (SImode,
19241 gen_rtvec (2, reg, vrsave),
19242 UNSPECV_SET_VRSAVE));
19246 /* We need to clobber the registers in the mask so the scheduler
19247 does not move sets to VRSAVE before sets of AltiVec registers.
19249 However, if the function receives nonlocal gotos, reload will set
19250 all call saved registers live. We will end up with:
19252 (set (reg 999) (mem))
19253 (parallel [ (set (reg vrsave) (unspec blah))
19254 (clobber (reg 999))])
19256 The clobber will cause the store into reg 999 to be dead, and
19257 flow will attempt to delete an epilogue insn. In this case, we
19258 need an unspec use/set of the register. */
19260 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19261 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19263 if (!epiloguep || call_used_regs [i])
19264 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19265 gen_rtx_REG (V4SImode, i));
19268 rtx reg = gen_rtx_REG (V4SImode, i);
19271 = gen_rtx_SET (VOIDmode,
19273 gen_rtx_UNSPEC (V4SImode,
19274 gen_rtvec (1, reg), 27));
19278 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19280 for (i = 0; i < nclobs; ++i)
19281 XVECEXP (insn, 0, i) = clobs[i];
19286 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19287 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19290 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19291 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19293 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19294 rtx replacea, replaceb;
19296 int_rtx = GEN_INT (offset);
19298 /* Some cases that need register indexed addressing. */
19299 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19300 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
19301 || (TARGET_E500_DOUBLE && mode == DFmode)
19303 && SPE_VECTOR_MODE (mode)
19304 && !SPE_CONST_OFFSET_OK (offset)))
19306 /* Whomever calls us must make sure r11 is available in the
19307 flow path of instructions in the prologue. */
19308 offset_rtx = gen_rtx_REG (Pmode, 11);
19309 emit_move_insn (offset_rtx, int_rtx);
19311 replacea = offset_rtx;
19312 replaceb = int_rtx;
19316 offset_rtx = int_rtx;
19317 replacea = NULL_RTX;
19318 replaceb = NULL_RTX;
19321 reg = gen_rtx_REG (mode, regno);
19322 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19323 mem = gen_frame_mem (mode, addr);
19325 insn = emit_move_insn (mem, reg);
19327 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19330 /* Emit an offset memory reference suitable for a frame store, while
19331 converting to a valid addressing mode. */
19334 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19336 rtx int_rtx, offset_rtx;
19338 int_rtx = GEN_INT (offset);
19340 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19341 || (TARGET_E500_DOUBLE && mode == DFmode))
19343 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19344 emit_move_insn (offset_rtx, int_rtx);
19347 offset_rtx = int_rtx;
19349 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19352 /* Look for user-defined global regs. We should not save and restore these,
19353 and cannot use stmw/lmw if there are any in its range. */
19356 no_global_regs_above (int first, bool gpr)
19359 int last = gpr ? 32 : 64;
19360 for (i = first; i < last; i++)
19361 if (global_regs[i])
19366 #ifndef TARGET_FIX_AND_CONTINUE
19367 #define TARGET_FIX_AND_CONTINUE 0
19370 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19371 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19372 #define LAST_SAVRES_REGISTER 31
19373 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19375 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19377 /* Temporary holding space for an out-of-line register save/restore
19379 static char savres_routine_name[30];
19381 /* Return the name for an out-of-line register save/restore routine.
19382 We are saving/restoring GPRs if GPR is true. */
19385 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19386 bool savep, bool gpr, bool lr)
19388 const char *prefix = "";
19389 const char *suffix = "";
19391 /* Different targets are supposed to define
19392 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19393 routine name could be defined with:
19395 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19397 This is a nice idea in practice, but in reality, things are
19398 complicated in several ways:
19400 - ELF targets have save/restore routines for GPRs.
19402 - SPE targets use different prefixes for 32/64-bit registers, and
19403 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19405 - PPC64 ELF targets have routines for save/restore of GPRs that
19406 differ in what they do with the link register, so having a set
19407 prefix doesn't work. (We only use one of the save routines at
19408 the moment, though.)
19410 - PPC32 elf targets have "exit" versions of the restore routines
19411 that restore the link register and can save some extra space.
19412 These require an extra suffix. (There are also "tail" versions
19413 of the restore routines and "GOT" versions of the save routines,
19414 but we don't generate those at present. Same problems apply,
19417 We deal with all this by synthesizing our own prefix/suffix and
19418 using that for the simple sprintf call shown above. */
19421 /* No floating point saves on the SPE. */
19425 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19427 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19432 else if (DEFAULT_ABI == ABI_V4)
19438 prefix = savep ? "_savegpr_" : "_restgpr_";
19440 prefix = savep ? "_savefpr_" : "_restfpr_";
19445 else if (DEFAULT_ABI == ABI_AIX)
19447 #ifndef POWERPC_LINUX
19448 /* No out-of-line save/restore routines for GPRs on AIX. */
19449 gcc_assert (!TARGET_AIX || !gpr);
19455 ? (lr ? "_savegpr0_" : "_savegpr1_")
19456 : (lr ? "_restgpr0_" : "_restgpr1_"));
19457 #ifdef POWERPC_LINUX
19459 prefix = (savep ? "_savefpr_" : "_restfpr_");
19463 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19464 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19467 else if (DEFAULT_ABI == ABI_DARWIN)
19468 sorry ("Out-of-line save/restore routines not supported on Darwin");
19470 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19472 return savres_routine_name;
19475 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19476 We are saving/restoring GPRs if GPR is true. */
19479 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19482 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19484 int select = ((savep ? 1 : 0) << 2
19486 /* On the SPE, we never have any FPRs, but we do have
19487 32/64-bit versions of the routines. */
19488 ? (info->spe_64bit_regs_used ? 1 : 0)
19489 : (gpr ? 1 : 0)) << 1)
19492 /* Don't generate bogus routine names. */
19493 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19494 && regno <= LAST_SAVRES_REGISTER);
19496 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19502 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19504 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19505 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19506 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19512 /* Emit a sequence of insns, including a stack tie if needed, for
19513 resetting the stack pointer. If SAVRES is true, then don't reset the
19514 stack pointer, but move the base of the frame into r11 for use by
19515 out-of-line register restore routines. */
19518 rs6000_emit_stack_reset (rs6000_stack_t *info,
19519 rtx sp_reg_rtx, rtx frame_reg_rtx,
19520 int sp_offset, bool savres)
19522 /* This blockage is needed so that sched doesn't decide to move
19523 the sp change before the register restores. */
19524 if (frame_reg_rtx != sp_reg_rtx
19526 && info->spe_64bit_regs_used != 0
19527 && info->first_gp_reg_save != 32))
19528 rs6000_emit_stack_tie ();
19530 if (frame_reg_rtx != sp_reg_rtx)
19532 if (sp_offset != 0)
19534 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19535 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19536 GEN_INT (sp_offset)));
19539 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19541 else if (sp_offset != 0)
19543 /* If we are restoring registers out-of-line, we will be using the
19544 "exit" variants of the restore routines, which will reset the
19545 stack for us. But we do need to point r11 into the right place
19546 for those routines. */
19547 rtx dest_reg = (savres
19548 ? gen_rtx_REG (Pmode, 11)
19551 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
19552 GEN_INT (sp_offset)));
19559 /* Construct a parallel rtx describing the effect of a call to an
19560 out-of-line register save/restore routine. */
19563 rs6000_make_savres_rtx (rs6000_stack_t *info,
19564 rtx frame_reg_rtx, int save_area_offset,
19565 enum machine_mode reg_mode,
19566 bool savep, bool gpr, bool lr)
19569 int offset, start_reg, end_reg, n_regs;
19570 int reg_size = GET_MODE_SIZE (reg_mode);
19576 ? info->first_gp_reg_save
19577 : info->first_fp_reg_save);
19578 end_reg = gpr ? 32 : 64;
19579 n_regs = end_reg - start_reg;
19580 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
19583 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
19585 RTVEC_ELT (p, offset++)
19586 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
19588 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
19589 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
19590 RTVEC_ELT (p, offset++)
19591 = gen_rtx_USE (VOIDmode,
19592 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19596 for (i = 0; i < end_reg - start_reg; i++)
19598 rtx addr, reg, mem;
19599 reg = gen_rtx_REG (reg_mode, start_reg + i);
19600 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19601 GEN_INT (save_area_offset + reg_size*i));
19602 mem = gen_frame_mem (reg_mode, addr);
19604 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19606 savep ? reg : mem);
19611 rtx addr, reg, mem;
19612 reg = gen_rtx_REG (Pmode, 0);
19613 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19614 GEN_INT (info->lr_save_offset));
19615 mem = gen_frame_mem (Pmode, addr);
19616 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19619 return gen_rtx_PARALLEL (VOIDmode, p);
19622 /* Determine whether the gp REG is really used. */
19625 rs6000_reg_live_or_pic_offset_p (int reg)
19627 return ((df_regs_ever_live_p (reg)
19628 && (!call_used_regs[reg]
19629 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19630 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19631 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19632 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19633 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19637 SAVRES_MULTIPLE = 0x1,
19638 SAVRES_INLINE_FPRS = 0x2,
19639 SAVRES_INLINE_GPRS = 0x4,
19640 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
19641 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
19642 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
19645 /* Determine the strategy for savings/restoring registers. */
19648 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
19649 int using_static_chain_p, int sibcall)
19651 bool using_multiple_p;
19653 bool savres_fprs_inline;
19654 bool savres_gprs_inline;
19655 bool noclobber_global_gprs
19656 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
19659 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
19660 && (!TARGET_SPE_ABI
19661 || info->spe_64bit_regs_used == 0)
19662 && info->first_gp_reg_save < 31
19663 && noclobber_global_gprs);
19664 /* Don't bother to try to save things out-of-line if r11 is occupied
19665 by the static chain. It would require too much fiddling and the
19666 static chain is rarely used anyway. */
19667 common = (using_static_chain_p
19669 || crtl->calls_eh_return
19670 || !info->lr_save_p
19671 || cfun->machine->ra_need_lr
19672 || info->total_size > 32767);
19673 savres_fprs_inline = (common
19674 || info->first_fp_reg_save == 64
19675 || !no_global_regs_above (info->first_fp_reg_save,
19677 /* The out-of-line FP routines use
19678 double-precision stores; we can't use those
19679 routines if we don't have such stores. */
19680 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
19681 || FP_SAVE_INLINE (info->first_fp_reg_save));
19682 savres_gprs_inline = (common
19683 /* Saving CR interferes with the exit routines
19684 used on the SPE, so just punt here. */
19687 && info->spe_64bit_regs_used != 0
19688 && info->cr_save_p != 0)
19689 || info->first_gp_reg_save == 32
19690 || !noclobber_global_gprs
19691 || GP_SAVE_INLINE (info->first_gp_reg_save));
19694 /* If we are going to use store multiple, then don't even bother
19695 with the out-of-line routines, since the store-multiple instruction
19696 will always be smaller. */
19697 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19700 /* The situation is more complicated with load multiple. We'd
19701 prefer to use the out-of-line routines for restores, since the
19702 "exit" out-of-line routines can handle the restore of LR and
19703 the frame teardown. But we can only use the out-of-line
19704 routines if we know that we've used store multiple or
19705 out-of-line routines in the prologue, i.e. if we've saved all
19706 the registers from first_gp_reg_save. Otherwise, we risk
19707 loading garbage from the stack. Furthermore, we can only use
19708 the "exit" out-of-line gpr restore if we haven't saved any
19710 bool saved_all = !savres_gprs_inline || using_multiple_p;
19712 if (saved_all && info->first_fp_reg_save != 64)
19713 /* We can't use the exit routine; use load multiple if it's
19715 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19718 strategy = (using_multiple_p
19719 | (savres_fprs_inline << 1)
19720 | (savres_gprs_inline << 2));
19721 #ifdef POWERPC_LINUX
19724 if (!savres_fprs_inline)
19725 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
19726 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
19727 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
19730 if (TARGET_AIX && !savres_fprs_inline)
19731 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
19736 /* Emit function prologue as insns. */
19739 rs6000_emit_prologue (void)
19741 rs6000_stack_t *info = rs6000_stack_info ();
19742 enum machine_mode reg_mode = Pmode;
19743 int reg_size = TARGET_32BIT ? 4 : 8;
19744 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19745 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19746 rtx frame_reg_rtx = sp_reg_rtx;
19747 rtx cr_save_rtx = NULL_RTX;
19750 int saving_FPRs_inline;
19751 int saving_GPRs_inline;
19752 int using_store_multiple;
19753 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19754 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19755 && call_used_regs[STATIC_CHAIN_REGNUM]);
19756 HOST_WIDE_INT sp_offset = 0;
19758 if (flag_stack_usage)
19759 current_function_static_stack_size = info->total_size;
19761 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
19762 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
19764 if (TARGET_FIX_AND_CONTINUE)
19766 /* gdb on darwin arranges to forward a function from the old
19767 address by modifying the first 5 instructions of the function
19768 to branch to the overriding function. This is necessary to
19769 permit function pointers that point to the old function to
19770 actually forward to the new function. */
19771 emit_insn (gen_nop ());
19772 emit_insn (gen_nop ());
19773 emit_insn (gen_nop ());
19774 emit_insn (gen_nop ());
19775 emit_insn (gen_nop ());
19778 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19780 reg_mode = V2SImode;
19784 strategy = rs6000_savres_strategy (info, /*savep=*/true,
19785 /*static_chain_p=*/using_static_chain_p,
19787 using_store_multiple = strategy & SAVRES_MULTIPLE;
19788 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19789 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19791 /* For V.4, update stack before we do any saving and set back pointer. */
19792 if (! WORLD_SAVE_P (info)
19794 && (DEFAULT_ABI == ABI_V4
19795 || crtl->calls_eh_return))
19797 bool need_r11 = (TARGET_SPE
19798 ? (!saving_GPRs_inline
19799 && info->spe_64bit_regs_used == 0)
19800 : (!saving_FPRs_inline || !saving_GPRs_inline));
19801 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19803 if (info->total_size < 32767)
19804 sp_offset = info->total_size;
19806 frame_reg_rtx = copy_reg;
19807 else if (info->cr_save_p
19809 || info->first_fp_reg_save < 64
19810 || info->first_gp_reg_save < 32
19811 || info->altivec_size != 0
19812 || info->vrsave_mask != 0
19813 || crtl->calls_eh_return)
19815 copy_reg = frame_ptr_rtx;
19816 frame_reg_rtx = copy_reg;
19820 /* The prologue won't be saving any regs so there is no need
19821 to set up a frame register to access any frame save area.
19822 We also won't be using sp_offset anywhere below, but set
19823 the correct value anyway to protect against future
19824 changes to this function. */
19825 sp_offset = info->total_size;
19827 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19828 if (frame_reg_rtx != sp_reg_rtx)
19829 rs6000_emit_stack_tie ();
19832 /* Handle world saves specially here. */
19833 if (WORLD_SAVE_P (info))
19840 /* save_world expects lr in r0. */
19841 reg0 = gen_rtx_REG (Pmode, 0);
19842 if (info->lr_save_p)
19844 insn = emit_move_insn (reg0,
19845 gen_rtx_REG (Pmode, LR_REGNO));
19846 RTX_FRAME_RELATED_P (insn) = 1;
19849 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19850 assumptions about the offsets of various bits of the stack
19852 gcc_assert (info->gp_save_offset == -220
19853 && info->fp_save_offset == -144
19854 && info->lr_save_offset == 8
19855 && info->cr_save_offset == 4
19858 && (!crtl->calls_eh_return
19859 || info->ehrd_offset == -432)
19860 && info->vrsave_save_offset == -224
19861 && info->altivec_save_offset == -416);
19863 treg = gen_rtx_REG (SImode, 11);
19864 emit_move_insn (treg, GEN_INT (-info->total_size));
19866 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19867 in R11. It also clobbers R12, so beware! */
19869 /* Preserve CR2 for save_world prologues */
19871 sz += 32 - info->first_gp_reg_save;
19872 sz += 64 - info->first_fp_reg_save;
19873 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19874 p = rtvec_alloc (sz);
19876 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19877 gen_rtx_REG (SImode,
19879 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19880 gen_rtx_SYMBOL_REF (Pmode,
19882 /* We do floats first so that the instruction pattern matches
19884 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19886 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19887 ? DFmode : SFmode),
19888 info->first_fp_reg_save + i);
19889 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19890 GEN_INT (info->fp_save_offset
19891 + sp_offset + 8 * i));
19892 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19893 ? DFmode : SFmode), addr);
19895 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19897 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19899 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19900 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19901 GEN_INT (info->altivec_save_offset
19902 + sp_offset + 16 * i));
19903 rtx mem = gen_frame_mem (V4SImode, addr);
19905 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19907 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19909 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19910 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19911 GEN_INT (info->gp_save_offset
19912 + sp_offset + reg_size * i));
19913 rtx mem = gen_frame_mem (reg_mode, addr);
19915 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19919 /* CR register traditionally saved as CR2. */
19920 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19921 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19922 GEN_INT (info->cr_save_offset
19924 rtx mem = gen_frame_mem (reg_mode, addr);
19926 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19928 /* Explain about use of R0. */
19929 if (info->lr_save_p)
19931 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19932 GEN_INT (info->lr_save_offset
19934 rtx mem = gen_frame_mem (reg_mode, addr);
19936 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
19938 /* Explain what happens to the stack pointer. */
19940 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
19941 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
19944 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19945 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19946 treg, GEN_INT (-info->total_size));
19947 sp_offset = info->total_size;
19950 /* If we use the link register, get it into r0. */
19951 if (!WORLD_SAVE_P (info) && info->lr_save_p)
19953 rtx addr, reg, mem;
19955 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
19956 gen_rtx_REG (Pmode, LR_REGNO));
19957 RTX_FRAME_RELATED_P (insn) = 1;
19959 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
19960 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
19962 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19963 GEN_INT (info->lr_save_offset + sp_offset));
19964 reg = gen_rtx_REG (Pmode, 0);
19965 mem = gen_rtx_MEM (Pmode, addr);
19966 /* This should not be of rs6000_sr_alias_set, because of
19967 __builtin_return_address. */
19969 insn = emit_move_insn (mem, reg);
19970 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19971 NULL_RTX, NULL_RTX);
19975 /* If we need to save CR, put it into r12 or r11. */
19976 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
19981 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
19983 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19984 RTX_FRAME_RELATED_P (insn) = 1;
19985 /* Now, there's no way that dwarf2out_frame_debug_expr is going
19986 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
19987 But that's OK. All we have to do is specify that _one_ condition
19988 code register is saved in this stack slot. The thrower's epilogue
19989 will then restore all the call-saved registers.
19990 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
19991 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
19992 gen_rtx_REG (SImode, CR2_REGNO));
19993 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19996 /* Do any required saving of fpr's. If only one or two to save, do
19997 it ourselves. Otherwise, call function. */
19998 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20001 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20002 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20003 && ! call_used_regs[info->first_fp_reg_save+i]))
20004 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20005 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20007 info->first_fp_reg_save + i,
20008 info->fp_save_offset + sp_offset + 8 * i,
20011 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20015 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20016 info->fp_save_offset + sp_offset,
20018 /*savep=*/true, /*gpr=*/false,
20020 & SAVRES_NOINLINE_FPRS_SAVES_LR)
20022 insn = emit_insn (par);
20023 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20024 NULL_RTX, NULL_RTX);
20027 /* Save GPRs. This is done as a PARALLEL if we are using
20028 the store-multiple instructions. */
20029 if (!WORLD_SAVE_P (info)
20031 && info->spe_64bit_regs_used != 0
20032 && info->first_gp_reg_save != 32)
20035 rtx spe_save_area_ptr;
20037 /* Determine whether we can address all of the registers that need
20038 to be saved with an offset from the stack pointer that fits in
20039 the small const field for SPE memory instructions. */
20040 int spe_regs_addressable_via_sp
20041 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20042 + (32 - info->first_gp_reg_save - 1) * reg_size)
20043 && saving_GPRs_inline);
20046 if (spe_regs_addressable_via_sp)
20048 spe_save_area_ptr = frame_reg_rtx;
20049 spe_offset = info->spe_gp_save_offset + sp_offset;
20053 /* Make r11 point to the start of the SPE save area. We need
20054 to be careful here if r11 is holding the static chain. If
20055 it is, then temporarily save it in r0. We would use r0 as
20056 our base register here, but using r0 as a base register in
20057 loads and stores means something different from what we
20059 int ool_adjust = (saving_GPRs_inline
20061 : (info->first_gp_reg_save
20062 - (FIRST_SAVRES_REGISTER+1))*8);
20063 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20064 + sp_offset - ool_adjust);
20066 if (using_static_chain_p)
20068 rtx r0 = gen_rtx_REG (Pmode, 0);
20069 gcc_assert (info->first_gp_reg_save > 11);
20071 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20074 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20075 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20077 GEN_INT (offset)));
20078 /* We need to make sure the move to r11 gets noted for
20079 properly outputting unwind information. */
20080 if (!saving_GPRs_inline)
20081 rs6000_frame_related (insn, frame_reg_rtx, offset,
20082 NULL_RTX, NULL_RTX);
20086 if (saving_GPRs_inline)
20088 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20089 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20091 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20092 rtx offset, addr, mem;
20094 /* We're doing all this to ensure that the offset fits into
20095 the immediate offset of 'evstdd'. */
20096 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20098 offset = GEN_INT (reg_size * i + spe_offset);
20099 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20100 mem = gen_rtx_MEM (V2SImode, addr);
20102 insn = emit_move_insn (mem, reg);
20104 rs6000_frame_related (insn, spe_save_area_ptr,
20105 info->spe_gp_save_offset
20106 + sp_offset + reg_size * i,
20107 offset, const0_rtx);
20114 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20116 /*savep=*/true, /*gpr=*/true,
20118 insn = emit_insn (par);
20119 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20120 NULL_RTX, NULL_RTX);
20124 /* Move the static chain pointer back. */
20125 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20126 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20128 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20132 /* Need to adjust r11 (r12) if we saved any FPRs. */
20133 if (info->first_fp_reg_save != 64)
20135 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20137 rtx offset = GEN_INT (sp_offset
20138 + (-8 * (64-info->first_fp_reg_save)));
20139 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20142 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20143 info->gp_save_offset + sp_offset,
20145 /*savep=*/true, /*gpr=*/true,
20147 & SAVRES_NOINLINE_GPRS_SAVES_LR)
20149 insn = emit_insn (par);
20150 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20151 NULL_RTX, NULL_RTX);
20153 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20157 p = rtvec_alloc (32 - info->first_gp_reg_save);
20158 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20160 rtx addr, reg, mem;
20161 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20162 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20163 GEN_INT (info->gp_save_offset
20166 mem = gen_frame_mem (reg_mode, addr);
20168 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20170 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20171 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20172 NULL_RTX, NULL_RTX);
20174 else if (!WORLD_SAVE_P (info))
20177 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20178 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20180 rtx addr, reg, mem;
20181 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20183 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20184 GEN_INT (info->gp_save_offset
20187 mem = gen_frame_mem (reg_mode, addr);
20189 insn = emit_move_insn (mem, reg);
20190 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20191 NULL_RTX, NULL_RTX);
20195 /* ??? There's no need to emit actual instructions here, but it's the
20196 easiest way to get the frame unwind information emitted. */
20197 if (crtl->calls_eh_return)
20199 unsigned int i, regno;
20203 regno = EH_RETURN_DATA_REGNO (i);
20204 if (regno == INVALID_REGNUM)
20207 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20208 info->ehrd_offset + sp_offset
20209 + reg_size * (int) i,
20214 /* In AIX ABI we need to make sure r2 is really saved. */
20215 if (TARGET_AIX && crtl->calls_eh_return)
20217 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20218 long toc_restore_insn;
20220 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20221 || frame_reg_rtx == sp_reg_rtx);
20222 tmp_reg = gen_rtx_REG (Pmode, 11);
20223 tmp_reg_si = gen_rtx_REG (SImode, 11);
20224 if (using_static_chain_p)
20225 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20226 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20227 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20228 /* Peek at instruction to which this function returns. If it's
20229 restoring r2, then we know we've already saved r2. We can't
20230 unconditionally save r2 because the value we have will already
20231 be updated if we arrived at this function via a plt call or
20232 toc adjusting stub. */
20233 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20234 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20235 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20236 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20237 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20238 validate_condition_mode (EQ, CCUNSmode);
20239 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20240 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20241 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20242 toc_save_done = gen_label_rtx ();
20243 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20244 gen_rtx_EQ (VOIDmode, compare_result,
20246 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20248 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20249 JUMP_LABEL (jump) = toc_save_done;
20250 LABEL_NUSES (toc_save_done) += 1;
20252 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2,
20253 sp_offset + 5 * reg_size, info->total_size);
20254 emit_label (toc_save_done);
20255 if (using_static_chain_p)
20256 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20259 /* Save CR if we use any that must be preserved. */
20260 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20262 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20263 GEN_INT (info->cr_save_offset + sp_offset));
20264 rtx mem = gen_frame_mem (SImode, addr);
20265 /* See the large comment above about why CR2_REGNO is used. */
20266 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20268 /* If r12 was used to hold the original sp, copy cr into r0 now
20270 if (REGNO (frame_reg_rtx) == 12)
20274 cr_save_rtx = gen_rtx_REG (SImode, 0);
20275 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20276 RTX_FRAME_RELATED_P (insn) = 1;
20277 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20278 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20280 insn = emit_move_insn (mem, cr_save_rtx);
20282 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20283 NULL_RTX, NULL_RTX);
20286 /* Update stack and set back pointer unless this is V.4,
20287 for which it was done previously. */
20288 if (!WORLD_SAVE_P (info) && info->push_p
20289 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20291 rtx copy_reg = NULL;
20293 if (info->total_size < 32767)
20294 sp_offset = info->total_size;
20295 else if (info->altivec_size != 0
20296 || info->vrsave_mask != 0)
20298 copy_reg = frame_ptr_rtx;
20299 frame_reg_rtx = copy_reg;
20302 sp_offset = info->total_size;
20303 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20304 if (frame_reg_rtx != sp_reg_rtx)
20305 rs6000_emit_stack_tie ();
20308 /* Set frame pointer, if needed. */
20309 if (frame_pointer_needed)
20311 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20313 RTX_FRAME_RELATED_P (insn) = 1;
20316 /* Save AltiVec registers if needed. Save here because the red zone does
20317 not include AltiVec registers. */
20318 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20322 /* There should be a non inline version of this, for when we
20323 are saving lots of vector registers. */
20324 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20325 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20327 rtx areg, savereg, mem;
20330 offset = info->altivec_save_offset + sp_offset
20331 + 16 * (i - info->first_altivec_reg_save);
20333 savereg = gen_rtx_REG (V4SImode, i);
20335 areg = gen_rtx_REG (Pmode, 0);
20336 emit_move_insn (areg, GEN_INT (offset));
20338 /* AltiVec addressing mode is [reg+reg]. */
20339 mem = gen_frame_mem (V4SImode,
20340 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20342 insn = emit_move_insn (mem, savereg);
20344 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20345 areg, GEN_INT (offset));
20349 /* VRSAVE is a bit vector representing which AltiVec registers
20350 are used. The OS uses this to determine which vector
20351 registers to save on a context switch. We need to save
20352 VRSAVE on the stack frame, add whatever AltiVec registers we
20353 used in this function, and do the corresponding magic in the
20356 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20357 && info->vrsave_mask != 0)
20359 rtx reg, mem, vrsave;
20362 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20363 as frame_reg_rtx and r11 as the static chain pointer for
20364 nested functions. */
20365 reg = gen_rtx_REG (SImode, 0);
20366 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20368 emit_insn (gen_get_vrsave_internal (reg));
20370 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20372 if (!WORLD_SAVE_P (info))
20375 offset = info->vrsave_save_offset + sp_offset;
20376 mem = gen_frame_mem (SImode,
20377 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20378 GEN_INT (offset)));
20379 insn = emit_move_insn (mem, reg);
20382 /* Include the registers in the mask. */
20383 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20385 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20388 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20389 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20390 || (DEFAULT_ABI == ABI_V4
20391 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20392 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20394 /* If emit_load_toc_table will use the link register, we need to save
20395 it. We use R12 for this purpose because emit_load_toc_table
20396 can use register 0. This allows us to use a plain 'blr' to return
20397 from the procedure more often. */
20398 int save_LR_around_toc_setup = (TARGET_ELF
20399 && DEFAULT_ABI != ABI_AIX
20401 && ! info->lr_save_p
20402 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20403 if (save_LR_around_toc_setup)
20405 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20407 insn = emit_move_insn (frame_ptr_rtx, lr);
20408 RTX_FRAME_RELATED_P (insn) = 1;
20410 rs6000_emit_load_toc_table (TRUE);
20412 insn = emit_move_insn (lr, frame_ptr_rtx);
20413 RTX_FRAME_RELATED_P (insn) = 1;
20416 rs6000_emit_load_toc_table (TRUE);
20420 if (DEFAULT_ABI == ABI_DARWIN
20421 && flag_pic && crtl->uses_pic_offset_table)
20423 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20424 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20426 /* Save and restore LR locally around this call (in R0). */
20427 if (!info->lr_save_p)
20428 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20430 emit_insn (gen_load_macho_picbase (src));
20432 emit_move_insn (gen_rtx_REG (Pmode,
20433 RS6000_PIC_OFFSET_TABLE_REGNUM),
20436 if (!info->lr_save_p)
20437 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20442 /* Write function prologue. */
20445 rs6000_output_function_prologue (FILE *file,
20446 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20448 rs6000_stack_t *info = rs6000_stack_info ();
20450 if (TARGET_DEBUG_STACK)
20451 debug_stack_info (info);
20453 /* Write .extern for any function we will call to save and restore
20455 if (info->first_fp_reg_save < 64
20456 && !FP_SAVE_INLINE (info->first_fp_reg_save))
20459 int regno = info->first_fp_reg_save - 32;
20461 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20462 /*gpr=*/false, /*lr=*/false);
20463 fprintf (file, "\t.extern %s\n", name);
20465 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20466 /*gpr=*/false, /*lr=*/true);
20467 fprintf (file, "\t.extern %s\n", name);
20470 /* Write .extern for AIX common mode routines, if needed. */
20471 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20473 fputs ("\t.extern __mulh\n", file);
20474 fputs ("\t.extern __mull\n", file);
20475 fputs ("\t.extern __divss\n", file);
20476 fputs ("\t.extern __divus\n", file);
20477 fputs ("\t.extern __quoss\n", file);
20478 fputs ("\t.extern __quous\n", file);
20479 common_mode_defined = 1;
20482 if (! HAVE_prologue)
20488 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
20489 the "toplevel" insn chain. */
20490 emit_note (NOTE_INSN_DELETED);
20491 rs6000_emit_prologue ();
20492 emit_note (NOTE_INSN_DELETED);
20494 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20498 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20500 INSN_ADDRESSES_NEW (insn, addr);
20505 prologue = get_insns ();
20508 if (TARGET_DEBUG_STACK)
20509 debug_rtx_list (prologue, 100);
20511 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
20515 rs6000_pic_labelno++;
20518 /* Non-zero if vmx regs are restored before the frame pop, zero if
20519 we restore after the pop when possible. */
20520 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20522 /* Reload CR from REG. */
20525 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20530 if (using_mfcr_multiple)
20532 for (i = 0; i < 8; i++)
20533 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20535 gcc_assert (count);
20538 if (using_mfcr_multiple && count > 1)
20543 p = rtvec_alloc (count);
20546 for (i = 0; i < 8; i++)
20547 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20549 rtvec r = rtvec_alloc (2);
20550 RTVEC_ELT (r, 0) = reg;
20551 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20552 RTVEC_ELT (p, ndx) =
20553 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20554 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20557 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20558 gcc_assert (ndx == count);
20561 for (i = 0; i < 8; i++)
20562 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20564 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20570 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20571 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20572 below stack pointer not cloberred by signals. */
20575 offset_below_red_zone_p (HOST_WIDE_INT offset)
20577 return offset < (DEFAULT_ABI == ABI_V4
20579 : TARGET_32BIT ? -220 : -288);
20582 /* Emit function epilogue as insns. */
20585 rs6000_emit_epilogue (int sibcall)
20587 rs6000_stack_t *info;
20588 int restoring_GPRs_inline;
20589 int restoring_FPRs_inline;
20590 int using_load_multiple;
20591 int using_mtcr_multiple;
20592 int use_backchain_to_restore_sp;
20596 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20597 rtx frame_reg_rtx = sp_reg_rtx;
20598 rtx cfa_restores = NULL_RTX;
20600 rtx cr_save_reg = NULL_RTX;
20601 enum machine_mode reg_mode = Pmode;
20602 int reg_size = TARGET_32BIT ? 4 : 8;
20605 info = rs6000_stack_info ();
20607 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20609 reg_mode = V2SImode;
20613 strategy = rs6000_savres_strategy (info, /*savep=*/false,
20614 /*static_chain_p=*/0, sibcall);
20615 using_load_multiple = strategy & SAVRES_MULTIPLE;
20616 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
20617 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
20618 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20619 || rs6000_cpu == PROCESSOR_PPC603
20620 || rs6000_cpu == PROCESSOR_PPC750
20622 /* Restore via the backchain when we have a large frame, since this
20623 is more efficient than an addis, addi pair. The second condition
20624 here will not trigger at the moment; We don't actually need a
20625 frame pointer for alloca, but the generic parts of the compiler
20626 give us one anyway. */
20627 use_backchain_to_restore_sp = (info->total_size > 32767
20628 || info->total_size
20629 + (info->lr_save_p ? info->lr_save_offset : 0)
20631 || (cfun->calls_alloca
20632 && !frame_pointer_needed));
20633 restore_lr = (info->lr_save_p
20634 && (restoring_FPRs_inline
20635 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20636 && (restoring_GPRs_inline
20637 || info->first_fp_reg_save < 64));
20639 if (WORLD_SAVE_P (info))
20643 const char *alloc_rname;
20646 /* eh_rest_world_r10 will return to the location saved in the LR
20647 stack slot (which is not likely to be our caller.)
20648 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20649 rest_world is similar, except any R10 parameter is ignored.
20650 The exception-handling stuff that was here in 2.95 is no
20651 longer necessary. */
20655 + 32 - info->first_gp_reg_save
20656 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20657 + 63 + 1 - info->first_fp_reg_save);
20659 strcpy (rname, ((crtl->calls_eh_return) ?
20660 "*eh_rest_world_r10" : "*rest_world"));
20661 alloc_rname = ggc_strdup (rname);
20664 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
20665 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20666 gen_rtx_REG (Pmode,
20669 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20670 /* The instruction pattern requires a clobber here;
20671 it is shared with the restVEC helper. */
20673 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20676 /* CR register traditionally saved as CR2. */
20677 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20678 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20679 GEN_INT (info->cr_save_offset));
20680 rtx mem = gen_frame_mem (reg_mode, addr);
20682 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20685 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20687 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20688 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20689 GEN_INT (info->gp_save_offset
20691 rtx mem = gen_frame_mem (reg_mode, addr);
20693 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20695 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20697 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20698 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20699 GEN_INT (info->altivec_save_offset
20701 rtx mem = gen_frame_mem (V4SImode, addr);
20703 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20705 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20707 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20708 ? DFmode : SFmode),
20709 info->first_fp_reg_save + i);
20710 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20711 GEN_INT (info->fp_save_offset
20713 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20714 ? DFmode : SFmode), addr);
20716 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20719 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20721 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20723 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20725 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20727 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20728 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20733 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20735 sp_offset = info->total_size;
20737 /* Restore AltiVec registers if we must do so before adjusting the
20739 if (TARGET_ALTIVEC_ABI
20740 && info->altivec_size != 0
20741 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20742 || (DEFAULT_ABI != ABI_V4
20743 && offset_below_red_zone_p (info->altivec_save_offset))))
20747 if (use_backchain_to_restore_sp)
20749 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20750 emit_move_insn (frame_reg_rtx,
20751 gen_rtx_MEM (Pmode, sp_reg_rtx));
20754 else if (frame_pointer_needed)
20755 frame_reg_rtx = hard_frame_pointer_rtx;
20757 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20758 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20760 rtx addr, areg, mem, reg;
20762 areg = gen_rtx_REG (Pmode, 0);
20764 (areg, GEN_INT (info->altivec_save_offset
20766 + 16 * (i - info->first_altivec_reg_save)));
20768 /* AltiVec addressing mode is [reg+reg]. */
20769 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20770 mem = gen_frame_mem (V4SImode, addr);
20772 reg = gen_rtx_REG (V4SImode, i);
20773 emit_move_insn (reg, mem);
20774 if (offset_below_red_zone_p (info->altivec_save_offset
20775 + (i - info->first_altivec_reg_save)
20777 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20782 /* Restore VRSAVE if we must do so before adjusting the stack. */
20784 && TARGET_ALTIVEC_VRSAVE
20785 && info->vrsave_mask != 0
20786 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20787 || (DEFAULT_ABI != ABI_V4
20788 && offset_below_red_zone_p (info->vrsave_save_offset))))
20790 rtx addr, mem, reg;
20792 if (frame_reg_rtx == sp_reg_rtx)
20794 if (use_backchain_to_restore_sp)
20796 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20797 emit_move_insn (frame_reg_rtx,
20798 gen_rtx_MEM (Pmode, sp_reg_rtx));
20801 else if (frame_pointer_needed)
20802 frame_reg_rtx = hard_frame_pointer_rtx;
20805 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20806 GEN_INT (info->vrsave_save_offset + sp_offset));
20807 mem = gen_frame_mem (SImode, addr);
20808 reg = gen_rtx_REG (SImode, 12);
20809 emit_move_insn (reg, mem);
20811 emit_insn (generate_set_vrsave (reg, info, 1));
20815 /* If we have a large stack frame, restore the old stack pointer
20816 using the backchain. */
20817 if (use_backchain_to_restore_sp)
20819 if (frame_reg_rtx == sp_reg_rtx)
20821 /* Under V.4, don't reset the stack pointer until after we're done
20822 loading the saved registers. */
20823 if (DEFAULT_ABI == ABI_V4)
20824 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20826 insn = emit_move_insn (frame_reg_rtx,
20827 gen_rtx_MEM (Pmode, sp_reg_rtx));
20830 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20831 && DEFAULT_ABI == ABI_V4)
20832 /* frame_reg_rtx has been set up by the altivec restore. */
20836 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20837 frame_reg_rtx = sp_reg_rtx;
20840 /* If we have a frame pointer, we can restore the old stack pointer
20842 else if (frame_pointer_needed)
20844 frame_reg_rtx = sp_reg_rtx;
20845 if (DEFAULT_ABI == ABI_V4)
20846 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20847 /* Prevent reordering memory accesses against stack pointer restore. */
20848 else if (cfun->calls_alloca
20849 || offset_below_red_zone_p (-info->total_size))
20851 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20852 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20853 MEM_NOTRAP_P (mem1) = 1;
20854 MEM_NOTRAP_P (mem2) = 1;
20855 emit_insn (gen_frame_tie (mem1, mem2));
20858 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20859 GEN_INT (info->total_size)));
20862 else if (info->push_p
20863 && DEFAULT_ABI != ABI_V4
20864 && !crtl->calls_eh_return)
20866 /* Prevent reordering memory accesses against stack pointer restore. */
20867 if (cfun->calls_alloca
20868 || offset_below_red_zone_p (-info->total_size))
20870 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20871 MEM_NOTRAP_P (mem) = 1;
20872 emit_insn (gen_stack_tie (mem));
20874 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20875 GEN_INT (info->total_size)));
20878 if (insn && frame_reg_rtx == sp_reg_rtx)
20882 REG_NOTES (insn) = cfa_restores;
20883 cfa_restores = NULL_RTX;
20885 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20886 RTX_FRAME_RELATED_P (insn) = 1;
20889 /* Restore AltiVec registers if we have not done so already. */
20890 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20891 && TARGET_ALTIVEC_ABI
20892 && info->altivec_size != 0
20893 && (DEFAULT_ABI == ABI_V4
20894 || !offset_below_red_zone_p (info->altivec_save_offset)))
20898 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20899 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20901 rtx addr, areg, mem, reg;
20903 areg = gen_rtx_REG (Pmode, 0);
20905 (areg, GEN_INT (info->altivec_save_offset
20907 + 16 * (i - info->first_altivec_reg_save)));
20909 /* AltiVec addressing mode is [reg+reg]. */
20910 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20911 mem = gen_frame_mem (V4SImode, addr);
20913 reg = gen_rtx_REG (V4SImode, i);
20914 emit_move_insn (reg, mem);
20915 if (DEFAULT_ABI == ABI_V4)
20916 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20921 /* Restore VRSAVE if we have not done so already. */
20922 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20924 && TARGET_ALTIVEC_VRSAVE
20925 && info->vrsave_mask != 0
20926 && (DEFAULT_ABI == ABI_V4
20927 || !offset_below_red_zone_p (info->vrsave_save_offset)))
20929 rtx addr, mem, reg;
20931 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20932 GEN_INT (info->vrsave_save_offset + sp_offset));
20933 mem = gen_frame_mem (SImode, addr);
20934 reg = gen_rtx_REG (SImode, 12);
20935 emit_move_insn (reg, mem);
20937 emit_insn (generate_set_vrsave (reg, info, 1));
20940 /* Get the old lr if we saved it. If we are restoring registers
20941 out-of-line, then the out-of-line routines can do this for us. */
20942 if (restore_lr && restoring_GPRs_inline)
20944 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20945 info->lr_save_offset + sp_offset);
20947 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20950 /* Get the old cr if we saved it. */
20951 if (info->cr_save_p)
20953 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20954 GEN_INT (info->cr_save_offset + sp_offset));
20955 rtx mem = gen_frame_mem (SImode, addr);
20957 cr_save_reg = gen_rtx_REG (SImode,
20958 DEFAULT_ABI == ABI_AIX
20959 && !restoring_GPRs_inline
20960 && info->first_fp_reg_save < 64
20962 emit_move_insn (cr_save_reg, mem);
20965 /* Set LR here to try to overlap restores below. LR is always saved
20966 above incoming stack, so it never needs REG_CFA_RESTORE. */
20967 if (restore_lr && restoring_GPRs_inline)
20968 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20969 gen_rtx_REG (Pmode, 0));
20971 /* Load exception handler data registers, if needed. */
20972 if (crtl->calls_eh_return)
20974 unsigned int i, regno;
20978 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20979 GEN_INT (sp_offset + 5 * reg_size));
20980 rtx mem = gen_frame_mem (reg_mode, addr);
20982 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
20989 regno = EH_RETURN_DATA_REGNO (i);
20990 if (regno == INVALID_REGNUM)
20993 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
20994 info->ehrd_offset + sp_offset
20995 + reg_size * (int) i);
20997 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21001 /* Restore GPRs. This is done as a PARALLEL if we are using
21002 the load-multiple instructions. */
21004 && info->spe_64bit_regs_used != 0
21005 && info->first_gp_reg_save != 32)
21007 /* Determine whether we can address all of the registers that need
21008 to be saved with an offset from the stack pointer that fits in
21009 the small const field for SPE memory instructions. */
21010 int spe_regs_addressable_via_sp
21011 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21012 + (32 - info->first_gp_reg_save - 1) * reg_size)
21013 && restoring_GPRs_inline);
21016 if (spe_regs_addressable_via_sp)
21017 spe_offset = info->spe_gp_save_offset + sp_offset;
21020 rtx old_frame_reg_rtx = frame_reg_rtx;
21021 /* Make r11 point to the start of the SPE save area. We worried about
21022 not clobbering it when we were saving registers in the prologue.
21023 There's no need to worry here because the static chain is passed
21024 anew to every function. */
21025 int ool_adjust = (restoring_GPRs_inline
21027 : (info->first_gp_reg_save
21028 - (FIRST_SAVRES_REGISTER+1))*8);
21030 if (frame_reg_rtx == sp_reg_rtx)
21031 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21032 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21033 GEN_INT (info->spe_gp_save_offset
21036 /* Keep the invariant that frame_reg_rtx + sp_offset points
21037 at the top of the stack frame. */
21038 sp_offset = -info->spe_gp_save_offset;
21043 if (restoring_GPRs_inline)
21045 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21046 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21048 rtx offset, addr, mem, reg;
21050 /* We're doing all this to ensure that the immediate offset
21051 fits into the immediate field of 'evldd'. */
21052 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21054 offset = GEN_INT (spe_offset + reg_size * i);
21055 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21056 mem = gen_rtx_MEM (V2SImode, addr);
21057 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21059 insn = emit_move_insn (reg, mem);
21060 if (DEFAULT_ABI == ABI_V4)
21062 if (frame_pointer_needed
21063 && info->first_gp_reg_save + i
21064 == HARD_FRAME_POINTER_REGNUM)
21066 add_reg_note (insn, REG_CFA_DEF_CFA,
21067 plus_constant (frame_reg_rtx,
21069 RTX_FRAME_RELATED_P (insn) = 1;
21072 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21081 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21083 /*savep=*/false, /*gpr=*/true,
21085 emit_jump_insn (par);
21086 /* We don't want anybody else emitting things after we jumped
21091 else if (!restoring_GPRs_inline)
21093 /* We are jumping to an out-of-line function. */
21094 bool can_use_exit = info->first_fp_reg_save == 64;
21097 /* Emit stack reset code if we need it. */
21099 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21100 sp_offset, can_use_exit);
21103 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21106 GEN_INT (sp_offset - info->fp_size)));
21107 if (REGNO (frame_reg_rtx) == 11)
21108 sp_offset += info->fp_size;
21111 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21112 info->gp_save_offset, reg_mode,
21113 /*savep=*/false, /*gpr=*/true,
21114 /*lr=*/can_use_exit);
21118 if (info->cr_save_p)
21120 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21121 if (DEFAULT_ABI == ABI_V4)
21123 = alloc_reg_note (REG_CFA_RESTORE,
21124 gen_rtx_REG (SImode, CR2_REGNO),
21128 emit_jump_insn (par);
21130 /* We don't want anybody else emitting things after we jumped
21135 insn = emit_insn (par);
21136 if (DEFAULT_ABI == ABI_V4)
21138 if (frame_pointer_needed)
21140 add_reg_note (insn, REG_CFA_DEF_CFA,
21141 plus_constant (frame_reg_rtx, sp_offset));
21142 RTX_FRAME_RELATED_P (insn) = 1;
21145 for (i = info->first_gp_reg_save; i < 32; i++)
21147 = alloc_reg_note (REG_CFA_RESTORE,
21148 gen_rtx_REG (reg_mode, i), cfa_restores);
21151 else if (using_load_multiple)
21154 p = rtvec_alloc (32 - info->first_gp_reg_save);
21155 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21157 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21158 GEN_INT (info->gp_save_offset
21161 rtx mem = gen_frame_mem (reg_mode, addr);
21162 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21164 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21165 if (DEFAULT_ABI == ABI_V4)
21166 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21169 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21170 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21172 add_reg_note (insn, REG_CFA_DEF_CFA,
21173 plus_constant (frame_reg_rtx, sp_offset));
21174 RTX_FRAME_RELATED_P (insn) = 1;
21179 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21180 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21182 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21183 GEN_INT (info->gp_save_offset
21186 rtx mem = gen_frame_mem (reg_mode, addr);
21187 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21189 insn = emit_move_insn (reg, mem);
21190 if (DEFAULT_ABI == ABI_V4)
21192 if (frame_pointer_needed
21193 && info->first_gp_reg_save + i
21194 == HARD_FRAME_POINTER_REGNUM)
21196 add_reg_note (insn, REG_CFA_DEF_CFA,
21197 plus_constant (frame_reg_rtx, sp_offset));
21198 RTX_FRAME_RELATED_P (insn) = 1;
21201 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21207 if (restore_lr && !restoring_GPRs_inline)
21209 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21210 info->lr_save_offset + sp_offset);
21212 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21213 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21214 gen_rtx_REG (Pmode, 0));
21217 /* Restore fpr's if we need to do it without calling a function. */
21218 if (restoring_FPRs_inline)
21219 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21220 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21221 && ! call_used_regs[info->first_fp_reg_save+i]))
21223 rtx addr, mem, reg;
21224 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21225 GEN_INT (info->fp_save_offset
21228 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21229 ? DFmode : SFmode), addr);
21230 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21231 ? DFmode : SFmode),
21232 info->first_fp_reg_save + i);
21234 emit_move_insn (reg, mem);
21235 if (DEFAULT_ABI == ABI_V4)
21236 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21240 /* If we saved cr, restore it here. Just those that were used. */
21241 if (info->cr_save_p)
21243 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21244 if (DEFAULT_ABI == ABI_V4)
21246 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21250 /* If this is V.4, unwind the stack pointer after all of the loads
21252 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21253 sp_offset, !restoring_FPRs_inline);
21258 REG_NOTES (insn) = cfa_restores;
21259 cfa_restores = NULL_RTX;
21261 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21262 RTX_FRAME_RELATED_P (insn) = 1;
21265 if (crtl->calls_eh_return)
21267 rtx sa = EH_RETURN_STACKADJ_RTX;
21268 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21274 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21275 if (! restoring_FPRs_inline)
21276 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21278 p = rtvec_alloc (2);
21280 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21281 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21282 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21283 : gen_rtx_CLOBBER (VOIDmode,
21284 gen_rtx_REG (Pmode, 65)));
21286 /* If we have to restore more than two FP registers, branch to the
21287 restore function. It will return to our caller. */
21288 if (! restoring_FPRs_inline)
21293 sym = rs6000_savres_routine_sym (info,
21297 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21298 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21299 gen_rtx_REG (Pmode,
21300 DEFAULT_ABI == ABI_AIX
21302 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21305 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21306 GEN_INT (info->fp_save_offset + 8*i));
21307 mem = gen_frame_mem (DFmode, addr);
21309 RTVEC_ELT (p, i+4) =
21310 gen_rtx_SET (VOIDmode,
21311 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21316 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21320 /* Write function epilogue. */
21323 rs6000_output_function_epilogue (FILE *file,
21324 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21326 if (! HAVE_epilogue)
21328 rtx insn = get_last_insn ();
21329 /* If the last insn was a BARRIER, we don't have to write anything except
21330 the trace table. */
21331 if (GET_CODE (insn) == NOTE)
21332 insn = prev_nonnote_insn (insn);
21333 if (insn == 0 || GET_CODE (insn) != BARRIER)
21335 /* This is slightly ugly, but at least we don't have two
21336 copies of the epilogue-emitting code. */
21339 /* A NOTE_INSN_DELETED is supposed to be at the start
21340 and end of the "toplevel" insn chain. */
21341 emit_note (NOTE_INSN_DELETED);
21342 rs6000_emit_epilogue (FALSE);
21343 emit_note (NOTE_INSN_DELETED);
21345 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21349 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21351 INSN_ADDRESSES_NEW (insn, addr);
21356 if (TARGET_DEBUG_STACK)
21357 debug_rtx_list (get_insns (), 100);
21358 final (get_insns (), file, FALSE);
21364 macho_branch_islands ();
21365 /* Mach-O doesn't support labels at the end of objects, so if
21366 it looks like we might want one, insert a NOP. */
21368 rtx insn = get_last_insn ();
21371 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21372 insn = PREV_INSN (insn);
21376 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21377 fputs ("\tnop\n", file);
21381 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21384 We don't output a traceback table if -finhibit-size-directive was
21385 used. The documentation for -finhibit-size-directive reads
21386 ``don't output a @code{.size} assembler directive, or anything
21387 else that would cause trouble if the function is split in the
21388 middle, and the two halves are placed at locations far apart in
21389 memory.'' The traceback table has this property, since it
21390 includes the offset from the start of the function to the
21391 traceback table itself.
21393 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21394 different traceback table. */
21395 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21396 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21398 const char *fname = NULL;
21399 const char *language_string = lang_hooks.name;
21400 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21402 int optional_tbtab;
21403 rs6000_stack_t *info = rs6000_stack_info ();
21405 if (rs6000_traceback == traceback_full)
21406 optional_tbtab = 1;
21407 else if (rs6000_traceback == traceback_part)
21408 optional_tbtab = 0;
21410 optional_tbtab = !optimize_size && !TARGET_ELF;
21412 if (optional_tbtab)
21414 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21415 while (*fname == '.') /* V.4 encodes . in the name */
21418 /* Need label immediately before tbtab, so we can compute
21419 its offset from the function start. */
21420 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21421 ASM_OUTPUT_LABEL (file, fname);
21424 /* The .tbtab pseudo-op can only be used for the first eight
21425 expressions, since it can't handle the possibly variable
21426 length fields that follow. However, if you omit the optional
21427 fields, the assembler outputs zeros for all optional fields
21428 anyways, giving each variable length field is minimum length
21429 (as defined in sys/debug.h). Thus we can not use the .tbtab
21430 pseudo-op at all. */
21432 /* An all-zero word flags the start of the tbtab, for debuggers
21433 that have to find it by searching forward from the entry
21434 point or from the current pc. */
21435 fputs ("\t.long 0\n", file);
21437 /* Tbtab format type. Use format type 0. */
21438 fputs ("\t.byte 0,", file);
21440 /* Language type. Unfortunately, there does not seem to be any
21441 official way to discover the language being compiled, so we
21442 use language_string.
21443 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21444 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21445 a number, so for now use 9. LTO isn't assigned a number either,
21446 so for now use 0. */
21447 if (! strcmp (language_string, "GNU C")
21448 || ! strcmp (language_string, "GNU GIMPLE"))
21450 else if (! strcmp (language_string, "GNU F77")
21451 || ! strcmp (language_string, "GNU Fortran"))
21453 else if (! strcmp (language_string, "GNU Pascal"))
21455 else if (! strcmp (language_string, "GNU Ada"))
21457 else if (! strcmp (language_string, "GNU C++")
21458 || ! strcmp (language_string, "GNU Objective-C++"))
21460 else if (! strcmp (language_string, "GNU Java"))
21462 else if (! strcmp (language_string, "GNU Objective-C"))
21465 gcc_unreachable ();
21466 fprintf (file, "%d,", i);
21468 /* 8 single bit fields: global linkage (not set for C extern linkage,
21469 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21470 from start of procedure stored in tbtab, internal function, function
21471 has controlled storage, function has no toc, function uses fp,
21472 function logs/aborts fp operations. */
21473 /* Assume that fp operations are used if any fp reg must be saved. */
21474 fprintf (file, "%d,",
21475 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21477 /* 6 bitfields: function is interrupt handler, name present in
21478 proc table, function calls alloca, on condition directives
21479 (controls stack walks, 3 bits), saves condition reg, saves
21481 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21482 set up as a frame pointer, even when there is no alloca call. */
21483 fprintf (file, "%d,",
21484 ((optional_tbtab << 6)
21485 | ((optional_tbtab & frame_pointer_needed) << 5)
21486 | (info->cr_save_p << 1)
21487 | (info->lr_save_p)));
21489 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21491 fprintf (file, "%d,",
21492 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21494 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21495 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21497 if (optional_tbtab)
21499 /* Compute the parameter info from the function decl argument
21502 int next_parm_info_bit = 31;
21504 for (decl = DECL_ARGUMENTS (current_function_decl);
21505 decl; decl = DECL_CHAIN (decl))
21507 rtx parameter = DECL_INCOMING_RTL (decl);
21508 enum machine_mode mode = GET_MODE (parameter);
21510 if (GET_CODE (parameter) == REG)
21512 if (SCALAR_FLOAT_MODE_P (mode))
21533 gcc_unreachable ();
21536 /* If only one bit will fit, don't or in this entry. */
21537 if (next_parm_info_bit > 0)
21538 parm_info |= (bits << (next_parm_info_bit - 1));
21539 next_parm_info_bit -= 2;
21543 fixed_parms += ((GET_MODE_SIZE (mode)
21544 + (UNITS_PER_WORD - 1))
21546 next_parm_info_bit -= 1;
21552 /* Number of fixed point parameters. */
21553 /* This is actually the number of words of fixed point parameters; thus
21554 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21555 fprintf (file, "%d,", fixed_parms);
21557 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21559 /* This is actually the number of fp registers that hold parameters;
21560 and thus the maximum value is 13. */
21561 /* Set parameters on stack bit if parameters are not in their original
21562 registers, regardless of whether they are on the stack? Xlc
21563 seems to set the bit when not optimizing. */
21564 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21566 if (! optional_tbtab)
21569 /* Optional fields follow. Some are variable length. */
21571 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21572 11 double float. */
21573 /* There is an entry for each parameter in a register, in the order that
21574 they occur in the parameter list. Any intervening arguments on the
21575 stack are ignored. If the list overflows a long (max possible length
21576 34 bits) then completely leave off all elements that don't fit. */
21577 /* Only emit this long if there was at least one parameter. */
21578 if (fixed_parms || float_parms)
21579 fprintf (file, "\t.long %d\n", parm_info);
21581 /* Offset from start of code to tb table. */
21582 fputs ("\t.long ", file);
21583 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21584 RS6000_OUTPUT_BASENAME (file, fname);
21586 rs6000_output_function_entry (file, fname);
21589 /* Interrupt handler mask. */
21590 /* Omit this long, since we never set the interrupt handler bit
21593 /* Number of CTL (controlled storage) anchors. */
21594 /* Omit this long, since the has_ctl bit is never set above. */
21596 /* Displacement into stack of each CTL anchor. */
21597 /* Omit this list of longs, because there are no CTL anchors. */
21599 /* Length of function name. */
21602 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21604 /* Function name. */
21605 assemble_string (fname, strlen (fname));
21607 /* Register for alloca automatic storage; this is always reg 31.
21608 Only emit this if the alloca bit was set above. */
21609 if (frame_pointer_needed)
21610 fputs ("\t.byte 31\n", file);
21612 fputs ("\t.align 2\n", file);
21616 /* A C compound statement that outputs the assembler code for a thunk
21617 function, used to implement C++ virtual function calls with
21618 multiple inheritance. The thunk acts as a wrapper around a virtual
21619 function, adjusting the implicit object parameter before handing
21620 control off to the real function.
21622 First, emit code to add the integer DELTA to the location that
21623 contains the incoming first argument. Assume that this argument
21624 contains a pointer, and is the one used to pass the `this' pointer
21625 in C++. This is the incoming argument *before* the function
21626 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21627 values of all other incoming arguments.
21629 After the addition, emit code to jump to FUNCTION, which is a
21630 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21631 not touch the return address. Hence returning from FUNCTION will
21632 return to whoever called the current `thunk'.
21634 The effect must be as if FUNCTION had been called directly with the
21635 adjusted first argument. This macro is responsible for emitting
21636 all of the code for a thunk function; output_function_prologue()
21637 and output_function_epilogue() are not invoked.
21639 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21640 been extracted from it.) It might possibly be useful on some
21641 targets, but probably not.
21643 If you do not define this macro, the target-independent code in the
21644 C++ frontend will generate a less efficient heavyweight thunk that
21645 calls FUNCTION instead of jumping to it. The generic approach does
21646 not support varargs. */
21649 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21650 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21653 rtx this_rtx, insn, funexp;
21655 reload_completed = 1;
21656 epilogue_completed = 1;
21658 /* Mark the end of the (empty) prologue. */
21659 emit_note (NOTE_INSN_PROLOGUE_END);
21661 /* Find the "this" pointer. If the function returns a structure,
21662 the structure return pointer is in r3. */
21663 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21664 this_rtx = gen_rtx_REG (Pmode, 4);
21666 this_rtx = gen_rtx_REG (Pmode, 3);
21668 /* Apply the constant offset, if required. */
21670 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21672 /* Apply the offset from the vtable, if required. */
21675 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21676 rtx tmp = gen_rtx_REG (Pmode, 12);
21678 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21679 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21681 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21682 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21686 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21688 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21690 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21693 /* Generate a tail call to the target function. */
21694 if (!TREE_USED (function))
21696 assemble_external (function);
21697 TREE_USED (function) = 1;
21699 funexp = XEXP (DECL_RTL (function), 0);
21700 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21703 if (MACHOPIC_INDIRECT)
21704 funexp = machopic_indirect_call_target (funexp);
21707 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21708 generate sibcall RTL explicitly. */
21709 insn = emit_call_insn (
21710 gen_rtx_PARALLEL (VOIDmode,
21712 gen_rtx_CALL (VOIDmode,
21713 funexp, const0_rtx),
21714 gen_rtx_USE (VOIDmode, const0_rtx),
21715 gen_rtx_USE (VOIDmode,
21716 gen_rtx_REG (SImode,
21718 gen_rtx_RETURN (VOIDmode))));
21719 SIBLING_CALL_P (insn) = 1;
21722 /* Run just enough of rest_of_compilation to get the insns emitted.
21723 There's not really enough bulk here to make other passes such as
21724 instruction scheduling worth while. Note that use_thunk calls
21725 assemble_start_function and assemble_end_function. */
21726 insn = get_insns ();
21727 insn_locators_alloc ();
21728 shorten_branches (insn);
21729 final_start_function (insn, file, 1);
21730 final (insn, file, 1);
21731 final_end_function ();
21733 reload_completed = 0;
21734 epilogue_completed = 0;
21737 /* A quick summary of the various types of 'constant-pool tables'
21740 Target Flags Name One table per
21741 AIX (none) AIX TOC object file
21742 AIX -mfull-toc AIX TOC object file
21743 AIX -mminimal-toc AIX minimal TOC translation unit
21744 SVR4/EABI (none) SVR4 SDATA object file
21745 SVR4/EABI -fpic SVR4 pic object file
21746 SVR4/EABI -fPIC SVR4 PIC translation unit
21747 SVR4/EABI -mrelocatable EABI TOC function
21748 SVR4/EABI -maix AIX TOC object file
21749 SVR4/EABI -maix -mminimal-toc
21750 AIX minimal TOC translation unit
21752 Name Reg. Set by entries contains:
21753 made by addrs? fp? sum?
21755 AIX TOC 2 crt0 as Y option option
21756 AIX minimal TOC 30 prolog gcc Y Y option
21757 SVR4 SDATA 13 crt0 gcc N Y N
21758 SVR4 pic 30 prolog ld Y not yet N
21759 SVR4 PIC 30 prolog gcc Y option option
21760 EABI TOC 30 prolog gcc Y option option
21764 /* Hash functions for the hash table. */
21767 rs6000_hash_constant (rtx k)
21769 enum rtx_code code = GET_CODE (k);
21770 enum machine_mode mode = GET_MODE (k);
21771 unsigned result = (code << 3) ^ mode;
21772 const char *format;
21775 format = GET_RTX_FORMAT (code);
21776 flen = strlen (format);
21782 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21785 if (mode != VOIDmode)
21786 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21798 for (; fidx < flen; fidx++)
21799 switch (format[fidx])
21804 const char *str = XSTR (k, fidx);
21805 len = strlen (str);
21806 result = result * 613 + len;
21807 for (i = 0; i < len; i++)
21808 result = result * 613 + (unsigned) str[i];
21813 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21817 result = result * 613 + (unsigned) XINT (k, fidx);
21820 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21821 result = result * 613 + (unsigned) XWINT (k, fidx);
21825 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21826 result = result * 613 + (unsigned) (XWINT (k, fidx)
21833 gcc_unreachable ();
21840 toc_hash_function (const void *hash_entry)
21842 const struct toc_hash_struct *thc =
21843 (const struct toc_hash_struct *) hash_entry;
21844 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21847 /* Compare H1 and H2 for equivalence. */
21850 toc_hash_eq (const void *h1, const void *h2)
21852 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21853 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21855 if (((const struct toc_hash_struct *) h1)->key_mode
21856 != ((const struct toc_hash_struct *) h2)->key_mode)
21859 return rtx_equal_p (r1, r2);
21862 /* These are the names given by the C++ front-end to vtables, and
21863 vtable-like objects. Ideally, this logic should not be here;
21864 instead, there should be some programmatic way of inquiring as
21865 to whether or not an object is a vtable. */
21867 #define VTABLE_NAME_P(NAME) \
21868 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21869 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21870 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21871 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21872 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21874 #ifdef NO_DOLLAR_IN_LABEL
21875 /* Return a GGC-allocated character string translating dollar signs in
21876 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21879 rs6000_xcoff_strip_dollar (const char *name)
21884 p = strchr (name, '$');
21886 if (p == 0 || p == name)
21889 len = strlen (name);
21890 strip = (char *) alloca (len + 1);
21891 strcpy (strip, name);
21892 p = strchr (strip, '$');
21896 p = strchr (p + 1, '$');
21899 return ggc_alloc_string (strip, len);
21904 rs6000_output_symbol_ref (FILE *file, rtx x)
21906 /* Currently C++ toc references to vtables can be emitted before it
21907 is decided whether the vtable is public or private. If this is
21908 the case, then the linker will eventually complain that there is
21909 a reference to an unknown section. Thus, for vtables only,
21910 we emit the TOC reference to reference the symbol and not the
21912 const char *name = XSTR (x, 0);
21914 if (VTABLE_NAME_P (name))
21916 RS6000_OUTPUT_BASENAME (file, name);
21919 assemble_name (file, name);
21922 /* Output a TOC entry. We derive the entry name from what is being
21926 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
21929 const char *name = buf;
21931 HOST_WIDE_INT offset = 0;
21933 gcc_assert (!TARGET_NO_TOC);
21935 /* When the linker won't eliminate them, don't output duplicate
21936 TOC entries (this happens on AIX if there is any kind of TOC,
21937 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
21939 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
21941 struct toc_hash_struct *h;
21944 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
21945 time because GGC is not initialized at that point. */
21946 if (toc_hash_table == NULL)
21947 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
21948 toc_hash_eq, NULL);
21950 h = ggc_alloc_toc_hash_struct ();
21952 h->key_mode = mode;
21953 h->labelno = labelno;
21955 found = htab_find_slot (toc_hash_table, h, INSERT);
21956 if (*found == NULL)
21958 else /* This is indeed a duplicate.
21959 Set this label equal to that label. */
21961 fputs ("\t.set ", file);
21962 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21963 fprintf (file, "%d,", labelno);
21964 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21965 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
21971 /* If we're going to put a double constant in the TOC, make sure it's
21972 aligned properly when strict alignment is on. */
21973 if (GET_CODE (x) == CONST_DOUBLE
21974 && STRICT_ALIGNMENT
21975 && GET_MODE_BITSIZE (mode) >= 64
21976 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
21977 ASM_OUTPUT_ALIGN (file, 3);
21980 (*targetm.asm_out.internal_label) (file, "LC", labelno);
21982 /* Handle FP constants specially. Note that if we have a minimal
21983 TOC, things we put here aren't actually in the TOC, so we can allow
21985 if (GET_CODE (x) == CONST_DOUBLE &&
21986 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
21988 REAL_VALUE_TYPE rv;
21991 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21992 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21993 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
21995 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
21999 if (TARGET_MINIMAL_TOC)
22000 fputs (DOUBLE_INT_ASM_OP, file);
22002 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22003 k[0] & 0xffffffff, k[1] & 0xffffffff,
22004 k[2] & 0xffffffff, k[3] & 0xffffffff);
22005 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22006 k[0] & 0xffffffff, k[1] & 0xffffffff,
22007 k[2] & 0xffffffff, k[3] & 0xffffffff);
22012 if (TARGET_MINIMAL_TOC)
22013 fputs ("\t.long ", file);
22015 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22016 k[0] & 0xffffffff, k[1] & 0xffffffff,
22017 k[2] & 0xffffffff, k[3] & 0xffffffff);
22018 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22019 k[0] & 0xffffffff, k[1] & 0xffffffff,
22020 k[2] & 0xffffffff, k[3] & 0xffffffff);
22024 else if (GET_CODE (x) == CONST_DOUBLE &&
22025 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22027 REAL_VALUE_TYPE rv;
22030 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22032 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22033 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22035 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22039 if (TARGET_MINIMAL_TOC)
22040 fputs (DOUBLE_INT_ASM_OP, file);
22042 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22043 k[0] & 0xffffffff, k[1] & 0xffffffff);
22044 fprintf (file, "0x%lx%08lx\n",
22045 k[0] & 0xffffffff, k[1] & 0xffffffff);
22050 if (TARGET_MINIMAL_TOC)
22051 fputs ("\t.long ", file);
22053 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22054 k[0] & 0xffffffff, k[1] & 0xffffffff);
22055 fprintf (file, "0x%lx,0x%lx\n",
22056 k[0] & 0xffffffff, k[1] & 0xffffffff);
22060 else if (GET_CODE (x) == CONST_DOUBLE &&
22061 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22063 REAL_VALUE_TYPE rv;
22066 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22067 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22068 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22070 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22074 if (TARGET_MINIMAL_TOC)
22075 fputs (DOUBLE_INT_ASM_OP, file);
22077 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22078 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22083 if (TARGET_MINIMAL_TOC)
22084 fputs ("\t.long ", file);
22086 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22087 fprintf (file, "0x%lx\n", l & 0xffffffff);
22091 else if (GET_MODE (x) == VOIDmode
22092 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22094 unsigned HOST_WIDE_INT low;
22095 HOST_WIDE_INT high;
22097 if (GET_CODE (x) == CONST_DOUBLE)
22099 low = CONST_DOUBLE_LOW (x);
22100 high = CONST_DOUBLE_HIGH (x);
22103 #if HOST_BITS_PER_WIDE_INT == 32
22106 high = (low & 0x80000000) ? ~0 : 0;
22110 low = INTVAL (x) & 0xffffffff;
22111 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22115 /* TOC entries are always Pmode-sized, but since this
22116 is a bigendian machine then if we're putting smaller
22117 integer constants in the TOC we have to pad them.
22118 (This is still a win over putting the constants in
22119 a separate constant pool, because then we'd have
22120 to have both a TOC entry _and_ the actual constant.)
22122 For a 32-bit target, CONST_INT values are loaded and shifted
22123 entirely within `low' and can be stored in one TOC entry. */
22125 /* It would be easy to make this work, but it doesn't now. */
22126 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22128 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22130 #if HOST_BITS_PER_WIDE_INT == 32
22131 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22132 POINTER_SIZE, &low, &high, 0);
22135 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22136 high = (HOST_WIDE_INT) low >> 32;
22143 if (TARGET_MINIMAL_TOC)
22144 fputs (DOUBLE_INT_ASM_OP, file);
22146 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22147 (long) high & 0xffffffff, (long) low & 0xffffffff);
22148 fprintf (file, "0x%lx%08lx\n",
22149 (long) high & 0xffffffff, (long) low & 0xffffffff);
22154 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22156 if (TARGET_MINIMAL_TOC)
22157 fputs ("\t.long ", file);
22159 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22160 (long) high & 0xffffffff, (long) low & 0xffffffff);
22161 fprintf (file, "0x%lx,0x%lx\n",
22162 (long) high & 0xffffffff, (long) low & 0xffffffff);
22166 if (TARGET_MINIMAL_TOC)
22167 fputs ("\t.long ", file);
22169 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22170 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22176 if (GET_CODE (x) == CONST)
22178 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22179 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22181 base = XEXP (XEXP (x, 0), 0);
22182 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22185 switch (GET_CODE (base))
22188 name = XSTR (base, 0);
22192 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22193 CODE_LABEL_NUMBER (XEXP (base, 0)));
22197 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22201 gcc_unreachable ();
22204 if (TARGET_MINIMAL_TOC)
22205 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22208 fputs ("\t.tc ", file);
22209 RS6000_OUTPUT_BASENAME (file, name);
22212 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22214 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22216 fputs ("[TC],", file);
22219 /* Currently C++ toc references to vtables can be emitted before it
22220 is decided whether the vtable is public or private. If this is
22221 the case, then the linker will eventually complain that there is
22222 a TOC reference to an unknown section. Thus, for vtables only,
22223 we emit the TOC reference to reference the symbol and not the
22225 if (VTABLE_NAME_P (name))
22227 RS6000_OUTPUT_BASENAME (file, name);
22229 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22230 else if (offset > 0)
22231 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22234 output_addr_const (file, x);
22238 /* Output an assembler pseudo-op to write an ASCII string of N characters
22239 starting at P to FILE.
22241 On the RS/6000, we have to do this using the .byte operation and
22242 write out special characters outside the quoted string.
22243 Also, the assembler is broken; very long strings are truncated,
22244 so we must artificially break them up early. */
22247 output_ascii (FILE *file, const char *p, int n)
22250 int i, count_string;
22251 const char *for_string = "\t.byte \"";
22252 const char *for_decimal = "\t.byte ";
22253 const char *to_close = NULL;
22256 for (i = 0; i < n; i++)
22259 if (c >= ' ' && c < 0177)
22262 fputs (for_string, file);
22265 /* Write two quotes to get one. */
22273 for_decimal = "\"\n\t.byte ";
22277 if (count_string >= 512)
22279 fputs (to_close, file);
22281 for_string = "\t.byte \"";
22282 for_decimal = "\t.byte ";
22290 fputs (for_decimal, file);
22291 fprintf (file, "%d", c);
22293 for_string = "\n\t.byte \"";
22294 for_decimal = ", ";
22300 /* Now close the string if we have written one. Then end the line. */
22302 fputs (to_close, file);
22305 /* Generate a unique section name for FILENAME for a section type
22306 represented by SECTION_DESC. Output goes into BUF.
22308 SECTION_DESC can be any string, as long as it is different for each
22309 possible section type.
22311 We name the section in the same manner as xlc. The name begins with an
22312 underscore followed by the filename (after stripping any leading directory
22313 names) with the last period replaced by the string SECTION_DESC. If
22314 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22318 rs6000_gen_section_name (char **buf, const char *filename,
22319 const char *section_desc)
22321 const char *q, *after_last_slash, *last_period = 0;
22325 after_last_slash = filename;
22326 for (q = filename; *q; q++)
22329 after_last_slash = q + 1;
22330 else if (*q == '.')
22334 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22335 *buf = (char *) xmalloc (len);
22340 for (q = after_last_slash; *q; q++)
22342 if (q == last_period)
22344 strcpy (p, section_desc);
22345 p += strlen (section_desc);
22349 else if (ISALNUM (*q))
22353 if (last_period == 0)
22354 strcpy (p, section_desc);
22359 /* Emit profile function. */
22362 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22364 /* Non-standard profiling for kernels, which just saves LR then calls
22365 _mcount without worrying about arg saves. The idea is to change
22366 the function prologue as little as possible as it isn't easy to
22367 account for arg save/restore code added just for _mcount. */
22368 if (TARGET_PROFILE_KERNEL)
22371 if (DEFAULT_ABI == ABI_AIX)
22373 #ifndef NO_PROFILE_COUNTERS
22374 # define NO_PROFILE_COUNTERS 0
22376 if (NO_PROFILE_COUNTERS)
22377 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22378 LCT_NORMAL, VOIDmode, 0);
22382 const char *label_name;
22385 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22386 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
22387 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22389 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22390 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22393 else if (DEFAULT_ABI == ABI_DARWIN)
22395 const char *mcount_name = RS6000_MCOUNT;
22396 int caller_addr_regno = LR_REGNO;
22398 /* Be conservative and always set this, at least for now. */
22399 crtl->uses_pic_offset_table = 1;
22402 /* For PIC code, set up a stub and collect the caller's address
22403 from r0, which is where the prologue puts it. */
22404 if (MACHOPIC_INDIRECT
22405 && crtl->uses_pic_offset_table)
22406 caller_addr_regno = 0;
22408 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22409 LCT_NORMAL, VOIDmode, 1,
22410 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22414 /* Write function profiler code. */
22417 output_function_profiler (FILE *file, int labelno)
22421 switch (DEFAULT_ABI)
22424 gcc_unreachable ();
22429 warning (0, "no profiling of 64-bit code for this ABI");
22432 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22433 fprintf (file, "\tmflr %s\n", reg_names[0]);
22434 if (NO_PROFILE_COUNTERS)
22436 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22437 reg_names[0], reg_names[1]);
22439 else if (TARGET_SECURE_PLT && flag_pic)
22441 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22442 reg_names[0], reg_names[1]);
22443 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22444 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22445 reg_names[12], reg_names[12]);
22446 assemble_name (file, buf);
22447 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22448 assemble_name (file, buf);
22449 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22451 else if (flag_pic == 1)
22453 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22454 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22455 reg_names[0], reg_names[1]);
22456 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22457 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22458 assemble_name (file, buf);
22459 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22461 else if (flag_pic > 1)
22463 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22464 reg_names[0], reg_names[1]);
22465 /* Now, we need to get the address of the label. */
22466 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22467 assemble_name (file, buf);
22468 fputs ("-.\n1:", file);
22469 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22470 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22471 reg_names[0], reg_names[11]);
22472 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22473 reg_names[0], reg_names[0], reg_names[11]);
22477 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22478 assemble_name (file, buf);
22479 fputs ("@ha\n", file);
22480 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22481 reg_names[0], reg_names[1]);
22482 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22483 assemble_name (file, buf);
22484 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22487 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22488 fprintf (file, "\tbl %s%s\n",
22489 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22494 if (!TARGET_PROFILE_KERNEL)
22496 /* Don't do anything, done in output_profile_hook (). */
22500 gcc_assert (!TARGET_32BIT);
22502 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22503 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22505 if (cfun->static_chain_decl != NULL)
22507 asm_fprintf (file, "\tstd %s,24(%s)\n",
22508 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22509 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22510 asm_fprintf (file, "\tld %s,24(%s)\n",
22511 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22514 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22522 /* The following variable value is the last issued insn. */
22524 static rtx last_scheduled_insn;
22526 /* The following variable helps to balance issuing of load and
22527 store instructions */
22529 static int load_store_pendulum;
22531 /* Power4 load update and store update instructions are cracked into a
22532 load or store and an integer insn which are executed in the same cycle.
22533 Branches have their own dispatch slot which does not count against the
22534 GCC issue rate, but it changes the program flow so there are no other
22535 instructions to issue in this cycle. */
22538 rs6000_variable_issue_1 (rtx insn, int more)
22540 last_scheduled_insn = insn;
22541 if (GET_CODE (PATTERN (insn)) == USE
22542 || GET_CODE (PATTERN (insn)) == CLOBBER)
22544 cached_can_issue_more = more;
22545 return cached_can_issue_more;
22548 if (insn_terminates_group_p (insn, current_group))
22550 cached_can_issue_more = 0;
22551 return cached_can_issue_more;
22554 /* If no reservation, but reach here */
22555 if (recog_memoized (insn) < 0)
22558 if (rs6000_sched_groups)
22560 if (is_microcoded_insn (insn))
22561 cached_can_issue_more = 0;
22562 else if (is_cracked_insn (insn))
22563 cached_can_issue_more = more > 2 ? more - 2 : 0;
22565 cached_can_issue_more = more - 1;
22567 return cached_can_issue_more;
22570 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22573 cached_can_issue_more = more - 1;
22574 return cached_can_issue_more;
22578 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22580 int r = rs6000_variable_issue_1 (insn, more);
22582 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22586 /* Adjust the cost of a scheduling dependency. Return the new cost of
22587 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22590 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22592 enum attr_type attr_type;
22594 if (! recog_memoized (insn))
22597 switch (REG_NOTE_KIND (link))
22601 /* Data dependency; DEP_INSN writes a register that INSN reads
22602 some cycles later. */
22604 /* Separate a load from a narrower, dependent store. */
22605 if (rs6000_sched_groups
22606 && GET_CODE (PATTERN (insn)) == SET
22607 && GET_CODE (PATTERN (dep_insn)) == SET
22608 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22609 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22610 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22611 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22614 attr_type = get_attr_type (insn);
22619 /* Tell the first scheduling pass about the latency between
22620 a mtctr and bctr (and mtlr and br/blr). The first
22621 scheduling pass will not know about this latency since
22622 the mtctr instruction, which has the latency associated
22623 to it, will be generated by reload. */
22624 return TARGET_POWER ? 5 : 4;
22626 /* Leave some extra cycles between a compare and its
22627 dependent branch, to inhibit expensive mispredicts. */
22628 if ((rs6000_cpu_attr == CPU_PPC603
22629 || rs6000_cpu_attr == CPU_PPC604
22630 || rs6000_cpu_attr == CPU_PPC604E
22631 || rs6000_cpu_attr == CPU_PPC620
22632 || rs6000_cpu_attr == CPU_PPC630
22633 || rs6000_cpu_attr == CPU_PPC750
22634 || rs6000_cpu_attr == CPU_PPC7400
22635 || rs6000_cpu_attr == CPU_PPC7450
22636 || rs6000_cpu_attr == CPU_POWER4
22637 || rs6000_cpu_attr == CPU_POWER5
22638 || rs6000_cpu_attr == CPU_POWER7
22639 || rs6000_cpu_attr == CPU_CELL)
22640 && recog_memoized (dep_insn)
22641 && (INSN_CODE (dep_insn) >= 0))
22643 switch (get_attr_type (dep_insn))
22647 case TYPE_DELAYED_COMPARE:
22648 case TYPE_IMUL_COMPARE:
22649 case TYPE_LMUL_COMPARE:
22650 case TYPE_FPCOMPARE:
22651 case TYPE_CR_LOGICAL:
22652 case TYPE_DELAYED_CR:
22661 case TYPE_STORE_UX:
22663 case TYPE_FPSTORE_U:
22664 case TYPE_FPSTORE_UX:
22665 if ((rs6000_cpu == PROCESSOR_POWER6)
22666 && recog_memoized (dep_insn)
22667 && (INSN_CODE (dep_insn) >= 0))
22670 if (GET_CODE (PATTERN (insn)) != SET)
22671 /* If this happens, we have to extend this to schedule
22672 optimally. Return default for now. */
22675 /* Adjust the cost for the case where the value written
22676 by a fixed point operation is used as the address
22677 gen value on a store. */
22678 switch (get_attr_type (dep_insn))
22685 if (! store_data_bypass_p (dep_insn, insn))
22689 case TYPE_LOAD_EXT:
22690 case TYPE_LOAD_EXT_U:
22691 case TYPE_LOAD_EXT_UX:
22692 case TYPE_VAR_SHIFT_ROTATE:
22693 case TYPE_VAR_DELAYED_COMPARE:
22695 if (! store_data_bypass_p (dep_insn, insn))
22701 case TYPE_FAST_COMPARE:
22704 case TYPE_INSERT_WORD:
22705 case TYPE_INSERT_DWORD:
22706 case TYPE_FPLOAD_U:
22707 case TYPE_FPLOAD_UX:
22709 case TYPE_STORE_UX:
22710 case TYPE_FPSTORE_U:
22711 case TYPE_FPSTORE_UX:
22713 if (! store_data_bypass_p (dep_insn, insn))
22721 case TYPE_IMUL_COMPARE:
22722 case TYPE_LMUL_COMPARE:
22724 if (! store_data_bypass_p (dep_insn, insn))
22730 if (! store_data_bypass_p (dep_insn, insn))
22736 if (! store_data_bypass_p (dep_insn, insn))
22749 case TYPE_LOAD_EXT:
22750 case TYPE_LOAD_EXT_U:
22751 case TYPE_LOAD_EXT_UX:
22752 if ((rs6000_cpu == PROCESSOR_POWER6)
22753 && recog_memoized (dep_insn)
22754 && (INSN_CODE (dep_insn) >= 0))
22757 /* Adjust the cost for the case where the value written
22758 by a fixed point instruction is used within the address
22759 gen portion of a subsequent load(u)(x) */
22760 switch (get_attr_type (dep_insn))
22767 if (set_to_load_agen (dep_insn, insn))
22771 case TYPE_LOAD_EXT:
22772 case TYPE_LOAD_EXT_U:
22773 case TYPE_LOAD_EXT_UX:
22774 case TYPE_VAR_SHIFT_ROTATE:
22775 case TYPE_VAR_DELAYED_COMPARE:
22777 if (set_to_load_agen (dep_insn, insn))
22783 case TYPE_FAST_COMPARE:
22786 case TYPE_INSERT_WORD:
22787 case TYPE_INSERT_DWORD:
22788 case TYPE_FPLOAD_U:
22789 case TYPE_FPLOAD_UX:
22791 case TYPE_STORE_UX:
22792 case TYPE_FPSTORE_U:
22793 case TYPE_FPSTORE_UX:
22795 if (set_to_load_agen (dep_insn, insn))
22803 case TYPE_IMUL_COMPARE:
22804 case TYPE_LMUL_COMPARE:
22806 if (set_to_load_agen (dep_insn, insn))
22812 if (set_to_load_agen (dep_insn, insn))
22818 if (set_to_load_agen (dep_insn, insn))
22829 if ((rs6000_cpu == PROCESSOR_POWER6)
22830 && recog_memoized (dep_insn)
22831 && (INSN_CODE (dep_insn) >= 0)
22832 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22839 /* Fall out to return default cost. */
22843 case REG_DEP_OUTPUT:
22844 /* Output dependency; DEP_INSN writes a register that INSN writes some
22846 if ((rs6000_cpu == PROCESSOR_POWER6)
22847 && recog_memoized (dep_insn)
22848 && (INSN_CODE (dep_insn) >= 0))
22850 attr_type = get_attr_type (insn);
22855 if (get_attr_type (dep_insn) == TYPE_FP)
22859 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22867 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22872 gcc_unreachable ();
22878 /* Debug version of rs6000_adjust_cost. */
22881 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22883 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
22889 switch (REG_NOTE_KIND (link))
22891 default: dep = "unknown depencency"; break;
22892 case REG_DEP_TRUE: dep = "data dependency"; break;
22893 case REG_DEP_OUTPUT: dep = "output dependency"; break;
22894 case REG_DEP_ANTI: dep = "anti depencency"; break;
22898 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22899 "%s, insn:\n", ret, cost, dep);
22907 /* The function returns a true if INSN is microcoded.
22908 Return false otherwise. */
22911 is_microcoded_insn (rtx insn)
22913 if (!insn || !NONDEBUG_INSN_P (insn)
22914 || GET_CODE (PATTERN (insn)) == USE
22915 || GET_CODE (PATTERN (insn)) == CLOBBER)
22918 if (rs6000_cpu_attr == CPU_CELL)
22919 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
22921 if (rs6000_sched_groups)
22923 enum attr_type type = get_attr_type (insn);
22924 if (type == TYPE_LOAD_EXT_U
22925 || type == TYPE_LOAD_EXT_UX
22926 || type == TYPE_LOAD_UX
22927 || type == TYPE_STORE_UX
22928 || type == TYPE_MFCR)
22935 /* The function returns true if INSN is cracked into 2 instructions
22936 by the processor (and therefore occupies 2 issue slots). */
22939 is_cracked_insn (rtx insn)
22941 if (!insn || !NONDEBUG_INSN_P (insn)
22942 || GET_CODE (PATTERN (insn)) == USE
22943 || GET_CODE (PATTERN (insn)) == CLOBBER)
22946 if (rs6000_sched_groups)
22948 enum attr_type type = get_attr_type (insn);
22949 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
22950 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
22951 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
22952 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
22953 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
22954 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
22955 || type == TYPE_IDIV || type == TYPE_LDIV
22956 || type == TYPE_INSERT_WORD)
22963 /* The function returns true if INSN can be issued only from
22964 the branch slot. */
22967 is_branch_slot_insn (rtx insn)
22969 if (!insn || !NONDEBUG_INSN_P (insn)
22970 || GET_CODE (PATTERN (insn)) == USE
22971 || GET_CODE (PATTERN (insn)) == CLOBBER)
22974 if (rs6000_sched_groups)
22976 enum attr_type type = get_attr_type (insn);
22977 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
22985 /* The function returns true if out_inst sets a value that is
22986 used in the address generation computation of in_insn */
22988 set_to_load_agen (rtx out_insn, rtx in_insn)
22990 rtx out_set, in_set;
22992 /* For performance reasons, only handle the simple case where
22993 both loads are a single_set. */
22994 out_set = single_set (out_insn);
22997 in_set = single_set (in_insn);
22999 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23005 /* The function returns true if the target storage location of
23006 out_insn is adjacent to the target storage location of in_insn */
23007 /* Return 1 if memory locations are adjacent. */
23010 adjacent_mem_locations (rtx insn1, rtx insn2)
23013 rtx a = get_store_dest (PATTERN (insn1));
23014 rtx b = get_store_dest (PATTERN (insn2));
23016 if ((GET_CODE (XEXP (a, 0)) == REG
23017 || (GET_CODE (XEXP (a, 0)) == PLUS
23018 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23019 && (GET_CODE (XEXP (b, 0)) == REG
23020 || (GET_CODE (XEXP (b, 0)) == PLUS
23021 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23023 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23026 if (GET_CODE (XEXP (a, 0)) == PLUS)
23028 reg0 = XEXP (XEXP (a, 0), 0);
23029 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23032 reg0 = XEXP (a, 0);
23034 if (GET_CODE (XEXP (b, 0)) == PLUS)
23036 reg1 = XEXP (XEXP (b, 0), 0);
23037 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23040 reg1 = XEXP (b, 0);
23042 val_diff = val1 - val0;
23044 return ((REGNO (reg0) == REGNO (reg1))
23045 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23046 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23052 /* A C statement (sans semicolon) to update the integer scheduling
23053 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23054 INSN earlier, reduce the priority to execute INSN later. Do not
23055 define this macro if you do not need to adjust the scheduling
23056 priorities of insns. */
23059 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23061 /* On machines (like the 750) which have asymmetric integer units,
23062 where one integer unit can do multiply and divides and the other
23063 can't, reduce the priority of multiply/divide so it is scheduled
23064 before other integer operations. */
23067 if (! INSN_P (insn))
23070 if (GET_CODE (PATTERN (insn)) == USE)
23073 switch (rs6000_cpu_attr) {
23075 switch (get_attr_type (insn))
23082 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23083 priority, priority);
23084 if (priority >= 0 && priority < 0x01000000)
23091 if (insn_must_be_first_in_group (insn)
23092 && reload_completed
23093 && current_sched_info->sched_max_insns_priority
23094 && rs6000_sched_restricted_insns_priority)
23097 /* Prioritize insns that can be dispatched only in the first
23099 if (rs6000_sched_restricted_insns_priority == 1)
23100 /* Attach highest priority to insn. This means that in
23101 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23102 precede 'priority' (critical path) considerations. */
23103 return current_sched_info->sched_max_insns_priority;
23104 else if (rs6000_sched_restricted_insns_priority == 2)
23105 /* Increase priority of insn by a minimal amount. This means that in
23106 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23107 considerations precede dispatch-slot restriction considerations. */
23108 return (priority + 1);
23111 if (rs6000_cpu == PROCESSOR_POWER6
23112 && ((load_store_pendulum == -2 && is_load_insn (insn))
23113 || (load_store_pendulum == 2 && is_store_insn (insn))))
23114 /* Attach highest priority to insn if the scheduler has just issued two
23115 stores and this instruction is a load, or two loads and this instruction
23116 is a store. Power6 wants loads and stores scheduled alternately
23118 return current_sched_info->sched_max_insns_priority;
23123 /* Return true if the instruction is nonpipelined on the Cell. */
23125 is_nonpipeline_insn (rtx insn)
23127 enum attr_type type;
23128 if (!insn || !NONDEBUG_INSN_P (insn)
23129 || GET_CODE (PATTERN (insn)) == USE
23130 || GET_CODE (PATTERN (insn)) == CLOBBER)
23133 type = get_attr_type (insn);
23134 if (type == TYPE_IMUL
23135 || type == TYPE_IMUL2
23136 || type == TYPE_IMUL3
23137 || type == TYPE_LMUL
23138 || type == TYPE_IDIV
23139 || type == TYPE_LDIV
23140 || type == TYPE_SDIV
23141 || type == TYPE_DDIV
23142 || type == TYPE_SSQRT
23143 || type == TYPE_DSQRT
23144 || type == TYPE_MFCR
23145 || type == TYPE_MFCRF
23146 || type == TYPE_MFJMPR)
23154 /* Return how many instructions the machine can issue per cycle. */
23157 rs6000_issue_rate (void)
23159 /* Unless scheduling for register pressure, use issue rate of 1 for
23160 first scheduling pass to decrease degradation. */
23161 if (!reload_completed && !flag_sched_pressure)
23164 switch (rs6000_cpu_attr) {
23165 case CPU_RIOS1: /* ? */
23167 case CPU_PPC601: /* ? */
23176 case CPU_PPCE300C2:
23177 case CPU_PPCE300C3:
23178 case CPU_PPCE500MC:
23179 case CPU_PPCE500MC64:
23199 /* Return how many instructions to look ahead for better insn
23203 rs6000_use_sched_lookahead (void)
23205 if (rs6000_cpu_attr == CPU_PPC8540)
23207 if (rs6000_cpu_attr == CPU_CELL)
23208 return (reload_completed ? 8 : 0);
23212 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23214 rs6000_use_sched_lookahead_guard (rtx insn)
23216 if (rs6000_cpu_attr != CPU_CELL)
23219 if (insn == NULL_RTX || !INSN_P (insn))
23222 if (!reload_completed
23223 || is_nonpipeline_insn (insn)
23224 || is_microcoded_insn (insn))
23230 /* Determine is PAT refers to memory. */
23233 is_mem_ref (rtx pat)
23239 /* stack_tie does not produce any real memory traffic. */
23240 if (GET_CODE (pat) == UNSPEC
23241 && XINT (pat, 1) == UNSPEC_TIE)
23244 if (GET_CODE (pat) == MEM)
23247 /* Recursively process the pattern. */
23248 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23250 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23253 ret |= is_mem_ref (XEXP (pat, i));
23254 else if (fmt[i] == 'E')
23255 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23256 ret |= is_mem_ref (XVECEXP (pat, i, j));
23262 /* Determine if PAT is a PATTERN of a load insn. */
23265 is_load_insn1 (rtx pat)
23267 if (!pat || pat == NULL_RTX)
23270 if (GET_CODE (pat) == SET)
23271 return is_mem_ref (SET_SRC (pat));
23273 if (GET_CODE (pat) == PARALLEL)
23277 for (i = 0; i < XVECLEN (pat, 0); i++)
23278 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23285 /* Determine if INSN loads from memory. */
23288 is_load_insn (rtx insn)
23290 if (!insn || !INSN_P (insn))
23293 if (GET_CODE (insn) == CALL_INSN)
23296 return is_load_insn1 (PATTERN (insn));
23299 /* Determine if PAT is a PATTERN of a store insn. */
23302 is_store_insn1 (rtx pat)
23304 if (!pat || pat == NULL_RTX)
23307 if (GET_CODE (pat) == SET)
23308 return is_mem_ref (SET_DEST (pat));
23310 if (GET_CODE (pat) == PARALLEL)
23314 for (i = 0; i < XVECLEN (pat, 0); i++)
23315 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23322 /* Determine if INSN stores to memory. */
23325 is_store_insn (rtx insn)
23327 if (!insn || !INSN_P (insn))
23330 return is_store_insn1 (PATTERN (insn));
23333 /* Return the dest of a store insn. */
23336 get_store_dest (rtx pat)
23338 gcc_assert (is_store_insn1 (pat));
23340 if (GET_CODE (pat) == SET)
23341 return SET_DEST (pat);
23342 else if (GET_CODE (pat) == PARALLEL)
23346 for (i = 0; i < XVECLEN (pat, 0); i++)
23348 rtx inner_pat = XVECEXP (pat, 0, i);
23349 if (GET_CODE (inner_pat) == SET
23350 && is_mem_ref (SET_DEST (inner_pat)))
23354 /* We shouldn't get here, because we should have either a simple
23355 store insn or a store with update which are covered above. */
23359 /* Returns whether the dependence between INSN and NEXT is considered
23360 costly by the given target. */
23363 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23368 /* If the flag is not enabled - no dependence is considered costly;
23369 allow all dependent insns in the same group.
23370 This is the most aggressive option. */
23371 if (rs6000_sched_costly_dep == no_dep_costly)
23374 /* If the flag is set to 1 - a dependence is always considered costly;
23375 do not allow dependent instructions in the same group.
23376 This is the most conservative option. */
23377 if (rs6000_sched_costly_dep == all_deps_costly)
23380 insn = DEP_PRO (dep);
23381 next = DEP_CON (dep);
23383 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23384 && is_load_insn (next)
23385 && is_store_insn (insn))
23386 /* Prevent load after store in the same group. */
23389 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23390 && is_load_insn (next)
23391 && is_store_insn (insn)
23392 && DEP_TYPE (dep) == REG_DEP_TRUE)
23393 /* Prevent load after store in the same group if it is a true
23397 /* The flag is set to X; dependences with latency >= X are considered costly,
23398 and will not be scheduled in the same group. */
23399 if (rs6000_sched_costly_dep <= max_dep_latency
23400 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23406 /* Return the next insn after INSN that is found before TAIL is reached,
23407 skipping any "non-active" insns - insns that will not actually occupy
23408 an issue slot. Return NULL_RTX if such an insn is not found. */
23411 get_next_active_insn (rtx insn, rtx tail)
23413 if (insn == NULL_RTX || insn == tail)
23418 insn = NEXT_INSN (insn);
23419 if (insn == NULL_RTX || insn == tail)
23424 || (NONJUMP_INSN_P (insn)
23425 && GET_CODE (PATTERN (insn)) != USE
23426 && GET_CODE (PATTERN (insn)) != CLOBBER
23427 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23433 /* We are about to begin issuing insns for this clock cycle. */
23436 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23437 rtx *ready ATTRIBUTE_UNUSED,
23438 int *pn_ready ATTRIBUTE_UNUSED,
23439 int clock_var ATTRIBUTE_UNUSED)
23441 int n_ready = *pn_ready;
23444 fprintf (dump, "// rs6000_sched_reorder :\n");
23446 /* Reorder the ready list, if the second to last ready insn
23447 is a nonepipeline insn. */
23448 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23450 if (is_nonpipeline_insn (ready[n_ready - 1])
23451 && (recog_memoized (ready[n_ready - 2]) > 0))
23452 /* Simply swap first two insns. */
23454 rtx tmp = ready[n_ready - 1];
23455 ready[n_ready - 1] = ready[n_ready - 2];
23456 ready[n_ready - 2] = tmp;
23460 if (rs6000_cpu == PROCESSOR_POWER6)
23461 load_store_pendulum = 0;
23463 return rs6000_issue_rate ();
23466 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23469 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23470 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23473 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23475 /* For Power6, we need to handle some special cases to try and keep the
23476 store queue from overflowing and triggering expensive flushes.
23478 This code monitors how load and store instructions are being issued
23479 and skews the ready list one way or the other to increase the likelihood
23480 that a desired instruction is issued at the proper time.
23482 A couple of things are done. First, we maintain a "load_store_pendulum"
23483 to track the current state of load/store issue.
23485 - If the pendulum is at zero, then no loads or stores have been
23486 issued in the current cycle so we do nothing.
23488 - If the pendulum is 1, then a single load has been issued in this
23489 cycle and we attempt to locate another load in the ready list to
23492 - If the pendulum is -2, then two stores have already been
23493 issued in this cycle, so we increase the priority of the first load
23494 in the ready list to increase it's likelihood of being chosen first
23497 - If the pendulum is -1, then a single store has been issued in this
23498 cycle and we attempt to locate another store in the ready list to
23499 issue with it, preferring a store to an adjacent memory location to
23500 facilitate store pairing in the store queue.
23502 - If the pendulum is 2, then two loads have already been
23503 issued in this cycle, so we increase the priority of the first store
23504 in the ready list to increase it's likelihood of being chosen first
23507 - If the pendulum < -2 or > 2, then do nothing.
23509 Note: This code covers the most common scenarios. There exist non
23510 load/store instructions which make use of the LSU and which
23511 would need to be accounted for to strictly model the behavior
23512 of the machine. Those instructions are currently unaccounted
23513 for to help minimize compile time overhead of this code.
23515 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23521 if (is_store_insn (last_scheduled_insn))
23522 /* Issuing a store, swing the load_store_pendulum to the left */
23523 load_store_pendulum--;
23524 else if (is_load_insn (last_scheduled_insn))
23525 /* Issuing a load, swing the load_store_pendulum to the right */
23526 load_store_pendulum++;
23528 return cached_can_issue_more;
23530 /* If the pendulum is balanced, or there is only one instruction on
23531 the ready list, then all is well, so return. */
23532 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23533 return cached_can_issue_more;
23535 if (load_store_pendulum == 1)
23537 /* A load has been issued in this cycle. Scan the ready list
23538 for another load to issue with it */
23543 if (is_load_insn (ready[pos]))
23545 /* Found a load. Move it to the head of the ready list,
23546 and adjust it's priority so that it is more likely to
23549 for (i=pos; i<*pn_ready-1; i++)
23550 ready[i] = ready[i + 1];
23551 ready[*pn_ready-1] = tmp;
23553 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23554 INSN_PRIORITY (tmp)++;
23560 else if (load_store_pendulum == -2)
23562 /* Two stores have been issued in this cycle. Increase the
23563 priority of the first load in the ready list to favor it for
23564 issuing in the next cycle. */
23569 if (is_load_insn (ready[pos])
23571 && INSN_PRIORITY_KNOWN (ready[pos]))
23573 INSN_PRIORITY (ready[pos])++;
23575 /* Adjust the pendulum to account for the fact that a load
23576 was found and increased in priority. This is to prevent
23577 increasing the priority of multiple loads */
23578 load_store_pendulum--;
23585 else if (load_store_pendulum == -1)
23587 /* A store has been issued in this cycle. Scan the ready list for
23588 another store to issue with it, preferring a store to an adjacent
23590 int first_store_pos = -1;
23596 if (is_store_insn (ready[pos]))
23598 /* Maintain the index of the first store found on the
23600 if (first_store_pos == -1)
23601 first_store_pos = pos;
23603 if (is_store_insn (last_scheduled_insn)
23604 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23606 /* Found an adjacent store. Move it to the head of the
23607 ready list, and adjust it's priority so that it is
23608 more likely to stay there */
23610 for (i=pos; i<*pn_ready-1; i++)
23611 ready[i] = ready[i + 1];
23612 ready[*pn_ready-1] = tmp;
23614 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23615 INSN_PRIORITY (tmp)++;
23617 first_store_pos = -1;
23625 if (first_store_pos >= 0)
23627 /* An adjacent store wasn't found, but a non-adjacent store was,
23628 so move the non-adjacent store to the front of the ready
23629 list, and adjust its priority so that it is more likely to
23631 tmp = ready[first_store_pos];
23632 for (i=first_store_pos; i<*pn_ready-1; i++)
23633 ready[i] = ready[i + 1];
23634 ready[*pn_ready-1] = tmp;
23635 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23636 INSN_PRIORITY (tmp)++;
23639 else if (load_store_pendulum == 2)
23641 /* Two loads have been issued in this cycle. Increase the priority
23642 of the first store in the ready list to favor it for issuing in
23648 if (is_store_insn (ready[pos])
23650 && INSN_PRIORITY_KNOWN (ready[pos]))
23652 INSN_PRIORITY (ready[pos])++;
23654 /* Adjust the pendulum to account for the fact that a store
23655 was found and increased in priority. This is to prevent
23656 increasing the priority of multiple stores */
23657 load_store_pendulum++;
23666 return cached_can_issue_more;
23669 /* Return whether the presence of INSN causes a dispatch group termination
23670 of group WHICH_GROUP.
23672 If WHICH_GROUP == current_group, this function will return true if INSN
23673 causes the termination of the current group (i.e, the dispatch group to
23674 which INSN belongs). This means that INSN will be the last insn in the
23675 group it belongs to.
23677 If WHICH_GROUP == previous_group, this function will return true if INSN
23678 causes the termination of the previous group (i.e, the dispatch group that
23679 precedes the group to which INSN belongs). This means that INSN will be
23680 the first insn in the group it belongs to). */
23683 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23690 first = insn_must_be_first_in_group (insn);
23691 last = insn_must_be_last_in_group (insn);
23696 if (which_group == current_group)
23698 else if (which_group == previous_group)
23706 insn_must_be_first_in_group (rtx insn)
23708 enum attr_type type;
23711 || GET_CODE (insn) == NOTE
23712 || DEBUG_INSN_P (insn)
23713 || GET_CODE (PATTERN (insn)) == USE
23714 || GET_CODE (PATTERN (insn)) == CLOBBER)
23717 switch (rs6000_cpu)
23719 case PROCESSOR_POWER5:
23720 if (is_cracked_insn (insn))
23722 case PROCESSOR_POWER4:
23723 if (is_microcoded_insn (insn))
23726 if (!rs6000_sched_groups)
23729 type = get_attr_type (insn);
23736 case TYPE_DELAYED_CR:
23737 case TYPE_CR_LOGICAL:
23751 case PROCESSOR_POWER6:
23752 type = get_attr_type (insn);
23756 case TYPE_INSERT_DWORD:
23760 case TYPE_VAR_SHIFT_ROTATE:
23767 case TYPE_INSERT_WORD:
23768 case TYPE_DELAYED_COMPARE:
23769 case TYPE_IMUL_COMPARE:
23770 case TYPE_LMUL_COMPARE:
23771 case TYPE_FPCOMPARE:
23782 case TYPE_LOAD_EXT_UX:
23784 case TYPE_STORE_UX:
23785 case TYPE_FPLOAD_U:
23786 case TYPE_FPLOAD_UX:
23787 case TYPE_FPSTORE_U:
23788 case TYPE_FPSTORE_UX:
23794 case PROCESSOR_POWER7:
23795 type = get_attr_type (insn);
23799 case TYPE_CR_LOGICAL:
23806 case TYPE_DELAYED_COMPARE:
23807 case TYPE_VAR_DELAYED_COMPARE:
23813 case TYPE_LOAD_EXT:
23814 case TYPE_LOAD_EXT_U:
23815 case TYPE_LOAD_EXT_UX:
23817 case TYPE_STORE_UX:
23818 case TYPE_FPLOAD_U:
23819 case TYPE_FPLOAD_UX:
23820 case TYPE_FPSTORE_U:
23821 case TYPE_FPSTORE_UX:
23837 insn_must_be_last_in_group (rtx insn)
23839 enum attr_type type;
23842 || GET_CODE (insn) == NOTE
23843 || DEBUG_INSN_P (insn)
23844 || GET_CODE (PATTERN (insn)) == USE
23845 || GET_CODE (PATTERN (insn)) == CLOBBER)
23848 switch (rs6000_cpu) {
23849 case PROCESSOR_POWER4:
23850 case PROCESSOR_POWER5:
23851 if (is_microcoded_insn (insn))
23854 if (is_branch_slot_insn (insn))
23858 case PROCESSOR_POWER6:
23859 type = get_attr_type (insn);
23866 case TYPE_VAR_SHIFT_ROTATE:
23873 case TYPE_DELAYED_COMPARE:
23874 case TYPE_IMUL_COMPARE:
23875 case TYPE_LMUL_COMPARE:
23876 case TYPE_FPCOMPARE:
23890 case PROCESSOR_POWER7:
23891 type = get_attr_type (insn);
23899 case TYPE_LOAD_EXT_U:
23900 case TYPE_LOAD_EXT_UX:
23901 case TYPE_STORE_UX:
23914 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
23915 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
23918 is_costly_group (rtx *group_insns, rtx next_insn)
23921 int issue_rate = rs6000_issue_rate ();
23923 for (i = 0; i < issue_rate; i++)
23925 sd_iterator_def sd_it;
23927 rtx insn = group_insns[i];
23932 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
23934 rtx next = DEP_CON (dep);
23936 if (next == next_insn
23937 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
23945 /* Utility of the function redefine_groups.
23946 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
23947 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
23948 to keep it "far" (in a separate group) from GROUP_INSNS, following
23949 one of the following schemes, depending on the value of the flag
23950 -minsert_sched_nops = X:
23951 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
23952 in order to force NEXT_INSN into a separate group.
23953 (2) X < sched_finish_regroup_exact: insert exactly X nops.
23954 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
23955 insertion (has a group just ended, how many vacant issue slots remain in the
23956 last group, and how many dispatch groups were encountered so far). */
23959 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
23960 rtx next_insn, bool *group_end, int can_issue_more,
23965 int issue_rate = rs6000_issue_rate ();
23966 bool end = *group_end;
23969 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
23970 return can_issue_more;
23972 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
23973 return can_issue_more;
23975 force = is_costly_group (group_insns, next_insn);
23977 return can_issue_more;
23979 if (sched_verbose > 6)
23980 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
23981 *group_count ,can_issue_more);
23983 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
23986 can_issue_more = 0;
23988 /* Since only a branch can be issued in the last issue_slot, it is
23989 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
23990 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
23991 in this case the last nop will start a new group and the branch
23992 will be forced to the new group. */
23993 if (can_issue_more && !is_branch_slot_insn (next_insn))
23996 while (can_issue_more > 0)
23999 emit_insn_before (nop, next_insn);
24007 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24009 int n_nops = rs6000_sched_insert_nops;
24011 /* Nops can't be issued from the branch slot, so the effective
24012 issue_rate for nops is 'issue_rate - 1'. */
24013 if (can_issue_more == 0)
24014 can_issue_more = issue_rate;
24016 if (can_issue_more == 0)
24018 can_issue_more = issue_rate - 1;
24021 for (i = 0; i < issue_rate; i++)
24023 group_insns[i] = 0;
24030 emit_insn_before (nop, next_insn);
24031 if (can_issue_more == issue_rate - 1) /* new group begins */
24034 if (can_issue_more == 0)
24036 can_issue_more = issue_rate - 1;
24039 for (i = 0; i < issue_rate; i++)
24041 group_insns[i] = 0;
24047 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24050 /* Is next_insn going to start a new group? */
24053 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24054 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24055 || (can_issue_more < issue_rate &&
24056 insn_terminates_group_p (next_insn, previous_group)));
24057 if (*group_end && end)
24060 if (sched_verbose > 6)
24061 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24062 *group_count, can_issue_more);
24063 return can_issue_more;
24066 return can_issue_more;
24069 /* This function tries to synch the dispatch groups that the compiler "sees"
24070 with the dispatch groups that the processor dispatcher is expected to
24071 form in practice. It tries to achieve this synchronization by forcing the
24072 estimated processor grouping on the compiler (as opposed to the function
24073 'pad_goups' which tries to force the scheduler's grouping on the processor).
24075 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24076 examines the (estimated) dispatch groups that will be formed by the processor
24077 dispatcher. It marks these group boundaries to reflect the estimated
24078 processor grouping, overriding the grouping that the scheduler had marked.
24079 Depending on the value of the flag '-minsert-sched-nops' this function can
24080 force certain insns into separate groups or force a certain distance between
24081 them by inserting nops, for example, if there exists a "costly dependence"
24084 The function estimates the group boundaries that the processor will form as
24085 follows: It keeps track of how many vacant issue slots are available after
24086 each insn. A subsequent insn will start a new group if one of the following
24088 - no more vacant issue slots remain in the current dispatch group.
24089 - only the last issue slot, which is the branch slot, is vacant, but the next
24090 insn is not a branch.
24091 - only the last 2 or less issue slots, including the branch slot, are vacant,
24092 which means that a cracked insn (which occupies two issue slots) can't be
24093 issued in this group.
24094 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24095 start a new group. */
24098 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24100 rtx insn, next_insn;
24102 int can_issue_more;
24105 int group_count = 0;
24109 issue_rate = rs6000_issue_rate ();
24110 group_insns = XALLOCAVEC (rtx, issue_rate);
24111 for (i = 0; i < issue_rate; i++)
24113 group_insns[i] = 0;
24115 can_issue_more = issue_rate;
24117 insn = get_next_active_insn (prev_head_insn, tail);
24120 while (insn != NULL_RTX)
24122 slot = (issue_rate - can_issue_more);
24123 group_insns[slot] = insn;
24125 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24126 if (insn_terminates_group_p (insn, current_group))
24127 can_issue_more = 0;
24129 next_insn = get_next_active_insn (insn, tail);
24130 if (next_insn == NULL_RTX)
24131 return group_count + 1;
24133 /* Is next_insn going to start a new group? */
24135 = (can_issue_more == 0
24136 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24137 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24138 || (can_issue_more < issue_rate &&
24139 insn_terminates_group_p (next_insn, previous_group)));
24141 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24142 next_insn, &group_end, can_issue_more,
24148 can_issue_more = 0;
24149 for (i = 0; i < issue_rate; i++)
24151 group_insns[i] = 0;
24155 if (GET_MODE (next_insn) == TImode && can_issue_more)
24156 PUT_MODE (next_insn, VOIDmode);
24157 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24158 PUT_MODE (next_insn, TImode);
24161 if (can_issue_more == 0)
24162 can_issue_more = issue_rate;
24165 return group_count;
24168 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24169 dispatch group boundaries that the scheduler had marked. Pad with nops
24170 any dispatch groups which have vacant issue slots, in order to force the
24171 scheduler's grouping on the processor dispatcher. The function
24172 returns the number of dispatch groups found. */
24175 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24177 rtx insn, next_insn;
24180 int can_issue_more;
24182 int group_count = 0;
24184 /* Initialize issue_rate. */
24185 issue_rate = rs6000_issue_rate ();
24186 can_issue_more = issue_rate;
24188 insn = get_next_active_insn (prev_head_insn, tail);
24189 next_insn = get_next_active_insn (insn, tail);
24191 while (insn != NULL_RTX)
24194 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24196 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24198 if (next_insn == NULL_RTX)
24203 /* If the scheduler had marked group termination at this location
24204 (between insn and next_insn), and neither insn nor next_insn will
24205 force group termination, pad the group with nops to force group
24208 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24209 && !insn_terminates_group_p (insn, current_group)
24210 && !insn_terminates_group_p (next_insn, previous_group))
24212 if (!is_branch_slot_insn (next_insn))
24215 while (can_issue_more)
24218 emit_insn_before (nop, next_insn);
24223 can_issue_more = issue_rate;
24228 next_insn = get_next_active_insn (insn, tail);
24231 return group_count;
24234 /* We're beginning a new block. Initialize data structures as necessary. */
24237 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24238 int sched_verbose ATTRIBUTE_UNUSED,
24239 int max_ready ATTRIBUTE_UNUSED)
24241 last_scheduled_insn = NULL_RTX;
24242 load_store_pendulum = 0;
24245 /* The following function is called at the end of scheduling BB.
24246 After reload, it inserts nops at insn group bundling. */
24249 rs6000_sched_finish (FILE *dump, int sched_verbose)
24254 fprintf (dump, "=== Finishing schedule.\n");
24256 if (reload_completed && rs6000_sched_groups)
24258 /* Do not run sched_finish hook when selective scheduling enabled. */
24259 if (sel_sched_p ())
24262 if (rs6000_sched_insert_nops == sched_finish_none)
24265 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24266 n_groups = pad_groups (dump, sched_verbose,
24267 current_sched_info->prev_head,
24268 current_sched_info->next_tail);
24270 n_groups = redefine_groups (dump, sched_verbose,
24271 current_sched_info->prev_head,
24272 current_sched_info->next_tail);
24274 if (sched_verbose >= 6)
24276 fprintf (dump, "ngroups = %d\n", n_groups);
24277 print_rtl (dump, current_sched_info->prev_head);
24278 fprintf (dump, "Done finish_sched\n");
24283 struct _rs6000_sched_context
24285 short cached_can_issue_more;
24286 rtx last_scheduled_insn;
24287 int load_store_pendulum;
24290 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24291 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24293 /* Allocate store for new scheduling context. */
24295 rs6000_alloc_sched_context (void)
24297 return xmalloc (sizeof (rs6000_sched_context_def));
24300 /* If CLEAN_P is true then initializes _SC with clean data,
24301 and from the global context otherwise. */
24303 rs6000_init_sched_context (void *_sc, bool clean_p)
24305 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24309 sc->cached_can_issue_more = 0;
24310 sc->last_scheduled_insn = NULL_RTX;
24311 sc->load_store_pendulum = 0;
24315 sc->cached_can_issue_more = cached_can_issue_more;
24316 sc->last_scheduled_insn = last_scheduled_insn;
24317 sc->load_store_pendulum = load_store_pendulum;
24321 /* Sets the global scheduling context to the one pointed to by _SC. */
24323 rs6000_set_sched_context (void *_sc)
24325 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24327 gcc_assert (sc != NULL);
24329 cached_can_issue_more = sc->cached_can_issue_more;
24330 last_scheduled_insn = sc->last_scheduled_insn;
24331 load_store_pendulum = sc->load_store_pendulum;
24336 rs6000_free_sched_context (void *_sc)
24338 gcc_assert (_sc != NULL);
24344 /* Length in units of the trampoline for entering a nested function. */
24347 rs6000_trampoline_size (void)
24351 switch (DEFAULT_ABI)
24354 gcc_unreachable ();
24357 ret = (TARGET_32BIT) ? 12 : 24;
24362 ret = (TARGET_32BIT) ? 40 : 48;
24369 /* Emit RTL insns to initialize the variable parts of a trampoline.
24370 FNADDR is an RTX for the address of the function's pure code.
24371 CXT is an RTX for the static chain value for the function. */
24374 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24376 int regsize = (TARGET_32BIT) ? 4 : 8;
24377 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24378 rtx ctx_reg = force_reg (Pmode, cxt);
24379 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24381 switch (DEFAULT_ABI)
24384 gcc_unreachable ();
24386 /* Under AIX, just build the 3 word function descriptor */
24389 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24390 rtx fn_reg = gen_reg_rtx (Pmode);
24391 rtx toc_reg = gen_reg_rtx (Pmode);
24393 /* Macro to shorten the code expansions below. */
24394 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24396 m_tramp = replace_equiv_address (m_tramp, addr);
24398 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24399 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24400 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24401 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24402 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24408 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24411 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24412 LCT_NORMAL, VOIDmode, 4,
24414 GEN_INT (rs6000_trampoline_size ()), SImode,
24422 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24423 identifier as an argument, so the front end shouldn't look it up. */
24426 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24428 return is_attribute_p ("altivec", attr_id);
24431 /* Handle the "altivec" attribute. The attribute may have
24432 arguments as follows:
24434 __attribute__((altivec(vector__)))
24435 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24436 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24438 and may appear more than once (e.g., 'vector bool char') in a
24439 given declaration. */
24442 rs6000_handle_altivec_attribute (tree *node,
24443 tree name ATTRIBUTE_UNUSED,
24445 int flags ATTRIBUTE_UNUSED,
24446 bool *no_add_attrs)
24448 tree type = *node, result = NULL_TREE;
24449 enum machine_mode mode;
24452 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24453 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24454 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24457 while (POINTER_TYPE_P (type)
24458 || TREE_CODE (type) == FUNCTION_TYPE
24459 || TREE_CODE (type) == METHOD_TYPE
24460 || TREE_CODE (type) == ARRAY_TYPE)
24461 type = TREE_TYPE (type);
24463 mode = TYPE_MODE (type);
24465 /* Check for invalid AltiVec type qualifiers. */
24466 if (type == long_double_type_node)
24467 error ("use of %<long double%> in AltiVec types is invalid");
24468 else if (type == boolean_type_node)
24469 error ("use of boolean types in AltiVec types is invalid");
24470 else if (TREE_CODE (type) == COMPLEX_TYPE)
24471 error ("use of %<complex%> in AltiVec types is invalid");
24472 else if (DECIMAL_FLOAT_MODE_P (mode))
24473 error ("use of decimal floating point types in AltiVec types is invalid");
24474 else if (!TARGET_VSX)
24476 if (type == long_unsigned_type_node || type == long_integer_type_node)
24479 error ("use of %<long%> in AltiVec types is invalid for "
24480 "64-bit code without -mvsx");
24481 else if (rs6000_warn_altivec_long)
24482 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24485 else if (type == long_long_unsigned_type_node
24486 || type == long_long_integer_type_node)
24487 error ("use of %<long long%> in AltiVec types is invalid without "
24489 else if (type == double_type_node)
24490 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24493 switch (altivec_type)
24496 unsigned_p = TYPE_UNSIGNED (type);
24500 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24503 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24506 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24509 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24511 case SFmode: result = V4SF_type_node; break;
24512 case DFmode: result = V2DF_type_node; break;
24513 /* If the user says 'vector int bool', we may be handed the 'bool'
24514 attribute _before_ the 'vector' attribute, and so select the
24515 proper type in the 'b' case below. */
24516 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24517 case V2DImode: case V2DFmode:
24525 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24526 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24527 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24528 case QImode: case V16QImode: result = bool_V16QI_type_node;
24535 case V8HImode: result = pixel_V8HI_type_node;
24541 /* Propagate qualifiers attached to the element type
24542 onto the vector type. */
24543 if (result && result != type && TYPE_QUALS (type))
24544 result = build_qualified_type (result, TYPE_QUALS (type));
24546 *no_add_attrs = true; /* No need to hang on to the attribute. */
24549 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24554 /* AltiVec defines four built-in scalar types that serve as vector
24555 elements; we must teach the compiler how to mangle them. */
24557 static const char *
24558 rs6000_mangle_type (const_tree type)
24560 type = TYPE_MAIN_VARIANT (type);
24562 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24563 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24566 if (type == bool_char_type_node) return "U6__boolc";
24567 if (type == bool_short_type_node) return "U6__bools";
24568 if (type == pixel_type_node) return "u7__pixel";
24569 if (type == bool_int_type_node) return "U6__booli";
24570 if (type == bool_long_type_node) return "U6__booll";
24572 /* Mangle IBM extended float long double as `g' (__float128) on
24573 powerpc*-linux where long-double-64 previously was the default. */
24574 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24576 && TARGET_LONG_DOUBLE_128
24577 && !TARGET_IEEEQUAD)
24580 /* For all other types, use normal C++ mangling. */
24584 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24585 struct attribute_spec.handler. */
24588 rs6000_handle_longcall_attribute (tree *node, tree name,
24589 tree args ATTRIBUTE_UNUSED,
24590 int flags ATTRIBUTE_UNUSED,
24591 bool *no_add_attrs)
24593 if (TREE_CODE (*node) != FUNCTION_TYPE
24594 && TREE_CODE (*node) != FIELD_DECL
24595 && TREE_CODE (*node) != TYPE_DECL)
24597 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24599 *no_add_attrs = true;
24605 /* Set longcall attributes on all functions declared when
24606 rs6000_default_long_calls is true. */
24608 rs6000_set_default_type_attributes (tree type)
24610 if (rs6000_default_long_calls
24611 && (TREE_CODE (type) == FUNCTION_TYPE
24612 || TREE_CODE (type) == METHOD_TYPE))
24613 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24615 TYPE_ATTRIBUTES (type));
24618 darwin_set_default_type_attributes (type);
24622 /* Return a reference suitable for calling a function with the
24623 longcall attribute. */
24626 rs6000_longcall_ref (rtx call_ref)
24628 const char *call_name;
24631 if (GET_CODE (call_ref) != SYMBOL_REF)
24634 /* System V adds '.' to the internal name, so skip them. */
24635 call_name = XSTR (call_ref, 0);
24636 if (*call_name == '.')
24638 while (*call_name == '.')
24641 node = get_identifier (call_name);
24642 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24645 return force_reg (Pmode, call_ref);
24648 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24649 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24652 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24653 struct attribute_spec.handler. */
24655 rs6000_handle_struct_attribute (tree *node, tree name,
24656 tree args ATTRIBUTE_UNUSED,
24657 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24660 if (DECL_P (*node))
24662 if (TREE_CODE (*node) == TYPE_DECL)
24663 type = &TREE_TYPE (*node);
24668 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24669 || TREE_CODE (*type) == UNION_TYPE)))
24671 warning (OPT_Wattributes, "%qE attribute ignored", name);
24672 *no_add_attrs = true;
24675 else if ((is_attribute_p ("ms_struct", name)
24676 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24677 || ((is_attribute_p ("gcc_struct", name)
24678 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24680 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24682 *no_add_attrs = true;
24689 rs6000_ms_bitfield_layout_p (const_tree record_type)
24691 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24692 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24693 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24696 #ifdef USING_ELFOS_H
24698 /* A get_unnamed_section callback, used for switching to toc_section. */
24701 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24703 if (DEFAULT_ABI == ABI_AIX
24704 && TARGET_MINIMAL_TOC
24705 && !TARGET_RELOCATABLE)
24707 if (!toc_initialized)
24709 toc_initialized = 1;
24710 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24711 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24712 fprintf (asm_out_file, "\t.tc ");
24713 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24714 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24715 fprintf (asm_out_file, "\n");
24717 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24718 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24719 fprintf (asm_out_file, " = .+32768\n");
24722 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24724 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24725 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24728 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24729 if (!toc_initialized)
24731 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24732 fprintf (asm_out_file, " = .+32768\n");
24733 toc_initialized = 1;
24738 /* Implement TARGET_ASM_INIT_SECTIONS. */
24741 rs6000_elf_asm_init_sections (void)
24744 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24747 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24748 SDATA2_SECTION_ASM_OP);
24751 /* Implement TARGET_SELECT_RTX_SECTION. */
24754 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24755 unsigned HOST_WIDE_INT align)
24757 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24758 return toc_section;
24760 return default_elf_select_rtx_section (mode, x, align);
24763 /* For a SYMBOL_REF, set generic flags and then perform some
24764 target-specific processing.
24766 When the AIX ABI is requested on a non-AIX system, replace the
24767 function name with the real name (with a leading .) rather than the
24768 function descriptor name. This saves a lot of overriding code to
24769 read the prefixes. */
24772 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24774 default_encode_section_info (decl, rtl, first);
24777 && TREE_CODE (decl) == FUNCTION_DECL
24779 && DEFAULT_ABI == ABI_AIX)
24781 rtx sym_ref = XEXP (rtl, 0);
24782 size_t len = strlen (XSTR (sym_ref, 0));
24783 char *str = XALLOCAVEC (char, len + 2);
24785 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24786 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24791 compare_section_name (const char *section, const char *templ)
24795 len = strlen (templ);
24796 return (strncmp (section, templ, len) == 0
24797 && (section[len] == 0 || section[len] == '.'));
24801 rs6000_elf_in_small_data_p (const_tree decl)
24803 if (rs6000_sdata == SDATA_NONE)
24806 /* We want to merge strings, so we never consider them small data. */
24807 if (TREE_CODE (decl) == STRING_CST)
24810 /* Functions are never in the small data area. */
24811 if (TREE_CODE (decl) == FUNCTION_DECL)
24814 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24816 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24817 if (compare_section_name (section, ".sdata")
24818 || compare_section_name (section, ".sdata2")
24819 || compare_section_name (section, ".gnu.linkonce.s")
24820 || compare_section_name (section, ".sbss")
24821 || compare_section_name (section, ".sbss2")
24822 || compare_section_name (section, ".gnu.linkonce.sb")
24823 || strcmp (section, ".PPC.EMB.sdata0") == 0
24824 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24829 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24832 && size <= g_switch_value
24833 /* If it's not public, and we're not going to reference it there,
24834 there's no need to put it in the small data section. */
24835 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24842 #endif /* USING_ELFOS_H */
24844 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24847 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24849 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24852 /* Return a REG that occurs in ADDR with coefficient 1.
24853 ADDR can be effectively incremented by incrementing REG.
24855 r0 is special and we must not select it as an address
24856 register by this routine since our caller will try to
24857 increment the returned register via an "la" instruction. */
24860 find_addr_reg (rtx addr)
24862 while (GET_CODE (addr) == PLUS)
24864 if (GET_CODE (XEXP (addr, 0)) == REG
24865 && REGNO (XEXP (addr, 0)) != 0)
24866 addr = XEXP (addr, 0);
24867 else if (GET_CODE (XEXP (addr, 1)) == REG
24868 && REGNO (XEXP (addr, 1)) != 0)
24869 addr = XEXP (addr, 1);
24870 else if (CONSTANT_P (XEXP (addr, 0)))
24871 addr = XEXP (addr, 1);
24872 else if (CONSTANT_P (XEXP (addr, 1)))
24873 addr = XEXP (addr, 0);
24875 gcc_unreachable ();
24877 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
24882 rs6000_fatal_bad_address (rtx op)
24884 fatal_insn ("bad address", op);
24889 typedef struct branch_island_d {
24890 tree function_name;
24895 DEF_VEC_O(branch_island);
24896 DEF_VEC_ALLOC_O(branch_island,gc);
24898 static VEC(branch_island,gc) *branch_islands;
24900 /* Remember to generate a branch island for far calls to the given
24904 add_compiler_branch_island (tree label_name, tree function_name,
24907 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
24909 bi->function_name = function_name;
24910 bi->label_name = label_name;
24911 bi->line_number = line_number;
24914 /* Generate far-jump branch islands for everything recorded in
24915 branch_islands. Invoked immediately after the last instruction of
24916 the epilogue has been emitted; the branch islands must be appended
24917 to, and contiguous with, the function body. Mach-O stubs are
24918 generated in machopic_output_stub(). */
24921 macho_branch_islands (void)
24925 while (!VEC_empty (branch_island, branch_islands))
24927 branch_island *bi = VEC_last (branch_island, branch_islands);
24928 const char *label = IDENTIFIER_POINTER (bi->label_name);
24929 const char *name = IDENTIFIER_POINTER (bi->function_name);
24930 char name_buf[512];
24931 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
24932 if (name[0] == '*' || name[0] == '&')
24933 strcpy (name_buf, name+1);
24937 strcpy (name_buf+1, name);
24939 strcpy (tmp_buf, "\n");
24940 strcat (tmp_buf, label);
24941 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24942 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24943 dbxout_stabd (N_SLINE, bi->line_number);
24944 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24947 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
24948 strcat (tmp_buf, label);
24949 strcat (tmp_buf, "_pic\n");
24950 strcat (tmp_buf, label);
24951 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
24953 strcat (tmp_buf, "\taddis r11,r11,ha16(");
24954 strcat (tmp_buf, name_buf);
24955 strcat (tmp_buf, " - ");
24956 strcat (tmp_buf, label);
24957 strcat (tmp_buf, "_pic)\n");
24959 strcat (tmp_buf, "\tmtlr r0\n");
24961 strcat (tmp_buf, "\taddi r12,r11,lo16(");
24962 strcat (tmp_buf, name_buf);
24963 strcat (tmp_buf, " - ");
24964 strcat (tmp_buf, label);
24965 strcat (tmp_buf, "_pic)\n");
24967 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
24971 strcat (tmp_buf, ":\nlis r12,hi16(");
24972 strcat (tmp_buf, name_buf);
24973 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
24974 strcat (tmp_buf, name_buf);
24975 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
24977 output_asm_insn (tmp_buf, 0);
24978 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24979 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24980 dbxout_stabd (N_SLINE, bi->line_number);
24981 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24982 VEC_pop (branch_island, branch_islands);
24986 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
24987 already there or not. */
24990 no_previous_def (tree function_name)
24995 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
24996 if (function_name == bi->function_name)
25001 /* GET_PREV_LABEL gets the label name from the previous definition of
25005 get_prev_label (tree function_name)
25010 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25011 if (function_name == bi->function_name)
25012 return bi->label_name;
25016 /* INSN is either a function call or a millicode call. It may have an
25017 unconditional jump in its delay slot.
25019 CALL_DEST is the routine we are calling. */
25022 output_call (rtx insn, rtx *operands, int dest_operand_number,
25023 int cookie_operand_number)
25025 static char buf[256];
25026 if (darwin_emit_branch_islands
25027 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25028 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25031 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25033 if (no_previous_def (funname))
25035 rtx label_rtx = gen_label_rtx ();
25036 char *label_buf, temp_buf[256];
25037 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25038 CODE_LABEL_NUMBER (label_rtx));
25039 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25040 labelname = get_identifier (label_buf);
25041 add_compiler_branch_island (labelname, funname, insn_line (insn));
25044 labelname = get_prev_label (funname);
25046 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25047 instruction will reach 'foo', otherwise link as 'bl L42'".
25048 "L42" should be a 'branch island', that will do a far jump to
25049 'foo'. Branch islands are generated in
25050 macho_branch_islands(). */
25051 sprintf (buf, "jbsr %%z%d,%.246s",
25052 dest_operand_number, IDENTIFIER_POINTER (labelname));
25055 sprintf (buf, "bl %%z%d", dest_operand_number);
25059 /* Generate PIC and indirect symbol stubs. */
25062 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25064 unsigned int length;
25065 char *symbol_name, *lazy_ptr_name;
25066 char *local_label_0;
25067 static int label = 0;
25069 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25070 symb = (*targetm.strip_name_encoding) (symb);
25073 length = strlen (symb);
25074 symbol_name = XALLOCAVEC (char, length + 32);
25075 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25077 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25078 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25081 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25083 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25087 fprintf (file, "\t.align 5\n");
25089 fprintf (file, "%s:\n", stub);
25090 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25093 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25094 sprintf (local_label_0, "\"L%011d$spb\"", label);
25096 fprintf (file, "\tmflr r0\n");
25097 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25098 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25099 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25100 lazy_ptr_name, local_label_0);
25101 fprintf (file, "\tmtlr r0\n");
25102 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25103 (TARGET_64BIT ? "ldu" : "lwzu"),
25104 lazy_ptr_name, local_label_0);
25105 fprintf (file, "\tmtctr r12\n");
25106 fprintf (file, "\tbctr\n");
25110 fprintf (file, "\t.align 4\n");
25112 fprintf (file, "%s:\n", stub);
25113 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25115 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25116 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25117 (TARGET_64BIT ? "ldu" : "lwzu"),
25119 fprintf (file, "\tmtctr r12\n");
25120 fprintf (file, "\tbctr\n");
25123 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25124 fprintf (file, "%s:\n", lazy_ptr_name);
25125 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25126 fprintf (file, "%sdyld_stub_binding_helper\n",
25127 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25130 /* Legitimize PIC addresses. If the address is already
25131 position-independent, we return ORIG. Newly generated
25132 position-independent addresses go into a reg. This is REG if non
25133 zero, otherwise we allocate register(s) as necessary. */
25135 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25138 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25143 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25144 reg = gen_reg_rtx (Pmode);
25146 if (GET_CODE (orig) == CONST)
25150 if (GET_CODE (XEXP (orig, 0)) == PLUS
25151 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25154 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25156 /* Use a different reg for the intermediate value, as
25157 it will be marked UNCHANGING. */
25158 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25159 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25162 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25165 if (GET_CODE (offset) == CONST_INT)
25167 if (SMALL_INT (offset))
25168 return plus_constant (base, INTVAL (offset));
25169 else if (! reload_in_progress && ! reload_completed)
25170 offset = force_reg (Pmode, offset);
25173 rtx mem = force_const_mem (Pmode, orig);
25174 return machopic_legitimize_pic_address (mem, Pmode, reg);
25177 return gen_rtx_PLUS (Pmode, base, offset);
25180 /* Fall back on generic machopic code. */
25181 return machopic_legitimize_pic_address (orig, mode, reg);
25184 /* Output a .machine directive for the Darwin assembler, and call
25185 the generic start_file routine. */
25188 rs6000_darwin_file_start (void)
25190 static const struct
25196 { "ppc64", "ppc64", MASK_64BIT },
25197 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25198 { "power4", "ppc970", 0 },
25199 { "G5", "ppc970", 0 },
25200 { "7450", "ppc7450", 0 },
25201 { "7400", "ppc7400", MASK_ALTIVEC },
25202 { "G4", "ppc7400", 0 },
25203 { "750", "ppc750", 0 },
25204 { "740", "ppc750", 0 },
25205 { "G3", "ppc750", 0 },
25206 { "604e", "ppc604e", 0 },
25207 { "604", "ppc604", 0 },
25208 { "603e", "ppc603", 0 },
25209 { "603", "ppc603", 0 },
25210 { "601", "ppc601", 0 },
25211 { NULL, "ppc", 0 } };
25212 const char *cpu_id = "";
25215 rs6000_file_start ();
25216 darwin_file_start ();
25218 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25219 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25220 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25221 && rs6000_select[i].string[0] != '\0')
25222 cpu_id = rs6000_select[i].string;
25224 /* Look through the mapping array. Pick the first name that either
25225 matches the argument, has a bit set in IF_SET that is also set
25226 in the target flags, or has a NULL name. */
25229 while (mapping[i].arg != NULL
25230 && strcmp (mapping[i].arg, cpu_id) != 0
25231 && (mapping[i].if_set & target_flags) == 0)
25234 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25237 #endif /* TARGET_MACHO */
25241 rs6000_elf_reloc_rw_mask (void)
25245 else if (DEFAULT_ABI == ABI_AIX)
25251 /* Record an element in the table of global constructors. SYMBOL is
25252 a SYMBOL_REF of the function to be called; PRIORITY is a number
25253 between 0 and MAX_INIT_PRIORITY.
25255 This differs from default_named_section_asm_out_constructor in
25256 that we have special handling for -mrelocatable. */
25259 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25261 const char *section = ".ctors";
25264 if (priority != DEFAULT_INIT_PRIORITY)
25266 sprintf (buf, ".ctors.%.5u",
25267 /* Invert the numbering so the linker puts us in the proper
25268 order; constructors are run from right to left, and the
25269 linker sorts in increasing order. */
25270 MAX_INIT_PRIORITY - priority);
25274 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25275 assemble_align (POINTER_SIZE);
25277 if (TARGET_RELOCATABLE)
25279 fputs ("\t.long (", asm_out_file);
25280 output_addr_const (asm_out_file, symbol);
25281 fputs (")@fixup\n", asm_out_file);
25284 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25288 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25290 const char *section = ".dtors";
25293 if (priority != DEFAULT_INIT_PRIORITY)
25295 sprintf (buf, ".dtors.%.5u",
25296 /* Invert the numbering so the linker puts us in the proper
25297 order; constructors are run from right to left, and the
25298 linker sorts in increasing order. */
25299 MAX_INIT_PRIORITY - priority);
25303 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25304 assemble_align (POINTER_SIZE);
25306 if (TARGET_RELOCATABLE)
25308 fputs ("\t.long (", asm_out_file);
25309 output_addr_const (asm_out_file, symbol);
25310 fputs (")@fixup\n", asm_out_file);
25313 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25317 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25321 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25322 ASM_OUTPUT_LABEL (file, name);
25323 fputs (DOUBLE_INT_ASM_OP, file);
25324 rs6000_output_function_entry (file, name);
25325 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25328 fputs ("\t.size\t", file);
25329 assemble_name (file, name);
25330 fputs (",24\n\t.type\t.", file);
25331 assemble_name (file, name);
25332 fputs (",@function\n", file);
25333 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25335 fputs ("\t.globl\t.", file);
25336 assemble_name (file, name);
25341 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25342 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25343 rs6000_output_function_entry (file, name);
25344 fputs (":\n", file);
25348 if (TARGET_RELOCATABLE
25349 && !TARGET_SECURE_PLT
25350 && (get_pool_size () != 0 || crtl->profile)
25355 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25357 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25358 fprintf (file, "\t.long ");
25359 assemble_name (file, buf);
25361 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25362 assemble_name (file, buf);
25366 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25367 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25369 if (DEFAULT_ABI == ABI_AIX)
25371 const char *desc_name, *orig_name;
25373 orig_name = (*targetm.strip_name_encoding) (name);
25374 desc_name = orig_name;
25375 while (*desc_name == '.')
25378 if (TREE_PUBLIC (decl))
25379 fprintf (file, "\t.globl %s\n", desc_name);
25381 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25382 fprintf (file, "%s:\n", desc_name);
25383 fprintf (file, "\t.long %s\n", orig_name);
25384 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25385 if (DEFAULT_ABI == ABI_AIX)
25386 fputs ("\t.long 0\n", file);
25387 fprintf (file, "\t.previous\n");
25389 ASM_OUTPUT_LABEL (file, name);
25393 rs6000_elf_end_indicate_exec_stack (void)
25396 file_end_indicate_exec_stack ();
25402 rs6000_xcoff_asm_output_anchor (rtx symbol)
25406 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25407 SYMBOL_REF_BLOCK_OFFSET (symbol));
25408 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25412 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25414 fputs (GLOBAL_ASM_OP, stream);
25415 RS6000_OUTPUT_BASENAME (stream, name);
25416 putc ('\n', stream);
25419 /* A get_unnamed_decl callback, used for read-only sections. PTR
25420 points to the section string variable. */
25423 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25425 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25426 *(const char *const *) directive,
25427 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25430 /* Likewise for read-write sections. */
25433 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25435 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25436 *(const char *const *) directive,
25437 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25440 /* A get_unnamed_section callback, used for switching to toc_section. */
25443 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25445 if (TARGET_MINIMAL_TOC)
25447 /* toc_section is always selected at least once from
25448 rs6000_xcoff_file_start, so this is guaranteed to
25449 always be defined once and only once in each file. */
25450 if (!toc_initialized)
25452 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25453 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25454 toc_initialized = 1;
25456 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25457 (TARGET_32BIT ? "" : ",3"));
25460 fputs ("\t.toc\n", asm_out_file);
25463 /* Implement TARGET_ASM_INIT_SECTIONS. */
25466 rs6000_xcoff_asm_init_sections (void)
25468 read_only_data_section
25469 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25470 &xcoff_read_only_section_name);
25472 private_data_section
25473 = get_unnamed_section (SECTION_WRITE,
25474 rs6000_xcoff_output_readwrite_section_asm_op,
25475 &xcoff_private_data_section_name);
25477 read_only_private_data_section
25478 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25479 &xcoff_private_data_section_name);
25482 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25484 readonly_data_section = read_only_data_section;
25485 exception_section = data_section;
25489 rs6000_xcoff_reloc_rw_mask (void)
25495 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25496 tree decl ATTRIBUTE_UNUSED)
25499 static const char * const suffix[3] = { "PR", "RO", "RW" };
25501 if (flags & SECTION_CODE)
25503 else if (flags & SECTION_WRITE)
25508 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25509 (flags & SECTION_CODE) ? "." : "",
25510 name, suffix[smclass], flags & SECTION_ENTSIZE);
25514 rs6000_xcoff_select_section (tree decl, int reloc,
25515 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25517 if (decl_readonly_section (decl, reloc))
25519 if (TREE_PUBLIC (decl))
25520 return read_only_data_section;
25522 return read_only_private_data_section;
25526 if (TREE_PUBLIC (decl))
25527 return data_section;
25529 return private_data_section;
25534 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25538 /* Use select_section for private and uninitialized data. */
25539 if (!TREE_PUBLIC (decl)
25540 || DECL_COMMON (decl)
25541 || DECL_INITIAL (decl) == NULL_TREE
25542 || DECL_INITIAL (decl) == error_mark_node
25543 || (flag_zero_initialized_in_bss
25544 && initializer_zerop (DECL_INITIAL (decl))))
25547 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25548 name = (*targetm.strip_name_encoding) (name);
25549 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25552 /* Select section for constant in constant pool.
25554 On RS/6000, all constants are in the private read-only data area.
25555 However, if this is being placed in the TOC it must be output as a
25559 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25560 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25562 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25563 return toc_section;
25565 return read_only_private_data_section;
25568 /* Remove any trailing [DS] or the like from the symbol name. */
25570 static const char *
25571 rs6000_xcoff_strip_name_encoding (const char *name)
25576 len = strlen (name);
25577 if (name[len - 1] == ']')
25578 return ggc_alloc_string (name, len - 4);
25583 /* Section attributes. AIX is always PIC. */
25585 static unsigned int
25586 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25588 unsigned int align;
25589 unsigned int flags = default_section_type_flags (decl, name, reloc);
25591 /* Align to at least UNIT size. */
25592 if (flags & SECTION_CODE)
25593 align = MIN_UNITS_PER_WORD;
25595 /* Increase alignment of large objects if not already stricter. */
25596 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25597 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25598 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25600 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25603 /* Output at beginning of assembler file.
25605 Initialize the section names for the RS/6000 at this point.
25607 Specify filename, including full path, to assembler.
25609 We want to go into the TOC section so at least one .toc will be emitted.
25610 Also, in order to output proper .bs/.es pairs, we need at least one static
25611 [RW] section emitted.
25613 Finally, declare mcount when profiling to make the assembler happy. */
25616 rs6000_xcoff_file_start (void)
25618 rs6000_gen_section_name (&xcoff_bss_section_name,
25619 main_input_filename, ".bss_");
25620 rs6000_gen_section_name (&xcoff_private_data_section_name,
25621 main_input_filename, ".rw_");
25622 rs6000_gen_section_name (&xcoff_read_only_section_name,
25623 main_input_filename, ".ro_");
25625 fputs ("\t.file\t", asm_out_file);
25626 output_quoted_string (asm_out_file, main_input_filename);
25627 fputc ('\n', asm_out_file);
25628 if (write_symbols != NO_DEBUG)
25629 switch_to_section (private_data_section);
25630 switch_to_section (text_section);
25632 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25633 rs6000_file_start ();
25636 /* Output at end of assembler file.
25637 On the RS/6000, referencing data should automatically pull in text. */
25640 rs6000_xcoff_file_end (void)
25642 switch_to_section (text_section);
25643 fputs ("_section_.text:\n", asm_out_file);
25644 switch_to_section (data_section);
25645 fputs (TARGET_32BIT
25646 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25649 #endif /* TARGET_XCOFF */
25651 /* Compute a (partial) cost for rtx X. Return true if the complete
25652 cost has been computed, and false if subexpressions should be
25653 scanned. In either case, *TOTAL contains the cost result. */
25656 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25659 enum machine_mode mode = GET_MODE (x);
25663 /* On the RS/6000, if it is valid in the insn, it is free. */
25665 if (((outer_code == SET
25666 || outer_code == PLUS
25667 || outer_code == MINUS)
25668 && (satisfies_constraint_I (x)
25669 || satisfies_constraint_L (x)))
25670 || (outer_code == AND
25671 && (satisfies_constraint_K (x)
25673 ? satisfies_constraint_L (x)
25674 : satisfies_constraint_J (x))
25675 || mask_operand (x, mode)
25677 && mask64_operand (x, DImode))))
25678 || ((outer_code == IOR || outer_code == XOR)
25679 && (satisfies_constraint_K (x)
25681 ? satisfies_constraint_L (x)
25682 : satisfies_constraint_J (x))))
25683 || outer_code == ASHIFT
25684 || outer_code == ASHIFTRT
25685 || outer_code == LSHIFTRT
25686 || outer_code == ROTATE
25687 || outer_code == ROTATERT
25688 || outer_code == ZERO_EXTRACT
25689 || (outer_code == MULT
25690 && satisfies_constraint_I (x))
25691 || ((outer_code == DIV || outer_code == UDIV
25692 || outer_code == MOD || outer_code == UMOD)
25693 && exact_log2 (INTVAL (x)) >= 0)
25694 || (outer_code == COMPARE
25695 && (satisfies_constraint_I (x)
25696 || satisfies_constraint_K (x)))
25697 || (outer_code == EQ
25698 && (satisfies_constraint_I (x)
25699 || satisfies_constraint_K (x)
25701 ? satisfies_constraint_L (x)
25702 : satisfies_constraint_J (x))))
25703 || (outer_code == GTU
25704 && satisfies_constraint_I (x))
25705 || (outer_code == LTU
25706 && satisfies_constraint_P (x)))
25711 else if ((outer_code == PLUS
25712 && reg_or_add_cint_operand (x, VOIDmode))
25713 || (outer_code == MINUS
25714 && reg_or_sub_cint_operand (x, VOIDmode))
25715 || ((outer_code == SET
25716 || outer_code == IOR
25717 || outer_code == XOR)
25719 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25721 *total = COSTS_N_INSNS (1);
25727 if (mode == DImode && code == CONST_DOUBLE)
25729 if ((outer_code == IOR || outer_code == XOR)
25730 && CONST_DOUBLE_HIGH (x) == 0
25731 && (CONST_DOUBLE_LOW (x)
25732 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25737 else if ((outer_code == AND && and64_2_operand (x, DImode))
25738 || ((outer_code == SET
25739 || outer_code == IOR
25740 || outer_code == XOR)
25741 && CONST_DOUBLE_HIGH (x) == 0))
25743 *total = COSTS_N_INSNS (1);
25753 /* When optimizing for size, MEM should be slightly more expensive
25754 than generating address, e.g., (plus (reg) (const)).
25755 L1 cache latency is about two instructions. */
25756 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25764 if (mode == DFmode)
25766 if (GET_CODE (XEXP (x, 0)) == MULT)
25768 /* FNMA accounted in outer NEG. */
25769 if (outer_code == NEG)
25770 *total = rs6000_cost->dmul - rs6000_cost->fp;
25772 *total = rs6000_cost->dmul;
25775 *total = rs6000_cost->fp;
25777 else if (mode == SFmode)
25779 /* FNMA accounted in outer NEG. */
25780 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25783 *total = rs6000_cost->fp;
25786 *total = COSTS_N_INSNS (1);
25790 if (mode == DFmode)
25792 if (GET_CODE (XEXP (x, 0)) == MULT
25793 || GET_CODE (XEXP (x, 1)) == MULT)
25795 /* FNMA accounted in outer NEG. */
25796 if (outer_code == NEG)
25797 *total = rs6000_cost->dmul - rs6000_cost->fp;
25799 *total = rs6000_cost->dmul;
25802 *total = rs6000_cost->fp;
25804 else if (mode == SFmode)
25806 /* FNMA accounted in outer NEG. */
25807 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25810 *total = rs6000_cost->fp;
25813 *total = COSTS_N_INSNS (1);
25817 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25818 && satisfies_constraint_I (XEXP (x, 1)))
25820 if (INTVAL (XEXP (x, 1)) >= -256
25821 && INTVAL (XEXP (x, 1)) <= 255)
25822 *total = rs6000_cost->mulsi_const9;
25824 *total = rs6000_cost->mulsi_const;
25826 /* FMA accounted in outer PLUS/MINUS. */
25827 else if ((mode == DFmode || mode == SFmode)
25828 && (outer_code == PLUS || outer_code == MINUS))
25830 else if (mode == DFmode)
25831 *total = rs6000_cost->dmul;
25832 else if (mode == SFmode)
25833 *total = rs6000_cost->fp;
25834 else if (mode == DImode)
25835 *total = rs6000_cost->muldi;
25837 *total = rs6000_cost->mulsi;
25842 if (FLOAT_MODE_P (mode))
25844 *total = mode == DFmode ? rs6000_cost->ddiv
25845 : rs6000_cost->sdiv;
25852 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25853 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25855 if (code == DIV || code == MOD)
25857 *total = COSTS_N_INSNS (2);
25860 *total = COSTS_N_INSNS (1);
25864 if (GET_MODE (XEXP (x, 1)) == DImode)
25865 *total = rs6000_cost->divdi;
25867 *total = rs6000_cost->divsi;
25869 /* Add in shift and subtract for MOD. */
25870 if (code == MOD || code == UMOD)
25871 *total += COSTS_N_INSNS (2);
25876 *total = COSTS_N_INSNS (4);
25880 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
25884 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
25888 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
25900 *total = COSTS_N_INSNS (1);
25908 /* Handle mul_highpart. */
25909 if (outer_code == TRUNCATE
25910 && GET_CODE (XEXP (x, 0)) == MULT)
25912 if (mode == DImode)
25913 *total = rs6000_cost->muldi;
25915 *total = rs6000_cost->mulsi;
25918 else if (outer_code == AND)
25921 *total = COSTS_N_INSNS (1);
25926 if (GET_CODE (XEXP (x, 0)) == MEM)
25929 *total = COSTS_N_INSNS (1);
25935 if (!FLOAT_MODE_P (mode))
25937 *total = COSTS_N_INSNS (1);
25943 case UNSIGNED_FLOAT:
25946 case FLOAT_TRUNCATE:
25947 *total = rs6000_cost->fp;
25951 if (mode == DFmode)
25954 *total = rs6000_cost->fp;
25958 switch (XINT (x, 1))
25961 *total = rs6000_cost->fp;
25973 *total = COSTS_N_INSNS (1);
25976 else if (FLOAT_MODE_P (mode)
25977 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
25979 *total = rs6000_cost->fp;
25987 /* Carry bit requires mode == Pmode.
25988 NEG or PLUS already counted so only add one. */
25990 && (outer_code == NEG || outer_code == PLUS))
25992 *total = COSTS_N_INSNS (1);
25995 if (outer_code == SET)
25997 if (XEXP (x, 1) == const0_rtx)
25999 if (TARGET_ISEL && !TARGET_MFCRF)
26000 *total = COSTS_N_INSNS (8);
26002 *total = COSTS_N_INSNS (2);
26005 else if (mode == Pmode)
26007 *total = COSTS_N_INSNS (3);
26016 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26018 if (TARGET_ISEL && !TARGET_MFCRF)
26019 *total = COSTS_N_INSNS (8);
26021 *total = COSTS_N_INSNS (2);
26025 if (outer_code == COMPARE)
26039 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26042 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26045 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26048 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26049 "total = %d, speed = %s, x:\n",
26050 ret ? "complete" : "scan inner",
26051 GET_RTX_NAME (code),
26052 GET_RTX_NAME (outer_code),
26054 speed ? "true" : "false");
26061 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26064 rs6000_debug_address_cost (rtx x, bool speed)
26066 int ret = TARGET_ADDRESS_COST (x, speed);
26068 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26069 ret, speed ? "true" : "false");
26076 /* A C expression returning the cost of moving data from a register of class
26077 CLASS1 to one of CLASS2. */
26080 rs6000_register_move_cost (enum machine_mode mode,
26081 reg_class_t from, reg_class_t to)
26085 /* Moves from/to GENERAL_REGS. */
26086 if (reg_classes_intersect_p (to, GENERAL_REGS)
26087 || reg_classes_intersect_p (from, GENERAL_REGS))
26089 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26092 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26093 ret = (rs6000_memory_move_cost (mode, from, false)
26094 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26096 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26098 else if (from == CR_REGS)
26101 /* Power6 has slower LR/CTR moves so make them more expensive than
26102 memory in order to bias spills to memory .*/
26103 else if (rs6000_cpu == PROCESSOR_POWER6
26104 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26105 ret = 6 * hard_regno_nregs[0][mode];
26108 /* A move will cost one instruction per GPR moved. */
26109 ret = 2 * hard_regno_nregs[0][mode];
26112 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26113 else if (VECTOR_UNIT_VSX_P (mode)
26114 && reg_classes_intersect_p (to, VSX_REGS)
26115 && reg_classes_intersect_p (from, VSX_REGS))
26116 ret = 2 * hard_regno_nregs[32][mode];
26118 /* Moving between two similar registers is just one instruction. */
26119 else if (reg_classes_intersect_p (to, from))
26120 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26122 /* Everything else has to go through GENERAL_REGS. */
26124 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26125 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26127 if (TARGET_DEBUG_COST)
26129 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26130 ret, GET_MODE_NAME (mode), reg_class_names[from],
26131 reg_class_names[to]);
26136 /* A C expressions returning the cost of moving data of MODE from a register to
26140 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26141 bool in ATTRIBUTE_UNUSED)
26145 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26146 ret = 4 * hard_regno_nregs[0][mode];
26147 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26148 ret = 4 * hard_regno_nregs[32][mode];
26149 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26150 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26152 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26154 if (TARGET_DEBUG_COST)
26156 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26157 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26162 /* Returns a code for a target-specific builtin that implements
26163 reciprocal of the function, or NULL_TREE if not available. */
26166 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26167 bool sqrt ATTRIBUTE_UNUSED)
26169 if (optimize_insn_for_size_p ())
26175 case VSX_BUILTIN_XVSQRTDP:
26176 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26179 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26181 case VSX_BUILTIN_XVSQRTSP:
26182 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26185 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26194 case BUILT_IN_SQRT:
26195 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26198 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26200 case BUILT_IN_SQRTF:
26201 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26204 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26211 /* Load up a constant. If the mode is a vector mode, splat the value across
26212 all of the vector elements. */
26215 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26219 if (mode == SFmode || mode == DFmode)
26221 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26222 reg = force_reg (mode, d);
26224 else if (mode == V4SFmode)
26226 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26227 rtvec v = gen_rtvec (4, d, d, d, d);
26228 reg = gen_reg_rtx (mode);
26229 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26231 else if (mode == V2DFmode)
26233 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26234 rtvec v = gen_rtvec (2, d, d);
26235 reg = gen_reg_rtx (mode);
26236 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26239 gcc_unreachable ();
26244 /* Generate a FMADD instruction:
26245 dst = (m1 * m2) + a
26247 generating different RTL based on the fused multiply/add switch. */
26250 rs6000_emit_madd (rtx dst, rtx m1, rtx m2, rtx a)
26252 enum machine_mode mode = GET_MODE (dst);
26254 if (!TARGET_FUSED_MADD)
26256 /* For the simple ops, use the generator function, rather than assuming
26257 that the RTL is standard. */
26258 enum insn_code mcode = optab_handler (smul_optab, mode);
26259 enum insn_code acode = optab_handler (add_optab, mode);
26260 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26261 gen_2arg_fn_t gen_add = (gen_2arg_fn_t) GEN_FCN (acode);
26262 rtx mreg = gen_reg_rtx (mode);
26264 gcc_assert (mcode != CODE_FOR_nothing && acode != CODE_FOR_nothing);
26265 emit_insn (gen_mul (mreg, m1, m2));
26266 emit_insn (gen_add (dst, mreg, a));
26270 emit_insn (gen_rtx_SET (VOIDmode, dst,
26271 gen_rtx_PLUS (mode,
26272 gen_rtx_MULT (mode, m1, m2),
26276 /* Generate a FMSUB instruction:
26277 dst = (m1 * m2) - a
26279 generating different RTL based on the fused multiply/add switch. */
26282 rs6000_emit_msub (rtx dst, rtx m1, rtx m2, rtx a)
26284 enum machine_mode mode = GET_MODE (dst);
26286 if (!TARGET_FUSED_MADD
26287 || (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (V4SFmode)))
26289 /* For the simple ops, use the generator function, rather than assuming
26290 that the RTL is standard. */
26291 enum insn_code mcode = optab_handler (smul_optab, mode);
26292 enum insn_code scode = optab_handler (add_optab, mode);
26293 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26294 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
26295 rtx mreg = gen_reg_rtx (mode);
26297 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
26298 emit_insn (gen_mul (mreg, m1, m2));
26299 emit_insn (gen_sub (dst, mreg, a));
26303 emit_insn (gen_rtx_SET (VOIDmode, dst,
26304 gen_rtx_MINUS (mode,
26305 gen_rtx_MULT (mode, m1, m2),
26309 /* Generate a FNMSUB instruction:
26310 dst = - ((m1 * m2) - a)
26312 Which is equivalent to (except in the prescence of -0.0):
26313 dst = a - (m1 * m2)
26315 generating different RTL based on the fast-math and fused multiply/add
26319 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26321 enum machine_mode mode = GET_MODE (dst);
26323 if (!TARGET_FUSED_MADD)
26325 /* For the simple ops, use the generator function, rather than assuming
26326 that the RTL is standard. */
26327 enum insn_code mcode = optab_handler (smul_optab, mode);
26328 enum insn_code scode = optab_handler (sub_optab, mode);
26329 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26330 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
26331 rtx mreg = gen_reg_rtx (mode);
26333 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
26334 emit_insn (gen_mul (mreg, m1, m2));
26335 emit_insn (gen_sub (dst, a, mreg));
26340 rtx m = gen_rtx_MULT (mode, m1, m2);
26342 if (!HONOR_SIGNED_ZEROS (mode))
26343 emit_insn (gen_rtx_SET (VOIDmode, dst, gen_rtx_MINUS (mode, a, m)));
26346 emit_insn (gen_rtx_SET (VOIDmode, dst,
26348 gen_rtx_MINUS (mode, m, a))));
26352 /* Newton-Raphson approximation of floating point divide with just 2 passes
26353 (either single precision floating point, or newer machines with higher
26354 accuracy estimates). Support both scalar and vector divide. Assumes no
26355 trapping math and finite arguments. */
26358 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26360 enum machine_mode mode = GET_MODE (dst);
26361 rtx x0, e0, e1, y1, u0, v0;
26362 enum insn_code code = optab_handler (smul_optab, mode);
26363 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26364 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26366 gcc_assert (code != CODE_FOR_nothing);
26368 /* x0 = 1./d estimate */
26369 x0 = gen_reg_rtx (mode);
26370 emit_insn (gen_rtx_SET (VOIDmode, x0,
26371 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26374 e0 = gen_reg_rtx (mode);
26375 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26377 e1 = gen_reg_rtx (mode);
26378 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26380 y1 = gen_reg_rtx (mode);
26381 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26383 u0 = gen_reg_rtx (mode);
26384 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26386 v0 = gen_reg_rtx (mode);
26387 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26389 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26392 /* Newton-Raphson approximation of floating point divide that has a low
26393 precision estimate. Assumes no trapping math and finite arguments. */
26396 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26398 enum machine_mode mode = GET_MODE (dst);
26399 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26400 enum insn_code code = optab_handler (smul_optab, mode);
26401 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26403 gcc_assert (code != CODE_FOR_nothing);
26405 one = rs6000_load_constant_and_splat (mode, dconst1);
26407 /* x0 = 1./d estimate */
26408 x0 = gen_reg_rtx (mode);
26409 emit_insn (gen_rtx_SET (VOIDmode, x0,
26410 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26413 e0 = gen_reg_rtx (mode);
26414 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26416 y1 = gen_reg_rtx (mode);
26417 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26419 e1 = gen_reg_rtx (mode);
26420 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26422 y2 = gen_reg_rtx (mode);
26423 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26425 e2 = gen_reg_rtx (mode);
26426 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26428 y3 = gen_reg_rtx (mode);
26429 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26431 u0 = gen_reg_rtx (mode);
26432 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26434 v0 = gen_reg_rtx (mode);
26435 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26437 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26440 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26441 add a reg_note saying that this was a division. Support both scalar and
26442 vector divide. Assumes no trapping math and finite arguments. */
26445 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26447 enum machine_mode mode = GET_MODE (dst);
26449 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26450 rs6000_emit_swdiv_high_precision (dst, n, d);
26452 rs6000_emit_swdiv_low_precision (dst, n, d);
26455 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26458 /* Newton-Raphson approximation of single/double-precision floating point
26459 rsqrt. Assumes no trapping math and finite arguments. */
26462 rs6000_emit_swrsqrt (rtx dst, rtx src)
26464 enum machine_mode mode = GET_MODE (src);
26465 rtx x0 = gen_reg_rtx (mode);
26466 rtx y = gen_reg_rtx (mode);
26467 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26468 REAL_VALUE_TYPE dconst3_2;
26471 enum insn_code code = optab_handler (smul_optab, mode);
26472 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26474 gcc_assert (code != CODE_FOR_nothing);
26476 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26477 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26478 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26480 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26482 /* x0 = rsqrt estimate */
26483 emit_insn (gen_rtx_SET (VOIDmode, x0,
26484 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26487 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26488 rs6000_emit_msub (y, src, halfthree, src);
26490 for (i = 0; i < passes; i++)
26492 rtx x1 = gen_reg_rtx (mode);
26493 rtx u = gen_reg_rtx (mode);
26494 rtx v = gen_reg_rtx (mode);
26496 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26497 emit_insn (gen_mul (u, x0, x0));
26498 rs6000_emit_nmsub (v, y, u, halfthree);
26499 emit_insn (gen_mul (x1, x0, v));
26503 emit_move_insn (dst, x0);
26507 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26508 (Power7) targets. DST is the target, and SRC is the argument operand. */
26511 rs6000_emit_popcount (rtx dst, rtx src)
26513 enum machine_mode mode = GET_MODE (dst);
26516 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26517 if (TARGET_POPCNTD)
26519 if (mode == SImode)
26520 emit_insn (gen_popcntdsi2 (dst, src));
26522 emit_insn (gen_popcntddi2 (dst, src));
26526 tmp1 = gen_reg_rtx (mode);
26528 if (mode == SImode)
26530 emit_insn (gen_popcntbsi2 (tmp1, src));
26531 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26533 tmp2 = force_reg (SImode, tmp2);
26534 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26538 emit_insn (gen_popcntbdi2 (tmp1, src));
26539 tmp2 = expand_mult (DImode, tmp1,
26540 GEN_INT ((HOST_WIDE_INT)
26541 0x01010101 << 32 | 0x01010101),
26543 tmp2 = force_reg (DImode, tmp2);
26544 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26549 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26550 target, and SRC is the argument operand. */
26553 rs6000_emit_parity (rtx dst, rtx src)
26555 enum machine_mode mode = GET_MODE (dst);
26558 tmp = gen_reg_rtx (mode);
26560 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26563 if (mode == SImode)
26565 emit_insn (gen_popcntbsi2 (tmp, src));
26566 emit_insn (gen_paritysi2_cmpb (dst, tmp));
26570 emit_insn (gen_popcntbdi2 (tmp, src));
26571 emit_insn (gen_paritydi2_cmpb (dst, tmp));
26576 if (mode == SImode)
26578 /* Is mult+shift >= shift+xor+shift+xor? */
26579 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26581 rtx tmp1, tmp2, tmp3, tmp4;
26583 tmp1 = gen_reg_rtx (SImode);
26584 emit_insn (gen_popcntbsi2 (tmp1, src));
26586 tmp2 = gen_reg_rtx (SImode);
26587 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26588 tmp3 = gen_reg_rtx (SImode);
26589 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26591 tmp4 = gen_reg_rtx (SImode);
26592 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26593 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26596 rs6000_emit_popcount (tmp, src);
26597 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26601 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26602 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26604 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26606 tmp1 = gen_reg_rtx (DImode);
26607 emit_insn (gen_popcntbdi2 (tmp1, src));
26609 tmp2 = gen_reg_rtx (DImode);
26610 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26611 tmp3 = gen_reg_rtx (DImode);
26612 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26614 tmp4 = gen_reg_rtx (DImode);
26615 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26616 tmp5 = gen_reg_rtx (DImode);
26617 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26619 tmp6 = gen_reg_rtx (DImode);
26620 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26621 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26624 rs6000_emit_popcount (tmp, src);
26625 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26629 /* Return an RTX representing where to find the function value of a
26630 function returning MODE. */
26632 rs6000_complex_function_value (enum machine_mode mode)
26634 unsigned int regno;
26636 enum machine_mode inner = GET_MODE_INNER (mode);
26637 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26639 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26640 regno = FP_ARG_RETURN;
26643 regno = GP_ARG_RETURN;
26645 /* 32-bit is OK since it'll go in r3/r4. */
26646 if (TARGET_32BIT && inner_bytes >= 4)
26647 return gen_rtx_REG (mode, regno);
26650 if (inner_bytes >= 8)
26651 return gen_rtx_REG (mode, regno);
26653 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26655 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26656 GEN_INT (inner_bytes));
26657 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26660 /* Target hook for TARGET_FUNCTION_VALUE.
26662 On the SPE, both FPs and vectors are returned in r3.
26664 On RS/6000 an integer value is in r3 and a floating-point value is in
26665 fp1, unless -msoft-float. */
26668 rs6000_function_value (const_tree valtype,
26669 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26670 bool outgoing ATTRIBUTE_UNUSED)
26672 enum machine_mode mode;
26673 unsigned int regno;
26675 /* Special handling for structs in darwin64. */
26677 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
26679 CUMULATIVE_ARGS valcum;
26683 valcum.fregno = FP_ARG_MIN_REG;
26684 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26685 /* Do a trial code generation as if this were going to be passed as
26686 an argument; if any part goes in memory, we return NULL. */
26687 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, true);
26690 /* Otherwise fall through to standard ABI rules. */
26693 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26695 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26696 return gen_rtx_PARALLEL (DImode,
26698 gen_rtx_EXPR_LIST (VOIDmode,
26699 gen_rtx_REG (SImode, GP_ARG_RETURN),
26701 gen_rtx_EXPR_LIST (VOIDmode,
26702 gen_rtx_REG (SImode,
26703 GP_ARG_RETURN + 1),
26706 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26708 return gen_rtx_PARALLEL (DCmode,
26710 gen_rtx_EXPR_LIST (VOIDmode,
26711 gen_rtx_REG (SImode, GP_ARG_RETURN),
26713 gen_rtx_EXPR_LIST (VOIDmode,
26714 gen_rtx_REG (SImode,
26715 GP_ARG_RETURN + 1),
26717 gen_rtx_EXPR_LIST (VOIDmode,
26718 gen_rtx_REG (SImode,
26719 GP_ARG_RETURN + 2),
26721 gen_rtx_EXPR_LIST (VOIDmode,
26722 gen_rtx_REG (SImode,
26723 GP_ARG_RETURN + 3),
26727 mode = TYPE_MODE (valtype);
26728 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26729 || POINTER_TYPE_P (valtype))
26730 mode = TARGET_32BIT ? SImode : DImode;
26732 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26733 /* _Decimal128 must use an even/odd register pair. */
26734 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26735 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26736 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26737 regno = FP_ARG_RETURN;
26738 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26739 && targetm.calls.split_complex_arg)
26740 return rs6000_complex_function_value (mode);
26741 else if (TREE_CODE (valtype) == VECTOR_TYPE
26742 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26743 && ALTIVEC_VECTOR_MODE (mode))
26744 regno = ALTIVEC_ARG_RETURN;
26745 else if (TREE_CODE (valtype) == VECTOR_TYPE
26746 && TARGET_VSX && TARGET_ALTIVEC_ABI
26747 && VSX_VECTOR_MODE (mode))
26748 regno = ALTIVEC_ARG_RETURN;
26749 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26750 && (mode == DFmode || mode == DCmode
26751 || mode == TFmode || mode == TCmode))
26752 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26754 regno = GP_ARG_RETURN;
26756 return gen_rtx_REG (mode, regno);
26759 /* Define how to find the value returned by a library function
26760 assuming the value has mode MODE. */
26762 rs6000_libcall_value (enum machine_mode mode)
26764 unsigned int regno;
26766 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26768 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26769 return gen_rtx_PARALLEL (DImode,
26771 gen_rtx_EXPR_LIST (VOIDmode,
26772 gen_rtx_REG (SImode, GP_ARG_RETURN),
26774 gen_rtx_EXPR_LIST (VOIDmode,
26775 gen_rtx_REG (SImode,
26776 GP_ARG_RETURN + 1),
26780 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26781 /* _Decimal128 must use an even/odd register pair. */
26782 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26783 else if (SCALAR_FLOAT_MODE_P (mode)
26784 && TARGET_HARD_FLOAT && TARGET_FPRS
26785 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26786 regno = FP_ARG_RETURN;
26787 else if (ALTIVEC_VECTOR_MODE (mode)
26788 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26789 regno = ALTIVEC_ARG_RETURN;
26790 else if (VSX_VECTOR_MODE (mode)
26791 && TARGET_VSX && TARGET_ALTIVEC_ABI)
26792 regno = ALTIVEC_ARG_RETURN;
26793 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26794 return rs6000_complex_function_value (mode);
26795 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26796 && (mode == DFmode || mode == DCmode
26797 || mode == TFmode || mode == TCmode))
26798 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26800 regno = GP_ARG_RETURN;
26802 return gen_rtx_REG (mode, regno);
26806 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26807 Frame pointer elimination is automatically handled.
26809 For the RS/6000, if frame pointer elimination is being done, we would like
26810 to convert ap into fp, not sp.
26812 We need r30 if -mminimal-toc was specified, and there are constant pool
26816 rs6000_can_eliminate (const int from, const int to)
26818 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26819 ? ! frame_pointer_needed
26820 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26821 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26825 /* Define the offset between two registers, FROM to be eliminated and its
26826 replacement TO, at the start of a routine. */
26828 rs6000_initial_elimination_offset (int from, int to)
26830 rs6000_stack_t *info = rs6000_stack_info ();
26831 HOST_WIDE_INT offset;
26833 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26834 offset = info->push_p ? 0 : -info->total_size;
26835 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26837 offset = info->push_p ? 0 : -info->total_size;
26838 if (FRAME_GROWS_DOWNWARD)
26839 offset += info->fixed_size + info->vars_size + info->parm_size;
26841 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26842 offset = FRAME_GROWS_DOWNWARD
26843 ? info->fixed_size + info->vars_size + info->parm_size
26845 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26846 offset = info->total_size;
26847 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26848 offset = info->push_p ? info->total_size : 0;
26849 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26852 gcc_unreachable ();
26858 rs6000_dwarf_register_span (rtx reg)
26862 unsigned regno = REGNO (reg);
26863 enum machine_mode mode = GET_MODE (reg);
26867 && (SPE_VECTOR_MODE (GET_MODE (reg))
26868 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26869 && mode != SFmode && mode != SDmode && mode != SCmode)))
26874 regno = REGNO (reg);
26876 /* The duality of the SPE register size wreaks all kinds of havoc.
26877 This is a way of distinguishing r0 in 32-bits from r0 in
26879 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26880 gcc_assert (words <= 4);
26881 for (i = 0; i < words; i++, regno++)
26883 if (BYTES_BIG_ENDIAN)
26885 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26886 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
26890 parts[2 * i] = gen_rtx_REG (SImode, regno);
26891 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
26895 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
26898 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26901 rs6000_init_dwarf_reg_sizes_extra (tree address)
26906 enum machine_mode mode = TYPE_MODE (char_type_node);
26907 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
26908 rtx mem = gen_rtx_MEM (BLKmode, addr);
26909 rtx value = gen_int_mode (4, mode);
26911 for (i = 1201; i < 1232; i++)
26913 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
26914 HOST_WIDE_INT offset
26915 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
26917 emit_move_insn (adjust_address (mem, mode, offset), value);
26922 /* Map internal gcc register numbers to DWARF2 register numbers. */
26925 rs6000_dbx_register_number (unsigned int regno)
26927 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
26929 if (regno == MQ_REGNO)
26931 if (regno == LR_REGNO)
26933 if (regno == CTR_REGNO)
26935 if (CR_REGNO_P (regno))
26936 return regno - CR0_REGNO + 86;
26937 if (regno == CA_REGNO)
26938 return 101; /* XER */
26939 if (ALTIVEC_REGNO_P (regno))
26940 return regno - FIRST_ALTIVEC_REGNO + 1124;
26941 if (regno == VRSAVE_REGNO)
26943 if (regno == VSCR_REGNO)
26945 if (regno == SPE_ACC_REGNO)
26947 if (regno == SPEFSCR_REGNO)
26949 /* SPE high reg number. We get these values of regno from
26950 rs6000_dwarf_register_span. */
26951 gcc_assert (regno >= 1200 && regno < 1232);
26955 /* target hook eh_return_filter_mode */
26956 static enum machine_mode
26957 rs6000_eh_return_filter_mode (void)
26959 return TARGET_32BIT ? SImode : word_mode;
26962 /* Target hook for scalar_mode_supported_p. */
26964 rs6000_scalar_mode_supported_p (enum machine_mode mode)
26966 if (DECIMAL_FLOAT_MODE_P (mode))
26967 return default_decimal_float_supported_p ();
26969 return default_scalar_mode_supported_p (mode);
26972 /* Target hook for vector_mode_supported_p. */
26974 rs6000_vector_mode_supported_p (enum machine_mode mode)
26977 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
26980 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
26983 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
26990 /* Target hook for invalid_arg_for_unprototyped_fn. */
26991 static const char *
26992 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
26994 return (!rs6000_darwin64_abi
26996 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
26997 && (funcdecl == NULL_TREE
26998 || (TREE_CODE (funcdecl) == FUNCTION_DECL
26999 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27000 ? N_("AltiVec argument passed to unprototyped function")
27004 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27005 setup by using __stack_chk_fail_local hidden function instead of
27006 calling __stack_chk_fail directly. Otherwise it is better to call
27007 __stack_chk_fail directly. */
27010 rs6000_stack_protect_fail (void)
27012 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27013 ? default_hidden_stack_protect_fail ()
27014 : default_external_stack_protect_fail ();
27018 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27019 int num_operands ATTRIBUTE_UNUSED)
27021 if (rs6000_warn_cell_microcode)
27024 int insn_code_number = recog_memoized (insn);
27025 location_t location = locator_location (INSN_LOCATOR (insn));
27027 /* Punt on insns we cannot recognize. */
27028 if (insn_code_number < 0)
27031 temp = get_insn_template (insn_code_number, insn);
27033 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27034 warning_at (location, OPT_mwarn_cell_microcode,
27035 "emitting microcode insn %s\t[%s] #%d",
27036 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27037 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27038 warning_at (location, OPT_mwarn_cell_microcode,
27039 "emitting conditional microcode insn %s\t[%s] #%d",
27040 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27045 /* Allocate a stack temp and fixup the address so it meets the particular
27046 memory requirements (either offetable or REG+REG addressing). */
27049 rs6000_allocate_stack_temp (enum machine_mode mode,
27050 bool offsettable_p,
27053 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
27054 rtx addr = XEXP (stack, 0);
27055 int strict_p = (reload_in_progress || reload_completed);
27057 if (!legitimate_indirect_address_p (addr, strict_p))
27060 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
27061 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27063 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
27064 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27070 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27071 to such a form to deal with memory reference instructions like STFIWX that
27072 only take reg+reg addressing. */
27075 rs6000_address_for_fpconvert (rtx x)
27077 int strict_p = (reload_in_progress || reload_completed);
27080 gcc_assert (MEM_P (x));
27081 addr = XEXP (x, 0);
27082 if (! legitimate_indirect_address_p (addr, strict_p)
27083 && ! legitimate_indexed_address_p (addr, strict_p))
27084 x = replace_equiv_address (x, copy_addr_to_reg (addr));
27089 /* Expand 32-bit int -> floating point conversions. Return true if
27093 rs6000_expand_convert_si_to_sfdf (rtx dest, rtx src, bool unsigned_p)
27095 enum machine_mode dmode = GET_MODE (dest);
27096 rtx (*func_si) (rtx, rtx, rtx, rtx);
27097 rtx (*func_si_mem) (rtx, rtx);
27098 rtx (*func_di) (rtx, rtx);
27101 gcc_assert (GET_MODE (src) == SImode);
27103 if (dmode == SFmode)
27107 gcc_assert (TARGET_FCFIDUS && TARGET_LFIWZX);
27108 func_si = gen_floatunssisf2_lfiwzx;
27109 func_si_mem = gen_floatunssisf2_lfiwzx_mem;
27110 func_di = gen_floatunsdisf2;
27114 gcc_assert (TARGET_FCFIDS && TARGET_LFIWAX);
27115 func_si = gen_floatsisf2_lfiwax;
27116 func_si_mem = gen_floatsisf2_lfiwax_mem;
27117 func_di = gen_floatdisf2;
27121 else if (dmode == DFmode)
27125 gcc_assert (TARGET_FCFIDU && TARGET_LFIWZX);
27126 func_si = gen_floatunssidf2_lfiwzx;
27127 func_si_mem = gen_floatunssidf2_lfiwzx_mem;
27128 func_di = gen_floatunsdidf2;
27132 gcc_assert (TARGET_FCFID && TARGET_LFIWAX);
27133 func_si = gen_floatsidf2_lfiwax;
27134 func_si_mem = gen_floatsidf2_lfiwax_mem;
27135 func_di = gen_floatdidf2;
27140 gcc_unreachable ();
27144 src = rs6000_address_for_fpconvert (src);
27145 emit_insn (func_si_mem (dest, src));
27147 else if (!TARGET_MFPGPR)
27149 reg = gen_reg_rtx (DImode);
27150 stack = rs6000_allocate_stack_temp (SImode, false, true);
27151 emit_insn (func_si (dest, src, stack, reg));
27156 src = force_reg (SImode, src);
27157 reg = convert_to_mode (DImode, src, unsigned_p);
27158 emit_insn (func_di (dest, reg));
27162 #include "gt-rs6000.h"